Files

66 lines
45 KiB
JSON

{
"contractName": "Delay",
"sourceName": "contracts/Delay.sol",
"compilerVersion": "v0.8.20+commit.a1b79de6",
"constructorArguments": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"input": {
"language": "Solidity",
"sources": {
"@gnosis-guild/zodiac-core/contracts/core/Modifier.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {ExecutionTracker} from \"../signature/ExecutionTracker.sol\";\nimport {IAvatar} from \"../interfaces/IAvatar.sol\";\nimport {Module} from \"./Module.sol\";\nimport {SignatureChecker} from \"../signature/SignatureChecker.sol\";\n\n/// @title Modifier Interface - A contract that sits between a Module and an Avatar and enforce some additional logic.\nabstract contract Modifier is\n Module,\n ExecutionTracker,\n SignatureChecker,\n IAvatar\n{\n address internal constant SENTINEL_MODULES = address(0x1);\n /// Mapping of modules.\n mapping(address => address) internal modules;\n\n /// `sender` is not an authorized module.\n /// @param sender The address of the sender.\n error NotAuthorized(address sender);\n\n /// `module` is invalid.\n error InvalidModule(address module);\n\n /// `pageSize` is invalid.\n error InvalidPageSize();\n\n /// `module` is already disabled.\n error AlreadyDisabledModule(address module);\n\n /// `module` is already enabled.\n error AlreadyEnabledModule(address module);\n\n /// @dev `setModules()` was already called.\n error SetupModulesAlreadyCalled();\n\n /*\n --------------------------------------------------\n You must override both of the following virtual functions,\n execTransactionFromModule() and execTransactionFromModuleReturnData().\n It is recommended that implementations of both functions make use the \n onlyModule modifier.\n */\n\n /// @dev Passes a transaction to the modifier.\n /// @notice Can only be called by enabled modules.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) public virtual returns (bool success);\n\n /// @dev Passes a transaction to the modifier, expects return data.\n /// @notice Can only be called by enabled modules.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) public virtual returns (bool success, bytes memory returnData);\n\n /*\n --------------------------------------------------\n */\n\n modifier moduleOnly() {\n if (modules[msg.sender] == address(0)) {\n (bytes32 hash, address signer) = moduleTxSignedBy();\n\n // is the signer a module?\n if (modules[signer] == address(0)) {\n revert NotAuthorized(msg.sender);\n }\n\n // is the provided signature fresh?\n if (consumed[signer][hash]) {\n revert HashAlreadyConsumed(hash);\n }\n\n consumed[signer][hash] = true;\n emit HashExecuted(hash);\n }\n\n _;\n }\n\n function sentOrSignedByModule() internal view returns (address) {\n if (modules[msg.sender] != address(0)) {\n return msg.sender;\n }\n\n (, address signer) = moduleTxSignedBy();\n if (modules[signer] != address(0)) {\n return signer;\n }\n\n return address(0);\n }\n\n /// @dev Disables a module on the modifier.\n /// @notice This can only be called by the owner.\n /// @param prevModule Module that pointed to the module to be removed in the linked list.\n /// @param module Module to be removed.\n function disableModule(\n address prevModule,\n address module\n ) public override onlyOwner {\n if (module == address(0) || module == SENTINEL_MODULES)\n revert InvalidModule(module);\n if (modules[prevModule] != module) revert AlreadyDisabledModule(module);\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Enables a module that can add transactions to the queue\n /// @param module Address of the module to be enabled\n /// @notice This can only be called by the owner\n function enableModule(address module) public override onlyOwner {\n if (module == address(0) || module == SENTINEL_MODULES)\n revert InvalidModule(module);\n if (modules[module] != address(0)) revert AlreadyEnabledModule(module);\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(\n address _module\n ) public view override returns (bool) {\n return SENTINEL_MODULES != _module && modules[_module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// If all entries fit into a single page, the next pointer will be 0x1.\n /// If another page is present, next will be the last element of the returned array.\n /// @param start Start of the page. Has to be a module or start pointer (0x1 address)\n /// @param pageSize Maximum number of modules that should be returned. Has to be > 0\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(\n address start,\n uint256 pageSize\n ) external view override returns (address[] memory array, address next) {\n if (start != SENTINEL_MODULES && !isModuleEnabled(start)) {\n revert InvalidModule(start);\n }\n if (pageSize == 0) {\n revert InvalidPageSize();\n }\n\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n next = modules[start];\n while (\n next != address(0) && next != SENTINEL_MODULES && moduleCount < pageSize\n ) {\n array[moduleCount] = next;\n next = modules[next];\n moduleCount++;\n }\n\n // Because of the argument validation we can assume that\n // the `currentModule` will always be either a module address\n // or sentinel address (aka the end). If we haven't reached the end\n // inside the loop, we need to set the next pointer to the last element\n // because it skipped over to the next module which is neither included\n // in the current page nor won't be included in the next one\n // if you pass it as a start.\n if (next != SENTINEL_MODULES) {\n next = array[moduleCount - 1];\n }\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n\n /// @dev Initializes the modules linked list.\n /// @notice Should be called as part of the `setUp` / initializing function and can only be called once.\n function setupModules() internal {\n if (modules[SENTINEL_MODULES] != address(0))\n revert SetupModulesAlreadyCalled();\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n }\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/core/Module.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\nimport {FactoryFriendly} from \"../factory/FactoryFriendly.sol\";\nimport {IAvatar} from \"../interfaces/IAvatar.sol\";\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\nabstract contract Module is FactoryFriendly {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal virtual returns (bool success) {\n return\n IAvatar(target).execTransactionFromModule(to, value, data, operation);\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal virtual returns (bool success, bytes memory returnData) {\n return\n IAvatar(target).execTransactionFromModuleReturnData(\n to,\n value,\n data,\n operation\n );\n }\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/factory/FactoryFriendly.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/interfaces/IAvatar.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(\n address start,\n uint256 pageSize\n ) external view returns (address[] memory array, address next);\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/signature/ExecutionTracker.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0 <0.9.0;\n\n/// @title ExecutionTracker - A contract that keeps track of executed and invalidated hashes\ncontract ExecutionTracker {\n error HashAlreadyConsumed(bytes32);\n\n event HashExecuted(bytes32);\n event HashInvalidated(bytes32);\n\n mapping(address => mapping(bytes32 => bool)) public consumed;\n\n function invalidate(bytes32 hash) external {\n consumed[msg.sender][hash] = true;\n emit HashInvalidated(hash);\n }\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/signature/IERC1271.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\n/* solhint-disable one-contract-per-file */\npragma solidity >=0.7.0 <0.9.0;\n\ninterface IERC1271 {\n /**\n * @notice EIP1271 method to validate a signature.\n * @param hash Hash of the data signed on the behalf of address(this).\n * @param signature Signature byte array associated with _data.\n *\n * MUST return the bytes4 magic value 0x1626ba7e when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n"
},
"@gnosis-guild/zodiac-core/contracts/signature/SignatureChecker.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0 <0.9.0;\n\nimport {IERC1271} from \"./IERC1271.sol\";\n\n/// @title SignatureChecker - A contract that retrieves and validates signatures appended to transaction calldata.\n/// @dev currently supports eip-712 and eip-1271 signatures\nabstract contract SignatureChecker {\n /**\n * @notice Searches for a signature, validates it, and returns the signer's address.\n * @dev When signature not found or invalid, zero address is returned\n * @return The address of the signer.\n */\n function moduleTxSignedBy() internal view returns (bytes32, address) {\n bytes calldata data = msg.data;\n\n /*\n * The idea is to extend `onlyModule` and provide signature checking\n * without code changes to inheriting contracts (Modifiers).\n *\n * Since it's a generic mechanism, there is no way to conclusively\n * identify the trailing bytes as a signature. We simply slice those\n * and recover signer.\n *\n * As a result, we impose a minimum calldata length equal to a function\n * selector plus salt, plus a signature (i.e., 4 + 32 + 65 bytes), any\n * shorter and calldata it guaranteed to not contain a signature.\n */\n if (data.length < 4 + 32 + 65) {\n return (bytes32(0), address(0));\n }\n\n (uint8 v, bytes32 r, bytes32 s) = _splitSignature(data);\n\n uint256 end = data.length - (32 + 65);\n bytes32 salt = bytes32(data[end:]);\n\n /*\n * When handling contract signatures:\n * v - is zero\n * r - contains the signer\n * s - contains the offset within calldata where the signer specific\n * signature is located\n *\n * We detect contract signatures by checking:\n * 1- `v` is zero\n * 2- `s` points within the buffer, is after selector, is before\n * salt and delimits a non-zero length buffer\n */\n if (v == 0) {\n uint256 start = uint256(s);\n if (start < 4 || start > end) {\n return (bytes32(0), address(0));\n }\n address signer = address(uint160(uint256(r)));\n\n bytes32 hash = moduleTxHash(data[:start], salt);\n return\n _isValidContractSignature(signer, hash, data[start:end])\n ? (hash, signer)\n : (bytes32(0), address(0));\n } else {\n bytes32 hash = moduleTxHash(data[:end], salt);\n return (hash, ecrecover(hash, v, r, s));\n }\n }\n\n /**\n * @notice Hashes the transaction EIP-712 data structure.\n * @dev The produced hash is intended to be signed.\n * @param data The current transaction's calldata.\n * @param salt The salt value.\n * @return The 32-byte hash that is to be signed.\n */\n function moduleTxHash(\n bytes calldata data,\n bytes32 salt\n ) public view returns (bytes32) {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_SEPARATOR_TYPEHASH, block.chainid, this)\n );\n bytes memory moduleTxData = abi.encodePacked(\n bytes1(0x19),\n bytes1(0x01),\n domainSeparator,\n keccak256(abi.encode(MODULE_TX_TYPEHASH, keccak256(data), salt))\n );\n return keccak256(moduleTxData);\n }\n\n /**\n * @dev Extracts signature from calldata, and divides it into `uint8 v, bytes32 r, bytes32 s`.\n * @param data The current transaction's calldata.\n * @return v The ECDSA v value\n * @return r The ECDSA r value\n * @return s The ECDSA s value\n */\n function _splitSignature(\n bytes calldata data\n ) private pure returns (uint8 v, bytes32 r, bytes32 s) {\n v = uint8(bytes1(data[data.length - 1:]));\n r = bytes32(data[data.length - 65:]);\n s = bytes32(data[data.length - 33:]);\n }\n\n /**\n * @dev Calls the signer contract, and validates the contract signature.\n * @param signer The address of the signer contract.\n * @param hash Hash of the data signed\n * @param signature The contract signature.\n * @return result Indicates whether the signature is valid.\n */\n function _isValidContractSignature(\n address signer,\n bytes32 hash,\n bytes calldata signature\n ) internal view returns (bool result) {\n uint256 size;\n // eslint-disable-line no-inline-assembly\n assembly {\n size := extcodesize(signer)\n }\n if (size == 0) {\n return false;\n }\n\n (, bytes memory returnData) = signer.staticcall(\n abi.encodeWithSelector(\n IERC1271.isValidSignature.selector,\n hash,\n signature\n )\n );\n\n return bytes4(returnData) == EIP1271_MAGIC_VALUE;\n }\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH =\n 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"ModuleTx(bytes data,bytes32 salt)\"\n // );\n bytes32 private constant MODULE_TX_TYPEHASH =\n 0x2939aeeda3ca260200c9f7b436b19e13207547ccc65cfedc857751c5ea6d91d4;\n\n // bytes4(keccak256(\n // \"isValidSignature(bytes32,bytes)\"\n // ));\n bytes4 private constant EIP1271_MAGIC_VALUE = 0x1626ba7e;\n}\n"
},
"@gnosis.pm/safe-contracts/contracts/common/Enum.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <[email protected]>\ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n"
},
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n struct OwnableStorage {\n address _owner;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n assembly {\n $.slot := OwnableStorageLocation\n }\n }\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n function __Ownable_init(address initialOwner) internal onlyInitializing {\n __Ownable_init_unchained(initialOwner);\n }\n\n function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n OwnableStorage storage $ = _getOwnableStorage();\n return $._owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n OwnableStorage storage $ = _getOwnableStorage();\n address oldOwner = $._owner;\n $._owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Storage of the initializable contract.\n *\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n * when using with upgradeable contracts.\n *\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n */\n struct InitializableStorage {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n uint64 _initialized;\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool _initializing;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n /**\n * @dev The contract is already initialized.\n */\n error InvalidInitialization();\n\n /**\n * @dev The contract is not initializing.\n */\n error NotInitializing();\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint64 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n * production.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n // Cache values to avoid duplicated sloads\n bool isTopLevelCall = !$._initializing;\n uint64 initialized = $._initialized;\n\n // Allowed calls:\n // - initialSetup: the contract is not in the initializing state and no previous version was\n // initialized\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\n // current contract is just being deployed\n bool initialSetup = initialized == 0 && isTopLevelCall;\n bool construction = initialized == 1 && address(this).code.length == 0;\n\n if (!initialSetup && !construction) {\n revert InvalidInitialization();\n }\n $._initialized = 1;\n if (isTopLevelCall) {\n $._initializing = true;\n }\n _;\n if (isTopLevelCall) {\n $._initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint64 version) {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing || $._initialized >= version) {\n revert InvalidInitialization();\n }\n $._initialized = version;\n $._initializing = true;\n _;\n $._initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n _checkInitializing();\n _;\n }\n\n /**\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n */\n function _checkInitializing() internal view virtual {\n if (!_isInitializing()) {\n revert NotInitializing();\n }\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing) {\n revert InvalidInitialization();\n }\n if ($._initialized != type(uint64).max) {\n $._initialized = type(uint64).max;\n emit Initialized(type(uint64).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint64) {\n return _getInitializableStorage()._initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _getInitializableStorage()._initializing;\n }\n\n /**\n * @dev Returns a pointer to the storage namespace.\n */\n // solhint-disable-next-line var-name-mixedcase\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n assembly {\n $.slot := INITIALIZABLE_STORAGE\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"
},
"contracts/Delay.sol": {
"content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {Enum, Modifier} from \"@gnosis-guild/zodiac-core/contracts/core/Modifier.sol\";\n\ncontract Delay is Modifier {\n event DelaySetup(\n address indexed initiator,\n address indexed owner,\n address indexed avatar,\n address target\n );\n event TxCooldownSet(uint256 cooldown);\n event TxExpirationSet(uint256 expiration);\n event TxNonceSet(uint256 nonce);\n event TransactionAdded(\n uint256 indexed queueNonce,\n bytes32 indexed txHash,\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation\n );\n\n uint256 public txCooldown;\n uint256 public txExpiration;\n uint256 public txNonce;\n uint256 public queueNonce;\n // Mapping of queue nonce to transaction hash.\n mapping(uint256 => bytes32) public txHash;\n // Mapping of queue nonce to creation timestamp.\n mapping(uint256 => uint256) public txCreatedAt;\n\n /// @param _owner Address of the owner\n /// @param _avatar Address of the avatar (e.g. a Gnosis Safe)\n /// @param _target Address of the contract that will call exec function\n /// @param _cooldown Cooldown in seconds that should be required after a transaction is proposed\n /// @param _expiration Duration that a proposed transaction is valid for after the cooldown, in seconds (or 0 if valid forever)\n /// @notice There need to be at least 60 seconds between end of cooldown and expiration\n constructor(\n address _owner,\n address _avatar,\n address _target,\n uint256 _cooldown,\n uint256 _expiration\n ) {\n bytes memory initParams = abi.encode(\n _owner,\n _avatar,\n _target,\n _cooldown,\n _expiration\n );\n setUp(initParams);\n }\n\n function setUp(bytes memory initParams) public override initializer {\n (\n address _owner,\n address _avatar,\n address _target,\n uint256 _cooldown,\n uint256 _expiration\n ) = abi.decode(\n initParams,\n (address, address, address, uint256, uint256)\n );\n require(_avatar != address(0), \"Avatar can not be zero address\");\n require(_target != address(0), \"Target can not be zero address\");\n require(\n _expiration == 0 || _expiration >= 60,\n \"Expiration must be 0 or at least 60 seconds\"\n );\n\n _transferOwnership(_owner);\n avatar = _avatar;\n target = _target;\n txExpiration = _expiration;\n txCooldown = _cooldown;\n setupModules();\n\n emit DelaySetup(msg.sender, _owner, _avatar, _target);\n emit AvatarSet(address(0), _avatar);\n emit TargetSet(address(0), _target);\n }\n\n /// @dev Sets the cooldown before a transaction can be executed.\n /// @param _txCooldown Cooldown in seconds that should be required before the transaction can be executed\n /// @notice This can only be called by the owner\n function setTxCooldown(uint256 _txCooldown) public onlyOwner {\n txCooldown = _txCooldown;\n emit TxCooldownSet(_txCooldown);\n }\n\n /// @dev Sets the duration for which a transaction is valid.\n /// @param _txExpiration Duration that a transaction is valid in seconds (or 0 if valid forever) after the cooldown\n /// @notice There need to be at least 60 seconds between end of cooldown and expiration\n /// @notice This can only be called by the owner\n function setTxExpiration(uint256 _txExpiration) public onlyOwner {\n require(\n _txExpiration == 0 || _txExpiration >= 60,\n \"Expiration must be 0 or at least 60 seconds\"\n );\n txExpiration = _txExpiration;\n emit TxExpirationSet(_txExpiration);\n }\n\n /// @dev Sets transaction nonce. Used to invalidate or skip transactions in queue.\n /// @param _txNonce New transaction nonce\n /// @notice This can only be called by the owner\n function setTxNonce(uint256 _txNonce) public onlyOwner {\n require(\n _txNonce > txNonce,\n \"New nonce must be higher than current txNonce\"\n );\n require(_txNonce <= queueNonce, \"Cannot be higher than queueNonce\");\n txNonce = _txNonce;\n emit TxNonceSet(_txNonce);\n }\n\n /// @dev Adds a transaction to the queue (same as avatar interface so that this can be placed between other modules and the avatar).\n /// @param to Destination address of module transaction\n /// @param value Ether value of module transaction\n /// @param data Data payload of module transaction\n /// @param operation Operation type of module transaction\n /// @return success Whether or not the call was successfully queued for execution\n /// @notice Can only be called by enabled modules\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) public override moduleOnly returns (bool success) {\n bytes32 hash = getTransactionHash(to, value, data, operation);\n txHash[queueNonce] = hash;\n txCreatedAt[queueNonce] = block.timestamp;\n emit TransactionAdded(queueNonce, hash, to, value, data, operation);\n queueNonce++;\n success = true;\n }\n\n /// @dev Adds a transaction to the queue (same as avatar interface so that this can be placed between other modules and the avatar).\n /// @param to Destination address of module transaction\n /// @param value Ether value of module transaction\n /// @param data Data payload of module transaction\n /// @param operation Operation type of module transaction\n /// @return success Whether or not the call was successfully queued for execution\n /// @return returnData ABI encoded queue nonce (uint256), transaction hash (bytes32), and block.timestamp (uint256)\n /// @notice Can only be called by enabled modules\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n )\n public\n override\n moduleOnly\n returns (bool success, bytes memory returnData)\n {\n bytes32 hash = getTransactionHash(to, value, data, operation);\n txHash[queueNonce] = hash;\n txCreatedAt[queueNonce] = block.timestamp;\n emit TransactionAdded(queueNonce, hash, to, value, data, operation);\n success = true;\n returnData = abi.encode(queueNonce, hash, block.timestamp);\n queueNonce++;\n }\n\n /// @dev Executes the next transaction only if the cooldown has passed and the transaction has not expired\n /// @param to Destination address of module transaction\n /// @param value Ether value of module transaction\n /// @param data Data payload of module transaction\n /// @param operation Operation type of module transaction\n /// @notice The txIndex used by this function is always 0\n function executeNextTx(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) public {\n require(txNonce < queueNonce, \"Transaction queue is empty\");\n uint256 txCreationTimestamp = txCreatedAt[txNonce];\n require(\n block.timestamp - txCreationTimestamp >= txCooldown,\n \"Transaction is still in cooldown\"\n );\n if (txExpiration != 0) {\n require(\n txCreationTimestamp + txCooldown + txExpiration >=\n block.timestamp,\n \"Transaction expired\"\n );\n }\n require(\n txHash[txNonce] == getTransactionHash(to, value, data, operation),\n \"Transaction hashes do not match\"\n );\n txNonce++;\n require(exec(to, value, data, operation), \"Module transaction failed\");\n }\n\n function skipExpired() public {\n while (\n txExpiration != 0 &&\n txCreatedAt[txNonce] + txCooldown + txExpiration <\n block.timestamp &&\n txNonce < queueNonce\n ) {\n txNonce++;\n }\n }\n\n function getTransactionHash(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public pure returns (bytes32) {\n return keccak256(abi.encodePacked(to, value, data, operation));\n }\n\n function getTxHash(uint256 _nonce) public view returns (bytes32) {\n return (txHash[_nonce]);\n }\n\n function getTxCreatedAt(uint256 _nonce) public view returns (uint256) {\n return (txCreatedAt[_nonce]);\n }\n}\n"
}
},
"settings": {
"evmVersion": "paris",
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}
}