Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 32,591 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Counterfa... | 20858360 | 5 hrs ago | IN | 0 ETH | 0.00287131 | ||||
Create Counterfa... | 20841824 | 2 days ago | IN | 0 ETH | 0.00334489 | ||||
Create Counterfa... | 20836920 | 3 days ago | IN | 0 ETH | 0.00547914 | ||||
Create Counterfa... | 20834732 | 3 days ago | IN | 0 ETH | 0.00433667 | ||||
Create Counterfa... | 20831507 | 3 days ago | IN | 0 ETH | 0.00342709 | ||||
Create Counterfa... | 20829133 | 4 days ago | IN | 0 ETH | 0.00996165 | ||||
Create Counterfa... | 20822490 | 5 days ago | IN | 0 ETH | 0.0103828 | ||||
Create Counterfa... | 20806767 | 7 days ago | IN | 0 ETH | 0.00278021 | ||||
Create Counterfa... | 20795544 | 8 days ago | IN | 0 ETH | 0.00490696 | ||||
Create Counterfa... | 20790230 | 9 days ago | IN | 0 ETH | 0.00310824 | ||||
Create Counterfa... | 20789100 | 9 days ago | IN | 0 ETH | 0.00144029 | ||||
Create Counterfa... | 20776967 | 11 days ago | IN | 0 ETH | 0.00177046 | ||||
Create Counterfa... | 20775276 | 11 days ago | IN | 0 ETH | 0.00293375 | ||||
Create Counterfa... | 20761151 | 13 days ago | IN | 0 ETH | 0.00030169 | ||||
Create Counterfa... | 20747615 | 15 days ago | IN | 0 ETH | 0.00046271 | ||||
Create Counterfa... | 20745381 | 16 days ago | IN | 0 ETH | 0.00065619 | ||||
Create Counterfa... | 20744981 | 16 days ago | IN | 0 ETH | 0.00072561 | ||||
Create Counterfa... | 20743571 | 16 days ago | IN | 0 ETH | 0.00080703 | ||||
Create Counterfa... | 20742789 | 16 days ago | IN | 0 ETH | 0.00225941 | ||||
Create Counterfa... | 20718306 | 19 days ago | IN | 0 ETH | 0.00050321 | ||||
Create Counterfa... | 20715418 | 20 days ago | IN | 0 ETH | 0.00201911 | ||||
Create Counterfa... | 20711415 | 20 days ago | IN | 0 ETH | 0.00038282 | ||||
Create Counterfa... | 20710871 | 20 days ago | IN | 0 ETH | 0.00039475 | ||||
Create Counterfa... | 20709283 | 21 days ago | IN | 0 ETH | 0.00029275 | ||||
Create Counterfa... | 20705953 | 21 days ago | IN | 0 ETH | 0.00041392 |
Latest 25 internal transactions (View All)
Advanced mode:
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.
Contract Name:
WalletFactory
Compiler Version
v0.8.3+commit.8d00100c
Optimization Enabled:
Yes with 999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; import "../wallet/Proxy.sol"; import "../wallet/BaseWallet.sol"; import "./base/Managed.sol"; import "./storage/IGuardianStorage.sol"; import "../modules/common/Utils.sol"; /** * @title WalletFactory * @notice The WalletFactory contract creates and assigns wallets to accounts. * @author Julien Niset, Olivier VDB - <[email protected]>, <[email protected]> */ contract WalletFactory is Managed { address constant internal ETH_TOKEN = address(0); // The address of the base wallet implementation address immutable public walletImplementation; // The address of the GuardianStorage address immutable public guardianStorage; // The recipient of the refund address public refundAddress; // *************** Events *************************** // event RefundAddressChanged(address addr); event WalletCreated(address indexed wallet, address indexed owner, address indexed guardian, address refundToken, uint256 refundAmount); // *************** Constructor ********************** // /** * @notice Default constructor. */ constructor(address _walletImplementation, address _guardianStorage, address _refundAddress) { require(_walletImplementation != address(0), "WF: empty wallet implementation"); require(_guardianStorage != address(0), "WF: empty guardian storage"); require(_refundAddress != address(0), "WF: empty refund address"); walletImplementation = _walletImplementation; guardianStorage = _guardianStorage; refundAddress = _refundAddress; } // *************** External Functions ********************* // /** * @notice Disables the ability for the owner of the factory to revoke a manager. */ function revokeManager(address /*_manager*/) override external pure { revert("WF: managers can't be revoked"); } /** * @notice Creates a wallet for an owner account at a specific address. * The wallet is initialised with the target modules and a first guardian by default. * The wallet is created using the CREATE2 opcode and must have been approved * by a manager of the factory. * @param _owner The account address. * @param _modules The list of modules for the wallet. * @param _guardian The guardian address. * @param _salt The salt. * @param _refundAmount The amount to refund to the relayer. * @param _refundToken The token to use to refund the relayer. * @param _ownerSignature The owner signature on the refund info. * @param _managerSignature The manager signature on the wallet address. */ function createCounterfactualWallet( address _owner, address[] calldata _modules, address _guardian, bytes20 _salt, uint256 _refundAmount, address _refundToken, bytes calldata _ownerSignature, bytes calldata _managerSignature ) external returns (address _wallet) { validateInputs(_owner, _modules, _guardian); bytes32 newsalt = newSalt(_salt, _owner, _modules, _guardian); address payable wallet = payable(new Proxy{salt: newsalt}(walletImplementation)); validateAuthorisedCreation(wallet, _managerSignature); configureWallet(BaseWallet(wallet), _owner, _modules, _guardian); if (_refundAmount > 0 && _ownerSignature.length == 65) { validateAndRefund(wallet, _owner, _refundAmount, _refundToken, _ownerSignature); } // remove the factory from the authorised modules BaseWallet(wallet).authoriseModule(address(this), false); // emit event emit WalletCreated(wallet, _owner, _guardian, _refundToken, _refundAmount); return wallet; } /** * @notice Gets the address of a counterfactual wallet with a first default guardian. * @param _owner The account address. * @param _modules The list of modules for wallet. * @param _guardian The guardian address. * @param _salt The salt. * @return _wallet The address that the wallet will have when created using CREATE2 and the same input parameters. */ function getAddressForCounterfactualWallet( address _owner, address[] calldata _modules, address _guardian, bytes20 _salt ) external view returns (address _wallet) { validateInputs(_owner, _modules, _guardian); bytes32 newsalt = newSalt(_salt, _owner, _modules, _guardian); bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(uint160(walletImplementation))); bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), newsalt, keccak256(code))); _wallet = address(uint160(uint256(hash))); } /** * @notice Lets the owner of the factory change the refund address. * @param _refundAddress The address to use for refunds. */ function changeRefundAddress(address _refundAddress) external onlyOwner { require(_refundAddress != address(0), "WF: cannot set to empty"); refundAddress = _refundAddress; emit RefundAddressChanged(_refundAddress); } /** * @notice Required to make the factory a module during the * initialisation of the wallet. * @param _wallet The wallet. */ function init(BaseWallet _wallet) external pure { //do nothing } // *************** Internal Functions ********************* // /** * @notice Helper method to configure a wallet for a set of input parameters. * @param _wallet The target wallet * @param _owner The owner address. * @param _modules The list of modules. * @param _guardian The guardian. */ function configureWallet(BaseWallet _wallet, address _owner, address[] calldata _modules, address _guardian) internal { // add the factory to modules so it can add the first guardian and trigger the refund address[] memory extendedModules = new address[](_modules.length + 1); extendedModules[0] = address(this); for (uint i = 0; i < _modules.length; i++) { extendedModules[i + 1] = _modules[i]; } // initialise the wallet with the owner and the extended modules _wallet.init(_owner, extendedModules); // add the first guardian IGuardianStorage(guardianStorage).addGuardian(address(_wallet), _guardian); } /** * @notice Generates a new salt based on a provided salt, an owner, a list of modules and an optional guardian. * The extra parameters are pre-hashed to be compatible with zk-sync CREATE2 API (!! the order of the parameters * assumes https://github.com/matter-labs/zksync/pull/259 has been merged !!). * @param _salt The salt provided. In practice the hash of the L2 public key. * @param _owner The owner address. * @param _modules The list of modules for wallet. * @param _guardian The guardian address. */ function newSalt(bytes20 _salt, address _owner, address[] calldata _modules, address _guardian) internal pure returns (bytes32) { return keccak256(abi.encodePacked(keccak256(abi.encodePacked(_owner, _modules, _guardian)), _salt)); } /** * @notice Throws if the owner, guardian, or module array is invalid. * @param _owner The owner address. * @param _modules The list of modules for the wallet. * @param _guardian The guardian address. */ function validateInputs(address _owner, address[] calldata _modules, address _guardian) internal pure { require(_owner != address(0), "WF: empty owner address"); require(_owner != _guardian, "WF: owner cannot be guardian"); require(_modules.length > 0, "WF: empty modules"); require(_guardian != (address(0)), "WF: empty guardian"); } /** * @notice Throws if the sender is not a manager and the manager's signature for the * creation of the new wallet is invalid. * @param _wallet The wallet address * @param _managerSignature The manager's signature */ function validateAuthorisedCreation(address _wallet, bytes memory _managerSignature) internal view { address manager; if(_managerSignature.length != 65) { manager = msg.sender; } else { bytes32 signedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", bytes32(uint256(uint160(_wallet))))); manager = Utils.recoverSigner(signedHash, _managerSignature, 0); } require(managers[manager], "WF: unauthorised wallet creation"); } /** * @notice Refunds the creation of the wallet when provided with a valid signature from the wallet owner. * @param _wallet The wallet created * @param _owner The owner address * @param _refundAmount The amount to refund * @param _refundToken The token to use for the refund * @param _ownerSignature A signature from the wallet owner approving the refund amount and token. */ function validateAndRefund( address _wallet, address _owner, uint256 _refundAmount, address _refundToken, bytes memory _ownerSignature ) internal { bytes32 signedHash = keccak256(abi.encodePacked( "\x19Ethereum Signed Message:\n32", keccak256(abi.encodePacked(_wallet, _refundAmount, _refundToken)) )); address signer = Utils.recoverSigner(signedHash, _ownerSignature, 0); if (signer == _owner) { if (_refundToken == ETH_TOKEN) { invokeWallet(_wallet, refundAddress, _refundAmount, ""); } else { bytes memory methodData = abi.encodeWithSignature("transfer(address,uint256)", refundAddress, _refundAmount); bytes memory transferSuccessBytes = invokeWallet(_wallet, _refundToken, 0, methodData); if (transferSuccessBytes.length > 0) { require(abi.decode(transferSuccessBytes, (bool)), "WF: Refund transfer failed"); } } } } /** * @notice Invoke the wallet to execute the refund transfer. * @param _wallet The wallet * @param _to The destination of the call * @param _value The value of the call * @param _data The data associated to the call */ function invokeWallet( address _wallet, address _to, uint256 _value, bytes memory _data ) internal returns (bytes memory _res) { bool success; (success, _res) = _wallet.call(abi.encodeWithSignature("invoke(address,uint256,bytes)", _to, _value, _data)); if (success) { (_res) = abi.decode(_res, (bytes)); } else { // solhint-disable-next-line no-inline-assembly assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; import "./Owned.sol"; /** * @title Managed * @notice Basic contract that defines a set of managers. Only the owner can add/remove managers. * @author Julien Niset, Olivier VDB - <[email protected]>, <[email protected]> */ contract Managed is Owned { // The managers mapping (address => bool) public managers; /** * @notice Throws if the sender is not a manager. */ modifier onlyManager { require(managers[msg.sender] == true, "M: Must be manager"); _; } event ManagerAdded(address indexed _manager); event ManagerRevoked(address indexed _manager); /** * @notice Adds a manager. * @param _manager The address of the manager. */ function addManager(address _manager) external onlyOwner { require(_manager != address(0), "M: Address must not be null"); if (managers[_manager] == false) { managers[_manager] = true; emit ManagerAdded(_manager); } } /** * @notice Revokes a manager. * @param _manager The address of the manager. */ function revokeManager(address _manager) external virtual onlyOwner { // solhint-disable-next-line reason-string require(managers[_manager] == true, "M: Target must be an existing manager"); delete managers[_manager]; emit ManagerRevoked(_manager); } }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.4 <0.9.0; /** * @title Owned * @notice Basic contract to define an owner. * @author Julien Niset - <[email protected]> */ contract Owned { // The owner address public owner; event OwnerChanged(address indexed _newOwner); /** * @notice Throws if the sender is not the owner. */ modifier onlyOwner { require(msg.sender == owner, "Must be owner"); _; } constructor() public { owner = msg.sender; } /** * @notice Lets the owner transfer ownership of the contract to a new owner. * @param _newOwner The new owner. */ function changeOwner(address _newOwner) external onlyOwner { require(_newOwner != address(0), "Address must not be null"); owner = _newOwner; emit OwnerChanged(_newOwner); } }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.4 <0.9.0; interface IGuardianStorage { /** * @notice Lets an authorised module add a guardian to a wallet. * @param _wallet The target wallet. * @param _guardian The guardian to add. */ function addGuardian(address _wallet, address _guardian) external; /** * @notice Lets an authorised module revoke a guardian from a wallet. * @param _wallet The target wallet. * @param _guardian The guardian to revoke. */ function revokeGuardian(address _wallet, address _guardian) external; /** * @notice Checks if an account is a guardian for a wallet. * @param _wallet The target wallet. * @param _guardian The account. * @return true if the account is a guardian for a wallet. */ function isGuardian(address _wallet, address _guardian) external view returns (bool); function isLocked(address _wallet) external view returns (bool); function getLock(address _wallet) external view returns (uint256); function getLocker(address _wallet) external view returns (address); function setLock(address _wallet, uint256 _releaseAfter) external; function getGuardians(address _wallet) external view returns (address[] memory); function guardianCount(address _wallet) external view returns (uint256); }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; /** * @title IModule * @notice Interface for a Module. * @author Julien Niset - <[email protected]>, Olivier VDB - <[email protected]> */ interface IModule { /** * @notice Adds a module to a wallet. Cannot execute when wallet is locked (or under recovery) * @param _wallet The target wallet. * @param _module The modules to authorise. */ function addModule(address _wallet, address _module) external; /** * @notice Inits a Module for a wallet by e.g. setting some wallet specific parameters in storage. * @param _wallet The wallet. */ function init(address _wallet) external; /** * @notice Returns whether the module implements a callback for a given static call method. * @param _methodId The method id. */ function supportsStaticCall(bytes4 _methodId) external view returns (bool _isSupported); }
// Copyright (C) 2020 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; /** * @title Utils * @notice Common utility methods used by modules. */ library Utils { // ERC20, ERC721 & ERC1155 transfers & approvals bytes4 private constant ERC20_TRANSFER = bytes4(keccak256("transfer(address,uint256)")); bytes4 private constant ERC20_APPROVE = bytes4(keccak256("approve(address,uint256)")); bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL = bytes4(keccak256("setApprovalForAll(address,bool)")); bytes4 private constant ERC721_TRANSFER_FROM = bytes4(keccak256("transferFrom(address,address,uint256)")); bytes4 private constant ERC721_SAFE_TRANSFER_FROM = bytes4(keccak256("safeTransferFrom(address,address,uint256)")); bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES = bytes4(keccak256("safeTransferFrom(address,address,uint256,bytes)")); bytes4 private constant ERC1155_SAFE_TRANSFER_FROM = bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")); bytes4 private constant OWNER_SIG = 0x8da5cb5b; /** * @notice Helper method to recover the signer at a given position from a list of concatenated signatures. * @param _signedHash The signed hash * @param _signatures The concatenated signatures. * @param _index The index of the signature to recover. */ function recoverSigner(bytes32 _signedHash, bytes memory _signatures, uint _index) internal pure returns (address) { uint8 v; bytes32 r; bytes32 s; // we jump 32 (0x20) as the first slot of bytes contains the length // we jump 65 (0x41) per signature // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(_signatures, add(0x20,mul(0x41,_index)))) s := mload(add(_signatures, add(0x40,mul(0x41,_index)))) v := and(mload(add(_signatures, add(0x41,mul(0x41,_index)))), 0xff) } require(v == 27 || v == 28, "Utils: bad v value in signature"); address recoveredAddress = ecrecover(_signedHash, v, r, s); require(recoveredAddress != address(0), "Utils: ecrecover returned 0"); return recoveredAddress; } /** * @notice Helper method to recover the spender from a contract call. * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token * in which case the spender is recovered from the data. * @param _to The target contract. * @param _data The data payload. */ function recoverSpender(address _to, bytes memory _data) internal pure returns (address spender) { if(_data.length >= 68) { bytes4 methodId; // solhint-disable-next-line no-inline-assembly assembly { methodId := mload(add(_data, 0x20)) } if( methodId == ERC20_TRANSFER || methodId == ERC20_APPROVE || methodId == ERC721_SET_APPROVAL_FOR_ALL) { // solhint-disable-next-line no-inline-assembly assembly { spender := mload(add(_data, 0x24)) } return spender; } if( methodId == ERC721_TRANSFER_FROM || methodId == ERC721_SAFE_TRANSFER_FROM || methodId == ERC721_SAFE_TRANSFER_FROM_BYTES || methodId == ERC1155_SAFE_TRANSFER_FROM) { // solhint-disable-next-line no-inline-assembly assembly { spender := mload(add(_data, 0x44)) } return spender; } } spender = _to; } /** * @notice Helper method to parse data and extract the method signature. */ function functionPrefix(bytes memory _data) internal pure returns (bytes4 prefix) { require(_data.length >= 4, "Utils: Invalid functionPrefix"); // solhint-disable-next-line no-inline-assembly assembly { prefix := mload(add(_data, 0x20)) } } /** * @notice Checks if an address is a contract. * @param _addr The address. */ function isContract(address _addr) internal view returns (bool) { uint32 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(_addr) } return (size > 0); } /** * @notice Checks if an address is a guardian or an account authorised to sign on behalf of a smart-contract guardian * given a list of guardians. * @param _guardians the list of guardians * @param _guardian the address to test * @return true and the list of guardians minus the found guardian upon success, false and the original list of guardians if not found. */ function isGuardianOrGuardianSigner(address[] memory _guardians, address _guardian) internal view returns (bool, address[] memory) { if (_guardians.length == 0 || _guardian == address(0)) { return (false, _guardians); } bool isFound = false; address[] memory updatedGuardians = new address[](_guardians.length - 1); uint256 index = 0; for (uint256 i = 0; i < _guardians.length; i++) { if (!isFound) { // check if _guardian is an account guardian if (_guardian == _guardians[i]) { isFound = true; continue; } // check if _guardian is the owner of a smart contract guardian if (isContract(_guardians[i]) && isGuardianOwner(_guardians[i], _guardian)) { isFound = true; continue; } } if (index < updatedGuardians.length) { updatedGuardians[index] = _guardians[i]; index++; } } return isFound ? (true, updatedGuardians) : (false, _guardians); } /** * @notice Checks if an address is the owner of a guardian contract. * The method does not revert if the call to the owner() method consumes more then 25000 gas. * @param _guardian The guardian contract * @param _owner The owner to verify. */ function isGuardianOwner(address _guardian, address _owner) internal view returns (bool) { address owner = address(0); // solhint-disable-next-line no-inline-assembly assembly { let ptr := mload(0x40) mstore(ptr,OWNER_SIG) let result := staticcall(25000, _guardian, ptr, 0x20, ptr, 0x20) if eq(result, 1) { owner := mload(ptr) } } return owner == _owner; } /** * @notice Returns ceil(a / b). */ function ceil(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a / b; if (a % b == 0) { return c; } else { return c + 1; } } }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; import "../modules/common/IModule.sol"; import "./IWallet.sol"; /** * @title BaseWallet * @notice Simple modular wallet that authorises modules to call its invoke() method. * @author Julien Niset - <[email protected]> */ contract BaseWallet is IWallet { // The owner address public override owner; // The authorised modules mapping (address => bool) public override authorised; // module executing static calls address public staticCallExecutor; // The number of modules uint public override modules; event AuthorisedModule(address indexed module, bool value); event Invoked(address indexed module, address indexed target, uint indexed value, bytes data); event Received(uint indexed value, address indexed sender, bytes data); event OwnerChanged(address owner); /** * @notice Throws if the sender is not an authorised module. */ modifier moduleOnly { require(authorised[msg.sender], "BW: sender not authorized"); _; } /** * @notice Inits the wallet by setting the owner and authorising a list of modules. * @param _owner The owner. * @param _modules The modules to authorise. */ function init(address _owner, address[] calldata _modules) external { require(owner == address(0) && modules == 0, "BW: wallet already initialised"); require(_modules.length > 0, "BW: empty modules"); owner = _owner; modules = _modules.length; for (uint256 i = 0; i < _modules.length; i++) { require(authorised[_modules[i]] == false, "BW: module is already added"); authorised[_modules[i]] = true; IModule(_modules[i]).init(address(this)); emit AuthorisedModule(_modules[i], true); } if (address(this).balance > 0) { emit Received(address(this).balance, address(0), ""); } } /** * @inheritdoc IWallet */ function authoriseModule(address _module, bool _value) external override moduleOnly { if (authorised[_module] != _value) { emit AuthorisedModule(_module, _value); if (_value == true) { modules += 1; authorised[_module] = true; IModule(_module).init(address(this)); } else { modules -= 1; require(modules > 0, "BW: cannot remove last module"); delete authorised[_module]; } } } /** * @inheritdoc IWallet */ function enabled(bytes4 _sig) public view override returns (address) { address executor = staticCallExecutor; if(executor != address(0) && IModule(executor).supportsStaticCall(_sig)) { return executor; } return address(0); } /** * @inheritdoc IWallet */ function enableStaticCall(address _module, bytes4 /* _method */) external override moduleOnly { if(staticCallExecutor != _module) { require(authorised[_module], "BW: unauthorized executor"); staticCallExecutor = _module; } } /** * @inheritdoc IWallet */ function setOwner(address _newOwner) external override moduleOnly { require(_newOwner != address(0), "BW: address cannot be null"); owner = _newOwner; emit OwnerChanged(_newOwner); } /** * @notice Performs a generic transaction. * @param _target The address for the transaction. * @param _value The value of the transaction. * @param _data The data of the transaction. */ function invoke(address _target, uint _value, bytes calldata _data) external moduleOnly returns (bytes memory _result) { bool success; (success, _result) = _target.call{value: _value}(_data); if (!success) { // solhint-disable-next-line no-inline-assembly assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } emit Invoked(msg.sender, _target, _value, _data); } /** * @notice This method delegates the static call to a target contract if the data corresponds * to an enabled module, or logs the call otherwise. */ fallback() external payable { address module = enabled(msg.sig); if (module == address(0)) { emit Received(msg.value, msg.sender, msg.data); } else { require(authorised[module], "BW: unauthorised module"); // solhint-disable-next-line no-inline-assembly assembly { calldatacopy(0, 0, calldatasize()) let result := staticcall(gas(), module, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 {revert(0, returndatasize())} default {return (0, returndatasize())} } } } receive() external payable { } }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.4 <0.9.0; /** * @title IWallet * @notice Interface for the BaseWallet */ interface IWallet { /** * @notice Returns the wallet owner. * @return The wallet owner address. */ function owner() external view returns (address); /** * @notice Returns the number of authorised modules. * @return The number of authorised modules. */ function modules() external view returns (uint); /** * @notice Sets a new owner for the wallet. * @param _newOwner The new owner. */ function setOwner(address _newOwner) external; /** * @notice Checks if a module is authorised on the wallet. * @param _module The module address to check. * @return `true` if the module is authorised, otherwise `false`. */ function authorised(address _module) external view returns (bool); /** * @notice Returns the module responsible for a static call redirection. * @param _sig The signature of the static call. * @return the module doing the redirection */ function enabled(bytes4 _sig) external view returns (address); /** * @notice Enables/Disables a module. * @param _module The target module. * @param _value Set to `true` to authorise the module. */ function authoriseModule(address _module, bool _value) external; /** * @notice Enables a static method by specifying the target module to which the call must be delegated. * @param _module The target module. * @param _method The static method signature. */ function enableStaticCall(address _module, bytes4 _method) external; }
// Copyright (C) 2018 Argent Labs Ltd. <https://argent.xyz> // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.3; /** * @title Proxy * @notice Basic proxy that delegates all calls to a fixed implementing contract. * The implementing contract cannot be upgraded. * @author Julien Niset - <[email protected]> */ contract Proxy { address immutable public implementation; event Received(uint indexed value, address indexed sender, bytes data); constructor(address _implementation) { implementation = _implementation; } fallback() external payable { address target = implementation; // solhint-disable-next-line no-inline-assembly assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), target, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 {revert(0, returndatasize())} default {return (0, returndatasize())} } } receive() external payable { emit Received(msg.value, msg.sender, ""); } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 999 }, "evmVersion": "istanbul", "libraries": { "": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_walletImplementation","type":"address"},{"internalType":"address","name":"_guardianStorage","type":"address"},{"internalType":"address","name":"_refundAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_manager","type":"address"}],"name":"ManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_manager","type":"address"}],"name":"ManagerRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"RefundAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"address","name":"refundToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"WalletCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"addManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"changeRefundAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_modules","type":"address[]"},{"internalType":"address","name":"_guardian","type":"address"},{"internalType":"bytes20","name":"_salt","type":"bytes20"},{"internalType":"uint256","name":"_refundAmount","type":"uint256"},{"internalType":"address","name":"_refundToken","type":"address"},{"internalType":"bytes","name":"_ownerSignature","type":"bytes"},{"internalType":"bytes","name":"_managerSignature","type":"bytes"}],"name":"createCounterfactualWallet","outputs":[{"internalType":"address","name":"_wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_modules","type":"address[]"},{"internalType":"address","name":"_guardian","type":"address"},{"internalType":"bytes20","name":"_salt","type":"bytes20"}],"name":"getAddressForCounterfactualWallet","outputs":[{"internalType":"address","name":"_wallet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardianStorage","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract BaseWallet","name":"_wallet","type":"address"}],"name":"init","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"managers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"revokeManager","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"walletImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162001b0f38038062001b0f8339810160408190526200003491620001b0565b600080546001600160a01b031916331790556001600160a01b038316620000a25760405162461bcd60e51b815260206004820152601f60248201527f57463a20656d7074792077616c6c657420696d706c656d656e746174696f6e0060448201526064015b60405180910390fd5b6001600160a01b038216620000fa5760405162461bcd60e51b815260206004820152601a60248201527f57463a20656d70747920677561726469616e2073746f72616765000000000000604482015260640162000099565b6001600160a01b038116620001525760405162461bcd60e51b815260206004820152601860248201527f57463a20656d70747920726566756e6420616464726573730000000000000000604482015260640162000099565b606092831b6001600160601b03199081166080529190921b1660a052600280546001600160a01b0319166001600160a01b03909216919091179055620001f9565b80516001600160a01b0381168114620001ab57600080fd5b919050565b600080600060608486031215620001c5578283fd5b620001d08462000193565b9250620001e06020850162000193565b9150620001f06040850162000193565b90509250925092565b60805160601c60a05160601c6118d56200023a600039600081816101ba0152610d3801526000818161015a0152818161059801526107e501526118d56000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063d89784fc1161005b578063d89784fc146101b5578063fbe2ec7d146101dc578063fdff9b4d146101ef576100d4565b80638da5cb5b1461017c578063a6f9dae11461018f578063a80dd9df146101a2576100d4565b80632d06177a116100b25780632d06177a1461012f578063377e32e6146101425780638117abc114610155576100d4565b80630cb61f6c146100d957806319ab453c146101095780632c8285251461011c575b600080fd5b6002546100ec906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61011a6101173660046112a1565b50565b005b61011a61012a3660046112a1565b610222565b61011a61013d3660046112a1565b610328565b61011a6101503660046112a1565b610437565b6100ec7f000000000000000000000000000000000000000000000000000000000000000081565b6000546100ec906001600160a01b031681565b61011a61019d3660046112a1565b61047f565b6100ec6101b036600461133b565b610574565b6100ec7f000000000000000000000000000000000000000000000000000000000000000081565b6100ec6101ea3660046112c4565b610790565b6102126101fd3660046112a1565b60016020526000908152604090205460ff1681565b6040519015158152602001610100565b6000546001600160a01b031633146102715760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b60448201526064015b60405180910390fd5b6001600160a01b0381166102c75760405162461bcd60e51b815260206004820152601760248201527f57463a2063616e6e6f742073657420746f20656d7074790000000000000000006044820152606401610268565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fa7cb165192538768851363c5aa55b1ade75d692a51063730feccdd57d002a6ed9060200160405180910390a150565b6000546001600160a01b031633146103725760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b6044820152606401610268565b6001600160a01b0381166103c85760405162461bcd60e51b815260206004820152601b60248201527f4d3a2041646472657373206d757374206e6f74206265206e756c6c00000000006044820152606401610268565b6001600160a01b03811660009081526001602052604090205460ff16610117576001600160a01b0381166000818152600160208190526040808320805460ff1916909217909155517f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a9190a250565b60405162461bcd60e51b815260206004820152601d60248201527f57463a206d616e61676572732063616e2774206265207265766f6b65640000006044820152606401610268565b6000546001600160a01b031633146104c95760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b6044820152606401610268565b6001600160a01b03811661051f5760405162461bcd60e51b815260206004820152601860248201527f41646472657373206d757374206e6f74206265206e756c6c00000000000000006044820152606401610268565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3691a250565b60006105828c8c8c8c610898565b6000610591898e8e8e8e6109f9565b90506000817f00000000000000000000000000000000000000000000000000000000000000006040516105c3906111dd565b6001600160a01b0390911681526020018190604051809103906000f59050801580156105f3573d6000803e3d6000fd5b5090506106368186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a6692505050565b610643818f8f8f8f610b4b565b6000891180156106535750604186145b1561069b5761069b818f8b8b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d9e92505050565b6040517f1f17732d000000000000000000000000000000000000000000000000000000008152306004820152600060248201526001600160a01b03821690631f17732d90604401600060405180830381600087803b1580156106fc57600080fd5b505af1158015610710573d6000803e3d6000fd5b505050508a6001600160a01b03168e6001600160a01b0316826001600160a01b03167facd43e061b8ee386537b57919358cfa44933c4e47ccd4b2e1916e54133cec7488b8d6040516107779291906001600160a01b03929092168252602082015260400190565b60405180910390a49d9c50505050505050505050505050565b600061079e86868686610898565b60006107ad83888888886109f9565b90506000604051806020016107c1906111dd565b601f1982820381018352601f90910116604081905261080e91906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690602001611565565b60408051808303601f1901815282825280516020918201207fff00000000000000000000000000000000000000000000000000000000000000828501523060601b6bffffffffffffffffffffffff19166021850152603584019590955260558084019590955281518084039095018552607590920190528251920191909120979650505050505050565b6001600160a01b0384166108ee5760405162461bcd60e51b815260206004820152601760248201527f57463a20656d707479206f776e657220616464726573730000000000000000006044820152606401610268565b806001600160a01b0316846001600160a01b031614156109505760405162461bcd60e51b815260206004820152601c60248201527f57463a206f776e65722063616e6e6f7420626520677561726469616e000000006044820152606401610268565b8161099d5760405162461bcd60e51b815260206004820152601160248201527f57463a20656d707479206d6f64756c65730000000000000000000000000000006044820152606401610268565b6001600160a01b0381166109f35760405162461bcd60e51b815260206004820152601260248201527f57463a20656d70747920677561726469616e00000000000000000000000000006044820152606401610268565b50505050565b600084848484604051602001610a1294939291906114e2565b60408051601f198184030181528282528051602091820120908301526bffffffffffffffffffffffff1988169082015260540160405160208183030381529060405280519060200120905095945050505050565b60008151604114610a78575033610ade565b6040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000060208201526001600160a01b038416603c820152600090605c01604051602081830303815290604052805190602001209050610ada81846000610f9c565b9150505b6001600160a01b03811660009081526001602052604090205460ff16610b465760405162461bcd60e51b815260206004820181905260248201527f57463a20756e617574686f72697365642077616c6c6574206372656174696f6e6044820152606401610268565b505050565b6000610b5883600161162b565b67ffffffffffffffff811115610b7e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ba7578160200160208202803683370190505b5090503081600081518110610bcc57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060005b83811015610c8057848482818110610c1757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610c2c91906112a1565b82610c3883600161162b565b81518110610c5657634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610c788161166f565b915050610bef565b506040517f3c5a3cea0000000000000000000000000000000000000000000000000000000081526001600160a01b03871690633c5a3cea90610cc89088908590600401611587565b600060405180830381600087803b158015610ce257600080fd5b505af1158015610cf6573d6000803e3d6000fd5b50506040517fc68452100000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015285811660248301527f000000000000000000000000000000000000000000000000000000000000000016925063c68452109150604401600060405180830381600087803b158015610d7e57600080fd5b505af1158015610d92573d6000803e3d6000fd5b50505050505050505050565b6040516bffffffffffffffffffffffff19606087811b821660208401526034830186905284901b16605482015260009060680160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090506000610e4082846000610f9c565b9050856001600160a01b0316816001600160a01b03161415610f93576001600160a01b038416610e9b57600254604080516020810190915260008152610e959189916001600160a01b039091169088906110dc565b50610f93565b6002546040516001600160a01b0390911660248201526044810186905260009060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905290506000610f26898783856110dc565b805190915015610f905780806020019051810190610f449190611424565b610f905760405162461bcd60e51b815260206004820152601a60248201527f57463a20526566756e64207472616e73666572206661696c65640000000000006044820152606401610268565b50505b50505050505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b831480610fce57508260ff16601c145b61101a5760405162461bcd60e51b815260206004820152601f60248201527f5574696c733a2062616420762076616c756520696e207369676e6174757265006044820152606401610268565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561106e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110d15760405162461bcd60e51b815260206004820152601b60248201527f5574696c733a2065637265636f7665722072657475726e6564203000000000006044820152606401610268565b979650505050505050565b60606000856001600160a01b03168585856040516024016110ff939291906115e1565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f6f033200000000000000000000000000000000000000000000000000000000179052516111629190611549565b6000604051808303816000865af19150503d806000811461119f576040519150601f19603f3d011682016040523d82523d6000602084013e6111a4565b606091505b509250905080156111ca57818060200190518101906111c39190611444565b91506111d4565b3d6000803e3d6000fd5b50949350505050565b6101d4806116cc83390190565b80356111f5816116b6565b919050565b60008083601f84011261120b578081fd5b50813567ffffffffffffffff811115611222578182fd5b6020830191508360208260051b850101111561123d57600080fd5b9250929050565b80356bffffffffffffffffffffffff19811681146111f557600080fd5b60008083601f840112611272578182fd5b50813567ffffffffffffffff811115611289578182fd5b60208301915083602082850101111561123d57600080fd5b6000602082840312156112b2578081fd5b81356112bd816116b6565b9392505050565b6000806000806000608086880312156112db578081fd5b85356112e6816116b6565b9450602086013567ffffffffffffffff811115611301578182fd5b61130d888289016111fa565b9095509350506040860135611321816116b6565b915061132f60608701611244565b90509295509295909350565b60008060008060008060008060008060006101008c8e03121561135c578586fd5b6113658c6111ea565b9a5067ffffffffffffffff8060208e01351115611380578687fd5b6113908e60208f01358f016111fa565b909b5099506113a160408e016111ea565b98506113af60608e01611244565b975060808d013596506113c460a08e016111ea565b95508060c08e013511156113d6578485fd5b6113e68e60c08f01358f01611261565b909550935060e08d01358110156113fb578283fd5b5061140c8d60e08e01358e01611261565b81935080925050509295989b509295989b9093969950565b600060208284031215611435578081fd5b815180151581146112bd578182fd5b600060208284031215611455578081fd5b815167ffffffffffffffff8082111561146c578283fd5b818401915084601f83011261147f578283fd5b815181811115611491576114916116a0565b604051601f8201601f19908116603f011681019083821181831017156114b9576114b96116a0565b816040528281528760208487010111156114d1578586fd5b6110d1836020830160208801611643565b60006bffffffffffffffffffffffff19808760601b1683526014830186835b87811015611532578135611514816116b6565b6001600160a01b031683526020928301929190910190600101611501565b505060609490941b16835250506014019392505050565b6000825161155b818460208701611643565b9190910192915050565b60008351611577818460208801611643565b9190910191825250602001919050565b6000604082016001600160a01b03808616845260206040818601528286518085526060870191508288019450855b818110156115d35785518516835294830194918301916001016115b5565b509098975050505050505050565b60006001600160a01b0385168252836020830152606060408301528251806060840152611615816080850160208701611643565b601f01601f191691909101608001949350505050565b6000821982111561163e5761163e61168a565b500190565b60005b8381101561165e578181015183820152602001611646565b838111156109f35750506000910152565b60006000198214156116835761168361168a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461011757600080fdfe60a060405234801561001057600080fd5b506040516101d43803806101d483398101604081905261002f91610044565b60601b6001600160601b031916608052610072565b600060208284031215610055578081fd5b81516001600160a01b038116811461006b578182fd5b9392505050565b60805160601c61013f610095600039600081816069015260be015261013f6000f3fe6080604052600436106100225760003560e01c80635c60da1b146100ac57610067565b3661006757604080516020808252600090820152339134917f606834f57405380c4fb88d1f4850326ad3885f014bab3b568dfbf7a041eef738910160405180910390a3005b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100a7573d6000f35b3d6000fd5b3480156100b857600080fd5b506100e07f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220b88a14f52e9d465328c9b3ab476e4b7fa40ed3615fd5409a6afc9885366e03a964736f6c63430008030033a2646970667358221220dec5ae87a38d164692a0d9f7a489556203efa01d593e3bbffea1447231dc89d664736f6c63430008030033000000000000000000000000ab00ea153c43575184ff11dd5e713c96be00557300000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f000000000000000000000000482579f93dc13e6b434e38b5a0447ca543d88a46
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063d89784fc1161005b578063d89784fc146101b5578063fbe2ec7d146101dc578063fdff9b4d146101ef576100d4565b80638da5cb5b1461017c578063a6f9dae11461018f578063a80dd9df146101a2576100d4565b80632d06177a116100b25780632d06177a1461012f578063377e32e6146101425780638117abc114610155576100d4565b80630cb61f6c146100d957806319ab453c146101095780632c8285251461011c575b600080fd5b6002546100ec906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61011a6101173660046112a1565b50565b005b61011a61012a3660046112a1565b610222565b61011a61013d3660046112a1565b610328565b61011a6101503660046112a1565b610437565b6100ec7f000000000000000000000000ab00ea153c43575184ff11dd5e713c96be00557381565b6000546100ec906001600160a01b031681565b61011a61019d3660046112a1565b61047f565b6100ec6101b036600461133b565b610574565b6100ec7f00000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f81565b6100ec6101ea3660046112c4565b610790565b6102126101fd3660046112a1565b60016020526000908152604090205460ff1681565b6040519015158152602001610100565b6000546001600160a01b031633146102715760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b60448201526064015b60405180910390fd5b6001600160a01b0381166102c75760405162461bcd60e51b815260206004820152601760248201527f57463a2063616e6e6f742073657420746f20656d7074790000000000000000006044820152606401610268565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fa7cb165192538768851363c5aa55b1ade75d692a51063730feccdd57d002a6ed9060200160405180910390a150565b6000546001600160a01b031633146103725760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b6044820152606401610268565b6001600160a01b0381166103c85760405162461bcd60e51b815260206004820152601b60248201527f4d3a2041646472657373206d757374206e6f74206265206e756c6c00000000006044820152606401610268565b6001600160a01b03811660009081526001602052604090205460ff16610117576001600160a01b0381166000818152600160208190526040808320805460ff1916909217909155517f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a9190a250565b60405162461bcd60e51b815260206004820152601d60248201527f57463a206d616e61676572732063616e2774206265207265766f6b65640000006044820152606401610268565b6000546001600160a01b031633146104c95760405162461bcd60e51b815260206004820152600d60248201526c26bab9ba1031329037bbb732b960991b6044820152606401610268565b6001600160a01b03811661051f5760405162461bcd60e51b815260206004820152601860248201527f41646472657373206d757374206e6f74206265206e756c6c00000000000000006044820152606401610268565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3691a250565b60006105828c8c8c8c610898565b6000610591898e8e8e8e6109f9565b90506000817f000000000000000000000000ab00ea153c43575184ff11dd5e713c96be0055736040516105c3906111dd565b6001600160a01b0390911681526020018190604051809103906000f59050801580156105f3573d6000803e3d6000fd5b5090506106368186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a6692505050565b610643818f8f8f8f610b4b565b6000891180156106535750604186145b1561069b5761069b818f8b8b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d9e92505050565b6040517f1f17732d000000000000000000000000000000000000000000000000000000008152306004820152600060248201526001600160a01b03821690631f17732d90604401600060405180830381600087803b1580156106fc57600080fd5b505af1158015610710573d6000803e3d6000fd5b505050508a6001600160a01b03168e6001600160a01b0316826001600160a01b03167facd43e061b8ee386537b57919358cfa44933c4e47ccd4b2e1916e54133cec7488b8d6040516107779291906001600160a01b03929092168252602082015260400190565b60405180910390a49d9c50505050505050505050505050565b600061079e86868686610898565b60006107ad83888888886109f9565b90506000604051806020016107c1906111dd565b601f1982820381018352601f90910116604081905261080e91906001600160a01b037f000000000000000000000000ab00ea153c43575184ff11dd5e713c96be0055731690602001611565565b60408051808303601f1901815282825280516020918201207fff00000000000000000000000000000000000000000000000000000000000000828501523060601b6bffffffffffffffffffffffff19166021850152603584019590955260558084019590955281518084039095018552607590920190528251920191909120979650505050505050565b6001600160a01b0384166108ee5760405162461bcd60e51b815260206004820152601760248201527f57463a20656d707479206f776e657220616464726573730000000000000000006044820152606401610268565b806001600160a01b0316846001600160a01b031614156109505760405162461bcd60e51b815260206004820152601c60248201527f57463a206f776e65722063616e6e6f7420626520677561726469616e000000006044820152606401610268565b8161099d5760405162461bcd60e51b815260206004820152601160248201527f57463a20656d707479206d6f64756c65730000000000000000000000000000006044820152606401610268565b6001600160a01b0381166109f35760405162461bcd60e51b815260206004820152601260248201527f57463a20656d70747920677561726469616e00000000000000000000000000006044820152606401610268565b50505050565b600084848484604051602001610a1294939291906114e2565b60408051601f198184030181528282528051602091820120908301526bffffffffffffffffffffffff1988169082015260540160405160208183030381529060405280519060200120905095945050505050565b60008151604114610a78575033610ade565b6040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000060208201526001600160a01b038416603c820152600090605c01604051602081830303815290604052805190602001209050610ada81846000610f9c565b9150505b6001600160a01b03811660009081526001602052604090205460ff16610b465760405162461bcd60e51b815260206004820181905260248201527f57463a20756e617574686f72697365642077616c6c6574206372656174696f6e6044820152606401610268565b505050565b6000610b5883600161162b565b67ffffffffffffffff811115610b7e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ba7578160200160208202803683370190505b5090503081600081518110610bcc57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060005b83811015610c8057848482818110610c1757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610c2c91906112a1565b82610c3883600161162b565b81518110610c5657634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610c788161166f565b915050610bef565b506040517f3c5a3cea0000000000000000000000000000000000000000000000000000000081526001600160a01b03871690633c5a3cea90610cc89088908590600401611587565b600060405180830381600087803b158015610ce257600080fd5b505af1158015610cf6573d6000803e3d6000fd5b50506040517fc68452100000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015285811660248301527f00000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f16925063c68452109150604401600060405180830381600087803b158015610d7e57600080fd5b505af1158015610d92573d6000803e3d6000fd5b50505050505050505050565b6040516bffffffffffffffffffffffff19606087811b821660208401526034830186905284901b16605482015260009060680160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090506000610e4082846000610f9c565b9050856001600160a01b0316816001600160a01b03161415610f93576001600160a01b038416610e9b57600254604080516020810190915260008152610e959189916001600160a01b039091169088906110dc565b50610f93565b6002546040516001600160a01b0390911660248201526044810186905260009060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905290506000610f26898783856110dc565b805190915015610f905780806020019051810190610f449190611424565b610f905760405162461bcd60e51b815260206004820152601a60248201527f57463a20526566756e64207472616e73666572206661696c65640000000000006044820152606401610268565b50505b50505050505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b831480610fce57508260ff16601c145b61101a5760405162461bcd60e51b815260206004820152601f60248201527f5574696c733a2062616420762076616c756520696e207369676e6174757265006044820152606401610268565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561106e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110d15760405162461bcd60e51b815260206004820152601b60248201527f5574696c733a2065637265636f7665722072657475726e6564203000000000006044820152606401610268565b979650505050505050565b60606000856001600160a01b03168585856040516024016110ff939291906115e1565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f6f033200000000000000000000000000000000000000000000000000000000179052516111629190611549565b6000604051808303816000865af19150503d806000811461119f576040519150601f19603f3d011682016040523d82523d6000602084013e6111a4565b606091505b509250905080156111ca57818060200190518101906111c39190611444565b91506111d4565b3d6000803e3d6000fd5b50949350505050565b6101d4806116cc83390190565b80356111f5816116b6565b919050565b60008083601f84011261120b578081fd5b50813567ffffffffffffffff811115611222578182fd5b6020830191508360208260051b850101111561123d57600080fd5b9250929050565b80356bffffffffffffffffffffffff19811681146111f557600080fd5b60008083601f840112611272578182fd5b50813567ffffffffffffffff811115611289578182fd5b60208301915083602082850101111561123d57600080fd5b6000602082840312156112b2578081fd5b81356112bd816116b6565b9392505050565b6000806000806000608086880312156112db578081fd5b85356112e6816116b6565b9450602086013567ffffffffffffffff811115611301578182fd5b61130d888289016111fa565b9095509350506040860135611321816116b6565b915061132f60608701611244565b90509295509295909350565b60008060008060008060008060008060006101008c8e03121561135c578586fd5b6113658c6111ea565b9a5067ffffffffffffffff8060208e01351115611380578687fd5b6113908e60208f01358f016111fa565b909b5099506113a160408e016111ea565b98506113af60608e01611244565b975060808d013596506113c460a08e016111ea565b95508060c08e013511156113d6578485fd5b6113e68e60c08f01358f01611261565b909550935060e08d01358110156113fb578283fd5b5061140c8d60e08e01358e01611261565b81935080925050509295989b509295989b9093969950565b600060208284031215611435578081fd5b815180151581146112bd578182fd5b600060208284031215611455578081fd5b815167ffffffffffffffff8082111561146c578283fd5b818401915084601f83011261147f578283fd5b815181811115611491576114916116a0565b604051601f8201601f19908116603f011681019083821181831017156114b9576114b96116a0565b816040528281528760208487010111156114d1578586fd5b6110d1836020830160208801611643565b60006bffffffffffffffffffffffff19808760601b1683526014830186835b87811015611532578135611514816116b6565b6001600160a01b031683526020928301929190910190600101611501565b505060609490941b16835250506014019392505050565b6000825161155b818460208701611643565b9190910192915050565b60008351611577818460208801611643565b9190910191825250602001919050565b6000604082016001600160a01b03808616845260206040818601528286518085526060870191508288019450855b818110156115d35785518516835294830194918301916001016115b5565b509098975050505050505050565b60006001600160a01b0385168252836020830152606060408301528251806060840152611615816080850160208701611643565b601f01601f191691909101608001949350505050565b6000821982111561163e5761163e61168a565b500190565b60005b8381101561165e578181015183820152602001611646565b838111156109f35750506000910152565b60006000198214156116835761168361168a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461011757600080fdfe60a060405234801561001057600080fd5b506040516101d43803806101d483398101604081905261002f91610044565b60601b6001600160601b031916608052610072565b600060208284031215610055578081fd5b81516001600160a01b038116811461006b578182fd5b9392505050565b60805160601c61013f610095600039600081816069015260be015261013f6000f3fe6080604052600436106100225760003560e01c80635c60da1b146100ac57610067565b3661006757604080516020808252600090820152339134917f606834f57405380c4fb88d1f4850326ad3885f014bab3b568dfbf7a041eef738910160405180910390a3005b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100a7573d6000f35b3d6000fd5b3480156100b857600080fd5b506100e07f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220b88a14f52e9d465328c9b3ab476e4b7fa40ed3615fd5409a6afc9885366e03a964736f6c63430008030033a2646970667358221220dec5ae87a38d164692a0d9f7a489556203efa01d593e3bbffea1447231dc89d664736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ab00ea153c43575184ff11dd5e713c96be00557300000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f000000000000000000000000482579f93dc13e6b434e38b5a0447ca543d88a46
-----Decoded View---------------
Arg [0] : _walletImplementation (address): 0xAb00eA153c43575184ff11Dd5e713c96bE005573
Arg [1] : _guardianStorage (address): 0x44DA3A8051bA88EAB0440DB3779cAB9D679ae76f
Arg [2] : _refundAddress (address): 0x482579F93dC13e6B434E38b5a0447ca543D88A46
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000ab00ea153c43575184ff11dd5e713c96be005573
Arg [1] : 00000000000000000000000044da3a8051ba88eab0440db3779cab9d679ae76f
Arg [2] : 000000000000000000000000482579f93dc13e6b434e38b5a0447ca543d88a46
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,644.51 | 0.001 | $2.64 |
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.