@ironblocks/firewall-consumer
Version:
Provided interface for smart contracts to connect to Ironblocks' Firewall
1 lines • 436 kB
JSON
{"id":"2e318fd64cd5144364ad93830a9d8c6c","_format":"hh-sol-build-info-1","solcVersion":"0.8.19","solcLongVersion":"0.8.19+commit.7dd6d404","input":{"language":"Solidity","sources":{"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\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 Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\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 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\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 require(_initializing, \"Initializable: contract is not initializing\");\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 require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _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 _initializing;\n }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"},"contracts/consumers/SimpleUpgradeableFirewallConsumer.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n// See LICENSE file for full license text.\n// Copyright (c) Ironblocks 2024\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {IFirewall} from \"../interfaces/IFirewall.sol\";\nimport {IFirewallConsumer} from \"../interfaces/IFirewallConsumer.sol\";\nimport {IFirewallConsumerStorage} from \"../interfaces/IFirewallConsumerStorage.sol\";\n\n/**\n * @title Firewall Minimal Upgradeable Consumer Contract\n * @author David Benchimol @ Ironblocks\n * @dev This contract is a parent contract that can be used to add firewall protection to any contract.\n *\n * The contract is the most minimal upgradeable contract that implements the FirewallConsumer interface.\n *\n */\ncontract SimpleUpgradeableFirewallConsumer is IFirewallConsumer, Initializable {\n\n // This slot is used to store the consumer storage address\n bytes32 private constant FIREWALL_CONSUMER_STORAGE_SLOT = bytes32(uint256(keccak256(\"eip1967.firewall.consumer.storage\")) - 1);\n bytes32 private constant FIREWALL_CONSUMER_INITIALIZER_FIREWALL_ADMIN_SLOT = bytes32(uint256(keccak256(\"eip1967.firewall.consumer.initializer.firewall.admin\")) - 1);\n\n /**\n * @dev modifier that will run the preExecution and postExecution hooks of the firewall, applying each of\n * the subscribed policies.\n *\n * NOTE: Applying this modifier on functions that exit execution flow by an inline assmebly \"return\" call will\n * prevent the postExecution hook from running - breaking the protection provided by the firewall.\n * If you have any questions, please refer to the Firewall's documentation and/or contact our support.\n */\n modifier firewallProtected() {\n address firewallConsumerStorage = _getFirewallConsumerStorage();\n if (firewallConsumerStorage == address(0)) {\n _;\n return;\n }\n address firewall = IFirewallConsumerStorage(firewallConsumerStorage).getFirewall();\n if (firewall == address(0)) {\n _;\n return;\n }\n // We do this because msg.value can only be accessed in payable functions.\n uint256 value;\n assembly {\n value := callvalue()\n }\n IFirewall(firewall).preExecution(msg.sender, msg.data, value);\n _;\n IFirewall(firewall).postExecution(msg.sender, msg.data, value);\n }\n\n /**\n * @dev modifier similar to onlyOwner, but for the firewall admin.\n */\n modifier onlyFirewallAdmin() {\n require(msg.sender == _getFirewallAdmin(), \"FirewallConsumer: not firewall admin\");\n _;\n }\n\n /**\n * @dev Allows calling an approved external Venn policy before executing a method.\n *\n * This can be used for multiple purposes, but the initial one is to call `approveCallsViaSignature` before\n * executing a function, allowing synchronous transaction approvals.\n *\n * NOTE: If userNativeFee is non zero, functions using this must take into account that\n * the value received will be slightly less than msg.value due to the fee.\n *\n * @param vennPolicyPayload payload to be sent to the Venn policy\n * @param data data to be executed after the Venn policy call\n */\n function safeFunctionCall(\n uint256 userNativeFee,\n bytes calldata vennPolicyPayload,\n bytes calldata data\n ) external payable {\n address firewallConsumerStorage = _getFirewallConsumerStorage();\n address vennPolicy = IFirewallConsumerStorage(firewallConsumerStorage).getApprovedVennPolicy();\n require(msg.value >= userNativeFee, \"FirewallConsumer: Not enough native value for fee\");\n (bool success,) = vennPolicy.call{value: userNativeFee}(vennPolicyPayload);\n require(success);\n Address.functionDelegateCall(address(this), data);\n }\n\n /**\n * @dev View function for the firewall admin\n */\n function firewallAdmin() external view returns (address) {\n return _getFirewallAdmin();\n }\n\n function setFirewallConsumerStorage(address _firewallConsumerStorage) external onlyFirewallAdmin {\n _setAddressBySlot(FIREWALL_CONSUMER_INITIALIZER_FIREWALL_ADMIN_SLOT, address(0));\n _setAddressBySlot(FIREWALL_CONSUMER_STORAGE_SLOT, _firewallConsumerStorage);\n }\n\n function __SimpleUpgradeableFirewallConsumer_init(IFirewallConsumerStorage _firewallConsumerStorage, address _firewallAdmin) internal onlyInitializing {\n require((address(_firewallConsumerStorage) != address(0)) || _firewallAdmin != address(0), \"FirewallConsumer: must have firewall consumer storage or firewall admin\");\n address _firewallConsumerStorageAddress = address(_firewallConsumerStorage);\n if (_firewallConsumerStorageAddress == address(0)) {\n _setAddressBySlot(FIREWALL_CONSUMER_INITIALIZER_FIREWALL_ADMIN_SLOT, _firewallAdmin);\n return;\n }\n _setAddressBySlot(FIREWALL_CONSUMER_STORAGE_SLOT, _firewallConsumerStorageAddress);\n }\n\n /**\n * @dev Internal view function for the firewall admin\n */\n function _getFirewallAdmin() internal view returns (address) {\n address firewallConsumerStorage = _getFirewallConsumerStorage();\n if (firewallConsumerStorage == address(0)) {\n return _getAddressBySlot(FIREWALL_CONSUMER_INITIALIZER_FIREWALL_ADMIN_SLOT);\n }\n return IFirewallConsumerStorage(firewallConsumerStorage).getFirewallAdmin();\n }\n\n /**\n * @dev Internal view function for the consumer storage\n */\n function _getFirewallConsumerStorage() internal view returns (address) {\n return _getAddressBySlot(FIREWALL_CONSUMER_STORAGE_SLOT);\n }\n\n\n /**\n * @dev Internal helper function to set an address in a storage slot\n * @param _slot storage slot\n * @param _address address to be set\n */\n function _setAddressBySlot(bytes32 _slot, address _address) internal {\n assembly {\n sstore(_slot, _address)\n }\n }\n\n /**\n * @dev Internal helper function to get an address from a storage slot\n * @param _slot storage slot\n * @return _address from the storage slot\n */\n function _getAddressBySlot(bytes32 _slot) internal view returns (address _address) {\n assembly {\n _address := sload(_slot)\n }\n }\n\n}"},"contracts/interfaces/IFirewall.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n// See LICENSE file for full license text.\n// Copyright (c) Ironblocks 2024\npragma solidity ^0.8;\n\ninterface IFirewall {\n function preExecution(address sender, bytes memory data, uint256 value) external;\n function postExecution(address sender, bytes memory data, uint256 value) external;\n function preExecutionPrivateInvariants(address sender, bytes memory data, uint256 value) external returns (bytes32[] calldata);\n function postExecutionPrivateInvariants(\n address sender,\n bytes memory data,\n uint256 value,\n bytes32[] calldata preValues,\n bytes32[] calldata postValues\n ) external;\n}"},"contracts/interfaces/IFirewallConsumer.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n// See LICENSE file for full license text.\n// Copyright (c) Ironblocks 2024\npragma solidity ^0.8;\n\ninterface IFirewallConsumer {\n function firewallAdmin() external view returns (address);\n}"},"contracts/interfaces/IFirewallConsumerStorage.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n// See LICENSE file for full license text.\n// Copyright (c) Ironblocks 2024\npragma solidity ^0.8.0;\n\ninterface IFirewallConsumerStorage {\n function getFirewallAdmin() external view returns (address);\n function getFirewall() external view returns (address);\n function getApprovedVennPolicy() external view returns (address);\n function getUserNativeFee() external view returns (uint256);\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":10000},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}}}},"output":{"sources":{"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol":{"ast":{"absolutePath":"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","exportedSymbols":{"AddressUpgradeable":[498],"Initializable":[168]},"id":169,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity","^","0.8",".2"],"nodeType":"PragmaDirective","src":"113:23:0"},{"absolutePath":"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol","file":"../../utils/AddressUpgradeable.sol","id":2,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":169,"sourceUnit":499,"src":"138:44:0","symbolAliases":[],"unitAlias":""},{"abstract":true,"baseContracts":[],"canonicalName":"Initializable","contractDependencies":[],"contractKind":"contract","documentation":{"id":3,"nodeType":"StructuredDocumentation","src":"184:2209:0","text":" @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 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 For example:\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 contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n function initializeV2() reinitializer(2) public {\n __ERC20Permit_init(\"MyToken\");\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 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 [CAUTION]\n ====\n Avoid leaving a contract uninitialized.\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 [.hljs-theme-light.nopadding]\n ```\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n ```\n ===="},"fullyImplemented":true,"id":168,"linearizedBaseContracts":[168],"name":"Initializable","nameLocation":"2412:13:0","nodeType":"ContractDefinition","nodes":[{"constant":false,"documentation":{"id":4,"nodeType":"StructuredDocumentation","src":"2432:109:0","text":" @dev Indicates that the contract has been initialized.\n @custom:oz-retyped-from bool"},"id":6,"mutability":"mutable","name":"_initialized","nameLocation":"2560:12:0","nodeType":"VariableDeclaration","scope":168,"src":"2546:26:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"},"typeName":{"id":5,"name":"uint8","nodeType":"ElementaryTypeName","src":"2546:5:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"visibility":"private"},{"constant":false,"documentation":{"id":7,"nodeType":"StructuredDocumentation","src":"2579:91:0","text":" @dev Indicates that the contract is in the process of being initialized."},"id":9,"mutability":"mutable","name":"_initializing","nameLocation":"2688:13:0","nodeType":"VariableDeclaration","scope":168,"src":"2675:26:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":8,"name":"bool","nodeType":"ElementaryTypeName","src":"2675:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"private"},{"anonymous":false,"documentation":{"id":10,"nodeType":"StructuredDocumentation","src":"2708:90:0","text":" @dev Triggered when the contract has been initialized or reinitialized."},"eventSelector":"7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498","id":14,"name":"Initialized","nameLocation":"2809:11:0","nodeType":"EventDefinition","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"indexed":false,"mutability":"mutable","name":"version","nameLocation":"2827:7:0","nodeType":"VariableDeclaration","scope":14,"src":"2821:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"},"typeName":{"id":11,"name":"uint8","nodeType":"ElementaryTypeName","src":"2821:5:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"visibility":"internal"}],"src":"2820:15:0"},"src":"2803:33:0"},{"body":{"id":69,"nodeType":"Block","src":"3269:483:0","statements":[{"assignments":[18],"declarations":[{"constant":false,"id":18,"mutability":"mutable","name":"isTopLevelCall","nameLocation":"3284:14:0","nodeType":"VariableDeclaration","scope":69,"src":"3279:19:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":17,"name":"bool","nodeType":"ElementaryTypeName","src":"3279:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":21,"initialValue":{"id":20,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"3301:14:0","subExpression":{"id":19,"name":"_initializing","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":9,"src":"3302:13:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"3279:36:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":42,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":27,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":23,"name":"isTopLevelCall","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":18,"src":"3347:14:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint8","typeString":"uint8"},"id":26,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":24,"name":"_initialized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":6,"src":"3365:12:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"hexValue":"31","id":25,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3380:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"3365:16:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"3347:34:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"id":28,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"3346:36:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":40,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":36,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"3387:45:0","subExpression":{"arguments":[{"arguments":[{"id":33,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3426:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_Initializable_$168","typeString":"contract Initializable"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_Initializable_$168","typeString":"contract Initializable"}],"id":32,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3418:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":31,"name":"address","nodeType":"ElementaryTypeName","src":"3418:7:0","typeDescriptions":{}}},"id":34,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3418:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":29,"name":"AddressUpgradeable","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":498,"src":"3388:18:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_AddressUpgradeable_$498_$","typeString":"type(library AddressUpgradeable)"}},"id":30,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3407:10:0","memberName":"isContract","nodeType":"MemberAccess","referencedDeclaration":186,"src":"3388:29:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$","typeString":"function (address) view returns (bool)"}},"id":35,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3388:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint8","typeString":"uint8"},"id":39,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":37,"name":"_initialized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":6,"src":"3436:12:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31","id":38,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3452:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"3436:17:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"3387:66:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"id":41,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"3386:68:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"3346:108:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564","id":43,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3468:48:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc23759","typeString":"literal_string \"Initializable: contract is already initialized\""},"value":"Initializable: contract is already initialized"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc23759","typeString":"literal_string \"Initializable: contract is already initialized\""}],"id":22,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"3325:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":44,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3325:201:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":45,"nodeType":"ExpressionStatement","src":"3325:201:0"},{"expression":{"id":48,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":46,"name":"_initialized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":6,"src":"3536:12:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"hexValue":"31","id":47,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3551:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"3536:16:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"id":49,"nodeType":"ExpressionStatement","src":"3536:16:0"},{"condition":{"id":50,"name":"isTopLevelCall","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":18,"src":"3566:14:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":56,"nodeType":"IfStatement","src":"3562:65:0","trueBody":{"id":55,"nodeType":"Block","src":"3582:45:0","statements":[{"expression":{"id":53,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":51,"name":"_initializing","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":9,"src":"3596:13:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"hexValue":"74727565","id":52,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"3612:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"src":"3596:20:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":54,"nodeType":"ExpressionStatement","src":"3596:20:0"}]}},{"id":57,"nodeType":"Placeh