Source Code
Overview
ETH Balance
4,185.4963965657956482 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 54,207 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Safe Function Ca... | 3526247 | 1 hr ago | IN | 0 ETH | 0.0000012 | ||||
Safe Function Ca... | 3526212 | 1 hr ago | IN | 0.2 ETH | 0.00000164 | ||||
Safe Function Ca... | 3526206 | 1 hr ago | IN | 0.2 ETH | 0.00000188 | ||||
Safe Function Ca... | 3526183 | 1 hr ago | IN | 0.1 ETH | 0.00000186 | ||||
Safe Function Ca... | 3526173 | 1 hr ago | IN | 0 ETH | 0.00000173 | ||||
Safe Function Ca... | 3526170 | 1 hr ago | IN | 0.01 ETH | 0.00000152 | ||||
Deposit | 3526169 | 1 hr ago | IN | 0.1 ETH | 0.00014985 | ||||
Deposit | 3526159 | 1 hr ago | IN | 0.1 ETH | 0.00014985 | ||||
Deposit | 3526008 | 2 hrs ago | IN | 0.12 ETH | 0.00014985 | ||||
Safe Function Ca... | 3526001 | 2 hrs ago | IN | 0.12 ETH | 0.0000017 | ||||
Safe Function Ca... | 3525852 | 2 hrs ago | IN | 0.01 ETH | 0.00000177 | ||||
Deposit | 3525727 | 3 hrs ago | IN | 1 ETH | 0.00014985 | ||||
Safe Function Ca... | 3525723 | 3 hrs ago | IN | 1 ETH | 0.0000015 | ||||
Deposit | 3525636 | 3 hrs ago | IN | 0.001 ETH | 0.00014985 | ||||
Safe Function Ca... | 3525632 | 3 hrs ago | IN | 0.001 ETH | 0.00000154 | ||||
Safe Function Ca... | 3525515 | 3 hrs ago | IN | 0.0001 ETH | 0.00000163 | ||||
Safe Function Ca... | 3525506 | 3 hrs ago | IN | 0 ETH | 0.00000166 | ||||
Withdraw | 3525502 | 3 hrs ago | IN | 0 ETH | 0.00015117 | ||||
Deposit | 3525494 | 4 hrs ago | IN | 0.0001 ETH | 0.00014985 | ||||
Safe Function Ca... | 3525481 | 4 hrs ago | IN | 0.0001 ETH | 0.00000176 | ||||
Deposit | 3525373 | 4 hrs ago | IN | 0.1 ETH | 0.00014985 | ||||
Deposit | 3525316 | 4 hrs ago | IN | 0.5 ETH | 0.00014985 | ||||
Safe Function Ca... | 3525303 | 4 hrs ago | IN | 1 ETH | 0.00001203 | ||||
Safe Function Ca... | 3525261 | 4 hrs ago | IN | 0 ETH | 0.00001477 | ||||
Safe Function Ca... | 3525204 | 5 hrs ago | IN | 0.5 ETH | 0.00002966 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Transfer | 3526247 | 1 hr ago | 0.2 ETH | ||||
Transfer | 3526173 | 1 hr ago | 0.01 ETH | ||||
Transfer | 3525506 | 3 hrs ago | 0.0001 ETH | ||||
Transfer | 3525261 | 4 hrs ago | 0.8 ETH | ||||
Transfer | 3525006 | 5 hrs ago | 0.000001 ETH | ||||
Transfer | 3524896 | 6 hrs ago | 0.001 ETH | ||||
Transfer | 3524815 | 6 hrs ago | 0.001 ETH | ||||
Transfer | 3524726 | 7 hrs ago | 0.002 ETH | ||||
Transfer | 3524711 | 7 hrs ago | 0.001 ETH | ||||
Transfer | 3524708 | 7 hrs ago | 0.002 ETH | ||||
Transfer | 3524705 | 7 hrs ago | 0.01 ETH | ||||
Transfer | 3524608 | 7 hrs ago | 0.5 ETH | ||||
Transfer | 3524598 | 7 hrs ago | 0.1 ETH | ||||
Transfer | 3524378 | 8 hrs ago | 0.02 ETH | ||||
Transfer | 3524334 | 8 hrs ago | 0.01 ETH | ||||
Transfer | 3524330 | 8 hrs ago | 0.01 ETH | ||||
Transfer | 3524316 | 8 hrs ago | 0.001 ETH | ||||
Transfer | 3524264 | 8 hrs ago | 1 ETH | ||||
Transfer | 3524167 | 9 hrs ago | 1 ETH | ||||
Transfer | 3524073 | 9 hrs ago | 0.01 ETH | ||||
Transfer | 3524063 | 9 hrs ago | 0.02 ETH | ||||
Transfer | 3524061 | 9 hrs ago | 0.02 ETH | ||||
Transfer | 3523305 | 12 hrs ago | 0.00001555 ETH | ||||
Transfer | 3523301 | 12 hrs ago | 0.00001555 ETH | ||||
Transfer | 3522719 | 14 hrs ago | 0.01 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x4110fd5d...12BcDA3D9 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
SafeVault
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED // See LICENSE file for full license text. // Copyright (c) Ironblocks 2024 pragma solidity ^0.8; import {VennFirewallConsumer} from "@ironblocks/firewall-consumer/contracts/consumers/VennFirewallConsumer.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; contract SafeVault is VennFirewallConsumer, Ownable { mapping (address user => uint256 ethBalance) public deposits; constructor() Ownable(msg.sender) {} function deposit() external payable firewallProtected { deposits[msg.sender] += msg.value; } function withdraw(uint256 amount) external firewallProtected { deposits[msg.sender] -= amount; Address.sendValue(payable(msg.sender), amount); } }
// SPDX-License-Identifier: UNLICENSED // See LICENSE file for full license text. // Copyright (c) Ironblocks 2024 pragma solidity ^0.8.0; import {VennFirewallConsumerBase} from "./VennFirewallConsumerBase.sol"; /** * @title Firewall Consumer * @author David Benchimol @ Ironblocks * @dev This contract is a parent contract that can be used to add firewall protection to any contract. * * The contract must initializes with the firewall contract disabled, and the deployer * as the firewall admin. * */ contract VennFirewallConsumer is VennFirewallConsumerBase(address(0), msg.sender) { }
// SPDX-License-Identifier: UNLICENSED // See LICENSE file for full license text. // Copyright (c) Ironblocks 2024 pragma solidity ^0.8.0; import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {Context} from "@openzeppelin/contracts/utils/Context.sol"; import {IFirewall} from "../interfaces/IFirewall.sol"; import {IFirewallConsumer} from "../interfaces/IFirewallConsumer.sol"; /** * @title Firewall Consumer Base Contract * @author David Benchimol @ Ironblocks * @dev This contract is a parent contract that can be used to add firewall protection to any contract. * * The contract must define a firewall contract which will manage the policies that are applied to the contract. * It also must define a firewall admin which will be able to add and remove policies. * */ contract VennFirewallConsumerBase is IFirewallConsumer, Context { bytes4 private constant SUPPORTS_APPROVE_VIA_SIGNATURE_INTERFACE_ID = bytes4(0x0c908cff); // sighash of approveCallsViaSignature // This slot is used to store the firewall address bytes32 private constant FIREWALL_STORAGE_SLOT = bytes32(uint256(keccak256("eip1967.firewall")) - 1); // This slot is used to store the firewall admin address bytes32 private constant FIREWALL_ADMIN_STORAGE_SLOT = bytes32(uint256(keccak256("eip1967.firewall.admin")) - 1); // This slot is used to store the new firewall admin address (when changing admin) bytes32 private constant NEW_FIREWALL_ADMIN_STORAGE_SLOT = bytes32(uint256(keccak256("eip1967.new.firewall.admin")) - 1); bytes32 private constant ATTESTATION_CENTER_PROXY_SLOT = bytes32(uint256(keccak256("eip1967.attestation.center.proxy")) - 1); bytes32 private constant USER_PAID_FEE_SLOT = bytes32(uint256(keccak256("eip1967.user.paid.fee")) - 1); bytes32 private constant SAFE_FUNCTION_CALLER_SLOT = bytes32(uint256(keccak256("eip1967.safe.function.caller")) - 1); bytes32 private constant SAFE_FUNCTION_CALL_FLAG_SLOT = bytes32(uint256(keccak256("eip1967.safe.function.call.flag")) - 1); event FirewallAdminUpdated(address newAdmin); event FirewallUpdated(address newFirewall); /** * @dev modifier that will run the preExecution and postExecution hooks of the firewall, applying each of * the subscribed policies. * * NOTE: Applying this modifier on functions that exit execution flow by an inline assmebly "return" call will * prevent the postExecution hook from running - breaking the protection provided by the firewall. * If you have any questions, please refer to the Firewall's documentation and/or contact our support. */ modifier firewallProtected() { address firewall = _getAddressBySlot(FIREWALL_STORAGE_SLOT); if (firewall == address(0)) { _; return; } uint256 value = _msgValue(); IFirewall(firewall).preExecution(_msgSender(), _msgData(), value); _; IFirewall(firewall).postExecution(_msgSender(), _msgData(), value); } /** * @dev modifier similar to onlyOwner, but for the firewall admin. */ modifier onlyFirewallAdmin() { require(msg.sender == _getAddressBySlot(FIREWALL_ADMIN_STORAGE_SLOT), "FirewallConsumer: not firewall admin"); _; } /** * @dev Initializes a contract protected by a firewall, with a firewall address and a firewall admin. */ constructor( address _firewall, address _firewallAdmin ) { _setAddressBySlot(FIREWALL_STORAGE_SLOT, _firewall); _setAddressBySlot(FIREWALL_ADMIN_STORAGE_SLOT, _firewallAdmin); _setAddressBySlot(SAFE_FUNCTION_CALLER_SLOT, address(1)); _setValueBySlot(SAFE_FUNCTION_CALL_FLAG_SLOT, 1); } function safeFunctionCall( uint256 userNativeFee, bytes calldata proxyPayload, bytes calldata data ) external payable { require(msg.value >= userNativeFee, "VennFirewallConsumer: Not enough ETH for fee"); _initSafeFunctionCallFlags(userNativeFee); address attestationCenterProxy = _getAddressBySlot(ATTESTATION_CENTER_PROXY_SLOT); (bool success, ) = attestationCenterProxy.call{value: userNativeFee}(proxyPayload); require(success, "VennFirewallConsumer: Proxy call failed"); // require(msg.sender == _msgSender(), "VennFirewallConsumer: No meta transactions"); Address.functionDelegateCall(address(this), data); _deInitSafeFunctionCallFlags(); } function _initSafeFunctionCallFlags(uint256 userNativeFee) internal { _setAddressBySlot(SAFE_FUNCTION_CALLER_SLOT, msg.sender); _setValueBySlot(SAFE_FUNCTION_CALL_FLAG_SLOT, 2); _setValueBySlot(USER_PAID_FEE_SLOT, userNativeFee); } function _deInitSafeFunctionCallFlags() internal { _setAddressBySlot(SAFE_FUNCTION_CALLER_SLOT, address(1)); _setValueBySlot(SAFE_FUNCTION_CALL_FLAG_SLOT, 1); _setValueBySlot(USER_PAID_FEE_SLOT, 0); } function setAttestationCenterProxy(address attestationCenterProxy) external onlyFirewallAdmin { if (attestationCenterProxy != address(0)) { require(ERC165Checker.supportsERC165InterfaceUnchecked(attestationCenterProxy, SUPPORTS_APPROVE_VIA_SIGNATURE_INTERFACE_ID)); } _setAddressBySlot(ATTESTATION_CENTER_PROXY_SLOT, attestationCenterProxy); } /** * @dev View function for the firewall admin */ function firewallAdmin() external view returns (address) { return _getAddressBySlot(FIREWALL_ADMIN_STORAGE_SLOT); } /** * @dev Admin only function allowing the consumers admin to set the firewall address. * @param _firewall address of the firewall */ function setFirewall(address _firewall) external onlyFirewallAdmin { _setAddressBySlot(FIREWALL_STORAGE_SLOT, _firewall); emit FirewallUpdated(_firewall); } /** * @dev Admin only function, sets new firewall admin. New admin must accept. * @param _firewallAdmin address of the new firewall admin */ function setFirewallAdmin(address _firewallAdmin) external onlyFirewallAdmin { require(_firewallAdmin != address(0), "FirewallConsumer: zero address"); _setAddressBySlot(NEW_FIREWALL_ADMIN_STORAGE_SLOT, _firewallAdmin); } /** * @dev Accept the role as firewall admin. */ function acceptFirewallAdmin() external { require(msg.sender == _getAddressBySlot(NEW_FIREWALL_ADMIN_STORAGE_SLOT), "FirewallConsumer: not new admin"); _setAddressBySlot(FIREWALL_ADMIN_STORAGE_SLOT, msg.sender); emit FirewallAdminUpdated(msg.sender); } /** * @dev Internal helper funtion to get the msg.value * @return value of the msg.value */ function _msgValue() internal view returns (uint256 value) { // We do this because msg.value can only be accessed in payable functions. assembly { value := callvalue() } if (uint256(_getValueBySlot(SAFE_FUNCTION_CALL_FLAG_SLOT)) == 2) { if (msg.sender == _getAddressBySlot(SAFE_FUNCTION_CALLER_SLOT)) { uint256 fee = uint256(_getValueBySlot(USER_PAID_FEE_SLOT)); value = value - fee; } } } /** * @dev Internal helper function to set an address in a storage slot * @param _slot storage slot * @param _address address to be set */ function _setAddressBySlot(bytes32 _slot, address _address) internal { assembly { sstore(_slot, _address) } } /** * @dev Internal helper function to get an address from a storage slot * @param _slot storage slot * @return _address from the storage slot */ function _getAddressBySlot(bytes32 _slot) internal view returns (address _address) { assembly { _address := sload(_slot) } } function _setValueBySlot(bytes32 _slot, uint256 _value) internal { assembly { sstore(_slot, _value) } } /** * @dev Internal helper function to get a value from a storage slot * @param _slot storage slot * @return _value from the storage slot */ function _getValueBySlot(bytes32 _slot) internal view returns (bytes32 _value) { assembly { _value := sload(_slot) } } }
// SPDX-License-Identifier: UNLICENSED // See LICENSE file for full license text. // Copyright (c) Ironblocks 2024 pragma solidity ^0.8; interface IFirewall { function preExecution(address sender, bytes memory data, uint256 value) external; function postExecution(address sender, bytes memory data, uint256 value) external; function preExecutionPrivateInvariants(address sender, bytes memory data, uint256 value) external returns (bytes32[] calldata); function postExecutionPrivateInvariants( address sender, bytes memory data, uint256 value, bytes32[] calldata preValues, bytes32[] calldata postValues ) external; }
// SPDX-License-Identifier: UNLICENSED // See LICENSE file for full license text. // Copyright (c) Ironblocks 2024 pragma solidity ^0.8; interface IFirewallConsumer { function firewallAdmin() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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 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) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. */ function getSupportedInterfaces( address account, bytes4[] memory interfaceIds ) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId)); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * 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); }
{ "evmVersion": "paris", "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"FirewallAdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFirewall","type":"address"}],"name":"FirewallUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptFirewallAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"ethBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"firewallAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userNativeFee","type":"uint256"},{"internalType":"bytes","name":"proxyPayload","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeFunctionCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"attestationCenterProxy","type":"address"}],"name":"setAttestationCenterProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_firewall","type":"address"}],"name":"setFirewall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_firewallAdmin","type":"address"}],"name":"setFirewallAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Deployed Bytecode
0x6080604052600436106100a75760003560e01c80638da5cb5b116100645780638da5cb5b1461017e578063cb09f61f146101a9578063d0e30db0146101c5578063f05c8582146101cf578063f2fde38b146101fa578063fc7e286d14610223576100a7565b80632e1a7d4d146100ac57806354222e6c146100d5578063715018a6146100fe578063734b7198146101155780637c65c38b1461013e5780638c36d02d14610155575b600080fd5b3480156100b857600080fd5b506100d360048036038101906100ce919061157e565b610260565b005b3480156100e157600080fd5b506100fc60048036038101906100f79190611609565b6104a7565b005b34801561010a57600080fd5b506101136105dd565b005b34801561012157600080fd5b5061013c60048036038101906101379190611609565b6105f1565b005b34801561014a57600080fd5b50610153610747565b005b34801561016157600080fd5b5061017c60048036038101906101779190611609565b610864565b005b34801561018a57600080fd5b50610193610982565b6040516101a09190611645565b60405180910390f35b6101c360048036038101906101be91906116c5565b6109ab565b005b6101cd610b46565b005b3480156101db57600080fd5b506101e4610d78565b6040516101f19190611645565b60405180910390f35b34801561020657600080fd5b50610221600480360381019061021c9190611609565b610dba565b005b34801561022f57600080fd5b5061024a60048036038101906102459190611609565b610e40565b6040516102579190611769565b60405180910390f35b600061029d60017f5dd2e3b890564a8f99f7f203f226a27a8aa59aee19a4ece5cf5eaa77ab91f66260001c61029591906117b3565b60001b610e58565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036103395781600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461032291906117b3565b925050819055506103333383610e63565b506104a4565b6000610343610f50565b90508173ffffffffffffffffffffffffffffffffffffffff16636fe1967c61036961105d565b610371611065565b856040518563ffffffff1660e01b81526004016103919493929190611845565b600060405180830381600087803b1580156103ab57600080fd5b505af11580156103bf573d6000803e3d6000fd5b5050505082600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461041291906117b3565b925050819055506104233384610e63565b8173ffffffffffffffffffffffffffffffffffffffff166393163a9161044761105d565b61044f611065565b856040518563ffffffff1660e01b815260040161046f9493929190611845565b600060405180830381600087803b15801561048957600080fd5b505af115801561049d573d6000803e3d6000fd5b5050505050505b50565b6104e260017f29982a6ac507a2a707ced6dee5d76285dd49725db977de83d9702c628c97413660001c6104da91906117b3565b60001b610e58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461054f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054690611908565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461059e5761059481630c908cff60e01b611072565b61059d57600080fd5b5b6105da60017fbb5f5c81badac71dead5c1b29002ce6bbac893e2645c265b13d7499de81ab6e160001c6105d191906117b3565b60001b82611111565b50565b6105e5611118565b6105ef600061119f565b565b61062c60017f29982a6ac507a2a707ced6dee5d76285dd49725db977de83d9702c628c97413660001c61062491906117b3565b60001b610e58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069090611908565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ff90611974565b60405180910390fd5b61074460017f8583d637b7eb6415d11ef26648cf0702cf161a357dfe51b6ff7a332110d4bdd360001c61073b91906117b3565b60001b82611111565b50565b61078260017f8583d637b7eb6415d11ef26648cf0702cf161a357dfe51b6ff7a332110d4bdd360001c61077a91906117b3565b60001b610e58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e6906119e0565b60405180910390fd5b61082b60017f29982a6ac507a2a707ced6dee5d76285dd49725db977de83d9702c628c97413660001c61082291906117b3565b60001b33611111565b7f2763a008a9a724a5da2f35346041f5c552001ab556d786252e1ff4ff798dfc1b3360405161085a9190611645565b60405180910390a1565b61089f60017f29982a6ac507a2a707ced6dee5d76285dd49725db977de83d9702c628c97413660001c61089791906117b3565b60001b610e58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461090c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090390611908565b60405180910390fd5b61094860017f5dd2e3b890564a8f99f7f203f226a27a8aa59aee19a4ece5cf5eaa77ab91f66260001c61093f91906117b3565b60001b82611111565b7f60c1452966d777aab347837b9ceeaa613af32925b5aab43918e878fd03608670816040516109779190611645565b60405180910390a150565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b843410156109ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e590611a72565b60405180910390fd5b6109f785611263565b6000610a3460017fbb5f5c81badac71dead5c1b29002ce6bbac893e2645c265b13d7499de81ab6e160001c610a2c91906117b3565b60001b610e58565b905060008173ffffffffffffffffffffffffffffffffffffffff16878787604051610a60929190611ac2565b60006040518083038185875af1925050503d8060008114610a9d576040519150601f19603f3d011682016040523d82523d6000602084013e610aa2565b606091505b5050905080610ae6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add90611b4d565b60405180910390fd5b610b343085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061131b565b50610b3d61139f565b50505050505050565b6000610b8360017f5dd2e3b890564a8f99f7f203f226a27a8aa59aee19a4ece5cf5eaa77ab91f66260001c610b7b91906117b3565b60001b610e58565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c155734600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c089190611b6d565b9250508190555050610d76565b6000610c1f610f50565b90508173ffffffffffffffffffffffffffffffffffffffff16636fe1967c610c4561105d565b610c4d611065565b856040518563ffffffff1660e01b8152600401610c6d9493929190611845565b600060405180830381600087803b158015610c8757600080fd5b505af1158015610c9b573d6000803e3d6000fd5b5050505034600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cee9190611b6d565b925050819055508173ffffffffffffffffffffffffffffffffffffffff166393163a91610d1961105d565b610d21611065565b856040518563ffffffff1660e01b8152600401610d419493929190611845565b600060405180830381600087803b158015610d5b57600080fd5b505af1158015610d6f573d6000803e3d6000fd5b5050505050505b565b6000610db560017f29982a6ac507a2a707ced6dee5d76285dd49725db977de83d9702c628c97413660001c610dad91906117b3565b60001b610e58565b905090565b610dc2611118565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e345760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610e2b9190611645565b60405180910390fd5b610e3d8161119f565b50565b60016020528060005260406000206000915090505481565b600081549050919050565b80471015610ea857306040517fcd786059000000000000000000000000000000000000000000000000000000008152600401610e9f9190611645565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051610ece90611bc7565b60006040518083038185875af1925050503d8060008114610f0b576040519150601f19603f3d011682016040523d82523d6000602084013e610f10565b606091505b5050905080610f4b576040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60003490506002610f9260017f649dd3ecd011e05f7b661f5786e7205a54d2201cb71ede57000d4047776e204060001c610f8a91906117b3565b60001b611458565b60001c0361105a57610fd560017f471011fb6f6f818490c7275a3f5781bd5ea022cb5a243dd8f2d009d0882c74a360001c610fcd91906117b3565b60001b610e58565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff160361105957600061104460017f249fe6ee22e6e15273c690c436e9cd06968fe8fb9e18a17365c2d2aa2add4e7260001c61103c91906117b3565b60001b611458565b60001c9050808261105591906117b3565b9150505b5b90565b600033905090565b3660008036915091509091565b600080826040516024016110869190611c17565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d915060005190508280156110f9575060208210155b80156111055750600081115b94505050505092915050565b8082555050565b61112061105d565b73ffffffffffffffffffffffffffffffffffffffff1661113e610982565b73ffffffffffffffffffffffffffffffffffffffff161461119d5761116161105d565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016111949190611645565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61129f60017f471011fb6f6f818490c7275a3f5781bd5ea022cb5a243dd8f2d009d0882c74a360001c61129691906117b3565b60001b33611111565b6112dc60017f649dd3ecd011e05f7b661f5786e7205a54d2201cb71ede57000d4047776e204060001c6112d291906117b3565b60001b6002611463565b61131860017f249fe6ee22e6e15273c690c436e9cd06968fe8fb9e18a17365c2d2aa2add4e7260001c61130f91906117b3565b60001b82611463565b50565b60606000808473ffffffffffffffffffffffffffffffffffffffff16846040516113459190611c98565b600060405180830381855af49150503d8060008114611380576040519150601f19603f3d011682016040523d82523d6000602084013e611385565b606091505b509150915061139585838361146a565b9250505092915050565b6113dc60017f471011fb6f6f818490c7275a3f5781bd5ea022cb5a243dd8f2d009d0882c74a360001c6113d291906117b3565b60001b6001611111565b61141960017f649dd3ecd011e05f7b661f5786e7205a54d2201cb71ede57000d4047776e204060001c61140f91906117b3565b60001b6001611463565b61145660017f249fe6ee22e6e15273c690c436e9cd06968fe8fb9e18a17365c2d2aa2add4e7260001c61144c91906117b3565b60001b6000611463565b565b600081549050919050565b8082555050565b60608261147f5761147a826114f9565b6114f1565b600082511480156114a7575060008473ffffffffffffffffffffffffffffffffffffffff163b145b156114e957836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016114e09190611645565b60405180910390fd5b8190506114f2565b5b9392505050565b60008151111561150c5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080fd5b600080fd5b6000819050919050565b61155b81611548565b811461156657600080fd5b50565b60008135905061157881611552565b92915050565b6000602082840312156115945761159361153e565b5b60006115a284828501611569565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115d6826115ab565b9050919050565b6115e6816115cb565b81146115f157600080fd5b50565b600081359050611603816115dd565b92915050565b60006020828403121561161f5761161e61153e565b5b600061162d848285016115f4565b91505092915050565b61163f816115cb565b82525050565b600060208201905061165a6000830184611636565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261168557611684611660565b5b8235905067ffffffffffffffff8111156116a2576116a1611665565b5b6020830191508360018202830111156116be576116bd61166a565b5b9250929050565b6000806000806000606086880312156116e1576116e061153e565b5b60006116ef88828901611569565b955050602086013567ffffffffffffffff8111156117105761170f611543565b5b61171c8882890161166f565b9450945050604086013567ffffffffffffffff81111561173f5761173e611543565b5b61174b8882890161166f565b92509250509295509295909350565b61176381611548565b82525050565b600060208201905061177e600083018461175a565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006117be82611548565b91506117c983611548565b92508282039050818111156117e1576117e0611784565b5b92915050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061182483856117e7565b93506118318385846117f8565b61183a83611807565b840190509392505050565b600060608201905061185a6000830187611636565b818103602083015261186d818587611818565b905061187c604083018461175a565b95945050505050565b600082825260208201905092915050565b7f4669726577616c6c436f6e73756d65723a206e6f74206669726577616c6c206160008201527f646d696e00000000000000000000000000000000000000000000000000000000602082015250565b60006118f2602483611885565b91506118fd82611896565b604082019050919050565b60006020820190508181036000830152611921816118e5565b9050919050565b7f4669726577616c6c436f6e73756d65723a207a65726f20616464726573730000600082015250565b600061195e601e83611885565b915061196982611928565b602082019050919050565b6000602082019050818103600083015261198d81611951565b9050919050565b7f4669726577616c6c436f6e73756d65723a206e6f74206e65772061646d696e00600082015250565b60006119ca601f83611885565b91506119d582611994565b602082019050919050565b600060208201905081810360008301526119f9816119bd565b9050919050565b7f56656e6e4669726577616c6c436f6e73756d65723a204e6f7420656e6f75676860008201527f2045544820666f72206665650000000000000000000000000000000000000000602082015250565b6000611a5c602c83611885565b9150611a6782611a00565b604082019050919050565b60006020820190508181036000830152611a8b81611a4f565b9050919050565b600081905092915050565b6000611aa98385611a92565b9350611ab68385846117f8565b82840190509392505050565b6000611acf828486611a9d565b91508190509392505050565b7f56656e6e4669726577616c6c436f6e73756d65723a2050726f78792063616c6c60008201527f206661696c656400000000000000000000000000000000000000000000000000602082015250565b6000611b37602783611885565b9150611b4282611adb565b604082019050919050565b60006020820190508181036000830152611b6681611b2a565b9050919050565b6000611b7882611548565b9150611b8383611548565b9250828201905080821115611b9b57611b9a611784565b5b92915050565b50565b6000611bb1600083611a92565b9150611bbc82611ba1565b600082019050919050565b6000611bd282611ba4565b9150819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611c1181611bdc565b82525050565b6000602082019050611c2c6000830184611c08565b92915050565b600081519050919050565b60005b83811015611c5b578082015181840152602081019050611c40565b60008484015250505050565b6000611c7282611c32565b611c7c8185611a92565b9350611c8c818560208601611c3d565b80840191505092915050565b6000611ca48284611c67565b91508190509291505056fea26469706673582212207fc22c572d8cb455aeab11359f601742c57db27f95779717fe29635dfe30c65964736f6c63430008180033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.