Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- SafeProxyFactory
- Optimization enabled
- false
- Compiler version
- v0.7.6+commit.7338295f
- EVM Version
- default
- Verified at
- 2024-06-26T04:09:12.230178Z
contracts/proxies/SafeProxyFactory.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./SafeProxy.sol";import "./IProxyCreationCallback.sol";/*** @title Proxy Factory - Allows to create a new proxy contract and execute a message call to the new proxy within one transaction.* @author Stefan George - @Georgi87*/contract SafeProxyFactory {event ProxyCreation(SafeProxy indexed proxy, address singleton);/// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.function proxyCreationCode() public pure returns (bytes memory) {return type(SafeProxy).creationCode;}/*** @notice Internal method to create a new proxy contract using CREATE2. Optionally executes an initializer call to a new proxy.* @param _singleton Address of singleton contract. Must be deployed at the time of execution.* @param initializer (Optional) Payload for a message call to be sent to a new proxy contract.* @param salt Create2 salt to use for calculating the address of the new proxy contract.* @return proxy Address of the new proxy contract.*/function deployProxy(address _singleton, bytes memory initializer, bytes32 salt) internal returns (SafeProxy proxy) {require(isContract(_singleton), "Singleton contract not deployed");bytes memory deploymentData = abi.encodePacked(type(SafeProxy).creationCode, uint256(uint160(_singleton)));// solhint-disable-next-line no-inline-assemblyassembly {proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)}require(address(proxy) != address(0), "Create2 call failed");if (initializer.length > 0) {// solhint-disable-next-line no-inline-assemblyassembly {if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {revert(0, 0)}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MITpragma solidity >=0.6.0 <0.8.0;/** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with GSN meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.*/abstract contract Context {function _msgSender() internal view virtual returns (address payable) {return msg.sender;}function _msgData() internal view virtual returns (bytes memory) {this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691return msg.data;}}
contracts/interfaces/ISignatureValidator.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;contract ISignatureValidatorConstants {// bytes4(keccak256("isValidSignature(bytes,bytes)")bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;}abstract contract ISignatureValidator is ISignatureValidatorConstants {/*** @notice Legacy EIP1271 method to validate a signature.* @param _data Arbitrary length data signed on the behalf of address(this).* @param _signature Signature byte array associated with _data.** MUST return the bytes4 magic value 0x20c13b0b when function passes.* MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)* MUST allow external calls*/function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);}
contracts/test/TestHandler.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../handler/HandlerContext.sol";/*** @title TestHandler - A test FallbackHandler contract*/contract TestHandler is HandlerContext {/*** @notice Returns the sender and manager address provided by the HandlerContext* @return sender The sender address* @return manager The manager address*/function dudududu() external view returns (address sender, address manager) {return (_msgSender(), _manager());}}
contracts/libraries/MultiSendCallOnly.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls* @notice The guard logic is not required here as this contract doesn't support nested delegate calls* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/contract MultiSendCallOnly {/*** @dev Sends multiple transactions and reverts all if one fails.* @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of* operation has to be uint8(0) in this version (=> 1 byte),* to as a address (=> 20 bytes),* value as a uint256 (=> 32 bytes),* data length as a uint256 (=> 32 bytes),* data as bytes.* see abi.encodePacked for more information on packed encoding* @notice The code is for most part the same as the normal MultiSend (to keep compatibility),* but reverts if a transaction tries to use a delegatecall.* @notice This method is payable as delegatecalls keep the msg.value from the previous call* If the calling method (e.g. execTransaction) received ETH this would revert otherwise*/function multiSend(bytes memory transactions) public payable {// solhint-disable-next-line no-inline-assemblyassembly {let length := mload(transactions)let i := 0x20for {// Pre block is not used in "while mode"} lt(i, length) {// Post block is not used in "while mode"} {// First byte of the data is the operation.// We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).// This will also zero out unused data.let operation := shr(0xf8, mload(add(transactions, i)))// We offset the load address by 1 byte (operation byte)// We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.let to := shr(0x60, mload(add(transactions, add(i, 0x01))))
contracts/proxies/SafeProxy.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title IProxy - Helper interface to access the singleton address of the Proxy on-chain.* @author Richard Meissner - @rmeissner*/interface IProxy {function masterCopy() external view returns (address);}/*** @title SafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.* @author Stefan George - <stefan@gnosis.io>* @author Richard Meissner - <richard@gnosis.io>*/contract SafeProxy {// Singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.// To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`address internal singleton;/*** @notice Constructor function sets address of singleton contract.* @param _singleton Singleton address.*/constructor(address _singleton) {require(_singleton != address(0), "Invalid singleton address provided");singleton = _singleton;}/// @dev Fallback function forwards all transactions and returns all received return data.fallback() external payable {// solhint-disable-next-line no-inline-assemblyassembly {let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)// 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0sif eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {mstore(0, _singleton)return(0, 0x20)}calldatacopy(0, 0, calldatasize())
contracts/common/SignatureDecoder.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title SignatureDecoder - Decodes signatures encoded as bytes* @author Richard Meissner - @rmeissner*/abstract contract SignatureDecoder {/*** @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`.* @dev Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures* The signature format is a compact form of {bytes32 r}{bytes32 s}{uint8 v}* Compact means uint8 is not padded to 32 bytes.* @param pos Which signature to read.* A prior bounds check of this parameter should be performed, to avoid out of bounds access.* @param signatures Concatenated {r, s, v} signatures.* @return v Recovery ID or Safe signature type.* @return r Output value r of the signature.* @return s Output value s of the signature.*/function signatureSplit(bytes memory signatures, uint256 pos) internal pure returns (uint8 v, bytes32 r, bytes32 s) {// solhint-disable-next-line no-inline-assemblyassembly {let signaturePos := mul(0x41, pos)r := mload(add(signatures, add(signaturePos, 0x20)))s := mload(add(signatures, add(signaturePos, 0x40)))/*** Here we are loading the last 32 bytes, including 31 bytes* of 's'. There is no 'mload8' to do this.* 'byte' is not working due to the Solidity parser, so lets* use the second best option, 'and'*/v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)}}}
contracts/libraries/SignMessageLib.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./SafeStorage.sol";import "../Safe.sol";/*** @title SignMessageLib - Allows to sign messages on-chain by writing the signed message hashes on-chain.* @author Richard Meissner - @rmeissner*/contract SignMessageLib is SafeStorage {// keccak256("SafeMessage(bytes message)");bytes32 private constant SAFE_MSG_TYPEHASH = 0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca;event SignMsg(bytes32 indexed msgHash);/*** @notice Marks a message (`_data`) as signed.* @dev Can be verified using EIP-1271 validation method by passing the pre-image of the message hash and empty bytes as the signature.* @param _data Arbitrary length data that should be marked as signed on the behalf of address(this).*/function signMessage(bytes calldata _data) external {bytes32 msgHash = getMessageHash(_data);signedMessages[msgHash] = 1;emit SignMsg(msgHash);}/*** @dev Returns hash of a message that can be signed by owners.* @param message Message that should be hashed.* @return Message hash.*/function getMessageHash(bytes memory message) public view returns (bytes32) {bytes32 safeMessageHash = keccak256(abi.encode(SAFE_MSG_TYPEHASH, keccak256(message)));return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), Safe(payable(address(this))).domainSeparator(), safeMessageHash));}}
contracts/interfaces/ERC777TokensRecipient.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title ERC777TokensRecipient* @dev Interface for contracts that will be called with the ERC777 token's `tokensReceived` method.* The contract receiving the tokens must implement this interface in order to receive the tokens.*/interface ERC777TokensRecipient {/*** @dev Called by the ERC777 token contract after a successful transfer or a minting operation.* @param operator The address of the operator performing the transfer or minting operation.* @param from The address of the sender.* @param to The address of the recipient.* @param amount The amount of tokens that were transferred or minted.* @param data Additional data that was passed during the transfer or minting operation.* @param operatorData Additional data that was passed by the operator during the transfer or minting operation.*/function tokensReceived(address operator,address from,address to,uint256 amount,bytes calldata data,bytes calldata operatorData) external;}
contracts/examples/guards/DebugTransactionGuard.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../../common/Enum.sol";import "../../base/GuardManager.sol";import "../../Safe.sol";/*** @title Debug Transaction Guard - Emits transaction events with extended information.* @dev This guard is only meant as a development tool and example* @author Richard Meissner - @rmeissner*/contract DebugTransactionGuard is BaseGuard {// solhint-disable-next-line payable-fallbackfallback() external {// We don't revert on fallback to avoid issues in case of a Safe upgrade// E.g. The expected check method might change and then the Safe would be locked.}event TransactionDetails(address indexed safe,bytes32 indexed txHash,address to,uint256 value,bytes data,Enum.Operation operation,uint256 safeTxGas,bool usesRefund,uint256 nonce,bytes signatures,address executor);event GasUsage(address indexed safe, bytes32 indexed txHash, uint256 indexed nonce, bool success);mapping(bytes32 => uint256) public txNonces;/*** @notice Called by the Safe contract before a transaction is executed.* @param to Destination address of Safe transaction.* @param value Ether value of Safe transaction.
contracts/proxies/IProxyCreationCallback.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./SafeProxy.sol";/*** @title IProxyCreationCallback* @dev An interface for a contract that implements a callback function to be executed after the creation of a proxy instance.*/interface IProxyCreationCallback {/*** @dev Function to be called after the creation of a SafeProxy instance.* @param proxy The newly created SafeProxy instance.* @param _singleton The address of the singleton contract used to create the proxy.* @param initializer The initializer function call data.* @param saltNonce The nonce used to generate the salt for the proxy deployment.*/function proxyCreated(SafeProxy proxy, address _singleton, bytes calldata initializer, uint256 saltNonce) external;}
contracts/handler/CompatibilityFallbackHandler.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./TokenCallbackHandler.sol";import "../interfaces/ISignatureValidator.sol";import "../Safe.sol";/*** @title Compatibility Fallback Handler - Provides compatibility between pre 1.3.0 and 1.3.0+ Safe contracts.* @author Richard Meissner - @rmeissner*/contract CompatibilityFallbackHandler is TokenCallbackHandler, ISignatureValidator {// keccak256("SafeMessage(bytes message)");bytes32 private constant SAFE_MSG_TYPEHASH = 0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca;bytes4 internal constant SIMULATE_SELECTOR = bytes4(keccak256("simulate(address,bytes)"));address internal constant SENTINEL_MODULES = address(0x1);bytes4 internal constant UPDATED_MAGIC_VALUE = 0x1626ba7e;/*** @notice Legacy EIP-1271 signature validation method.* @dev Implementation of ISignatureValidator (see `interfaces/ISignatureValidator.sol`)* @param _data Arbitrary length data signed on the behalf of address(msg.sender).* @param _signature Signature byte array associated with _data.* @return The EIP-1271 magic value.*/function isValidSignature(bytes memory _data, bytes memory _signature) public view override returns (bytes4) {// Caller should be a SafeSafe safe = Safe(payable(msg.sender));bytes memory messageData = encodeMessageDataForSafe(safe, _data);bytes32 messageHash = keccak256(messageData);if (_signature.length == 0) {require(safe.signedMessages(messageHash) != 0, "Hash not approved");} else {safe.checkSignatures(messageHash, messageData, _signature);}return EIP1271_MAGIC_VALUE;}/**
contracts/handler/HandlerContext.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Handler Context - Allows the fallback handler to extract addition context from the calldata* @dev The fallback manager appends the following context to the calldata:* 1. Fallback manager caller address (non-padded)* based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/f8cc8b844a9f92f63dc55aa581f7d643a1bc5ac1/contracts/metatx/ERC2771Context.sol* @author Richard Meissner - @rmeissner*/abstract contract HandlerContext {/*** @notice Allows fetching the original caller address.* @dev This is only reliable in combination with a FallbackManager that supports this (e.g. Safe contract >=1.3.0).* When using this functionality make sure that the linked _manager (aka msg.sender) supports this.* This function does not rely on a trusted forwarder. Use the returned value only to* check information against the calling manager.* @return sender Original caller address.*/function _msgSender() internal pure returns (address sender) {// The assembly code is more direct than the Solidity version using `abi.decode`.// solhint-disable-next-line no-inline-assemblyassembly {sender := shr(96, calldataload(sub(calldatasize(), 20)))}}/*** @notice Returns the FallbackManager address* @return Fallback manager address*/function _manager() internal view returns (address) {return msg.sender;}}
contracts/handler/TokenCallbackHandler.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../interfaces/ERC1155TokenReceiver.sol";import "../interfaces/ERC721TokenReceiver.sol";import "../interfaces/ERC777TokensRecipient.sol";import "../interfaces/IERC165.sol";/*** @title Default Callback Handler - Handles supported tokens' callbacks, allowing Safes receiving these tokens.* @author Richard Meissner - @rmeissner*/contract TokenCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 {/*** @notice Handles ERC1155 Token callback.* return Standardized onERC1155Received return value.*/function onERC1155Received(address, address, uint256, uint256, bytes calldata) external pure override returns (bytes4) {return 0xf23a6e61;}/*** @notice Handles ERC1155 Token batch callback.* return Standardized onERC1155BatchReceived return value.*/function onERC1155BatchReceived(address,address,uint256[] calldata,uint256[] calldata,bytes calldata) external pure override returns (bytes4) {return 0xbc197c81;}/*** @notice Handles ERC721 Token callback.* return Standardized onERC721Received return value.*/function onERC721Received(address, address, uint256, bytes calldata) external pure override returns (bytes4) {return 0x150b7a02;
contracts/common/SelfAuthorized.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title SelfAuthorized - Authorizes current contract to perform actions to itself.* @author Richard Meissner - @rmeissner*/abstract contract SelfAuthorized {function requireSelfCall() private view {require(msg.sender == address(this), "GS031");}modifier authorized() {// Modifiers are copied around during compilation. This is a function call as it minimized the bytecode sizerequireSelfCall();_;}}
contracts/examples/libraries/Migrate_1_3_0_to_1_2_0.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../../libraries/SafeStorage.sol";/*** @title Migration - Migrates a Safe contract from 1.3.0 to 1.2.0* @author Richard Meissner - @rmeissner*/contract Migration is SafeStorage {bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d4749;address public immutable migrationSingleton;address public immutable safe120Singleton;constructor(address targetSingleton) {// Singleton address cannot be zero address.require(targetSingleton != address(0), "Invalid singleton address provided");safe120Singleton = targetSingleton;migrationSingleton = address(this);}event ChangedMasterCopy(address singleton);/*** @notice Migrates the Safe to the Singleton contract at `migrationSingleton`.* @dev This can only be called via a delegatecall.*/function migrate() public {require(address(this) != migrationSingleton, "Migration should only be called via delegatecall");singleton = safe120Singleton;_deprecatedDomainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, this));emit ChangedMasterCopy(singleton);}}
contracts/common/SecuredTokenTransfer.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title SecuredTokenTransfer - Secure token transfer.* @author Richard Meissner - @rmeissner*/abstract contract SecuredTokenTransfer {/*** @notice Transfers a token and returns a boolean if it was a success* @dev It checks the return data of the transfer call and returns true if the transfer was successful.* It doesn't check if the `token` address is a contract or not.* @param token Token that should be transferred* @param receiver Receiver to whom the token should be transferred* @param amount The amount of tokens that should be transferred* @return transferred Returns true if the transfer was successful*/function transferToken(address token, address receiver, uint256 amount) internal returns (bool transferred) {// 0xa9059cbb - keccack("transfer(address,uint256)")bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);// solhint-disable-next-line no-inline-assemblyassembly {// We write the return value to scratch space.// See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memorylet success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)switch returndatasize()case 0 {transferred := success}case 0x20 {transferred := iszero(or(iszero(success), iszero(mload(0))))}default {transferred := 0}}}}
contracts/SafeL2.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./Safe.sol";/*** @title SafeL2 - An implementation of the Safe contract that emits additional events on transaction executions.* @notice For a more complete description of the Safe contract, please refer to the main Safe contract `Safe.sol`.* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/contract SafeL2 is Safe {event SafeMultiSigTransaction(address to,uint256 value,bytes data,Enum.Operation operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address payable refundReceiver,bytes signatures,// We combine nonce, sender and threshold into one to avoid stack too deep// Dev note: additionalInfo should not contain `bytes`, as this complicates decodingbytes additionalInfo);event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);// @inheritdoc Safefunction execTransaction(address to,uint256 value,bytes calldata data,Enum.Operation operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address payable refundReceiver,
contracts/Safe.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "./base/ModuleManager.sol";import "./base/OwnerManager.sol";import "./base/FallbackManager.sol";import "./base/GuardManager.sol";import "./common/NativeCurrencyPaymentFallback.sol";import "./common/Singleton.sol";import "./common/SignatureDecoder.sol";import "./common/SecuredTokenTransfer.sol";import "./common/StorageAccessible.sol";import "./interfaces/ISignatureValidator.sol";import "./external/SafeMath.sol";/*** @title Safe - A multisignature wallet with support for confirmations using signed messages based on EIP-712.* @dev Most important concepts:* - Threshold: Number of required confirmations for a Safe transaction.* - Owners: List of addresses that control the Safe. They are the only ones that can add/remove owners, change the threshold and* approve transactions. Managed in `OwnerManager`.* - Transaction Hash: Hash of a transaction is calculated using the EIP-712 typed structured data hashing scheme.* - Nonce: Each transaction should have a different nonce to prevent replay attacks.* - Signature: A valid signature of an owner of the Safe for a transaction hash.* - Guard: Guard is a contract that can execute pre- and post- transaction checks. Managed in `GuardManager`.* - Modules: Modules are contracts that can be used to extend the write functionality of a Safe. Managed in `ModuleManager`.* - Fallback: Fallback handler is a contract that can provide additional read-only functional for Safe. Managed in `FallbackManager`.* Note: This version of the implementation contract doesn't emit events for the sake of gas efficiency and therefore requires a tracing node for indexing/* For the events-based implementation see `SafeL2.sol`.* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/contract Safe isSingleton,NativeCurrencyPaymentFallback,ModuleManager,OwnerManager,SignatureDecoder,SecuredTokenTransfer,ISignatureValidatorConstants,FallbackManager,
contracts/accessors/SimulateTxAccessor.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../base/Executor.sol";/*** @title Simulate Transaction Accessor.* @notice Can be used with StorageAccessible to simulate Safe transactions.* @author Richard Meissner - @rmeissner*/contract SimulateTxAccessor is Executor {address private immutable accessorSingleton;constructor() {accessorSingleton = address(this);}/*** @notice Modifier to make a function callable via delegatecall only.* If the function is called via a regular call, it will revert.*/modifier onlyDelegateCall() {require(address(this) != accessorSingleton, "SimulateTxAccessor should only be called via delegatecall");_;}/*** @notice Simulates a Safe transaction and returns the used gas, success boolean and the return data.* @dev Executes the specified operation {Call, DelegateCall} and returns operation-specific data.* Has to be called via delegatecall.* This returns the data equal to `abi.encode(uint256(etimate), bool(success), bytes(returnData))`.* Specifically, the returndata will be:* `estimate:uint256 || success:bool || returnData.length:uint256 || returnData:bytes`.* @param to Destination address .* @param value Native token value.* @param data Data payload.* @param operation Operation type {Call, DelegateCall}.* @return estimate Gas used.* @return success Success boolean value.* @return returnData Return data.*/
contracts/base/Executor.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../common/Enum.sol";/*** @title Executor - A contract that can execute transactions* @author Richard Meissner - @rmeissner*/abstract contract Executor {/*** @notice Executes either a delegatecall or a call with provided parameters.* @dev This method doesn't perform any sanity check of the transaction, such as:* - if the contract at `to` address has code or not* It is the responsibility of the caller to perform such checks.* @param to Destination address.* @param value Ether value.* @param data Data payload.* @param operation Operation type.* @return success boolean flag indicating if the call succeeded.*/function execute(address to,uint256 value,bytes memory data,Enum.Operation operation,uint256 txGas) internal returns (bool success) {if (operation == Enum.Operation.DelegateCall) {// solhint-disable-next-line no-inline-assemblyassembly {success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)}} else {// solhint-disable-next-line no-inline-assemblyassembly {success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)}}}}
contracts/test/4337/Test4337ModuleAndHandler.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;pragma abicoder v2;import "../../libraries/SafeStorage.sol";struct UserOperation {address sender;uint256 nonce;bytes initCode;bytes callData;uint256 callGasLimit;uint256 verificationGasLimit;uint256 preVerificationGas;uint256 maxFeePerGas;uint256 maxPriorityFeePerGas;bytes paymasterAndData;bytes signature;}interface ISafe {function execTransactionFromModule(address to, uint256 value, bytes memory data, uint8 operation) external returns (bool success);}/// @dev A Dummy 4337 Module/Handler for testing purposes/// ⚠️ ⚠️ ⚠️ DO NOT USE IN PRODUCTION ⚠️ ⚠️ ⚠️/// The module does not perform ANY validation, it just executes validateUserOp and execTransaction/// to perform the opcode level compliance by the bundler.contract Test4337ModuleAndHandler is SafeStorage {address public immutable myAddress;address public immutable entryPoint;address internal constant SENTINEL_MODULES = address(0x1);constructor(address entryPointAddress) {entryPoint = entryPointAddress;myAddress = address(this);}function validateUserOp(UserOperation calldata userOp, bytes32, uint256 missingAccountFunds) external returns (uint256 validationData) {address payable safeAddress = payable(userOp.sender);
contracts/test/ERC1155Token.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../interfaces/ERC1155TokenReceiver.sol";import "../external/SafeMath.sol";/*** @title ERC1155Token - A test ERC1155 token contract*/contract ERC1155Token {using SafeMath for uint256;// Mapping from token ID to owner balancesmapping(uint256 => mapping(address => uint256)) private _balances;// Mapping from owner to operator approvalsmapping(address => mapping(address => bool)) private _operatorApprovals;/*** @dev Get the specified address' balance for token with specified ID.* @param owner The address of the token holder* @param id ID of the token* @return The owner's balance of the token type requested*/function balanceOf(address owner, uint256 id) public view returns (uint256) {require(owner != address(0), "ERC1155: balance query for the zero address");return _balances[id][owner];}/*** @notice Transfers `value` amount of an `id` from the `from` address to the `to` address specified.* Caller must be approved to manage the tokens being transferred out of the `from` account.* If `to` is a smart contract, will call `onERC1155Received` on `to` and act appropriately.* @param from Source address* @param to Target address* @param id ID of the token type* @param value Transfer amount* @param data Data forwarded to `onERC1155Received` if `to` is a contract receiver*/function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external {require(to != address(0), "ERC1155: target address must be non-zero");
contracts/interfaces/ViewStorageAccessible.sol
pragma solidity >=0.5.0 <0.9.0;/// @title ViewStorageAccessible - Interface on top of StorageAccessible base class to allow simulations from view functions./// @notice Adjusted version of https://github.com/gnosis/util-contracts/blob/3db1e531cb243a48ea91c60a800d537c1000612a/contracts/StorageAccessible.solinterface ViewStorageAccessible {/*** @dev Same as `simulate` on StorageAccessible. Marked as view so that it can be called from external contracts* that want to run simulations from within view functions. Will revert if the invoked simulation attempts to change state.*/function simulate(address targetContract, bytes calldata calldataPayload) external view returns (bytes memory);}
contracts/examples/guards/DelegateCallTransactionGuard.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../../common/Enum.sol";import "../../base/GuardManager.sol";import "../../Safe.sol";/*** @title DelegateCallTransactionGuard - Limits delegate calls to a specific target.* @author Richard Meissner - @rmeissner*/contract DelegateCallTransactionGuard is BaseGuard {address public immutable allowedTarget;constructor(address target) {allowedTarget = target;}// solhint-disable-next-line payable-fallbackfallback() external {// We don't revert on fallback to avoid issues in case of a Safe upgrade// E.g. The expected check method might change and then the Safe would be locked.}/*** @notice Called by the Safe contract before a transaction is executed.* @dev Reverts if the transaction is a delegate call to contract other than the allowed one.* @param to Destination address of Safe transaction.* @param operation Operation type of Safe transaction.*/function checkTransaction(address to,uint256,bytes memory,Enum.Operation operation,uint256,uint256,uint256,address,// solhint-disable-next-line no-unused-varsaddress payable,
contracts/interfaces/ERC721TokenReceiver.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.interface ERC721TokenReceiver {/*** @notice Handle the receipt of an NFT* @dev The ERC721 smart contract calls this function on the recipient* after a `transfer`. This function MAY throw to revert and reject the* transfer. Return of other than the magic value MUST result in the* transaction being reverted.* Note: the contract address is always the message sender.* @param _operator The address which called `safeTransferFrom` function.* @param _from The address which previously owned the token.* @param _tokenId The NFT identifier which is being transferred.* @param _data Additional data with no specified format.* @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.* unless throwing*/function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns (bytes4);}
contracts/interfaces/IERC165.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.solinterface IERC165 {/*** @dev Returns true if this contract implements the interface defined by `interfaceId`.* See the corresponding EIP section* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified* to learn more about how these ids are created.** This function call must use less than 30 000 gas.*/function supportsInterface(bytes4 interfaceId) external view returns (bool);}
contracts/common/NativeCurrencyPaymentFallback.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title NativeCurrencyPaymentFallback - A contract that has a fallback to accept native currency payments.* @author Richard Meissner - @rmeissner*/abstract contract NativeCurrencyPaymentFallback {event SafeReceived(address indexed sender, uint256 value);/*** @notice Receive function accepts native currency transactions.* @dev Emits an event with sender and received value.*/receive() external payable {emit SafeReceived(msg.sender, msg.value);}}
contracts/common/StorageAccessible.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title StorageAccessible - A generic base contract that allows callers to access all internal storage.* @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol* It removes a method from the original contract not needed for the Safe contracts.* @author Gnosis Developers*/abstract contract StorageAccessible {/*** @notice Reads `length` bytes of storage in the currents contract* @param offset - the offset in the current contract's storage in words to start reading from* @param length - the number of words (32 bytes) of data to read* @return the bytes that were read.*/function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {bytes memory result = new bytes(length * 32);for (uint256 index = 0; index < length; index++) {// solhint-disable-next-line no-inline-assemblyassembly {let word := sload(add(offset, index))mstore(add(add(result, 0x20), mul(index, 0x20)), word)}}return result;}/*** @dev Performs a delegatecall on a targetContract in the context of self.* Internally reverts execution to avoid side effects (making it static).** This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.* Specifically, the `returndata` after a call to this method will be:* `success:bool || response.length:uint256 || response:bytes`.** @param targetContract Address of the contract containing the code to execute.* @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).*/function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {// solhint-disable-next-line no-inline-assembly
contracts/external/SafeMath.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title SafeMath* @notice Math operations with safety checks that revert on error (overflow/underflow)*/library SafeMath {/*** @notice Multiplies two numbers, reverts on overflow.* @param a First number* @param b Second number* @return Product of a and b*/function mul(uint256 a, uint256 b) internal pure returns (uint256) {// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522if (a == 0) {return 0;}uint256 c = a * b;require(c / a == b);return c;}/*** @notice Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).* @param a First number* @param b Second number* @return Difference of a and b*/function sub(uint256 a, uint256 b) internal pure returns (uint256) {require(b <= a);uint256 c = a - b;return c;}
@openzeppelin/contracts/math/SafeMath.sol
// SPDX-License-Identifier: MITpragma solidity >=0.6.0 <0.8.0;/*** @dev Wrappers over Solidity's arithmetic operations with added overflow* checks.** Arithmetic operations in Solidity wrap on overflow. This can easily result* in bugs, because programmers usually assume that an overflow raises an* error, which is the standard behavior in high level programming languages.* `SafeMath` restores this intuition by reverting the transaction when an* operation overflows.** Using this library instead of the unchecked operations eliminates an entire* class of bugs, so it's recommended to use it always.*/library SafeMath {/*** @dev Returns the addition of two unsigned integers, with an overflow flag.** _Available since v3.4._*/function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {uint256 c = a + b;if (c < a) return (false, 0);return (true, c);}/*** @dev Returns the substraction of two unsigned integers, with an overflow flag.** _Available since v3.4._*/function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {if (b > a) return (false, 0);return (true, a - b);}/*** @dev Returns the multiplication of two unsigned integers, with an overflow flag.
contracts/common/Singleton.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Singleton - Base for singleton contracts (should always be the first super contract)* This contract is tightly coupled to our proxy contract (see `proxies/SafeProxy.sol`)* @author Richard Meissner - @rmeissner*/abstract contract Singleton {// singleton always has to be the first declared variable to ensure the same location as in the Proxy contract.// It should also always be ensured the address is stored alone (uses a full word)address private singleton;}
@openzeppelin/contracts/token/ERC20/ERC20.sol
// SPDX-License-Identifier: MITpragma solidity >=0.6.0 <0.8.0;import "../../utils/Context.sol";import "./IERC20.sol";import "../../math/SafeMath.sol";/*** @dev Implementation of the {IERC20} interface.** This implementation is agnostic to the way tokens are created. This means* that a supply mechanism has to be added in a derived contract using {_mint}.* For a generic mechanism see {ERC20PresetMinterPauser}.** TIP: For a detailed writeup see our guide* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How* to implement supply mechanisms].** We have followed general OpenZeppelin guidelines: functions revert instead* of returning `false` on failure. This behavior is nonetheless conventional* and does not conflict with the expectations of ERC20 applications.** Additionally, an {Approval} event is emitted on calls to {transferFrom}.* This allows applications to reconstruct the allowance for all accounts just* by listening to said events. Other implementations of the EIP may not emit* these events, as it isn't required by the specification.** Finally, the non-standard {decreaseAllowance} and {increaseAllowance}* functions have been added to mitigate the well-known issues around setting* allowances. See {IERC20-approve}.*/contract ERC20 is Context, IERC20 {using SafeMath for uint256;mapping (address => uint256) private _balances;mapping (address => mapping (address => uint256)) private _allowances;uint256 private _totalSupply;
contracts/common/Enum.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Enum - Collection of enums used in Safe contracts.* @author Richard Meissner - @rmeissner*/abstract contract Enum {enum Operation {Call,DelegateCall}}
contracts/base/GuardManager.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../common/Enum.sol";import "../common/SelfAuthorized.sol";import "../interfaces/IERC165.sol";interface Guard is IERC165 {function checkTransaction(address to,uint256 value,bytes memory data,Enum.Operation operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address payable refundReceiver,bytes memory signatures,address msgSender) external;function checkAfterExecution(bytes32 txHash, bool success) external;}abstract contract BaseGuard is Guard {function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {returninterfaceId == type(Guard).interfaceId || // 0xe6d7a83ainterfaceId == type(IERC165).interfaceId; // 0x01ffc9a7}}/*** @title Guard Manager - A contract managing transaction guards which perform pre and post-checks on Safe transactions.* @author Richard Meissner - @rmeissner*/abstract contract GuardManager is SelfAuthorized {event ChangedGuard(address indexed guard);// keccak256("guard_manager.guard.address")
contracts/interfaces/ERC1155TokenReceiver.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;// Note: The ERC-165 identifier for this interface is 0x4e2312e0.interface ERC1155TokenReceiver {/*** @notice Handle the receipt of a single ERC1155 token type.* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.* This function MUST return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61) if it accepts the transfer.* This function MUST revert if it rejects the transfer.* Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.* @param _operator The address which initiated the transfer (i.e. msg.sender).* @param _from The address which previously owned the token.* @param _id The ID of the token being transferred.* @param _value The amount of tokens being transferred.* @param _data Additional data with no specified format.* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.*/function onERC1155Received(address _operator,address _from,uint256 _id,uint256 _value,bytes calldata _data) external returns (bytes4);/*** @notice Handle the receipt of multiple ERC1155 token types.* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.* This function MUST return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81) if it accepts the transfer(s).* This function MUST revert if it rejects the transfer(s).* Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.* @param _operator The address which initiated the batch transfer (i.e. msg.sender).* @param _from The address which previously owned the token.* @param _ids An array containing ids of each token being transferred (order and length must match _values array).* @param _values An array containing amounts of each token being transferred (order and length must match _ids array).* @param _data Additional data with no specified format.* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.*/function onERC1155BatchReceived(address _operator,
contracts/base/ModuleManager.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../common/Enum.sol";import "../common/SelfAuthorized.sol";import "./Executor.sol";/*** @title Module Manager - A contract managing Safe modules* @notice Modules are extensions with unlimited access to a Safe that can be added to a Safe by its owners.⚠️ WARNING: Modules are a security risk since they can execute arbitrary transactions,so only trusted and audited modules should be added to a Safe. A malicious module cancompletely takeover a Safe.* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/abstract contract ModuleManager is SelfAuthorized, Executor {event EnabledModule(address indexed module);event DisabledModule(address indexed module);event ExecutionFromModuleSuccess(address indexed module);event ExecutionFromModuleFailure(address indexed module);address internal constant SENTINEL_MODULES = address(0x1);mapping(address => address) internal modules;/*** @notice Setup function sets the initial storage of the contract.* Optionally executes a delegate call to another contract to setup the modules.* @param to Optional destination address of call to execute.* @param data Optional data of call to execute.*/function setupModules(address to, bytes memory data) internal {require(modules[SENTINEL_MODULES] == address(0), "GS100");modules[SENTINEL_MODULES] = SENTINEL_MODULES;if (to != address(0)) {require(isContract(to), "GS002");// Setup has to complete successfully or transaction fails.require(execute(to, 0, data, Enum.Operation.DelegateCall, type(uint256).max), "GS000");}}
contracts/libraries/CreateCall.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Create Call - Allows to use the different create opcodes to deploy a contract.* @author Richard Meissner - @rmeissner* @notice This contract provides functions for deploying a new contract using the create and create2 opcodes.*/contract CreateCall {/// @notice Emitted when a new contract is createdevent ContractCreation(address indexed newContract);/*** @notice Deploys a new contract using the create2 opcode.* @param value The value in wei to be sent with the contract creation.* @param deploymentData The initialisation code of the contract to be created.* @param salt The salt value to use for the contract creation.* @return newContract The address of the newly created contract.*/function performCreate2(uint256 value, bytes memory deploymentData, bytes32 salt) public returns (address newContract) {// solhint-disable-next-line no-inline-assemblyassembly {newContract := create2(value, add(0x20, deploymentData), mload(deploymentData), salt)}require(newContract != address(0), "Could not deploy contract");emit ContractCreation(newContract);}/*** @notice Deploys a new contract using the create opcode.* @param value The value in wei to be sent with the contract creation.* @param deploymentData The initialisation code of the contract to be created.* @return newContract The address of the newly created contract.*/function performCreate(uint256 value, bytes memory deploymentData) public returns (address newContract) {// solhint-disable-next-line no-inline-assemblyassembly {newContract := create(value, add(deploymentData, 0x20), mload(deploymentData))}require(newContract != address(0), "Could not deploy contract");
contracts/base/OwnerManager.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../common/SelfAuthorized.sol";/*** @title OwnerManager - Manages Safe owners and a threshold to authorize transactions.* @dev Uses a linked list to store the owners because the code generate by the solidity compiler* is more efficient than using a dynamic array.* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/abstract contract OwnerManager is SelfAuthorized {event AddedOwner(address indexed owner);event RemovedOwner(address indexed owner);event ChangedThreshold(uint256 threshold);address internal constant SENTINEL_OWNERS = address(0x1);mapping(address => address) internal owners;uint256 internal ownerCount;uint256 internal threshold;/*** @notice Sets the initial storage of the contract.* @param _owners List of Safe owners.* @param _threshold Number of required confirmations for a Safe transaction.*/function setupOwners(address[] memory _owners, uint256 _threshold) internal {// Threshold can only be 0 at initialization.// Check ensures that setup function can only be called once.require(threshold == 0, "GS200");// Validate that threshold is smaller than number of added owners.require(_threshold <= _owners.length, "GS201");// There has to be at least one Safe owner.require(_threshold >= 1, "GS202");// Initializing Safe owners.address currentOwner = SENTINEL_OWNERS;for (uint256 i = 0; i < _owners.length; i++) {// Owner address cannot be null.address owner = _owners[i];require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, "GS203");
contracts/test/ERC20Token.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.6.0 <0.8.0;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";/*** @title ERC20Token* @dev This contract is an ERC20 token contract that extends the OpenZeppelin ERC20 contract.*/contract ERC20Token is ERC20 {/*** @dev Constructor that sets the name and symbol of the token and mints an initial supply to the contract deployer.*/constructor() public ERC20("TestToken", "TT") {_mint(msg.sender, 1000000000000000);}}
contracts/libraries/MultiSend.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title Multi Send - Allows to batch multiple transactions into one.* @author Nick Dodson - <nick.dodson@consensys.net>* @author Gonçalo Sá - <goncalo.sa@consensys.net>* @author Stefan George - @Georgi87* @author Richard Meissner - @rmeissner*/contract MultiSend {address private immutable multisendSingleton;constructor() {multisendSingleton = address(this);}/*** @dev Sends multiple transactions and reverts all if one fails.* @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of* operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),* to as a address (=> 20 bytes),* value as a uint256 (=> 32 bytes),* data length as a uint256 (=> 32 bytes),* data as bytes.* see abi.encodePacked for more information on packed encoding* @notice This method is payable as delegatecalls keep the msg.value from the previous call* If the calling method (e.g. execTransaction) received ETH this would revert otherwise*/function multiSend(bytes memory transactions) public payable {require(address(this) != multisendSingleton, "MultiSend should only be called via delegatecall");// solhint-disable-next-line no-inline-assemblyassembly {let length := mload(transactions)let i := 0x20for {// Pre block is not used in "while mode"} lt(i, length) {// Post block is not used in "while mode"} {// First byte of the data is the operation.
contracts/libraries/SafeStorage.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;/*** @title SafeStorage - Storage layout of the Safe contracts to be used in libraries.* @dev Should be always the first base contract of a library that is used with a Safe.* @author Richard Meissner - @rmeissner*/contract SafeStorage {// From /common/Singleton.soladdress internal singleton;// From /common/ModuleManager.solmapping(address => address) internal modules;// From /common/OwnerManager.solmapping(address => address) internal owners;uint256 internal ownerCount;uint256 internal threshold;// From /Safe.soluint256 internal nonce;bytes32 internal _deprecatedDomainSeparator;mapping(bytes32 => uint256) internal signedMessages;mapping(address => mapping(bytes32 => uint256)) internal approvedHashes;}
contracts/examples/guards/ReentrancyTransactionGuard.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../../common/Enum.sol";import "../../base/GuardManager.sol";import "../../Safe.sol";/*** @title ReentrancyTransactionGuard - Prevents reentrancy into the transaction execution function.* @author Richard Meissner - @rmeissner*/contract ReentrancyTransactionGuard is BaseGuard {bytes32 internal constant GUARD_STORAGE_SLOT = keccak256("reentrancy_guard.guard.struct");struct GuardValue {bool active;}// solhint-disable-next-line payable-fallbackfallback() external {// We don't revert on fallback to avoid issues in case of a Safe upgrade// E.g. The expected check method might change and then the Safe would be locked.}/*** @notice Returns the guard value for the current context.* @dev The guard value is stored in a slot that is unique to the contract instance and the function in which it is called.* @return guard The guard value.*/function getGuard() internal pure returns (GuardValue storage guard) {bytes32 slot = GUARD_STORAGE_SLOT;// solhint-disable-next-line no-inline-assemblyassembly {guard.slot := slot}}/*** @notice Called by the Safe contract before a transaction is executed.* @dev Reverts if reentrancy is detected.*/
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MITpragma solidity >=0.6.0 <0.8.0;/*** @dev Interface of the ERC20 standard as defined in the EIP.*/interface IERC20 {/*** @dev Returns the amount of tokens in existence.*/function totalSupply() external view returns (uint256);/*** @dev Returns the amount of tokens owned by `account`.*/function balanceOf(address account) external view returns (uint256);/*** @dev Moves `amount` tokens from the caller's account to `recipient`.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transfer(address recipient, uint256 amount) external returns (bool);/*** @dev Returns the remaining number of tokens that `spender` will be* allowed to spend on behalf of `owner` through {transferFrom}. This is* zero by default.** This value changes when {approve} or {transferFrom} are called.*/function allowance(address owner, address spender) external view returns (uint256);/*** @dev Sets `amount` as the allowance of `spender` over the caller's tokens.** Returns a boolean value indicating whether the operation succeeded.*
contracts/base/FallbackManager.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../common/SelfAuthorized.sol";/*** @title Fallback Manager - A contract managing fallback calls made to this contract* @author Richard Meissner - @rmeissner*/abstract contract FallbackManager is SelfAuthorized {event ChangedFallbackHandler(address indexed handler);// keccak256("fallback_manager.handler.address")bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;/*** @notice Internal function to set the fallback handler.* @param handler contract to handle fallback calls.*/function internalSetFallbackHandler(address handler) internal {/*If a fallback handler is set to self, then the following attack vector is opened:Imagine we have a function like this:function withdraw() internal authorized {withdrawalAddress.call.value(address(this).balance)("");}If the fallback method is triggered, the fallback handler appends the msg.sender address to the calldata and calls the fallback handler.A potential attacker could call a Safe with the 3 bytes signature of a withdraw function. Since 3 bytes do not create a valid signature,the call would end in a fallback handler. Since it appends the msg.sender address to the calldata, the attacker could craft an addresswhere the first 3 bytes of the previous calldata + the first byte of the address make up a valid function signature. The subsequent call would result in unsanctioned access to Safe's internal protected methods.For some reason, solidity matches the first 4 bytes of the calldata to a function signature, regardless if more data follow these 4 bytes.*/require(handler != address(this), "GS400");bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;// solhint-disable-next-line no-inline-assemblyassembly {sstore(slot, handler)}}
contracts/examples/guards/OnlyOwnersGuard.sol
// SPDX-License-Identifier: LGPL-3.0-onlypragma solidity >=0.7.0 <0.9.0;import "../../common/Enum.sol";import "../../base/GuardManager.sol";import "../../Safe.sol";interface ISafe {function getOwners() external view returns (address[] memory);}/*** @title OnlyOwnersGuard - Only allows owners to execute transactions.* @author Richard Meissner - @rmeissner*/contract OnlyOwnersGuard is BaseGuard {ISafe public safe;constructor() {}// solhint-disable-next-line payable-fallbackfallback() external {// We don't revert on fallback to avoid issues in case of a Safe upgrade// E.g. The expected check method might change and then the Safe would be locked.}/*** @notice Called by the Safe contract before a transaction is executed.* @dev Reverts if the transaction is not executed by an owner.* @param msgSender Executor of the transaction.*/function checkTransaction(address,uint256,bytes memory,Enum.Operation,uint256,uint256,uint256,address,// solhint-disable-next-line no-unused-vars
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":false},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"proxy","internalType":"contract SafeProxy"}],"name":"createChainSpecificProxyWithNonce","inputs":[{"type":"address","name":"_singleton","internalType":"address"},{"type":"bytes","name":"initializer","internalType":"bytes"},{"type":"uint256","name":"saltNonce","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"proxy","internalType":"contract SafeProxy"}],"name":"createProxyWithCallback","inputs":[{"type":"address","name":"_singleton","internalType":"address"},{"type":"bytes","name":"initializer","internalType":"bytes"},{"type":"uint256","name":"saltNonce","internalType":"uint256"},{"type":"address","name":"callback","internalType":"contract IProxyCreationCallback"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"proxy","internalType":"contract SafeProxy"}],"name":"createProxyWithNonce","inputs":[{"type":"address","name":"_singleton","internalType":"address"},{"type":"bytes","name":"initializer","internalType":"bytes"},{"type":"uint256","name":"saltNonce","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getChainId","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"proxyCreationCode","inputs":[]},{"type":"event","name":"ProxyCreation","inputs":[{"type":"address","name":"proxy","indexed":true},{"type":"address","name":"singleton","indexed":false}],"anonymous":false}]
Contract Creation Code
0x608060405234801561001057600080fd5b50610bee806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80631688f0b91461005c5780633408e4701461016b57806353e5d93514610189578063d18af54d1461020c578063ec9e80bb1461033b575b600080fd5b61013f6004803603606081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100af57600080fd5b8201836020820111156100c157600080fd5b803590602001918460018302840111640100000000831117156100e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061044a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101736104fe565b6040518082815260200191505060405180910390f35b61019161050b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101d15780820151818401526020810190506101b6565b50505050905090810190601f1680156101fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61030f6004803603608081101561022257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561025f57600080fd5b82018360208201111561027157600080fd5b8035906020019184600183028401116401000000008311171561029357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610536565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61041e6004803603606081101561035157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561038e57600080fd5b8201836020820111156103a057600080fd5b803590602001918460018302840111640100000000831117156103c257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506106e5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008083805190602001208360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506104908585836107a8565b91508173ffffffffffffffffffffffffffffffffffffffff167f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e23586604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2509392505050565b6000804690508091505090565b60606040518060200161051d906109c5565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c905061059186868361044a565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146106dc578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610674578082015181840152602081019050610659565b50505050905090810190601f1680156106a15780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156106c357600080fd5b505af11580156106d7573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836106f96104fe565b60405160200180848152602001838152602001828152602001935050505060405160208183030381529060405280519060200120905061073a8585836107a8565b91508173ffffffffffffffffffffffffffffffffffffffff167f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e23586604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2509392505050565b60006107b3846109b2565b610825576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640081525060200191505060405180910390fd5b600060405180602001610837906109c5565b6020820181038252601f19601f820116604052508573ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b602083106108985780518252602082019150602081019050602083039250610875565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050828151826020016000f59150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610984576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b6000845111156109aa5760008060008651602088016000875af114156109a957600080fd5b5b509392505050565b600080823b905060008111915050919050565b6101e6806109d38339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea264697066735822122003d1488ee65e08fa41e58e888a9865554c535f2c77126a82cb4c0f917f31441364736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564a26469706673582212200fd975ca8e62d9bf08aa3d09c74b9bdc9d7acba7621835be4187989ddd0e54b164736f6c63430007060033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100575760003560e01c80631688f0b91461005c5780633408e4701461016b57806353e5d93514610189578063d18af54d1461020c578063ec9e80bb1461033b575b600080fd5b61013f6004803603606081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100af57600080fd5b8201836020820111156100c157600080fd5b803590602001918460018302840111640100000000831117156100e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061044a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101736104fe565b6040518082815260200191505060405180910390f35b61019161050b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101d15780820151818401526020810190506101b6565b50505050905090810190601f1680156101fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61030f6004803603608081101561022257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561025f57600080fd5b82018360208201111561027157600080fd5b8035906020019184600183028401116401000000008311171561029357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610536565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61041e6004803603606081101561035157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561038e57600080fd5b8201836020820111156103a057600080fd5b803590602001918460018302840111640100000000831117156103c257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506106e5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008083805190602001208360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506104908585836107a8565b91508173ffffffffffffffffffffffffffffffffffffffff167f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e23586604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2509392505050565b6000804690508091505090565b60606040518060200161051d906109c5565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c905061059186868361044a565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146106dc578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610674578082015181840152602081019050610659565b50505050905090810190601f1680156106a15780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156106c357600080fd5b505af11580156106d7573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836106f96104fe565b60405160200180848152602001838152602001828152602001935050505060405160208183030381529060405280519060200120905061073a8585836107a8565b91508173ffffffffffffffffffffffffffffffffffffffff167f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e23586604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2509392505050565b60006107b3846109b2565b610825576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640081525060200191505060405180910390fd5b600060405180602001610837906109c5565b6020820181038252601f19601f820116604052508573ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b602083106108985780518252602082019150602081019050602083039250610875565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050828151826020016000f59150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610984576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b6000845111156109aa5760008060008651602088016000875af114156109a957600080fd5b5b509392505050565b600080823b905060008111915050919050565b6101e6806109d38339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea264697066735822122003d1488ee65e08fa41e58e888a9865554c535f2c77126a82cb4c0f917f31441364736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564a26469706673582212200fd975ca8e62d9bf08aa3d09c74b9bdc9d7acba7621835be4187989ddd0e54b164736f6c63430007060033