# Safe and EIP-7702 Source: https://docs.safefoundation.org/features/eip-7702/7702-safe How to use EIP-7702 with Safe Smart Accounts EIP-7702 doesn't specify how to initialise the storage of the account but only gives a way to set the code of the account. This means that the account will be created with an empty storage, and the user will have to set the storage manually. Existing Safe contracts cannot be used with EIP-7702, because of following reasons: * Delegating to Safe Singleton or the Safe Proxy contract will expose the EOA account to the risk of front-running during setup. * In its current implementation, the Safe Singleton contract doesn't let itself to become an owner meaning that after delegating to the Safe Singleton, the EOA account cannot sign Safe transactions and will need to keep another private key to do so. ## Possible approaches ### Modified Safe Proxy This approach uses the [SafeEIP7702Proxy](https://github.com/5afe/safe-eip7702/blob/main/safe-eip7702-contracts/contracts/SafeEIP7702Proxy.sol), a proxy contract derived from the [Safe Proxy](https://github.com/5afe/safe-eip7702/blob/main/safe-eip7702-contracts/contracts/SafeEIP7702Proxy.sol) with the following changes: * The constructor of the `SafeEIP7702Proxy` contract has the additional `setupDataHash` parameter, which is the hash of the `setup` function call data. Thus, the address of the proxy contract also depends on the `setupDataHash` and not just the Safe Singleton contract address. The proxy contract uses this hash to verify that the `setup` function parameter values are unchanged during the initialization of storage. * The proxy implements the `setup` function, which calls the `setup` function of the Safe Singleton contract and has additional logic: * Set the storage slot 0, that is, the address of the Safe Singleton in the EOA storage. * Verify that the `setupDataHash` equals the hash of the `setup` function call data. This approach has a gas overhead as a new proxy contract has to be deployed for each EOA account, as the `setupDataHash` may be unique for each user. However, using this approach, users can use Safe\{Wallet} with minor modifications and import the EOA account as a Safe account. diagram-7702-approach-1 Follow the instructions here to use this approach to set code in EOA: [https://github.com/5afe/safe-eip7702/tree/main/safe-eip7702-contracts#execute-scripts](https://github.com/5afe/safe-eip7702/tree/main/safe-eip7702-contracts#execute-scripts) ### Modified Safe Singleton This approach uses the [SafeEIP7702](https://github.com/safe-fndn/safe-smart-account/blob/feature/eip-7702/contracts/experimental/SafeEIP7702.sol) contract, a derived version of Safe Singleton that overrides the `setup` function and reverts when called. Instead, the contract's new `setupEIP7702` function has a `signature` parameter. The default owner will be set to the address of the EOA account that delegates to this Safe Singleton contract with a threshold of 1. Because this approach doesn't use a proxy contract, storage slot 0 remains unused. The Safe Transaction Service and other services that depend on the value at storage slot 0 will not work with this approach. diagram-7702-approach-2 ### SafeLite [SafeLite](https://github.com/5afe/safe-eip7702/blob/main/safe-eip7702-contracts/contracts/experimental/SafeLite.sol) is a lite version of Safe that is compatible with EIP-7702. The contract does not have a proxy and doesn't need initialization. SafeLite supports ERC-4337 and can use features such as sponsored transactions and batch transactions. SafeLite also supports ERC-1271 for contract-based signatures. SafeLite is not compatible with Safe\{Wallet} as it doesn't use the same storage layout as the existing Safe contracts. It doesn't have the features of the existing Safe contracts such as Modules, Fallback Handler, and Guards. diagram-7702-approach-3 All the above approaches are experimental and the contracts are not yet audited. Use them at your own risk. ## Other resources * [SafeEIP7702Proxy GitHub repository](https://github.com/5afe/safe-eip7702/blob/main/README.md#demo-using-ui) * [Safe + EIP-7702 tutorial](https://www.youtube.com/watch?v=dx4mk6tKHCo) * [Safe + EIP-7702 Slides](https://docs.google.com/presentation/d/1blYoVXLdPUNXhfSlck5bgbs8-h9StI9om7wsxj1SxVM) # Overview Source: https://docs.safefoundation.org/features/eip-7702/overview What is EIP-7702 and why do we need it? ## What is ERC-7702? EIP-7702 is a step towards account abstraction, enabling EOAs (Externally Owned Accounts) to have both code and storage. This enhancement allows EOAs to function as smart contract accounts, unlocking new features such as: * **Transaction batching**. * **Gas sponsorship**. * **Delegated actions**: Granting other addresses limited access to act on behalf of the EOA. ## Signing Process In its current implementation, EIP-7702 requires the EOA to sign a special hash calculated using the following parameters: * `chain_id`: The identifier of the blockchain network. * `address`: The account address to which calls will be delegated. * `nonce`: Current nonce of the account. Once the EOA signs the hash, an authorization list is sent to the EVM node through a new transaction type, the set code transaction, introduced in EIP-7702. The execution client then performs the following checks: * Verifies the signature. * Checks the account's nonce. * Confirms the chain ID (`0` or the current chain ID). If all checks pass, the execution client sets the EOA's code in the format `(0xef0100 ++ address)`. EIP-7702 is available on devnets and testnets such as Pectra Devnet, Ithaca and will be enabled on Ethereum Mainnet after the Pectra upgrade. An important consideration that applies for EOAs that have code set is that the private key can still be used to sign transactions and even change delegations. Hence, it is important to keep the private key secure even after the authorization has been signed. This signing method is not compatible with the EIP-712 or EIP-191 standards. Wallet providers must add support for this specific signing method. ## Further reading * [EIP-7702 on Ethereum EIPs](https://eips.ethereum.org/EIPS/eip-7702) # Safe and ERC-4337 Source: https://docs.safefoundation.org/features/erc-4337/4337-safe How to use ERC-4337 with Safe Smart Accounts Safe has adopted a modular and flexible approach to integrating the ERC-4337, allowing users to turn their Safe account into an ERC-4337 smart account. Safe ERC-4337 compatibility is provided via [Safe Modules](/more/glossary#safe-module) and the Fallback Handler. This means the functionality is not implemented directly in the Safe Smart Account, but in the [Safe4337Module](https://github.com/safe-fndn/safe-modules/blob/main/modules/4337/contracts/Safe4337Module.sol) contract, which can be enabled in any Safe account at the Safe deployment time or afterward. ## Safe4337Module This module is an extension to the Safe Smart Account that acts both as a Fallback Handler, meaning that the Safe Proxy contract will fallback to this contract when its functions are called in the proxy, and a Safe Module, having the right to execute Safe transactions once it's enabled in a Safe account. It implements the ERC-4337 interface, including the functions to validate and execute the user operation, and it's limited to the `EntryPoint` address. This module must only be used with Safe [v1.4.1](https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1/CHANGELOG.md) or newer. ### UserOperation validation The Safe Proxy contract receives a call to the `validateUserOp` function from the `EntryPoint` and forwards it to the `Safe4337Module`. The module validates the `UserOperation` object by checking that the Safe owners signed the `UserOperation` hash and returns the result. It also executes a module transaction to pay the fees back. diagram validate UserOp ### UserOperation execution After successful validation, the `EntryPoint` calls the `executeUserOp` function, forwarding it again to the module, which executes a module transaction with the target and data specified in the `UserOperation` object. diagram execute UserOp # Overview Source: https://docs.safefoundation.org/features/erc-4337/overview What is ERC-4337 and why do we need it? ## What is ERC-4337? [ERC-4337](/more/glossary#erc-4337) addresses the challenges associated with account abstraction without requiring changes to the consensus-layer protocol. It serves as a transaction relayer for smart accounts like Safe. It does so by introducing a pseudo-transaction object called a `UserOperation`, which sends a transaction on behalf of the user. Nodes in Ethereum can act as a Bundler, which picks up multiple user operations and packs them into a single transaction known as a bundle transaction. The bundle transactions are then sent to a global smart contract on Ethereum (of which there is only one) called the `EntryPoint`. ```mermaid theme={null} --- title: Simplified ERC-4337 flow --- flowchart TD A(Dapp Users kick off a ERC-4337 flow through a dapp) -->|UserOperation| B(Bundler Decentralized network of relayers to propagate UserOperations) B -->|Bundle Transactions| C(EntryPoint Contract Contract to ensure onchain authentication) C -->|Invoke UserOperation| D(Smart Account Smart contract validates and executes the individual UserOperations) style A stroke:#12ff80 style B stroke:#12ff80 style C stroke:#12ff80 style D stroke:#12ff80 ``` ERC-4337 enhances usability by introducing paymasters. This decentralized mechanism allows users to pay gas fees using ERC-20 tokens (like USDC) instead of native tokens like ETH or to seek a third party to cover their gas fees entirely. ERC-4337 is currently under development and still needs to be finalized, so developers should pay attention to new changes that may occur. ## Why ERC-4337? ERC-4337 provides a bunch of benefits along with all the inherent advantages of utilizing smart accounts: Users can decide how to pay the gas fees. Use native tokens like ETH, ERC-20 tokens, or even sponsored transactions. It enables the use of different authentication mechanisms, such as multi-signature, passkeys, and future quantum-proof cryptography. It's supported by various providers, avoiding lock-in to a single-relayer technology, offering an anti-fragile approach with no single point of failure. ## Further reading * [Official documentation](https://www.erc4337.io) * [EIP document](https://eips.ethereum.org/EIPS/eip-4337) # Safe and ERC-7579 Source: https://docs.safefoundation.org/features/erc-7579/7579-safe How to use ERC-7579 with Safe Smart Accounts The Safe7579 Adapter is a smart contract developed by Rhinestone and Safe to make Safe Smart Accounts compliant with ERC-7579. Through this, [14 audited modules](https://github.com/rhinestonewtf/core-modules/tree/main/src) developed by Rhinestone will be available for builders building with the Safe7579 Adapter, such as a dead man switch, flash-loan, social recovery, etc. Additionally, the Rhinestone registry provides per-transaction security checks on modules, so modules with security compromises are automatically disabled for your account. diagram-safe-7579 ## Safe7579 Adapter As ERC-7579 is a superset of ERC-4337, the Safe7579 Adapter ensures full compliance with ERC-4337. The Safe7579 Adapter is both a Safe Module and a Fallback Handler. * **Safe Module:** It extends the functionality of a Safe account, allowing it to utilize ERC-7579 modules. * **Fallback Handler:** It is a fallback handler because certain functions, such as validateUserOp in ERC-7579, are not natively supported by Safe. Additionally, a launchpad contract facilitates the setup of new Safes with Safe7579 Adapter. ## Creation of new Safes compatible with ERC-7579 The launchpad contract works around the 4337 limitations, which allows the deployment of exactly one contract whose address matches the sender of the user operation. The creation of new Safes occurs in the following three high-level steps. * Bundler informs `Entrypoint` to `handleUserOps`. * Entrypoint calls `SenderCreator` to call `SafeProxyFactory`. * `SenderCreator` requests `safeProxy` creation from `SafeProxyFactory` using `createProxyWithNonce`. * `SafeProxyFactory` creates a new `SafeProxy` using `create2`. * `SafeProxy` is created with a singleton address set to `Launchpad` . * `initHash` is stored in the `SafeProxy` storage. * `Entrypoint` validates user operations in `SafeProxy` via `validateUserOp`. * `SafeProxy` delegates validation to `Launchpad`. * `Launchpad` ensures the presence of `initHash` from phase one and calls `Safe7579.launchpadValidators`. * `ValidatorModule` gets installed by `Launchpad`. * `ValidatorModule` validates user operations and returns `packedValidationData`. * `Launchpad` returns packedValidationData to `SafeProxy`, `SafeProxy` returns to `Entrypoint`. * `Entrypoint` triggers `launchpad.setupSafe()` in `SafeProxy`. * `SafeProxy` delegates the setup to `Launchpad`. * `LaunchPad` upgrades `SafeStorage.singleton` to `SafeSingleton`. * `LaunchPad` calls `SafeProxy.setup()` to initialize `SafeSingleton`. * Setup function in `SafeProxy.setup()` delegatecalls to `lauchpad.initSafe7579`. * `initSafe7579()` initializes `Safe7579` with executors, fallbacks, hooks, `IERC7484` registry. The following detailed sequence outlines the creation, validation, and execution phases in the system's operation. ```mermaid theme={null} sequenceDiagram participant Bundler participant Entrypoint participant SenderCreator participant SafeProxyFactory participant SafeProxy participant SafeSingleton participant Launchpad participant Safe7579 participant Registry participant EventEmitter participant ValidatorModule participant Executor alt Creation by Factory Bundler->>Entrypoint: handleUserOps Entrypoint->>SenderCreator: create this initcode SenderCreator->>+SafeProxyFactory: createProxyWithNonce(launchpad, intializer, salt) SafeProxyFactory-->>SafeProxy: create2 SafeProxy-->Launchpad: singleton = launchpad SafeProxyFactory->>+SafeProxy: preValidationSetup (initHash, to, preInit) SafeProxy-->>+Launchpad: preValidationSetup (initHash, to, preInit) [delegatecall] Note over Launchpad: sstore initHash SafeProxy-->>SafeProxyFactory: created SafeProxyFactory-->>Entrypoint: created sender end alt Validation Phase Entrypoint->>+SafeProxy: validateUserOp SafeProxy-->>Launchpad: validateUserOp [delegatecall] Note right of Launchpad: only initializeThenUserOp.selector Note over Launchpad: require inithash (sload) Launchpad->>Safe7579: launchpadValidators() [call] Note over Safe7579: write validator(s) to storage loop Launchpad ->> ValidatorModule: onInstall() Note over Launchpad: emit ModuleInstalled (as SafeProxy) end Note over Launchpad: get validator module selection from userOp.nonce Launchpad ->> ValidatorModule: validateUserOp(userOp, userOpHash) ValidatorModule ->> Launchpad: packedValidationData Launchpad-->>SafeProxy: packedValidationData SafeProxy->>-Entrypoint: packedValidationData end alt Execution Phase Entrypoint->>+SafeProxy: setupSafe SafeProxy-->>Launchpad: setupSafe [delegatecall] Note over SafeProxy, Launchpad: sstore safe.singleton == SafeSingleton Launchpad->>SafeProxy: safe.setup() [call] SafeProxy->>SafeSingleton: safe.setup() [delegatecall] Note over SafeSingleton: setup function in Safe has a delegatecall SafeSingleton-->>Launchpad: initSafe7579WithRegistry [delegatecall] Launchpad->>SafeProxy: this.enableModule(safe7579) SafeProxy-->>SafeSingleton: enableModule (safe7579) [delegatecall] SafeSingleton->>Safe7579: initializeAccountWithRegistry Note over Safe7579: msg.sender: SafeProxy alt SetupRegistry Safe7579-->SafeProxy: exec set attesters on registry SafeProxy-->>SafeSingleton: exec set attesters on registry SafeSingleton->>Registry: set attesters (attesters[], threshold) end loop installation of modules Safe7579->>Registry: checkForAccount(SafeProxy, moduleaddr, moduleType) Safe7579->>SafeProxy: exec call onInstall on module SafeProxy-->>SafeSingleton: exec call onInstall on Module [delegatecall] SafeSingleton->>Executor: onInstall() [call] Safe7579->>SafeProxy: exec EventEmitter SafeProxy-->>SafeSingleton: exec EventEmitter [delegatecall] SafeSingleton-->>EventEmitter: emit ModuleInstalled() [delegatecall] Note over EventEmitter: emit ModuleInstalled() as SafeProxy end Safe7579->>SafeProxy: exec done SafeProxy->-Entrypoint: exec done end ``` ## Further reading * [Safe7579 on GitHub](https://github.com/rhinestonewtf/safe7579) # Overview Source: https://docs.safefoundation.org/features/erc-7579/overview What is ERC-7579 and why do we need it? ## What is ERC-7579? [ERC-7579](https://erc7579.com/) outlines the minimally required interfaces and behavior for modular smart accounts and modules to ensure interoperability across implementations. ERC-7579 is a standard for accounts but does not specify how accounts work internally. Instead, it defines the account interface so developers can implement modules for all smart accounts that follow this standard. The primary consumers of ERC-7579 are module developers, not account implementers. However, the account implementers implement ERC-7579 so that module developers can support all account implementations that implement this standard. That being said, a module for Safe will work with the Biconomy wallet, ZeroDev wallet, etc. diagram-7579 ## Why ERC-7579? Without ERC-7579, smart account implementations were fragmented as different implementations required unique adaptations. Different assumptions can lead to security bugs under one account implementation, creating barriers for developers and limiting the user experience. ERC-7579 offers a universal standard that ensures all modules can work across all smart account implementations supporting ERC-7579. It enables modules to work across different smart accounts. It ensures smart accounts can be used with various wallet applications and SDKs. It helps prevent vendor lock-in for smart account users and application developers. ## Further reading * [Official documentation](https://erc7579.com/) * [EIP document](https://eips.ethereum.org/EIPS/eip-7579) # Overview Source: https://docs.safefoundation.org/features/passkeys/overview What are passkeys and why do we need them? ## What are passkeys? Passkeys are a standard authentication method designed to avoid using traditional passwords, providing a more secure and user-friendly experience. Passkeys are based on public and private key pairs to secure user authentication. The public key is stored on the server side, while the private key is secured in the user's device. The user is authenticated by proving ownership of the private key, usually with biometric sensors, without extracting it from the device at any time. This method ensures that sensitive information remains protected and reduces the risk of credential theft. ## Why do we need passkeys? Passkeys offer significant security improvements over traditional passwords. In the context of web3, where secure key management is paramount, passkeys provide an efficient alternative to seed phrases, which are often considered both a security liability and a subpar user experience. Passkeys eliminate the need for users to store seed phrases securely. They ensure the user's private key remains secure even if a server is compromised. Passkeys streamline the authentication process by allowing users to sign in to accounts with a biometric sensor, pin, or gesture. Passkeys are stored in a device secure element, ensuring they can not be easily accessible to the internet. They can also be synced across multiple devices. Safe offers the capability to sign into your wallet using passkeys by implementing a dedicated module that verifies the integrity of the key provided. ## Passkeys Support Passkeys and syncing are supported by Apple and Android devices. If a device uses [Cross-device authentication (CDA)](https://passkeys.dev/docs/reference/terms/#cross-device-authentication-cda), its passkeys will be portable to other devices. You can read more about device support [here](https://passkeys.dev/device-support/#matrix). Passkeys can also be integrated with ERC-4337, providing enhanced user experience in managing web3 accounts. See our tutorials to build your own implementation, or check out [ERC-4337 support contract for passkeys](https://github.com/safe-fndn/safe-modules/tree/main/modules/passkey/contracts/4337) for more information. ## Further reading * [The official W3C standard](https://www.w3.org/TR/webauthn) * [WebAuthn API specification](https://webauthn.wtf/how-it-works/basics) * [Passkeys 101 by FIDO Alliance](https://fidoalliance.org/passkeys) # Safe and Passkeys Source: https://docs.safefoundation.org/features/passkeys/passkeys-safe How to use Passkeys with Safe Smart Accounts Passkeys are compatible with Safe versions `≥1.3.0`. Safe's standard-agnostic nature allows adding or removing user flows, such as custom signature verification logic. This flexibility facilitates the integration of a Passkeys-based execution flow into a Safe. Safe passkey contracts conform to both ERC-1271 and WebAuthn standards, enabling the verification of signatures for WebAuthn credentials that use the `secp256r1` curve. These contracts can utilize EIP-7212 precompiles for signature verification on supported networks or alternatively employ any verifier contract as a fallback mechanism. ## Passkey contracts ### `SafeWebAuthnSignerProxy` A proxy contract is uniquely deployed for each `Passkey` signer. The signer information, such as Public key coordinates, Verifier address, and Singleton address, is immutable. All calls to the signer are forwarded to the `SafeWebAuthnSignerSingleton` contract. `SafeWebAuthnSignerProxy` provides gas savings compared to the whole contract deployment for each signer creation. `SafeWebAuthnSignerProxy` and `SafeWebAuthnSignerSingleton` use no storage slots to avoid storage access violations defined in ERC-4337. Check [this PR](https://github.com/safe-fndn/safe-modules/pull/370) for details on gas savings. This non-standard proxy contract appends signer information, like public key coordinates and verifier data, to the call data before forwarding the calls to the singleton contract. ### `SafeWebAuthnSignerSingleton` `SafeWebAuthnSignerSingleton` is a singleton contract that implements the ERC-1271 interface to support signature verification. It enables signature data to be forwarded from a Safe to the `WebAuthn` library. This contract expects the caller to append public key coordinates and the verifier address (inspired by [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)). ### `SafeWebAuthnSignerFactory` The `SafeWebAuthnSignerFactory` contract deploys the `SafeWebAuthnSignerProxy` contract with the public key coordinates and verifier information. The factory contract also supports signature verification for the public key and signature information without deploying the signer contract, which is used during the validation of ERC-4337 user operations by the experimental `SafeSignerLaunchpad` contract. New signers can be deployed using the [ISafeSignerFactory](https://github.com/safe-fndn/safe-modules/blob/466a9b8ef169003c5df856c6ecd295e6ecb9e99d/modules/passkey/contracts/interfaces/ISafeSignerFactory.sol) interface and this factory contract address. ### `WebAuthn` This library generates a signing message, hashing it, and forwards the call to the verifier contract. The `WebAuthn` library defines a `Signature` struct containing `authenticatorData` and `clientDataFields`, followed by the ECDSA signature's `r` and `s` components. The `authenticatorData` and `clientDataFields` are required for generating the signing message. The `bytes` signature received in the `verifySignature(...)` function is cast to the `Signature` struct, so the caller has to take into account formatting the signature bytes as expected by the `WebAuthn` library. The code snippet below shows signature encoding for verification using the WebAuthn library. ``` bytes authenticatorData = ...; string clientDataFields = ...; uint256 r = ...; uint256 s = ...; // Encode the signature data bytes memory signature = abi.encode(authenticatorData, clientDataFields, r, s); ``` ### `P256` `P256` is a library for P256 signature verification with contracts that follow the EIP-7212 EC verify precompile interface. This library defines a custom type `Verifiers`, which encodes two addresses into a single `uint176`. The first address (2 bytes) is a precompile address dedicated to verification, and the second (20 bytes) is a fallback address. This setup allows the library to support networks where the precompile is not yet available. It seamlessly transitions to the precompile when it becomes active while relying on a fallback contract address in the meantime. ## Further reading * [Passkeys module](https://github.com/safe-fndn/safe-modules/blob/466a9b8ef169003c5df856c6ecd295e6ecb9e99d/modules/passkey/README.md) * [Safe and Passkeys demo application](https://github.com/safe-fndn/safe-modules/tree/main/examples/4337-passkeys) * [4337 support for passkeys](https://github.com/safe-fndn/safe-modules/tree/main/modules/passkey/contracts/4337) # Glossary Source: https://docs.safefoundation.org/more/glossary Definitions of terms and concepts used throughout the Safe documentation. ## Account Abstraction Account Abstraction is a paradigm aimed at improving the blockchain user experience by replacing the reliance on [externally-owned accounts](#externally-owned-account) (EOAs) with programmable [smart accounts](#smart-account). Key benefits of Account Abstraction include: * Elimination of seed phrase reliance * Improved multi-chain interactions * Account recovery mechanisms * [Gasless transactions](#gasless-transaction) * Transaction batching See also: * [Ethereum Account Abstraction roadmap](https://ethereum.org/en/roadmap/account-abstraction) * [ERC-4337: Account Abstraction](https://www.erc4337.io) *** ## Bundler Bundlers are specialized nodes defined by the [ERC-4337](#erc-4337) standard. They collect [UserOperation](#useroperation) objects from a dedicated mempool, bundle them together, and submit them to the blockchain via the [EntryPoint](#entrypoint) contract. Bundlers initially pay the transaction fees and are later reimbursed by the user’s smart account or a [Paymaster](#paymaster). See also: * [ERC-4337 bundling process](https://eips.ethereum.org/EIPS/eip-4337#bundling) * [Bundlers documentation](https://docs.erc4337.io/bundlers) *** ## ERC-1271 [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) defines a standard interface that allows smart contracts to validate signatures. A contract implementing ERC-1271 exposes an `isValidSignature(hash, signature)` function that returns whether a given signature is valid for that contract. This enables smart accounts to participate in signature-based authentication flows. *** ## ERC-712 [ERC-712](https://eips.ethereum.org/EIPS/eip-712) specifies a standard for hashing and signing typed structured data, making signed messages more readable and secure compared to raw bytestring signing. *** ## EntryPoint The EntryPoint is a singleton smart contract defined by [ERC-4337](#erc-4337). It is responsible for validating and executing bundles of [UserOperation](#useroperation) objects submitted by [Bundlers](#bundler). See also: * [EntryPoint specification](https://eips.ethereum.org/EIPS/eip-4337#entrypoint-definition) *** ## ERC-4337 [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) introduces Account Abstraction without requiring changes to Ethereum’s consensus layer. It defines a new pseudo-transaction object called `UserOperation` and a dedicated mempool. [Bundlers](#bundler) aggregate UserOperations and submit them to the blockchain via the [EntryPoint](#entrypoint) contract. See also: * [ERC-4337 documentation](https://www.erc4337.io) *** ## Externally-Owned Account An externally-owned account (EOA) is one of the two Ethereum account types. EOAs are controlled by a private key, contain no executable code, and initiate transactions by signing them directly. See also: * [Ethereum accounts](https://ethereum.org/en/developers/docs/accounts) * [Ethereum whitepaper – accounts](https://ethereum.org/en/whitepaper/#ethereum-accounts) *** ## Gasless Transaction Gasless transactions (also called meta-transactions) allow users to interact with the blockchain without directly paying gas fees. Instead, a third party-commonly a [Relayer](#relayer) or a [Paymaster](#paymaster)-submits and pays for the transaction on the user’s behalf. Users sign a message describing the desired action, while the relayer constructs and executes the on-chain transaction. *** ## Multi-signature A multi-signature account is a type of [smart account](#smart-account) that requires approvals from multiple owners to execute transactions. Owners can be [externally-owned accounts](#externally-owned-account) or other smart accounts. ### Common configurations * **0/0 Safe** An account with no owners, fully controlled by [Safe Modules](#safe-module). Commonly used for automation. * **1/1 Safe** A single-owner account. Simple to manage but requires a recovery plan in case the owner loses access. * **N/N Safe** All owners must approve each transaction. Offers strong shared control but requires careful key management. * **N/M Safe** Only a subset of owners must approve transactions, balancing security and flexibility. ### How it works * Owners and thresholds are stored on-chain. * Transactions include signatures from the required owners. * The Safe contract verifies signatures before execution. ### Benefits * **Enhanced security** through reduced single points of failure * **Flexible ownership** and threshold configuration * **Broad wallet compatibility**, including: * Hardware wallets (Ledger, Trezor) * Software wallets (MetaMask, Trust Wallet) * MPC wallets (Fireblocks, Zengo) * Other smart accounts * Social login or passkey-based wallets * **Upgradability**, including owner and threshold changes * **Auditability** of all executed transactions *** ## Network A blockchain network is a distributed system of nodes that maintain a shared ledger using a consensus mechanism. Networks enable decentralized transaction execution without a central authority. See also: * [Ethereum networks](https://ethereum.org/en/developers/docs/networks) *** ## Owner A Safe owner is an account authorized to manage a Safe and approve transactions. Owners can be EOAs or smart accounts. The [threshold](#threshold) determines how many owner approvals are required. See also: * [OwnerManager.sol](https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/base/OwnerManager.sol) *** ## Paymaster Paymasters are smart contracts that sponsor gas fees for users under [ERC-4337](#erc-4337). They can enable gasless experiences or allow gas payments using ERC-20 tokens. See also: * [ERC-4337 Paymasters](https://eips.ethereum.org/EIPS/eip-4337#extension-paymasters) * [Paymasters documentation](https://docs.erc4337.io/paymasters) *** ## Relayer A relayer is a third-party service that submits transactions to the blockchain on behalf of users, often paying gas costs upfront. See also: * [What is relaying?](https://docs.gelato.network/developer-services/relay/what-is-relaying) *** ## Safe\{DAO} Safe\{DAO} is a decentralized autonomous organization that governs and supports the Safe ecosystem through grants, governance, and ecosystem investments. See also: * [Safe\{DAO} Forum](https://forum.safe.global) * [Governance process](https://forum.safe.global/t/how-to-safedao-governance-process/846) * [Proposals on Snapshot](https://snapshot.org/#/safe.eth) *** ## Safe\{Wallet} [Safe\{Wallet}](https://app.safe.global) is the official interface for creating and managing Safe accounts. See also: * [Getting started with Safe\{Wallet}](https://help.safe.global/en/collections/9801-getting-started) *** ## Safe Apps Safe Apps are third-party web applications integrated into the Safe Apps marketplace. They interact with Safe accounts via the Safe Apps SDK and are not owned or audited by Safe. See also: * [Safe Apps SDK](https://github.com/safe-global/safe-apps-sdk) *** ## Safe Guard A Safe Guard is a smart contract that adds pre- and post-execution checks to Safe transactions. See also: * [Safe Guards documentation](/smart-account/guards) * [Zodiac Guards](https://zodiac.wiki/index.php%3Ftitle=Introduction:_Zodiac_Protocol.html#Guards) *** ## Safe Module A Safe Module is a smart contract that extends Safe functionality while keeping core contracts minimal. See also: * [Safe Modules documentation](/smart-account/modules) * [Safe Modules repository](https://github.com/safe-fndn/safe-modules) * [Zodiac Modules](https://zodiac.wiki/index.php%3Ftitle=Introduction:_Zodiac_Protocol.html#Modules) *** ## Smart Account A smart account is a smart-contract-based account that provides enhanced security and programmability compared to EOAs. Transactions are executed according to on-chain logic rather than a single private key. Common features include: * [Multi-signature](#multi-signature) * Transaction batching * Account recovery * [Gasless transactions](#gasless-transaction) Safe is a widely adopted implementation of smart accounts. *** ## Transaction A transaction updates blockchain state and is typically initiated by an [externally-owned account](#externally-owned-account). A Safe transaction is executed via the Safe contract’s `execTransaction` function. See also: * [Ethereum transactions](https://ethereum.org/developers/docs/transactions) *** ## Threshold The threshold defines how many owner approvals are required to execute a Safe transaction. *** ## UserOperation `UserOperation` is a pseudo-transaction type introduced by [ERC-4337](#erc-4337). UserOperations are sent to a dedicated mempool and executed through the [EntryPoint](#entrypoint) contract. See also: * [UserOperation specification](https://eips.ethereum.org/EIPS/eip-4337#useroperation) * [UserOperation mempool](https://docs.erc4337.io/bundlers/userop-mempool-overview) *** ## Wallet A wallet is an application or interface that allows users to manage blockchain accounts, sign messages, and submit transactions. See also: * [Ethereum wallets](https://ethereum.org/wallets) # Safenet Beta Source: https://docs.safefoundation.org/safenet/overview/beta Current status of the Safenet Beta network - what is live, what is being tested, and how to observe network activity. Safenet Beta is the first live deployment of the Safenet protocol. It runs with a permissioned Validator set and focuses on core consensus, transaction attestation, and SAFE token staking. ## What is live in Beta * Validator coordination and threshold signing (FROST) * SAFE token staking and open delegation * Transaction proposal and attestation flow * Static transaction security checks * Public explorer for network activity ## Beta goals Safenet Beta is designed to validate the protocol's core assumptions under real-world conditions: * Can the Validator network reliably process transaction checks at scale? * Can Validator participation be measured and enforced through reward eligibility? * Can SAFE staking and delegation bootstrap meaningful economic security? Beta staking rewards are subsidized for an initial period. Long-term, rewards will be funded by transaction fees paid by users and integrators. ## Validator set The Beta Validator set consists of Validators run by independent organizations, selected by the Safe Ecosystem Foundation. All Validators must maintain a minimum self-stake of 3,500,000 SAFE. Validator coordination is handled via contracts on Gnosis Chain. Deployment info: * Consensus contract: `0x223624cBF099e5a8f8cD5aF22aFa424a1d1acEE9` * Coordinator contract: `0xaE27021CEB45316f1efe69D8E362aC07ED3Bd7E4` Safenet Beta uses the following permissioned Validator set: | Validator | Address | | ------------------ | -------------------------------------------- | | Gnosis | `0x3D58a5475c1336b0A755c3aBd298CeB9b7BB9CDe` | | Greenfield | `0x7B0A8EFA45dE81F11F2846EC28259B62155a2b37` | | RockawayX | `0xb0E735D4a3b70195420E0ae933689A55750CFcd2` | | Core Contributors | `0xCc00DE0eA14c08669b26DcBFE365dBD9890B04D9` | | Blockchain Capital | `0xD8997c2a94052C4FB79B53b3e255c1F07c99305B` | | Safe Labs | `0xF6EA21D702983c443f58A267265912FE03D2FF0b` | A JSON with validator stats is published at [safe-fndn/safebet-beta-data](https://github.com/safe-fndn/safenet-beta-data/blob/main/assets/validator-info.json). ## Transaction checks In Safenet Beta, Validators attest to a fixed set of static security checks. These checks are fully deterministic: given the same transaction data, every honest Validator reaches the same conclusion. [Current checks applied to every proposed Safe transaction:](https://github.com/safe-research/safenet/tree/beta/validator/src/consensus/verify/safeTx/checks) * No unexpected delegatecalls * Upgrade only to trusted Safe Singletons * Only allow adding trusted Safe Modules * Only trusted Safe Fallback Handlers can be set * Only trusted Safe Guards can be set Advanced, context-specific checks (transfer volume analysis, allow/deny lists, actively exploited contracts) are planned for later phases. See the [Roadmap](/safenet/overview/roadmap). ## Scope and limitations Safenet Beta is a deliberate starting point: * **Safe transactions on EVM chains only** * **Permissioned Validator set**: Validators are selected by the Safe Ecosystem Foundation * **Static security checks only**: no open Transaction Checker market yet * **No slashing**: stake is not at risk of being slashed in Beta See the [Roadmap](/safenet/overview/roadmap) for what comes after Beta. ## Explorer The Beta Explorer is a public tool for viewing transactions proposed and checked by the Safenet Validator set. See the [FAQ](/safenet/resources/faq) for details. # Overview Source: https://docs.safefoundation.org/safenet/overview/introduction Safenet enforces transaction security onchain by preventing high-risk transactions from executing. Safenet is currently in Beta. The Validator set is permissioned and slashing is not yet active. See [Safenet Beta](/safenet/overview/beta) for current status. Safenet is a protocol for **onchain transaction security enforcement**. It acts as a **last line of defense** against malicious or high-risk transactions by ensuring that transactions are **validated before execution**, rather than merely displaying warnings. Safenet replaces centralized transaction-checking services with a **resilient, Validator-based network** that enforces security guarantees onchain. Existing security providers can participate in this network. ## How Safenet protects accounts Most transaction security tools today only issue warnings and have no effect on transaction execution. Safenet introduces a different approach: its Validator process enforces transaction attestations directly at the protocol level. When a transaction is proposed, Safenet Validators evaluate it against a defined set of security rules. If the transaction satisfies these rules, Validators produce a cryptographic attestation. The Safe Guard verifies this attestation onchain as part of the execution process. Transactions without a valid attestation cannot satisfy the protocol's execution requirements. ```mermaid theme={null} flowchart LR A[Transaction proposed] --> B[Validators evaluate] B -->|Rules satisfied| C[Onchain attestation] B -->|Rules not met| D[No attestation] C --> E[Safe Guard verifies onchain] E --> F[Transaction executes] D --> G[Execution requirements not met] style A fill:#555555,stroke:#555555,color:#ffffff style B fill:#555555,stroke:#555555,color:#ffffff style C fill:#00855a,stroke:#00855a,color:#ffffff style E fill:#00855a,stroke:#00855a,color:#ffffff style F fill:#00855a,stroke:#00855a,color:#ffffff style D fill:#f07030,stroke:#f07030,color:#ffffff style G fill:#f07030,stroke:#f07030,color:#ffffff ``` *How a transaction moves through Safenet.* Users remain in full self-custody at all times. If a transaction does not satisfy the protocol's requirements and you still want to proceed, that is possible upon explicit, additional owner approval after a time delay. Safenet does not override owner control. As a result, protection is enforced at the protocol level rather than relying on user behavior. A phishing site, a compromised wallet UI, or an opaque approval flow cannot circumvent these enforced attestations. ## What makes Safenet different **Decentralized validation** Security checks are performed by a network of Validators, not a single API or server. The network tolerates up to one-third of Validators acting dishonestly and still produces correct attestations. This property is known as Byzantine Fault Tolerance (BFT). **Onchain enforcement** Attestations are compact cryptographic signatures. Verification is gas-efficient and permissionless: any EVM-compatible chain can integrate without proprietary infrastructure. A transaction without a valid attestation does not satisfy the protocol's execution requirements, regardless of who signed it. **A path to sustainable security incentives** Safenet aims to create a market for transaction security: Transaction Checkers compete to provide real-time risk signals, and Validators attest to market outcomes. It is envisioned that this creates a sustainable path toward fee-based security mechanisms, which makes staking economically meaningful. These mechanisms are planned for after Beta. **Open to all chains and wallets** Any Safe on any supported EVM chain can use Safenet. No proprietary infrastructure required. ## Who is Safenet for? **Safe users** Safenet protects your account from malicious transactions, even if your wallet UI is compromised. See the [FAQ](/safenet/resources/faq) to learn more and explore recent network activity. **Stakers and Delegators** Delegate SAFE tokens to Validators and earn rewards for securing the network. See [Staking](/safenet/staking/validator-staking). **Validators, wallet operators, and security firms** If you are interested in running a Validator, integrating Safenet into your wallet, or contributing transaction security logic, [reach out](https://contact.safefoundation.org/). ## Safenet Beta Safenet is currently live in Beta, focusing on core consensus, threshold signing, and SAFE token staking with a permissioned Validator set. See [Safenet Beta](/safenet/overview/beta) for what is live today, and the [Roadmap](/safenet/overview/roadmap) for what comes next. # Roadmap Source: https://docs.safefoundation.org/safenet/overview/roadmap Building the enforcement layer for transaction security Safenet is developed iteratively based on user feedback, research, and ecosystem needs. This roadmap is directional and will evolve over time. If you would like to contribute, [please reach out](mailto:research+safenet@safe.dev). Safenet roadmap ## Q1 2026 - Safenet Beta & SAFE Staking Safenet Beta marks the first live deployment of the network, focused on Validator coordination and core consensus with a permissioned Validator set. **Focus areas** * Launch of the Safenet Beta network * Validator onboarding and coordination * Initial SAFE token staking and open delegation * Basic transaction attestation flow * Explorer and network monitoring tools This phase validates the core architecture, staking mechanics, and Validator participation in a limited production environment. ## Q2 2026 - Advanced Checks & Guard Enforcement Safenet expands its transaction verification capabilities (target manipulation) and introduces onchain enforcement via the Safe Guard. The Guard verifies Safenet attestations directly onchain before allowing transaction execution, providing enforcement at low cost on supported chains. **Focus areas** * Expanded checks (target manipulation) * Improved attack pattern detection * Safe Guard deployment and onchain enforcement * Validator performance monitoring This phase strengthens Safenet's ability to proactively prevent malicious or high-risk transactions before execution. ## Q3 2026 - Safe\{Wallet} Integration & Fee Implementation Safenet integrates directly into wallet flows and introduces a sustainable economic model. **Focus areas** * Native Safe\{Wallet} integrations * Seamless transaction proposal UX * Fee model design and implementation * Validator reward distribution logic This phase improves accessibility for end users while aligning long-term incentives across Validators and token holders. ## Q4 2026 - Open Sentinel Markets Safenet evolves into a market-based enforcement layer for transaction validation. **Focus areas** * Transaction check specialization * Market-based pricing for validation mechanisms * Sentinel reputation mechanisms This phase introduces economic competition to optimize security quality, responsiveness, and efficiency. ## 2027+ - Slashing, Insurance & Permissionless Validators Safenet transitions toward stronger crypto-economic guarantees, optional protection layers, and an open Validator set. **Focus areas** * Slashing mechanisms for Validator misbehavior * Cryptoeconomic accountability guarantees * Risk-weighted validation models * Transaction insurance primitives * Permissionless Validator onboarding * P2P Validator network (replacing onchain communication for scalability) This phase establishes Safenet as a fully incentive-aligned, open security layer with enforceable accountability and optional insurance coverage. Interested in becoming a Validator or Transaction Checker? [Reach out](https://contact.safefoundation.org/). # Safenet Validators Source: https://docs.safefoundation.org/safenet/overview/validators The role of Validators in the Safenet protocol - what they do, why decentralization matters, and how they are incentivized. Validators are the core participants in the Safenet network. They collectively check and attest to Safe transactions before execution. Because attestations require a threshold of Validators to cooperate, no single participant controls whether a transaction is approved or not. ## What Validators do When a Safe transaction is proposed to Safenet, Validators check it against a defined set of security rules. If the transaction satisfies all rules, Validators coordinate to produce a FROST threshold signature: a cryptographic attestation that the transaction is valid. The Safe Guard checks this attestation onchain before allowing execution. Without a valid attestation, the transaction cannot proceed. Validators only attest to outcomes that are fully deterministic. Given the same transaction data, every honest Validator reaches the same conclusion. This is what allows the network to maintain its security guarantees even when some Validators behave dishonestly. The network tolerates up to one-third of Validators acting dishonestly. As long as fewer than one-third are compromised, no invalid attestation can be produced. This property is known as Byzantine Fault Tolerance (BFT). ## Decentralization and trust The Safenet Validator set is run by a varied group of independent organizations. This is a deliberate design choice: no single company controls whether a transaction is attested. This distinguishes Safenet from centralized transaction checking services, where a single server or API is the sole arbiter of transaction safety. A compromised or captured central service can fail silently. Safenet requires a coordinated majority of independent Validators to be compromised simultaneously, and even then, the onchain nature of attestations means any failure is publicly visible and auditable. All Validator attestations are recorded onchain. Anyone can inspect which Validators participated in a given signing round and independently verify the threshold signature. See [Safenet Beta](/safenet/overview/beta) for the current Validator set. ## Validator incentives Validators earn SAFE token rewards in proportion to their stake and participation rate. Reward mechanics, including commission rates, minimum stake, and distribution schedule, are defined in the staking rewards design. See [Staking rewards](/safenet/staking/rewards) for full details. ## Joining as a Validator In Safenet Beta, Validators are onboarded by the Safe Ecosystem Foundation. The Validator set is planned to expand and eventually become permissionless. See [Safenet Beta](/safenet/overview/beta) for details on the current set, and the [Roadmap](/safenet/overview/roadmap) for plans toward permissionless onboarding. Please [reach out](https://contact.safefoundation.org/) if you are interested in running a Safenet validator in the future. # FAQs Source: https://docs.safefoundation.org/safenet/resources/faq Frequently asked questions about Safenet and Safenet Beta. Safenet Beta is initiated by the Safe Ecosystem Foundation (SEF), which is accountable to SafeDAO governance. The Safenet Beta, the Staking contract, and the Validator network are live and run under SEF's mandate. The staking rewards mechanism has been [approved by SafeDAO](https://snapshot.org/#/s:safe.eth/proposal/0xb85ed0346bb07196786df5145e57f5e3e5054d35ba7d5f67594faaa6b7a98bcd). Rewards are distributed regularly according to the mechanism described in [Staking rewards](/safenet/staking/rewards). Configuration changes to the protocol, including any updates to the withdrawal delay, require a timelock before taking effect. Changes to reward parameters require a governance proposal. The rewards proposal is not yet approved. This page will be updated when the SafeDAO vote concludes. Yes. The Safenet Beta contracts, Explorer and staking UI are publicly available on GitHub: [safe-research/safenet](https://github.com/safe-research/safenet) * **Smart contracts**: [safe-research/safenet/contracts](https://github.com/safe-research/safenet/tree/beta/contracts) * **Explorer**: [safe-research/safenet/explorer](https://github.com/safe-research/safenet/tree/beta/explorer) * **Staking UI**: [safe-fndn/safenet/safenet-staking-ui](https://github.com/safe-fndn/safenet-staking-ui) The Staking contract has been independently audited. The audit report is available in the repository. See [Security](/safenet/resources/security) for the full audit report and contract details. A technical overview is provided in the [Safenet repository](https://github.com/safe-research/safenet/blob/beta/docs/overview.md). **Smart contracts** The full source for the Staking and Consensus contracts is in [safe-research/safenet/contracts](https://github.com/safe-research/safenet/tree/beta/contracts). Inline documentation covers the key functions, events, and parameters. **FROST threshold signing** Safenet uses FROST (Flexible Round-Optimized Schnorr Threshold Signatures) for Validator attestations. The standard is defined in [RFC 9591](https://datatracker.ietf.org/doc/html/rfc9591). **Staking mechanics** The staking and rewards documentation covers how stake is weighted, how rewards are calculated, and what conditions affect eligibility. Start with [Staking](/safenet/staking/overview). **Validators** There is a [Validator handbook](https://github.com/safe-research/safenet/blob/beta/docs/validator-handbook.md) available. For questions not covered by the documentation, open an issue on [GitHub](https://github.com/safe-research/safenet/issues/new). The Safenet Beta Explorer is a public interface for observing transaction validation activity on the network. No wallet connection or account is required to view activity. **Exploring network activity** The Explorer provides a live stream of Safe transactions that have been proposed to the Safenet Validator set. Each transaction shows its current status (**Proposed**, **Attested**, or **Timed-out**) and a detail page with the full transaction breakdown, Validator participation, and links to Safe\{Wallet} and chain explorers. You can search by Safe address or `safeTxHash`. **Submitting a transaction for validation** If your Safe transaction has not yet been proposed to Safenet Beta, you can submit it directly from the Explorer: 1. Navigate to the Explorer at [explorer.safenet-beta.eth.limo](https://explorer.safenet-beta.eth.limo) 2. Enter your `safeTxHash` or paste the transaction details manually 3. Submit - no wallet required, the submission is relayed for you Under normal network conditions, a transaction moves from **Proposed** to **Attested** within a few signing rounds. In practice this is typically a matter of seconds to low minutes. The exact duration depends on two factors. First, Validator participation: if enough Validators are online and responsive, the FROST threshold signature completes in a single round. If some Validators are slow or offline, the signing coordinator retries until quorum is reached or the round times out. Second, network conditions: latency between Validators affects round-trip times for the threshold signing protocol. You can monitor the status of any transaction in the Explorer. A transaction that reaches **Timed-out** did not receive enough Validator signatures within the signing window. You can resubmit it for a new signing round. Safenet Beta only does basic transaction security checks. It is a Beta product and might misbehave. **Check the attestation status in the Explorer** Look up your transaction by `safeTxHash` in the Explorer. The status field shows one of three states: * **Proposed**: the transaction has been submitted to the Validator set and a signing round is in progress. * **Attested**: a threshold of Validators produced a FROST signature over the transaction. This signature is recorded onchain on Gnosis Chain. * **Timed-out**: the signing round did not reach quorum within the allowed window. The transaction can be resubmitted. **What "Attested" means** An attested transaction has a threshold FROST signature from the active Validator set. FROST is a standard threshold signing scheme (see [RFC 9591](https://datatracker.ietf.org/doc/html/rfc9591)). It means no single Validator approved the transaction alone: a defined minimum number of independent Validators all participated in producing the signature. The signature and the signed message are stored in the Consensus contract on Gnosis Chain. Anyone can retrieve and verify the signature against the Validator set's public key using standard cryptographic tools. **Checking onchain** ```solidity theme={null} (bytes32 msg, FROST.Signature memory sig) = consensus.getRecentAttestation(tx); ``` See the Consensus contract documentation for the full verification flow. In Safenet Beta, the Validator set is **permissioned**. Validators are selected and onboarded by the Safe Ecosystem Foundation. The Validator set is intentionally small in Beta to allow the core staking, consensus, and FROST threshold signing mechanics to be proven out in a controlled environment. If you are interested in running a Validator node in a future phase, watch the [Roadmap](/safenet/overview/roadmap) for updates on when the Validator set opens up and [reach out](https://contact.safefoundation.org/). Transactions are submitted to the Consensus contract on Gnosis Chain via the `proposeTransaction` function. ```solidity theme={null} // Submit a transaction for validation bytes32 message = consensus.proposeTransaction(tx); // Listen for the TransactionAttested event, then retrieve the signature: (bytes32 msg, FROST.Signature memory sig) = consensus.getRecentAttestation(tx); ``` The `tx` parameter is a `SafeTransaction.T` struct containing the standard Safe transaction fields. After calling `proposeTransaction`, listen for the `TransactionProposed` event to confirm submission, then wait for `TransactionAttested` before using the resulting FROST signature. **Events to listen for** * `TransactionProposed(bytes32 indexed safeTxHash, ...)`: emitted on successful submission * `TransactionAttested(bytes32 indexed safeTxHash, FROST.Signature sig)`: emitted when threshold signing completes See the [Consensus contract source](https://github.com/safe-research/safenet) for the full interface and struct definitions. For questions not covered here, reach out at [research+safenet@safe.dev](mailto:research+safenet@safe.dev). # Security Source: https://docs.safefoundation.org/safenet/resources/security Deployed contracts, source code, audit reports, and what is immutable vs configurable in Safenet Beta. Safenet Beta is built on three smart contracts. The Staking contract lives on Ethereum Mainnet and holds staked SAFE tokens. The Consensus and FROSTCoordinator contracts live on Gnosis Chain and handle transaction attestation and threshold signing. ## Deployed contracts | Contract | Chain | Address | Source | Audit | | ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | Staking | Ethereum Mainnet | [`0x115E78f160e1E3eF163B05C84562Fa16fA338509`](https://etherscan.io/address/0x115E78f160e1E3eF163B05C84562Fa16fA338509) | [Staking.sol](https://github.com/safe-research/safenet/blob/beta/contracts/src/Staking.sol) | [Report](https://github.com/safe-research/safenet/blob/beta/contracts/audits/audit.md) | | Consensus | Gnosis Chain | [`0x223624cBF099e5a8f8cD5aF22aFa424a1d1acEE9`](https://gnosisscan.io/address/0x223624cBF099e5a8f8cD5aF22aFa424a1d1acEE9) | [Consensus.sol](https://github.com/safe-research/safenet/blob/main/contracts/src/Consensus.sol) | **Not audited** | | FROSTCoordinator | Gnosis Chain | [`0xaE27021CEB45316f1efe69D8E362aC07ED3Bd7E4`](https://gnosisscan.io/address/0xaE27021CEB45316f1efe69D8E362aC07ED3Bd7E4) | [FROSTCoordinator.sol](https://github.com/safe-research/safenet/blob/beta/contracts/src/FROSTCoordinator.sol) | **Not audited** | Consensus and FROSTCoordinator contract addresses will be added once deployed. Both Consensus and FROSTCoordinator contracts are non-upgradeable and hold **no user funds**. ## Immutability and parameters **Staking contract** The Staking contract has an owner (the SafeDAO via the Safe Ecosystem Foundation) but is not upgradeable. The owner can propose changes to two parameters. All proposed changes go through a mandatory 7-day timelock before taking effect. After the timelock, anyone can execute the queued change. | Parameter | Current value | Mutable | Who can propose | Constraint | | ------------------- | ---------------------------------------------------------------------------------------- | ------- | ---------------------------- | ------------------------------------------------------------------------------------------- | | `SAFE_TOKEN` | [SAFE on Mainnet](https://etherscan.io/token/0x5afe3855358e112b5647b952709e6165e1c1eeee) | No | — | — | | `CONFIG_TIME_DELAY` | 7 days | No | — | — | | `withdrawDelay` | 2 days | Yes | Contract owner (SafeDAO/SEF) | Max value capped at `CONFIG_TIME_DELAY` (7 days); 7-day timelock before change takes effect | | Validator registry | Permissioned set | Yes | Contract owner (SafeDAO/SEF) | 7-day timelock before changes take effect | The Staking contract has been independently formally verified and audited by [Certora](https://www.certora.com/). See the [full report](https://github.com/safe-research/safenet/blob/beta/contracts/audits/audit.md) for details. **Consensus and FROSTCoordinator contracts** Both contracts are non-upgradeable and have no owner. There are no admin functions and no configurable parameters. Validator Staker addresses in the Consensus contract are self-set by each Validator. Epoch transitions (changes to the active Validator set) require a threshold signature from the current Validator set, not any central authority. In case there is an unrecoverable failure in Safenet Beta, both contracts have to be redeployed and the network needs to be relaunched. # How to delegate stake? Source: https://docs.safefoundation.org/safenet/staking/delegate How to delegate SAFE tokens to a Safenet Validator and earn staking rewards. Anyone holding SAFE tokens can delegate stake to a Validator and earn a share of their rewards, without running a node. See [Staking overview](/safenet/staking/overview) for how delegation fits into the broader staking system. ## Choosing a Validator Your rewards depend directly on the Validator you back. **Participation rate** is the most important factor. If a Validator's participation falls below 75% in a reward period, neither they nor their Delegators earn rewards for that period. Look for Validators with a consistently high participation rate. **Self-stake level** signals a Validator's own exposure. Validators must maintain a minimum average self-stake of 3,500,000 SAFE to be eligible for their own reward share. If they fall below this, they forfeit their own rewards but Delegator rewards are unaffected. **Total stake** affects reward efficiency. Reward weight grows sub-linearly once a Validator's total stake exceeds a per-Validator threshold. Very large Validators earn proportionally less per token than smaller ones, so delegating to a mid-sized Validator may yield better returns. You can view Validator stats, including participation rates and stake levels in the staking interface. There is also a [Safenet Beta dashboard on Dune](https://dune.com/safe/safenet-beta) available. You can split your delegation across more than one Validator simultaneously. ## How to delegate Choose one of the [available staking interfaces](http://safefoundation.org/safenet). 1. Connect your wallet to the staking interface 2. Browse the Validator list and select a Validator 3. Enter the amount of SAFE to delegate 4. Approve the SAFE token transfer 5. Confirm the staking transaction For those who prefer to interact with the contract directly, the Staking contract source and ABI are available on [GitHub](https://github.com/safe-research/safenet). Your delegation is active once the transaction is confirmed. Rewards are calculated using a time-weighted average over the reward period, so stake added mid-period earns proportionally for the time it was active. ## Checking your balance Your current delegation balance and accrued rewards are visible in the staking interface. You can look up your wallet address to see which Validators you have delegated to and your current stake amounts for each. ## Moving to a different Validator There is no direct redelegation path. To move stake from one Validator to another, you must go through a full withdrawal and restake cycle: 1. Initiate a withdrawal from your current Validator 2. Wait out the **2-day** withdrawal delay 3. Execute your withdrawal 4. Delegate to your new Validator Your tokens are locked and not earning rewards during the withdrawal delay. Factor this time cost in when deciding whether to switch Validators. → See: [Staking lock-up periods](/safenet/staking/lockup) for the withdrawal flow and current delay duration. # Lock-up periods Source: https://docs.safefoundation.org/safenet/staking/lockup How withdrawal delays work and what to expect when unstaking SAFE tokens. Staked SAFE tokens are not immediately withdrawable. After initiating a withdrawal, a mandatory **2-day waiting period** applies before you can execute your withdrawal and receive your tokens back. Withdrawal timeline showing staked, initiate withdrawal, 2-day waiting period, and execute withdrawal *Tokens stop earning rewards as soon as you initiate a withdrawal. The 2-day waiting period must pass before you can execute it.* ## How to withdraw Choose one of the [available staking interfaces](http://safefoundation.org/safenet). 1. Go to the staking interface and connect your wallet 2. Select the Validator you want to withdraw from and enter the amount 3. Confirm the withdrawal transaction. Your tokens enter the 2-day waiting period 4. After 2 days, return to the staking interface to execute your withdrawal Tokens in the withdrawal queue do not count toward your time-weighted stake average, so they do not earn rewards during the waiting period. ## Waiting period The withdrawal delay is currently **2 days**. This delay exists so that if a Validator misbehaves, there is time to respond before they can exit their stake. **Multiple pending withdrawals**: If you initiate more than one withdrawal, they are processed in the order they were submitted. You must execute each one before the next becomes available. ## Changing the delay The withdrawal delay is a protocol parameter governed by SafeDAO. Any proposed change must wait **7 days** after approval before taking effect. This ensures Stakers always have advance notice before a change applies. The maximum withdrawal delay that can be set is 7 days, ie. **there will never be a withdrawal delay longer than 7 days** with the current, immutable Staking contract. The current withdrawal delay is 2 days. If this changes upon SafeDAO approval, the new value will be reflected here. The Staking contract is deployed on Ethereum Mainnet at [`0x115E78f160e1E3eF163B05C84562Fa16fA338509`](https://etherscan.io/address/0x115E78f160e1E3eF163B05C84562Fa16fA338509). # Overview Source: https://docs.safefoundation.org/safenet/staking/overview How SAFE tokens are staked in Safenet, who participates, and how rewards are earned. Safenet is currently in Beta. Slashing is not active and the Validator set is permissioned. The mechanics described here reflect the live Beta state. Safenet uses staked SAFE tokens to align Validator incentives and determine reward eligibility. Validators commit locked SAFE to participate, and SAFE token holders can delegate to a Validator to earn a share of rewards without running a node themselves. ## Actors and incentives **Validators** run Safenet nodes and stake SAFE toward their own address. In Safenet Beta, Validators also act as Transaction Checkers: they evaluate each transaction against security rules and attest to the result. They must maintain a minimum self-stake to be eligible for proposed Validator rewards. Rewards are proposed to scale with total stake weight and Validator participation rate. If a Validator's participation falls below a certain threshold in a reward period, neither the Validator nor its Delegators earn rewards for that period. **Delegators** are any SAFE token holders who stake toward a Validator's address without operating a node. Delegators earn rewards generated by their delegated stake, with a small percentage reserved as commission for the Validator. In Safenet Beta, neither Validators nor Delegators risk losing staked tokens. There is no slashing mechanism. The primary risk is missed rewards from backing an underperforming Validator. ## Types of stake **Validator self-stake** is SAFE staked by a Validator toward their own Validator address. A minimum stake is required for the Validator to be eligible for rewards. **Delegated stake** is SAFE staked by any token holder toward a Validator's address. It contributes to the Validator's total stake weight for reward calculation and earns rewards. Both stake types use the same Staking contract with the same deposit and withdrawal mechanics. ## Deployed contract **Key characteristics** * **Non-upgradeable**: Immutable after deployment * **No Rewards/Slashing in Beta**: Pure ledger for deposits (rewards handled separately) * **Timelocked Config**: All configuration changes require waiting periods The Staking contract is deployed on Ethereum Mainnet at [`0x115E78f160e1E3eF163B05C84562Fa16fA338509`](https://etherscan.io/address/0x115E78f160e1E3eF163B05C84562Fa16fA338509). The Staking contract source is available on GitHub: [Staking.sol](https://github.com/safe-research/safenet/blob/beta/contracts/src/Staking.sol). It has been independently audited and formally verified by Certora. See [Security](/safenet/resources/security) for the full report. ## In this section * [How are Validators staked?](/safenet/staking/validator-staking): Validator stake requirements, and how Validators are held accountable. * [How to delegate stake](/safenet/staking/delegate): choosing a Validator and staking SAFE toward them. * [Staking rewards](/safenet/staking/rewards): how rewards are calculated and distributed each reward period. * [Staking lock-up periods](/safenet/staking/lockup): the withdrawal delay and what to expect when unstaking. * [Is my stake at risk?](/safenet/staking/risk): smart contract risk, audits, and the absence of slashing in Beta. # Rewards Source: https://docs.safefoundation.org/safenet/staking/rewards How staking rewards are calculated and distributed in Safenet Beta. The reward mechanism described on this page [has been approved by SafeDAO](https://snapshot.org/#/s:safe.eth/proposal/0xb85ed0346bb07196786df5145e57f5e3e5054d35ba7d5f67594faaa6b7a98bcd). Safenet Beta distributes rewards to Validators and Delegators every two weeks (the "reward period") in recognition of their contribution to securing the network. Rewards are variable - your actual earnings depend on two factors: your proportional stake in the network and the performance of the Validator you delegate to. As a simple approximation: **Variable reward rate approximation** $$ \frac{4{,}500{,}000\ \text{SAFE}}{\text{Total SAFE staked across the network}} $$ However, this rate is not distributed uniformly. Each period, rewards are allocated based on: * Your **average staked balance** over the reward period, relative to total network stake * Your **Validator's participation rate** in transaction attestations - Validators who miss attestations earn fewer rewards, which directly reduces Delegator earnings * **Validator commission** (fixed at 5%), deducted from Delegator rewards * **Stake concentration caps** - rewards growth is penalised for Validators holding disproportionate stake relative to the network average There is no fixed or guaranteed reward rate. For further details please refer to the [disclaimer](https://safefoundation.org/beta-disclaimer). A Validator with low participation will earn materially less than one with full participation - and so will their Delegators. Always consider a Validator's uptime and attestation track record before delegating. Actual rewards may also vary based on compliance requirements, including KYC obligations for rewards exceeding 1,000 USD per reward period. **Time-weighted stake** * Rewards are calculated using the **average staked balance over the reward period**, not a single snapshot. * For both Validators and Delegators, stake is treated as a **time-weighted average** of the balance held during the reward period. **Stake-weighted rewards with centralization caps** * Rewards grow **linearly with total stake** up to a threshold **T**. * Above **T**, rewards grow **sub-linearly** (proportional to √x), reducing incentives for oversized Validators. * The threshold is defined as the total network stake divided by the number of active Validators. **Minimum Validator self-stake requirement** * Validators must maintain a minimum time-weighted average self-stake ($\bar s_i$) of **3,500,000 SAFE** over the reward period. * Validators below this threshold earn **no commission** on delegated stake for that period. Rewards on their own self-stake are unaffected. * Delegators who delegated to such Validators remain eligible to receive rewards, provided the Validator meets the participation requirement. **Participation-based eligibility** * Rewards are conditional on Validator participation. * Validators with participation below **75%** during the reward period generate **no rewards**. * If a Validator fails to meet the participation threshold, neither the Validator nor its Delegators receive rewards for that reward period. **Validator commission** * Validators charge a **5% commission** on rewards generated by delegated stake. * **95%** of delegated rewards are distributed to Delegators. * **5%** is retained by the Validator, in addition to rewards earned on their own stake (if eligible). * If the Validator's registered Staker address changes during the period, the full period's commission (including any earned before the change) is paid to the address registered at period end. ```mermaid theme={null} flowchart TD classDef neutral fill:#555555,stroke:#555555,color:#ffffff classDef green fill:#00855a,stroke:#00855a,color:#ffffff classDef blue fill:#1a6fa8,stroke:#1a6fa8,color:#ffffff R[Reward pool]:::neutral -->|proportional to stake weight| V[Validator share]:::neutral V --> RS[Self-stake rewards]:::green V --> RD[Delegated rewards]:::neutral RS --> Val[Validator]:::green RD -->|5% commission| Val RD -->|95%| Dels[Delegators]:::blue Dels -->|pro-rata by stake| D1[Delegator A]:::blue Dels -->|pro-rata by stake| D2[Delegator B]:::blue ``` *How rewards flow from the pool to a single Validator and its Delegators in a reward period.* *Simplified: omits the stake weight curve, participation filter, and minimum self-stake requirement. These affect the size of each Validator's share but not the flow shown above. See [Calculation](#calculation) for the full mechanics.* **Minimum payout threshold** * Rewards are only paid out if the recipient is entitled to at least **1 SAFE token** for the reward period. * This prevents economically inefficient micro-payouts. * Any unpaid rewards are carried forward and added to the reward pool of the next reward period. ## Calculation This section provides the formal definition of the Safenet Beta reward mechanism. All stake values are time-averaged over the reward period. **Glossary** *Sets and participants* * $V$ – set of Validators active at any point during the reward period * $N = |V|$ – number of Validators in $V$ *Stake* * $\bar s_i$ - average SAFE tokens self-staked by Validator $i$ over the reward period * $\bar d_{j,i}$ - average SAFE tokens delegated by Delegator $j$ to Validator $i$ * $\bar d_i = \sum_j \bar d_{j,i}$ - total average delegated stake to Validator $i$ * $\bar S_i = \bar s_i + \bar d_i$ - total average stake backing Validator $i$ * $\bar S_{\text{total}} = \sum_{i \in V} \bar S_i$ - total average stake in the network *Participation* * $p_i \in [0,1]$ - participation rate of Validator $i$ during the reward period * $p_{\min} = 0.75$ - minimum participation threshold required to earn rewards *Minimum self-stake requirement* * $s_{\min} = 3{,}500{,}000$ SAFE - threshold applied to $\bar s_i$, not to the balance at any single point in time *Rewards* * $\Delta t$ - duration of the reward period * $R$ - total reward pool distributed in the reward period * $R_i$ - reward allocated to Validator $i$ before commission * $R_i^{\text{self}}$ - portion of $R_i$ attributable to Validator self-stake * $R_i^{\text{del}}$ - portion of $R_i$ attributable to delegated stake * $R_i^{\text{Validator}}$ - total reward earned by Validator $i$ before minimum payout filtering * $R_i^{\text{Delegators}}$ - total reward allocated to Delegators of Validator $i$ * $R_{j,i}$ - reward allocated to Delegator $j$ for delegation to Validator $i$ *Incentive parameters* * $T$ - stake threshold where linear rewards stop * $c = 0.05$ - Validator commission rate on delegated rewards * $m = 1$ - minimum payout threshold (in SAFE tokens) *Weights* * $w(\bar S_i)$ - stake-based reward weight for Validator $i$ * $\tilde w_i$ - effective reward weight after participation filtering *Payouts* * $P_i$ - raw reward payout allocated to Validator $i$ **before applying the minimum payout rule** * $P_{j,i}$ - raw reward payout allocated to Delegator $j$ **before applying the minimum payout rule** * $\hat P_i$ - final reward payout transferred to Validator $i$ **after applying the minimum payout rule** * $\hat P_{j,i}$ - final reward payout transferred to Delegator $j$ **after applying the minimum payout rule** * $R_{\text{paid}}$ - total rewards paid out in the reward period * $R_{\text{unpaid}}$ - rewards not paid out and carried forward **Time-averaged stake** For any stake balance $x(t)$ over the reward period $[t_0, t_1]$ with $\Delta t = t_1 - t_0$, the time-average is defined as: $$ \bar x = \frac{1}{\Delta t} \int_{t_0}^{t_1} x(t)\, dt $$ Here $t$ represents Unix time (seconds). Averages are not block-weighted. **Stake threshold** The linear reward threshold is defined as the average stake per Validator: $$ T = \frac{\bar S_{\text{total}}}{N} $$ **Stake weighting function** Rewards grow linearly up to $T$ and sub-linearly beyond $T$: $$ w(\bar S_i) = \begin{cases} \bar S_i, & \text{if } \bar S_i \le T \\ \sqrt{\bar S_i \cdot T}, & \text{if } \bar S_i > T \end{cases} $$ This penalizes oversized Validators and incentivizes delegation toward smaller Validators. The curve is linear from zero up to the threshold $T$ (the average stake per Validator in the network). Above $T$, additional stake continues to earn rewards but at a diminishing rate. In practice: delegating to a Validator already above $T$ earns less marginal reward than delegating to one below it. Reward weight curve showing linear growth up to T and sub-linear growth above T *Reward weight as a function of total stake. Below $T$, each additional SAFE earns the same marginal reward. Above $T$, marginal reward decreases smoothly. $T$ is recalculated each reward period as total network stake divided by the number of active Validators.* **Participation filter** Validators must satisfy the minimum participation requirement in order for **any rewards (Validator or Delegator)** to be generated for that Validator: $$ \tilde w_i = \begin{cases} p_i \cdot w(\bar S_i), & \text{if } p_i \ge p_{\min} \\ 0, & \text{if } p_i < p_{\min} \end{cases} $$ If $p_i < p_{\min}$, no rewards are generated for Validator $i$ or its Delegators during that reward period. The minimum self-stake requirement affects Validator earnings only: if $\bar s_i < s_{\min}$ and $p_i \ge p_{\min}$, the Validator forfeits its commission on delegated stake, while Delegator rewards remain unaffected. **Reward allocation across Validators** $$ W = \sum_{k \in V} \tilde w_k $$ Validator $i$'s reward allocation: $$ R_i = R \cdot \frac{\tilde w_i}{W} $$ **Split between Validator and Delegators** *Attribution by stake source* Reward attributable to Validator self-stake: $$ R_i^{\text{self}} = R_i \cdot \frac{\bar s_i}{\bar S_i} $$ Reward attributable to delegated stake: $$ R_i^{\text{del}} = R_i \cdot \frac{\bar d_i}{\bar S_i} $$ *Commission split* If $\bar s_i \ge s_{\min}$: $$ R_i^{\text{Validator}} = R_i^{\text{self}} + c \cdot R_i^{\text{del}} $$ If $\bar s_i < s_{\min}$: $$ R_i^{\text{Validator}} = R_i^{\text{self}} $$ Delegator earnings: $$ R_i^{\text{Delegators}} = \begin{cases} (1 - c) \cdot R_i^{\text{del}}, & \text{if } \bar s_i \ge s_{\min} \\ R_i^{\text{del}}, & \text{if } \bar s_i < s_{\min} \end{cases} $$ Validator commission and self-stake rewards are paid to the Validator's registered Staker address as recorded at the end of the reward period. If the Staker address changes during the period, the full period's Validator rewards (including commission accrued before the change) are paid to the address registered at period end. **Per-Delegator reward** $$ R_{j,i} = R_i^{\text{Delegators}} \cdot \frac{\bar d_{j,i}}{\bar d_i} $$ **Minimum payout rule** Raw payouts: $$ P_i = R_i^{\text{Validator}} $$ $$ P_{j,i} = R_{j,i} $$ Final payouts: $$ \hat P_i = \begin{cases} P_i, & \text{if } P_i \ge m \\ 0, & \text{if } P_i < m \end{cases} $$ $$ \hat P_{j,i} = \begin{cases} P_{j,i}, & \text{if } P_{j,i} \ge m \\ 0, & \text{if } P_{j,i} < m \end{cases} $$ Total rewards paid out: $$ R_{\text{paid}} = \sum_{i \in V} \hat P_i + \sum_{i \in V} \sum_j \hat P_{j,i} $$ Unpaid rewards: $$ R_{\text{unpaid}} = R - R_{\text{paid}} $$ Unpaid rewards remain in the reward pool and are carried forward to the next reward period. ## Distribution Rewards are calculated offchain and distributed onchain via a Merkle distributor contract. Once allocated, rewards do not expire. Recipients must actively claim their rewards either: * Directly from the Merkle distributor contract, or * Through the dedicated staking / claiming interface. **Resources** * Rewards calculation & distribution: [safe-fndn/safenet-staking-scripts](https://github.com/safe-fndn/safenet-staking-scripts) * If approved, rewards can be claimed via one of the [available staking interfaces](http://safefoundation.org/safenet). ## Compliance As rewards are funded by assets of the SafeDAO and/or the Safe Ecosystem Foundation (SEF) compliance requirements apply. * Addresses sanctioned by OFAC, as identified through [Chainalysis' on-chain oracle](https://go.chainalysis.com/chainalysis-oracle-docs.html), are excluded from receiving rewards. * Addresses receiving rewards exceeding the equivalent of USD 1,000 within a two-week payout period are required to complete a compliance (potentially KYC/KYB) process prior to distribution. For KYC inquiries or to initiate the verification process, please contact [legal@safefoundation.org](mailto:legal@safefoundation.org). # Is my stake at risk? Source: https://docs.safefoundation.org/safenet/staking/risk Understanding the risks to staked SAFE tokens in Safenet Beta. Safenet is currently in Beta. Please carefully refer to the [Disclaimers](#disclaimers) section. ## No slashing in Beta In Safenet Beta, **staked tokens cannot be slashed**. There is no mechanism for the protocol to confiscate or destroy staked SAFE under any circumstances in the current phase. **Post-Beta**: Once slashing is introduced, a portion of staked tokens could be at risk if a Validator is found to have acted maliciously or violated protocol rules. The specific conditions, amounts, and governance process for slashing will be proposed ahead of that phase. It would need an active migration by every Staker. See: [Roadmap](/safenet/overview/roadmap) for a plan post-beta. ## Smart contract risk Staking SAFE tokens in any smart contract carries inherent risk. Key facts about the Staking contract: * The contract is **non-upgradeable**: its logic cannot be changed after deployment * It has been independently **audited**: See: [Security](/safenet/resources/security) for the full audit report and contract details * It holds no protocol-level permissions over your tokens beyond what you approve * By locking SAFE Tokens into the Staking Contract, you do so at your own risk, fully understanding and accepting the inherent risks associated with staking smart contracts As with any smart contract interaction, you should only stake amounts you are comfortable locking under these conditions. ## Withdrawal delay risk During the lock-up period, Stakers **cannot immediately exit**. Your tokens remain in the contract until the 2-day withdrawal delay passes after you initiate a withdrawal. * If a Validator is deregistered by the protocol owner, your withdrawal proceeds normally; deregistration does not block pending withdrawals. * If you need to exit urgently, you must wait out the delay period regardless of what happens to your Validator. → See: [Staking lock-up periods](/safenet/staking/lockup) for the full withdrawal flow. ## Validator performance risk If your chosen Validator's participation falls below **75%** during a reward period, **neither you nor the Validator earn rewards for that period**. Your staked SAFE tokens are not at risk; only your rewards for that period are forfeited. You can monitor your Validator's participation rate in the staking interface. If you want to move to a different Validator, you must go through a full withdrawal and restake cycle. There is no direct redelegation path. → See: [How to delegate stake](/safenet/staking/delegate) for how to choose a Validator and what to look for. ## Disclaimers * Participation in Safenet Beta Staking and the interaction with the Staking Contract and access to and use of any user interface happen AT YOUR OWN RISK and may be interfered with as a result of technical issues or other factors. * This Safenet Beta version is not final, exploratory, and may contain bugs, defects, logic errors, vulnerabilities, and other unforeseen risks. Features and functions may change, break, become unavailable, or behave unpredictably. Data loss or corruption may occur, including a potential loss of your SAFE Tokens or other digital assets that interact with the Safenet Beta Staking # How are Validators staked? Source: https://docs.safefoundation.org/safenet/staking/validator-staking Validator self-stake mechanics, minimum requirements, and how Validators are held accountable through reward penalties. Validators stake SAFE toward their own Validator address using the [Staking contract](https://github.com/safe-research/safenet/blob/beta/contracts/src/Staking.sol). They connect their Validator to their staking address by setting the `Staker` on the [Consensus contract](https://github.com/safe-research/safenet/blob/beta/contracts/src/Consensus.sol). Validator self-stake and delegated stake use the same deposit and withdrawal mechanics, but only Validator self-stake counts toward the minimum self-stake requirement. Validators earn 5% commission on rewards generated by delegated stake. → See: [Staking rewards](/safenet/staking/rewards) for the full reward and commission split. ## Minimum Validator stake Validators must maintain a minimum average stake of **3,500,000 SAFE** over each reward period to be eligible for Validator rewards. The average is time-weighted: tokens staked for the full period count fully; tokens added mid-period contribute proportionally. → See: [Staking rewards](/safenet/staking/rewards) for how the time-weighted average is calculated and how it affects reward allocation. ## Validator penalties In Safenet Beta, staked tokens cannot be confiscated. There is no slashing. Validators are subject to two reward penalties only. **Participation threshold**: If a Validator's participation falls below 75% in a reward period, no rewards are generated for that Validator or any of its Delegators for that period. **Self-stake requirement**: If a Validator's average self-stake falls below 3,500,000 SAFE, the Validator forfeits its own reward share for that period. Delegator rewards are unaffected. → See: [Is my stake at risk?](/safenet/staking/risk) for smart contract risk, audits, and future slashing plans. ## How to stake **Via the staking interface** Choose one of the [available staking interfaces](http://safefoundation.org/safenet). 1. Connect your wallet to the staking interface 2. Navigate to the Validator staking section 3. Enter the amount of SAFE to stake toward your Validator address 4. Approve the SAFE token transfer 5. Confirm the staking transaction Your stake is active once the transaction is confirmed. You can monitor your balance and reward eligibility in the Explorer. Validators need to set the `STAKER_ADDRESS` in their environment so their Gnosis Chain Validator address is connected to their Ethereum staking address. **Via the contract directly** For Validators who prefer to interact with the contract without a UI: ```solidity theme={null} // 1. Approve the Staking contract to spend your SAFE IERC20(SAFE_TOKEN_ADDRESS).approve(STAKING_ADDRESS, amount); // 2. Stake toward your Validator address Staking(STAKING_ADDRESS).stake(ValidatorAddress, amount); ``` If your wallet supports batch transactions, both steps can be combined into one. # Audits Source: https://docs.safefoundation.org/security/audits Independent security audits and formal verification reports for Safe smart contracts and core modules. Security is a top priority for Safe. All core Safe smart contracts and critical modules undergo independent security audits and, where applicable, formal verification. Below is a list of publicly available audit reports for Safe Smart Accounts and modules: ## Safe Smart Account audits * [Safe v1.5.0](https://github.com/safe-fndn/safe-smart-account/blob/release/v1.5.0/docs/audit_1_5_0.md) * [Safe v1.4.0](https://github.com/safe-fndn/safe-smart-account/blob/release/v1.4.1/docs/audit_1_4_0.md) * [Safe v1.3.0](https://github.com/safe-fndn/safe-smart-account/blob/release/v1.3.0/docs/audit_1_3_0.md) * [Safe v1.2.0](https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/docs/audit_1_2_0.md) * [Safe v1.1.0 & v1.1.1](https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/audit_1_1_1.md) * [Safe v1.0.0 (formal verification)](https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/rv_1_0_0.md) * [Safe v0.0.1](https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/docs/alexey_audit.md) ## Module audits * [Allowance Module v1.0.0](https://github.com/safe-fndn/safe-modules/blob/allowances/v1.0.0/modules/allowances/docs/v1.0.0/audit.md) * [Allowance Module v0.1.1](https://github.com/safe-fndn/safe-modules/blob/allowances/v1.0.0/modules/allowances/docs/v0.1.1/audit-report-ackee.pdf) * [Allowance Module v0.1.0](https://github.com/safe-fndn/safe-modules/blob/allowances/v1.0.0/modules/allowances/docs/v0.1.0/audit-report-g0.md) * [Safe 4337 Module v0.3.0](https://github.com/safe-fndn/safe-modules/blob/4337/v0.3.0/modules/4337/docs/v0.3.0/audit.md) * [Safe 4337 Module v0.2.0](https://github.com/safe-fndn/safe-modules/blob/4337/v0.3.0/modules/4337/docs/v0.2.0/audit.md) * [Safe 4337 Module v0.1.0](https://github.com/safe-fndn/safe-modules/blob/4337/v0.3.0/modules/4337/docs/v0.1.0/audit.md) * [Safe Passkey Module v0.2.1](https://github.com/safe-fndn/safe-modules/blob/passkey/v0.2.1/modules/passkey/docs/v0.2.1/audit.md) * [Safe Passkey Module v0.2.0](https://github.com/safe-fndn/safe-modules/blob/passkey/v0.2.1/modules/passkey/docs/v0.2.0/audit.md) * [Social Recovery Module v0.1.0](https://github.com/safe-fndn/safe-modules/blob/recovery/v0.1.0/modules/recovery/docs/v0.1.0/audit.md) ## Bug bounty If you discover a security issue, please report it responsibly. Contact us via email at [bounty@safefoundation.org](mailto:bounty@safefoundation.org) or learn more about our [bug bounty program](/security/bug-bounty). # Bug Bounty Program Source: https://docs.safefoundation.org/security/bug-bounty Report smart contract vulnerabilities in Safe Smart Accounts and earn rewards of up to $1,000,000 through responsible disclosure. This bug bounty program **applies only to smart contract–related vulnerabilities**. For issues related to [Safe\{Wallet}](https://app.safe.global), please contact [wallet-reports@safe.global](mailto:wallet-reports@safe.global). The Safe Bug Bounty program rewards security researchers who help identify vulnerabilities in Safe Smart Accounts and officially supported modules. Rewards can reach **up to \$1,000,000**, depending on severity and impact. Before submitting, please carefully review the rules and scope below. To report a vulnerability, contact us at [bounty@safefoundation.org](mailto:bounty@safefoundation.org). You can also review [past bounties](/security/past-bounties). ## Audits Safe smart contracts are regularly reviewed by independent security experts. For details, see the [Audits](/security/audits) page. ## Rules Many rules from the [Ethereum Foundation Bug Bounty Program](https://bounty.ethereum.org) apply to Safe as well: * Issues already known to the Safe team or previously reported are not eligible. * Public disclosure of a vulnerability makes it ineligible for a bounty. * Safe employees, contractors, auditors, and anyone paid by Safe (directly or indirectly) are not eligible. * Eligibility, severity classification, and reward amounts are determined solely by the Safe Bug Bounty panel. ## Scope The bug bounty covers core Safe contracts and selected officially supported modules. ### Safe Smart Account versions * **v1.5.0** ([Release](https://github.com/safe-fndn/safe-smart-account/releases/tag/v1.5.0), [README](https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/README.md)) * **v1.4.1** ([Release](https://github.com/safe-fndn/safe-smart-account/releases/tag/v1.4.1),[README](https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1/README.md)) * **v1.3.0** ([Release](https://github.com/safe-fndn/safe-smart-account/releases/tag/v1.3.0),[README](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/README.md)) * **v1.2.0** ([Release](https://github.com/safe-fndn/safe-smart-account/releases/tag/v1.2.0),[README](https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/README.md)) * **v1.1.1** ([Release](https://github.com/safe-fndn/safe-smart-account/releases/tag/v1.1.1),[README](https://github.com/safe-fndn/safe-smart-account/blob/v1.1.1/README.md)) ### Supported Safe Modules * [Safe Allowance Module v1.0.0](https://github.com/safe-fndn/safe-modules/tree/allowances/v1.0.0/modules/allowances) * [Safe 4337 Module v0.3.0](https://github.com/safe-fndn/safe-modules/tree/4337/v0.3.0/modules/4337) * [Safe Passkey Module v0.2.1](https://github.com/safe-fndn/safe-modules/tree/passkey/v0.2.1/modules/passkey) * [Social Recovery Module v0.1.0](https://github.com/safe-fndn/safe-modules/tree/recovery/v0.1.0/modules/recovery) ### Safenet Beta * [Safenet Beta Staking Contract v0.1.0](https://github.com/safe-research/safenet/blob/v0.1.0-rc.1/contracts/src/Staking.sol) ### In scope contracts **Safe core contracts (v1.4.1, v1.5.0)** * `Safe.sol`, `SafeL2.sol` * `SafeProxy.sol`, `SafeProxyFactory.sol` * `MultiSend.sol`, `MultiSendCallOnly.sol`, `CreateCall.sol` * `TokenCallbackHandler.sol`, `CompatibilityFallbackHandler.sol`, `ExtensibleFallbackHandler.sol` **Legacy Gnosis Safe contracts (v1.1.1, v1.2.0, v1.3.0)** * `GnosisSafe.sol`, `GnosisSafeL2.sol` * `GnosisSafeProxy.sol`, `GnosisSafeProxyFactory.sol` * `CreateAndAddModules.sol`, `MultiSend.sol`, `MultiSendCallOnly.sol`, `CreateCall.sol` * `DefaultCallbackHandler.sol`, `CompatibilityFallbackHandler.sol` **Module contracts** * `AllowanceModule.sol` * `Safe4337Module.sol` * `SafeWebAuthnSignerFactory.sol` * `SafeWebAuthnSignerProxy.sol` * `SafeWebAuthnSignerSingleton.sol` * `SafeWebAuthnSharedSigner.sol` * `WebAuthn.sol`, `P256.sol` **Safenet Beta contracts** * `Staking.sol` Deployed contract addresses can be found in the [Safe Deployments repository](https://github.com/safe-global/safe-deployments). ### Examples of issues in scope * Theft of funds or tokens * Freezing or permanently locking funds * Replay attacks on the same chain * Changing Safe or module settings without owner consent ### Out of scope * Contracts, modules, or libraries not listed above * Gas optimizations * Known issues listed in audits or documentation * Issues already fixed in newer versions * Issues related to additional non-standard features or alternative gas schedules on EVM-compatible chains that differ from Ethereum Mainnet ## Intended behavior To understand expected contract behavior, refer to: * The [Safe Smart Account README](https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/README.md) * Release notes and the [CHANGELOG](https://github.com/safe-fndn/safe-smart-account/blob/v1.5.0/CHANGELOG.md) * The [Safe Smart Account documentation](/smart-account/overview) For modules: * [Safe Allowance Module README](https://github.com/safe-fndn/safe-modules/tree/allowances/v1.0.0/modules/allowances/README.md) * [Safe 4337 Module README](https://github.com/safe-fndn/safe-modules/tree/4337/v0.3.0/modules/4337/README.md) * [Safe Passkey README](https://github.com/safe-fndn/safe-modules/tree/passkey/v0.2.1/modules/passkey/README.md) * [Social Recovery Module README](https://github.com/safe-fndn/safe-modules/blob/recovery/v0.1.0/modules/recovery/README.md) For Safenet Beta: * [Safenet Beta Staking Documentation](/safenet/staking/overview) ## Compensation All valid bug reports are considered for a bounty. Rewards depend on severity and impact. ### High severity — up to \$1,000,000 * Direct theft of funds or tokens * Permanent fund lockups * Bugs that require an urgent redeploy ### Medium severity — up to \$50,000 * Fund loss due to unexpected or unintuitive behavior * Issues users cannot reasonably anticipate ### Low severity — up to \$10,000 * Fee avoidance * Exploits that degrade user experience Bounties are paid in [USDC on Ethereum Mainnet](https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48). Submission quality matters. A strong report includes a clear explanation and reproducible steps. ## Submission process Email your report to [bounty@safefoundation.org](mailto:bounty@safefoundation.org). Please include: * A detailed description of the issue * Steps to reproduce * Your Ethereum Mainnet address for payment Anonymous submissions are welcome. If multiple addresses are provided, one will be selected at Safe’s discretion. For details on data handling, see our [Privacy Policy](https://safefoundation.org/privacy). ## Responsible disclosure policy If you follow the guidelines below, Safe will not pursue legal action in response to your report. We ask that you: * Allow reasonable time for investigation and remediation before public disclosure * Avoid privacy violations or service disruption * Do not exploit the issue in production * Comply with all applicable laws Public disclosure or intent to exploit a vulnerability on Mainnet will make a report ineligible for a bounty. When in doubt, the [Ethereum Foundation Bug Bounty rules](https://bounty.ethereum.org) apply. Questions? Contact us at [bounty@safefoundation.org](mailto:bounty@safefoundation.org). *Happy hunting!* ## Note on Safe\{Wallet} Issues related to **Safe\{Wallet}** (web, mobile, or backend services) are generally **out of scope**. For non-security bugs, open an issue in the relevant repository, such as [safe-wallet-monorepo](https://github.com/safe-global/safe-wallet-monorepo/issues). For **severe security issues** affecting Safe\{Wallet}, contact [wallet-reports@safe.global](mailto:wallet-reports@safe.global).\ Any rewards for Safe\{Wallet} issues are granted at the sole discretion of the team maintaining Safe\{Wallet}. # Past bounties Source: https://docs.safefoundation.org/security/past-bounties This list includes valid submissions from past and current contract versions for which a bounty has been paid. ## Potential suicide of MultiSend library We use a [MultiSend](https://github.com/safe-fndn/safe-smart-account/blob/v1.2.0/contracts/libraries/MultiSend.sol) library to batch multiple transactions together. A transaction could be created that would self-destruct the contract. While this would not have put any funds at risk, user experience would have been seriously impacted. We've updated the library as well as our interfaces. Details about the fix can be found on [GitHub](https://github.com/safe-fndn/safe-smart-account/pull/156). This bug was submitted by [Micah Zoltu](https://x.com/micahzoltu). It was regarded as a "Low Threat," and a bounty of 1,000 USD has been paid out. ## Transaction failure when receiving funds via `transfer` or `send` Since the beginning of the bug bounty period, the contract update has been live on the Ethereum Mainnet. We performed extensive internal testing and discovered an edge case where a Safe couldn't receive funds from another contract via `send` or `transfer`. This was due to additional gas costs caused by the [emission of additional events](https://github.com/safe-fndn/safe-smart-account/pull/135) and [gas price changes](https://eips.ethereum.org/EIPS/eip-1884) in the latest hard fork. This issue has been fixed, and more details can be found on [GitHub](https://github.com/safe-fndn/safe-smart-account/issues/149). ## Duplicate owners during setup could render Safe unusable A bug in the `setupOwners` function on `OwnerManager.sol` allows duplicate owners to be set when the duplicated address is next to itself in the `_owners` array. This could cause unexpected behavior. While stealing funds from existing Safes is impossible, it's unexpected, and user funds might be locked. During Safe creation, the threshold of a Safe could be set to something unreachable, making it impossible to execute a transaction afterward. The Safe interfaces prevent this by checking for duplicates, but if users directly interact with the contracts, this can still happen. The issue is tracked on [GitHub](https://github.com/safe-fndn/safe-smart-account/issues/244). This bug was submitted by [David Nicholas](https://x.com/davidnich11). It was regarded as a "Medium Threat," and a bounty of 2,500 USD has been paid out. ## Setting a Safe as an owner of itself essentially reduces the threshold by 1 The contracts allow to set a Safe as an owner of itself. This has the same effect as lowering the threshold by 1, as it's possible for anyone to generate a valid signature for the Safe itself when triggering `execTransaction`. This is especially an issue for Safes with a threshold of 1. Anyone can execute transactions if a Safe with threshold 1 adds itself as an owner. To our knowledge, there is no actual use case where it would make sense to set a Safe as an owner of itself. Hence, only a few number of Safes used themselves as owners. Most of these Safes could be contacted, and the Safe has been removed as an owner. The Safes still affected are Safes used for testing by us or Safes owned by a single owner with a threshold > 1 (so no immediate risk). To fix this, the next contract update will prevent the Safe as its owner via `require(owner != address(this), "Safe can't be an owner")`. This check can be performed when adding owners and/or when checking signatures. Details about this issue can be found on [GitHub](https://github.com/safe-fndn/safe-smart-account/issues/229). The bug was submitted by [Kevin Foesenek](https://github.com/keviinfoes). It was regarded as a "Medium Threat," and a bounty of 5,000 USD has been paid out. ## The function `getModulesPaginated` doesn't return all modules The method [getModuledPaginated](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/contracts/base/ModuleManager.sol#L114) is used to return enabled modules page by page. For this, a `start` and a `pageSize` need to be specified, and the method will return an array of Safe Module addresses and `next`. This next can be used as the `start` to load the next page. When another page exists, then `next` is a module address. This module address, however, won't be present in any of the returned arrays. While this doesn't put any user assets at risk directly, it could lead to a wrong perception of the enabled modules of a Safe and, thereby, its state. The workaround is to append the `next` to the returned array of module addresses if it's not the zero or sentinel address. Alternatively, the last element of the returned array can be used as the `start` for the next page. This bug was submitted by [Renan Souza](https://github.com/RenanSouza2). It was regarded as a "Low Threat," and a bounty of 2,000 USD has been paid out. ## Signature verification does not enforce a maximum size on the signature bytes The function [`checkNSignatures`](https://github.com/safe-fndn/safe-smart-account/blob/v1.4.1/contracts/Safe.sol#L274) does not enforce a size limit on the signature bytes. This means that they can be padded with arbitrary data. This can be used by manipulating the `signatures` by padding them with additional data while remaining valid and, since the `signatures` bytes get copied from `calldata` into memory, increase the total gas consumption of the `checkNSignatures` function. This is an issue when the Safe is combined with the [ERC-4337 module](https://github.com/safe-fndn/safe-modules/tree/4337/v0.3.0/modules/4337), where the account pays the gas costs for the ERC-4337 user operation. A malicious relayer can grief the account by padding the `signatures` bytes to include extra 0s, causing the account to pay more fees than it would have with optimally encoded `signatures` bytes. The workaround is to set a strict `verificationGasLimit` for ERC-4337 user operations. This would set a strict upper bound on how much gas can be paid during signature verification and limit the potential additional fees. This bug was submitted by [Adam Egyed](https://github.com/adamegyed). It was regarded as a "Low Threat," and a bounty of 1,000 USD has been paid out. ## Transfer replay in Allowance Module A bug in the allowance module would overflow the `nonce` for a delegate and allow past executed transfers for that particular delegate and token to be replayed. This would allow previously signed transfers to be executed again, as the nonce would start counting again from 0. Note that this only affects delegates that have executed 65536 transfers for a specific token allowance, including a transfer with nonce 0. This does not seem to affect any active accounts at the time of writing. This bug was submitted by [Max Knyazev](https://x.com/mattakuro10). It was regarded as a "Medium Threat," and a bounty of 30,000 USD has been paid out. # Concepts Source: https://docs.safefoundation.org/smart-account/concepts Core concepts behind Safe Smart Accounts, including ownership, thresholds, signature verification, and transaction execution. ## Owners Each Safe Smart Account stores a list of [owners](/more/glossary#owner) on-chain as Ethereum addresses. Owners collectively control the account: they can approve transactions and update the Safe’s configuration. Adding or removing an owner requires a valid Safe transaction approved by the current owners (according to the threshold). ## Threshold A Safe also stores a [threshold](/more/glossary#threshold): the minimum number of owner approvals required to execute a transaction. Owners can update the threshold through a Safe transaction. The threshold must be between **1** and the **total number of owners**. ## Signature verification Because a Safe is a smart contract, it does not have a private key. The EVM therefore cannot “authenticate” a Safe transaction the way it does for EOAs. Instead, the Safe contract performs authentication and authorization in its own code. When a transaction is submitted to a Safe, the Safe: 1. Computes the transaction hash from the submitted parameters. 2. Verifies that each signer is a current owner. 3. Validates each signature according to its type (for example EOAs, contract signatures, or other supported schemes). 4. Checks that the number of valid approvals meets the threshold. 5. Executes the transaction if the checks pass; otherwise, the call reverts. To learn about supported signature types and encoding, see [Signatures](/smart-account/signatures). ## Transaction flow Safe executes transactions through two main paths: **Safe transactions** (approved by owners) and **module transactions** (initiated by enabled modules). ### Safe transaction Safe Smart Account exposes `execTransaction` to execute a transaction that has been approved by the owners. To execute a Safe transaction, call `execTransaction` with: * `to`: Recipient address. * `value`: Amount of ETH to send (in wei). * `data`: Calldata, typically a function call on `to`. * `operation`: Execution type: `CALL` or `DELEGATECALL`. * `safeTxGas`: Gas allocated to the Safe transaction execution. * `baseGas`: Gas overhead for tasks such as signature checks and refunds. `safeTxGas + baseGas` is comparable to the gas limit of a regular transaction. * `gasPrice`: Gas price used for refunds. If set to `0`, no refund is paid. * `gasToken`: Token used to pay the refund. Use `0x0` for ETH; otherwise an ERC-20 token address. Refund cost is calculated as `(baseGas + safeTxGas) * gasPrice`. * `refundReceiver`: Address that receives the refund. If set to `0`, `tx.origin` is used. * `signatures`: Hex-encoded owner signatures over the transaction hash. Signatures must be **sorted by owner address** so the Safe can efficiently prevent duplicates. ### Module transaction Safe also exposes `execTransactionFromModule` and `execTransactionFromModuleReturnData` to execute transactions initiated by enabled modules. A module can be any contract address that has been explicitly enabled on the Safe. Once enabled, a module can execute transactions through the Safe **without going through owner signature verification** (which is why modules are security-critical). Module calls include: * `to`: Recipient address. * `value`: Amount of ETH to send (in wei). * `data`: Calldata, typically a function call on `to`. * `operation`: Execution type: `CALL` or `DELEGATECALL`. ## Core components The following components are central to how Safe Smart Accounts are extended and secured. ## Safe Modules [Safe Modules](/more/glossary#safe-module) are smart contracts that extend Safe functionality while keeping module logic separate from the Safe core contracts. Learn more on the [Safe Modules](/smart-account/modules) page. ## Safe Guards [Safe Guards](/more/glossary#safe-guard) perform checks before and after a Safe transaction is executed. Learn more on the [Safe Guards](/smart-account/guards) page. ## Signatures Safe supports multiple signature schemes, including [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712). It also supports relayed execution by keeping confirmation and verification logic independent of `msg.sender`. For details on supported signature schemes and encoding, see: * [Signatures](/smart-account/signatures) * [Safe signature documentation](https://github.com/safe-fndn/safe-smart-account/blob/main/docs/signatures.md) # Fallback handler Source: https://docs.safefoundation.org/smart-account/fallback-handler Extend Safe Smart Accounts with additional logic executed on unmatched function calls, while keeping the core contract minimal. Using a Safe Fallback Handler is security-critical. Because fallback handlers can execute arbitrary external logic within a Safe Smart Account, only use handlers from trusted sources that have undergone thorough security audits. The **Safe Fallback Handler** allows a Safe Smart Account to support additional functionality without modifying the core Safe contract. It exists primarily to work around Ethereum’s **24 KB contract size limit** by delegating optional or auxiliary logic to an external smart contract. Fallback handlers enable Safe to remain minimal and secure, while still supporting advanced behaviors such as token callbacks, signature validation, and compatibility utilities. A Safe Smart Account does **not** require a fallback handler by default. Adding or removing a fallback handler requires a Safe transaction approved by the configured owner threshold. Whenever the fallback handler is updated, an event is emitted to ensure transparency and auditability. ## How it works When a fallback handler is configured, it is invoked whenever a transaction is sent to the Safe and the function selector in the calldata does **not** match any function defined in the Safe singleton contract. When forwarding a call, the Safe: * delegates execution to the configured fallback handler * appends the original caller’s address to the calldata This allows the fallback handler to reliably identify who initiated the call and apply appropriate logic or validation. Fallback handler diagram ## Examples The following fallback handlers demonstrate common patterns and real-world use cases for extending Safe Smart Accounts. ### TokenCallbackHandler Source code:\ [TokenCallbackHandler](https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/handler/TokenCallbackHandler.sol) Handles callbacks from supported token standards, enabling Safe accounts to receive tokens safely. Supported interfaces: * `ERC1155TokenReceiver` * `ERC777TokensRecipient` * `ERC721TokenReceiver` ### CompatibilityFallbackHandler Source code:\ [CompatibilityFallbackHandler](https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) Extends `TokenCallbackHandler` and adds several compatibility and utility features: * Implements **ERC-1271** via `isValidSignature`, enabling on-chain signature verification * Provides a `simulate` function that performs a static `delegatecall` and then reverts, allowing off-chain simulation without state changes * Exposes helper functions: * **`getMessageHash`**: Generates a message hash scoped to the calling Safe * **`encodeMessageDataForSafe`**: Encodes messages using the Safe’s domain separator and a predefined type hash * **`getMessageHashForSafe`**: Combines encoding and hashing into a final message hash * **`getModules`**: Returns a paginated list (first 10 entries) of enabled Safe modules ### ExtensibleFallbackHandler Source code:\ [ExtensibleFallbackHandler](https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/handler/ExtensibleFallbackHandler.sol) Allows assigning different fallback handlers to specific function selectors, enabling fine-grained control over how unmatched calls are handled. ### Safe4337Module as fallback handler Source code:\ [Safe4337Module](https://github.com/safe-fndn/safe-modules/blob/main/modules/4337/contracts/Safe4337Module.sol) Implements the `validateUserOp` function defined by **ERC-4337**, enabling Safe Smart Accounts to act as ERC-4337–compatible smart contract wallets. # Guards Source: https://docs.safefoundation.org/smart-account/guards Add programmable pre- and post-execution checks to Safe Smart Accounts to enforce custom transaction restrictions. Safe Guards were introduced in [Safe contracts version 1.3.0](https://github.com/safe-fndn/safe-smart-account/blob/v1.3.0/CHANGELOG.md). Safe Guards add an additional security layer on top of Safe’s `n`-out-of-`m` multi-signature scheme. They allow Safe owners to define **custom rules** that determine whether a transaction should be allowed to execute. A Safe Guard can perform checks: * **Before execution**, to validate the transaction parameters and context * **After execution**, to verify the final state of the Safe once the transaction has completed Pre-execution checks can inspect all transaction parameters—such as the target address, calldata, value, and operation type—and decide whether the transaction should proceed.\ Post-execution checks run at the end of the transaction and can be used to assert invariants or detect unexpected state changes. Guards are commonly used to: * restrict interactions to approved contracts * enforce protocol-specific invariants * add additional safety checks around sensitive operations To explore real-world examples of Safe Guards, see: * [Zodiac Guard implementations](https://github.com/gnosis/zodiac-guard-scope) * [Yearn Guard design](https://mirror.xyz/yearn-finance-engineering.eth/9uInM_sCrogPBs5qkFSNF6qe-32-0XLN5bty5wKLVqU) Safe Guards diagram Important: Safe Guards are security-critical. Because a Guard can block transaction execution entirely, a faulty or malicious Guard can cause a denial of service and lock funds in a Safe. Only use well-reviewed and audited Guards, and always consider recovery mechanisms. # Migration Source: https://docs.safefoundation.org/smart-account/migration Safely upgrade an existing Safe Smart Account proxy to a newer Singleton implementation. ## Overview As the smart account ecosystem evolves, Safe periodically releases new versions of the **Safe Singleton** contract. Each Safe Smart Account is implemented as a **SafeProxy**, which delegates all logic to a Singleton contract whose address is stored in storage slot `0`. Existing SafeProxy contracts can be upgraded to point to a newer Singleton implementation. This process preserves the Safe’s address, owners, and configuration, but requires an explicit migration transaction approved by the Safe owners. The migration is performed via `delegatecall` and must be executed with care. This guide walks through a step-by-step example of migrating an existing SafeProxy to a newer Singleton using the **SafeMigration** contract and the Safe Protocol Kit. Only migrate to trusted and audited Singleton implementations. A malicious or incompatible implementation can take control of the SafeProxy, resulting in permanent loss of access and funds. Always verify compatibility between the existing SafeProxy and the target Singleton version before migrating. ## Migration process The first step in any migration is identifying the address of the target Singleton contract. Safe provides the **SafeMigration** contract, which updates the Singleton address stored in a SafeProxy. * SafeMigration source:\ [https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/libraries/SafeMigration.sol](https://github.com/safe-fndn/safe-smart-account/blob/main/contracts/libraries/SafeMigration.sol) * Official SafeMigration deployments are listed in the\ [Safe Deployments repository](https://github.com/safe-global/safe-deployments) ## SafeMigration contract methods The currently available SafeMigration contract supports upgrades to **Safe Singleton v1.4.1**. ### `migrateSingleton()` Updates the SafeProxy to point to the new L1 Singleton implementation. ### `migrateWithFallbackHandler()` Updates both the Singleton implementation and the fallback handler. ### `migrateL2Singleton()` Updates the SafeProxy to point to the L2 Singleton implementation. ### `migrateL2WithFallbackHandler()` Updates the L2 Singleton implementation and the fallback handler. ## Requirements * An already deployed SafeProxy contract * Compatibility between the existing SafeProxy and Singleton v1.4.1 * For simplicity, this example assumes a Safe with a **threshold of 1** ## Migration tutorial ```bash theme={null} mkdir safe-migration-tutorial && cd safe-migration-tutorial npm init -y npm install @safe-global/protocol-kit @safe-global/types-kit viem ``` Add typescript support to the project: ```bash theme={null} npm install --save-dev typescript ts-node npx tsc --init ``` The `SafeMigration` contract provides four methods for migration. Update the `package.json` to add the following script commands: The migration script will read the argument and choose the appropriate method to execute. ```json theme={null} ... "scripts": { ... "migrate:L1": "ts-node ./src/migrate.ts migrateSingleton", "migrate:L2": "ts-node ./src/migrate.ts migrateL2Singleton", "migrate:L1:withFH": "ts-node ./src/migrate.ts migrateWithFallbackHandler", "migrate:L2:withFH": "ts-node ./src/migrate.ts migrateL2WithFallbackHandler" }, ... ``` Create a new file `src/migrate.ts` and add the following code: ```bash theme={null} mkdir src touch src/migrate.ts ``` ```typescript theme={null} import Safe from "@safe-global/protocol-kit"; import { MetaTransactionData, OperationType } from "@safe-global/types-kit"; import { parseAbi, encodeFunctionData, http, createPublicClient } from "viem"; type MigrationMethod = | "migrateSingleton" | "migrateWithFallbackHandler" | "migrateL2Singleton" | "migrateL2WithFallbackHandler"; async function main(migrationMethod: MigrationMethod) { // Define constants // Build calldata for the migration // Initialize the Protocol Kit // Create and execute transaction } const migrationMethod = process.argv.slice(2)[0] as MigrationMethod; main(migrationMethod).catch(console.error); ``` Define the constants required for the migration script. Replace the placeholders with the actual values. ```typescript theme={null} // Define constants const SAFE_ADDRESS = // ... const OWNER_PRIVATE_KEY = // ... const RPC_URL = // ... const SAFE_MIGRATION_CONTRACT_ADDRESS = // ... const ABI = parseAbi([ "function migrateSingleton() public", "function migrateWithFallbackHandler() external", "function migrateL2Singleton() public", "function migrateL2WithFallbackHandler() external", ]); ``` ```typescript theme={null} // Build calldata for the migration const calldata = encodeFunctionData({ abi: ABI, functionName: migrationMethod, }); const safeTransactionData: MetaTransactionData = { to: SAFE_MIGRATION_CONTRACT_ADDRESS, value: "0", data: calldata, operation: OperationType.DelegateCall, }; ``` ```typescript theme={null} // Initialize the Protocol Kit const preExistingSafe = await Safe.init({ provider: RPC_URL, signer: OWNER_PRIVATE_KEY, safeAddress: SAFE_ADDRESS, }); ``` ```typescript theme={null} // Create and execute transaction const safeTransaction = await preExistingSafe.createTransaction({ transactions: [safeTransactionData], }); console.log( `Executing migration method [${migrationMethod}] using Safe [${SAFE_ADDRESS}]` ); const result = await preExistingSafe.executeTransaction(safeTransaction); const publicClient = createPublicClient({ transport: http(RPC_URL), }); console.log(`Transaction hash [${result.hash}]`); await publicClient.waitForTransactionReceipt({ hash: result.hash as `0x${string}`, }); ``` ```typescript theme={null} import Safe from "@safe-global/protocol-kit"; import { MetaTransactionData, OperationType } from "@safe-global/types-kit"; import { parseAbi, encodeFunctionData, http, createPublicClient } from "viem"; type MigrationMethod = | "migrateSingleton" | "migrateWithFallbackHandler" | "migrateL2Singleton" | "migrateL2WithFallbackHandler"; async function main(migrationMethod: MigrationMethod) { const SAFE_ADDRESS = // ... const OWNER_PRIVATE_KEY = // ... const RPC_URL = // ... const SAFE_MIGRATION_CONTRACT_ADDRESS = // ... const ABI = parseAbi([ "function migrateSingleton() public", "function migrateWithFallbackHandler() external", "function migrateL2Singleton() public", "function migrateL2WithFallbackHandler() external", ]); const calldata = encodeFunctionData({ abi: ABI, functionName: migrationMethod, }); const safeTransactionData: MetaTransactionData = { to: SAFE_MIGRATION_CONTRACT_ADDRESS, value: "0", data: calldata, operation: OperationType.DelegateCall, }; const preExistingSafe = await Safe.init({ provider: RPC_URL, signer: OWNER_PRIVATE_KEY, safeAddress: SAFE_ADDRESS, }); const safeTransaction = await preExistingSafe.createTransaction({ transactions: [safeTransactionData], }); console.log( `Executing migration method [${migrationMethod}] using Safe [${SAFE_ADDRESS}]` ); const result = await preExistingSafe.executeTransaction(safeTransaction); const publicClient = createPublicClient({ transport: http(RPC_URL), }); console.log(`Transaction hash [${result.hash}]`); await publicClient.waitForTransactionReceipt({ hash: result.hash as `0x${string}`, }); } const migrationMethod = process.argv.slice(2)[0] as MigrationMethod; main(migrationMethod).catch(console.error); ``` Run one of the below commands: ```bash theme={null} npm run migrate:L1 ``` ```bash theme={null} npm run migrate:L2 ``` ```bash theme={null} npm run migrate:L1:withFH ``` ```bash theme={null} npm run migrate:L2:withFH ``` ## Further actions * The migration script can be extended to support Safe Account migration with a threshold of more than one. Users can use the [Safe API Kit](https://github.com/safe-global/safe-core-sdk/tree/main/packages/api-kit) to propose the transactions, fetch transaction data, and sign them. * The source code for this script is available in the [Safe Migration Script repository](https://github.com/5afe/safe-migration-script). # Modules Source: https://docs.safefoundation.org/smart-account/modules Extend Safe Smart Accounts with modular smart contracts that enable automation, custom authorization, and advanced execution logic. ## Overview Safe Modules are smart contract extensions that add custom functionality to a Safe Smart Account. They operate alongside Safe’s core multi-signature logic and can execute transactions on behalf of a Safe according to their own rules. Modules allow Safe accounts to support automation, custom authorization schemes, and advanced workflows, while keeping this logic **separate from the Safe core contracts**. A basic Safe does not require any modules, but modules can be enabled or disabled through a Safe transaction approved by the required owner threshold. Multiple modules can be enabled at the same time, making Safe highly configurable for different use cases. Events are emitted whenever a module is added or removed, and when a module-initiated transaction succeeds or fails. ### Why use Safe Modules? Safe Modules enable: * **Automation**\ Recurring payments, scheduled transactions, or automated DeFi interactions without manual approvals. * **Enhanced security controls**\ Rules such as spending limits, whitelists, or rate limits that restrict how funds can be used. * **Scalability**\ Complex logic can be delegated to specialized contracts instead of bloating the Safe core. * **Flexibility**\ Safes can be tailored to unique workflows, DAO operations, or integrations with DeFi protocols. By decoupling this functionality from the Safe Smart Account itself, modules allow new capabilities to be developed and deployed without weakening Safe’s core security guarantees. Common examples of Safe Modules include: * daily or periodic spending allowances * recurring payment and standing order modules * social recovery modules that restore access if owners lose their keys Safe Modules diagram ## How Safe Modules work 1. **Enable a module**\ A module is enabled by calling `enableModule()` through a Safe transaction.\ The Safe stores the module address in an internal registry of authorized modules. 2. **Trigger a module action**\ A user (either an EOA or a contract) interacts with the module by calling one of its functions. 3. **Module validation**\ The module verifies that: * the caller is authorized * the requested action complies with the module’s rules 4. **Transaction execution**\ If the checks pass, the module calls `execTransactionFromModule` on the Safe to execute the transaction. ## Creating a Safe Module The best way to understand Safe Modules is to build one. A good starting point is the tutorial: [Safe Modding 101: Create your own Safe Module](https://www.youtube.com/watch?v=nmDYc9PlAic) ## Examples * [Safe Modules repository](https://github.com/safe-fndn/safe-modules) * [Zodiac-compliant modules](https://www.zodiac.wiki/documentation) * [Pimlico Safe integrations](https://docs.pimlico.io/permissionless/how-to/accounts/use-safe-account) Safe Modules are security-critical. Because modules can execute arbitrary transactions on behalf of a Safe, only enable modules that are trusted, well-reviewed, and audited. A malicious module can fully compromise a Safe. # Multi-chain Source: https://docs.safefoundation.org/smart-account/multi-chain Deploy the same Safe Smart Account address across multiple EVM-compatible chains using deterministic deployment. ## Why deploy a Safe on multiple chains? Deploying the same Safe Smart Account on multiple chains can be useful in several scenarios: * **Accidental fund transfers**\ If funds are mistakenly sent to a chain where the Safe has not yet been deployed, deploying the Safe on that chain allows the funds to be recovered. * **Cross-chain operations**\ Users and teams operating across multiple chains benefit from having the **same Safe address** everywhere, simplifying treasury management, access control, and operational workflows. *** ## How it works A Safe can be deployed on multiple chains at the **same address** by replaying the original deployment using deterministic contract creation. In addition to manually constructing the deployment transaction, Safe provides the following supported options: * **Safe\{Wallet} UI**\ The Safe\{Wallet} interface allows users to deploy an existing Safe to additional chains using the same address. * **Safe Protocol Kit**\ The Safe Protocol Kit supports multi-chain Safe deployments programmatically.\ See the [Protocol Kit multi-chain deployment guide](https://docs.safe.global/sdk/protocol-kit/guides/multichain-safe-deployment). ### Deployment process Multi-chain deployment is performed via the **Safe Proxy Factory** using deterministic deployment (`CREATE2`). The resulting Safe address is derived from the following inputs: * Proxy Factory contract address * Safe Singleton contract address * Deployment salt * `initializer` calldata * Proxy creation bytecode As long as all inputs are identical, the deployed Safe address will be the same across chains. *** ## Exceptions and limitations * **Non-EVM chains**\ This method only works on EVM-compatible chains. Non-EVM chains (for example, zkSync Era) are not supported. * **Version compatibility**\ Safes created using Singleton **v1.3.0 or later** are compatible with multi-chain deployment.\ Safes created from Singletons **v1.0.0, v1.1.1, or v1.2.0** cannot be replayed on additional chains using this method. *** ## Important considerations When deploying a Safe across multiple chains, keep the following in mind: * **Identical configuration**\ The Safe deployed on another chain will start with the *exact same configuration* as the original Safe at deployment time, including owners, threshold, and enabled modules. All required owner keys must be available to access and manage the Safe on the new chain. * **Security assumptions**\ Do not use this method if any of the initial owner keys are compromised, as the compromised configuration will be replicated on the new chain. * **Version immutability**\ The Singleton version used during deployment is fixed. You cannot change the Singleton version while replaying the deployment on additional chains. *** ## References * [Deploying a multi-chain Safe](https://help.safe.global/en/articles/222612-deploying-a-multi-chain-safe) By understanding these constraints and guarantees, you can safely deploy and operate the same Safe Smart Account across multiple chains. # Overview Source: https://docs.safefoundation.org/smart-account/overview How Safe Smart Accounts work ## Externally-Owned Accounts (EOAs) [Externally-Owned Accounts (EOAs)](/more/glossary#externally-owned-account) are the traditional type of Ethereum account. They are controlled by a single private key, which is used to sign transactions and messages. Anyone with access to this private key has **full control** over the account. As a result, EOAs have a **single point of failure**: if the private key is lost or compromised, the funds and permissions associated with the account are lost as well. ## Smart Accounts The second type of Ethereum account is the [Smart Account](/more/glossary#smart-account), also referred to as a smart contract account. Like EOAs, smart accounts: * have a unique Ethereum address * can receive funds * can interact with other contracts From the outside, smart accounts are indistinguishable from EOAs based on their address alone. The key difference is **how transactions are authorized**.\ Smart accounts do not rely on a single private key. Instead, **on-chain smart contract logic** defines who can execute transactions, under which conditions, and how they are validated. Because this logic is programmable, smart accounts can support advanced features such as: * multi-signature authorization * fine-grained access control * transaction batching * account recovery mechanisms * custom execution rules ## EOAs vs. Smart Accounts Ethereum Accounts ## Safe Smart Account A **Safe Smart Account** is a smart account with **multi-signature security** at its core. It is designed to be both secure by default and highly extensible, making it suitable for managing funds and executing transactions across Ethereum and other EVM-compatible networks. The long-term vision for Safe Smart Accounts is to serve as the **standard account abstraction layer** for smart contract–based wallets, making the benefits of Account Abstraction accessible to both users and developers. ### Design Principles The architecture of Safe Smart Accounts follows two core principles: #### Secure by default Safe uses a multi-signature model where a configurable threshold of owners must approve a transaction before it can be executed. This provides strong security guarantees without requiring trust in additional components such as modules, guards, or fallback handlers. #### Maximum flexibility Safe supports: * **Modules**, which enable alternative execution patterns beyond multi-signature * **`delegatecall`**, allowing Safe to execute logic defined in external contracts This design enables advanced workflows while keeping the core contract minimal and secure. ## Features ### High security Safe’s **multi-signature** functionality allows you to define: * a list of owner accounts * a threshold number of approvals required to execute a transaction Owners can be: * EOAs * other smart accounts * passkeys or other authentication mechanisms Once the required number of approvals is collected, the transaction can be executed on-chain. ### Advanced execution logic Safe supports complex execution patterns through **Safe library contracts**. A common example is **batched transactions**, where multiple Ethereum transactions are grouped and executed together. This allows users to approve a single transaction instead of signing many individual ones. ### Advanced access management Safe can be extended using **Safe Modules**, which enable fine-grained access control. Examples include: * **Recovery modules** that restore access under predefined conditions * **Allowance modules** that grant limited execution rights, such as daily spending limits for external accounts Modules are optional and can be added or removed through owner confirmations. ### Token callback support Many token standards require wallet contracts to implement callbacks.\ Safe supports token callbacks for standards such as: * **ERC-721** * **ERC-1155** This allows Safe to react to incoming token transfers and, if necessary, reject them. ### Sponsored and token-paid transactions Normally, Ethereum transactions require ETH to pay gas fees. Safe enables alternative payment models, including: * paying gas fees with supported ERC-20 tokens * fully gasless transactions where a third party sponsors the fees This is implemented via transaction relay services that submit transactions on behalf of the Safe and handle gas payment in ETH. ## Architecture Safe Smart Accounts Architecture ### Safe Singleton Factory The **Safe Singleton Factory** deploys Safe-related contracts and enables deterministic contract addresses across different networks. This allows Safe Smart Accounts and their proxies to be deployed at the same address on multiple chains. See also: * [Safe Singleton Factory repository](https://github.com/safe-fndn/safe-singleton-factory) ### Safe Proxy Factory The **Safe Proxy Factory** provides a convenient way to: * deploy a Safe proxy * point it to a Safe singleton * execute the initial setup All of this happens within a single transaction. ### Safe (Singleton) The **Safe** contract is a singleton that contains the core logic for: * signature verification * transaction execution * owner management * module management * fallback handling * guards The Safe singleton is **not used directly**. Instead, Safe accounts interact with it via proxy contracts using `delegatecall`. There are two variants: * **Safe** (mainnet and compatible chains) * **SafeL2**, which emits additional events for L2 chains that do not support tracing > For historical reasons, both variants are often referred to simply as “Safe”. The diagram below shows the main components of the Safe contract: Safe Smart Account Components ### Owner Management Safe supports multiple owners per account. The `OwnerManager.sol` contract enables: * adding, removing, and replacing owners * changing the approval threshold * retrieving the current owner list Events are emitted whenever owners or thresholds are updated. ### Module Management Modules extend Safe functionality while keeping the core contract minimal. They can, for example: * allow transaction execution without collecting all signatures * enable alternative authorization schemes Adding or removing a module requires confirmation from the owner threshold. Because modules can bypass standard authorization logic, they are **security-critical** and must be carefully audited. Examples: * [Allowance Module](https://github.com/safe-fndn/safe-modules/s/tree/main/modules/allowances) * [Recovery Module](https://github.com/safe-fndn/safe-modules/s/tree/main/modules/recovery) * [ERC-4337 Module](https://github.com/safe-fndn/safe-modules/s/tree/main/modules/4337) * [Passkey Module](https://github.com/safe-fndn/safe-modules/s/tree/main/modules/passkey) ### Executor The Executor component contains the logic for executing `call` and `delegatecall` operations to external contracts. ### Fallback Manager Fallback functions are executed when a function selector does not match any defined function. Because EVM contracts are limited to 24 KB in size, Safe uses a **Fallback Manager** to: * delegate fallback logic to a separate contract * extend functionality without increasing the core contract size ### Guard Management Guards define additional checks that run before and after transaction execution. The Guard Manager allows guards to be added, removed, or replaced. Guards are security-critical: a faulty or malicious guard can block transactions or lock funds. Events are emitted whenever a guard is updated. ### Safe Proxy A **Safe Proxy** is a lightweight contract that delegates all calls to the Safe singleton. Using proxies significantly reduces deployment costs, since the proxy’s bytecode is much smaller than the full Safe contract. Safe Proxy Creation # Signatures Source: https://docs.safefoundation.org/smart-account/signatures How Safe Smart Accounts encode, validate, and combine different signature types for transaction execution. Safe Smart Accounts support multiple signature types. All signatures required to authorize a transaction are **combined into a single `bytes` value** and passed to the Safe contract when executing a transaction. This page explains how signatures are encoded, ordered, and interpreted by the Safe contract. ## Encoding overview Each signature has a **constant-length part of 65 bytes**. If additional data is required (for example, for contract signatures), it is appended as a **dynamic part** after all constant parts. The position of the dynamic data is encoded in the constant part of the signature. Constant part per signature: `{(max) 64-bytes signature data}{1-byte signature type}` All the signatures are sorted by the signer address and concatenated. #### ECDSA signature `31 > signature type > 26` To be able to have the ECDSA signature without the need of additional data we use the signature type byte to encode `v`. **Constant part:** `{32-bytes r}{32-bytes s}{1-byte v}` `r`, `s` and `v` are the required parts of the ECDSA signature to recover the signer. #### `eth_sign` signature `signature type > 30` To be able to use `eth_sign` we need to take the parameters `r`, `s` and `v` from calling `eth_sign` and set `v = v + 4` **Constant part:** `{32-bytes r}{32-bytes s}{1-byte v}` `r`, `s` and `v`are the required parts of the ECDSA signature to recover the signer. `v` will be subtracted by `4` to calculate the signature. #### Contract signature (ERC-1271) `signature type == 0` **Constant part:** `{32-bytes signature verifier}{32-bytes data position}{1-byte signature type}` **Signature verifier** - Padded address of the contract that implements the ERC-1271 interface to verify the signature **Data position** - Position of the start of the signature data (offset relative to the beginning of the signature data) **Signature type** - 0 **Dynamic part (solidity bytes):** `{32-bytes signature length}{bytes signature data}` **Signature data** - Signature bytes that are verified by the signature verifier The method `signMessage` can be used to mark a message as signed on-chain. #### Pre-validated signatures `signature type == 1` **Constant Part:** `{32-bytes hash validator}{32-bytes ignored}{1-byte signature type}` **Hash validator** - Padded address of the account that pre-validated the hash that should be validated. The Safe keeps track of all hashes that have been pre-validated. This is done with a **mapping address to mapping of bytes32 to boolean** where it's possible to set a hash as validated by a certain address (hash validator). To add an entry to this mapping use `approveHash`. Also if the validator is the sender of transaction that executed the Safe transaction it's **not** required to use `approveHash` to add an entry to the mapping. (This can be seen in the [Team Edition tests](https://github.com/safe-fndn/safe-smart-account/blob/v1.0.0/test/gnosisSafeTeamEdition.js)) **Signature type** - 1 ### Examples Assuming that three signatures are required to confirm a transaction where one signer uses an EOA to generate a ECDSA signature, another a contract signature and the last a pre-validated signature: We assume that the following addresses generate the following signatures: 1. `0x3` (EOA address) -> `bde0b9f486b1960454e326375d0b1680243e031fd4fb3f070d9a3ef9871ccfd5` (r) + `7d1a653cffb6321f889169f08e548684e005f2b0c3a6c06fba4c4a68f5e00624` (s) + `1c` (v) 2. `0x1` (ERC-1271 validator contract address) -> `0000000000000000000000000000000000000000000000000000000000000001` (address) + `00000000000000000000000000000000000000000000000000000000000000c3` (dynamic position) + `00` (signature type) * The contract takes the following `bytes` (dynamic part) for verification `00000000000000000000000000000000000000000000000000000000deadbeef` 3. `0x2` (Validator address) -> `0000000000000000000000000000000000000000000000000000000000000002` (address) +`0000000000000000000000000000000000000000000000000000000000000000` (padding - not used) + `01` (signature type) The constant parts need to be sorted so that the recovered signers are sorted **ascending** (natural order) by address (not checksummed). The signatures bytes used for `execTransaction` would therefore be the following: ```text theme={null} "0x" + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c300" + // encoded EIP-1271 signature "0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001" + // encoded pre-validated signature "bde0b9f486b1960454e326375d0b1680243e031fd4fb3f070d9a3ef9871ccfd57d1a653cffb6321f889169f08e548684e005f2b0c3a6c06fba4c4a68f5e006241c" + // encoded ECDSA signature "0000000000000000000000000000000000000000000000000000000000000004deadbeef" // length of bytes + data of bytes ```