Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
0x60c06040 | 18010134 | 578 days ago | Contract Creation | 0 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.
Contract Name:
WalletFactory
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "../iface/ILoopringWalletV2.sol"; import "../lib/EIP712.sol"; import "../lib/SignatureUtil.sol"; import "./WalletDeploymentLib.sol"; import "../lib/Ownable.sol"; import "../lib/AddressSet.sol"; /// @title WalletFactory /// @dev A factory contract to create a new wallet by deploying a proxy /// in front of a real wallet. /// @author Daniel Wang - <[email protected]> contract WalletFactory is WalletDeploymentLib, Ownable, AddressSet { bytes32 internal constant OPERATOR = keccak256("__OPERATOR__"); using SignatureUtil for bytes32; event WalletCreated (address wallet, address owner); event OperatorRemoved (address indexed operator); event OperatorAdded(address indexed operator); bytes32 public immutable DOMAIN_SEPARATOR; bytes32 public constant CREATE_WALLET_TYPEHASH = keccak256( "createWallet(address owner,address[] guardians,uint256 quota,address inheritor,address feeRecipient,address feeToken,uint256 maxFeeAmount,uint256 salt)"); ///////////////////////////////// opeartor /////////////////// modifier onlyOperator { require(isOperator(msg.sender), "DISALLOWED_ON_IMPLEMENTATION_CONTRACT"); _; } function isOperator(address addr) public view returns (bool) { return isAddressInSet(OPERATOR, addr); } /// @dev Gets the operators. /// @return The list of operators. function operators() public view returns (address[] memory) { return addressesInSet(OPERATOR); } /// @dev Gets the number of operators. /// @return The numer of operators. function numOperators() public view returns (uint) { return numAddressesInSet(OPERATOR); } /// @dev Adds a new operator. /// @param operator The new address to add. function addOperator(address operator) public onlyOwner { addOperatorInternal(operator); } /// @dev Removes a operator. /// @param operator The operator to remove. function removeOperator(address operator) public onlyOwner { removeAddressFromSet(OPERATOR, operator); emit OperatorRemoved(operator); } function addOperatorInternal(address operator) internal { addAddressToSet(OPERATOR, operator, true); emit OperatorAdded(operator); } struct WalletConfig { address owner; address[] guardians; uint quota; address inheritor; address feeRecipient; address feeToken; uint maxFeeAmount; uint salt; bytes signature; } struct WalletConfigV2 { address owner; address initOwner; address[] guardians; uint quota; address inheritor; address feeRecipient; address feeToken; uint maxFeeAmount; uint salt; } constructor( address _walletImplementation ) WalletDeploymentLib(_walletImplementation) { DOMAIN_SEPARATOR = EIP712.hash( EIP712.Domain("WalletFactory", "2.0.0", address(this)) ); } /// @dev Create a new wallet by deploying a proxy. /// @param config The wallet's config. /// @param feeAmount The fee amount actually paid. /// @return wallet The new wallet address function createWallet( WalletConfig calldata config, uint feeAmount ) onlyOperator external returns (address wallet) { require(feeAmount <= config.maxFeeAmount, "INVALID_FEE_AMOUNT"); _validateConfig(config); wallet = _deploy(config.owner, config.salt); _initializeWallet(wallet, config, feeAmount); } /// @dev Create a new wallet by deploying a proxy. /// @param config The wallet's config. /// @param feeAmount The fee amount actually paid. /// @return wallet The new wallet address function createWalletByOperator( WalletConfigV2 calldata config, uint feeAmount ) onlyOperator external returns (address wallet) { require(feeAmount <= config.maxFeeAmount, "INVALID_FEE_AMOUNT"); require(config.owner != address(0), "INVALID_OWNER"); wallet = _deploy(config.initOwner, config.salt); ILoopringWalletV2(wallet).initialize( config.owner, config.guardians, config.quota, config.inheritor, config.feeRecipient, config.feeToken, feeAmount ); emit WalletCreated(wallet, config.owner); } /// @dev Computes the wallet address /// @param salt The initial wallet owner. /// @param salt A salt. /// @return wallet The wallet address function computeWalletAddress( address owner, uint salt ) public view returns (address) { return _computeWalletAddress( owner, salt, address(this) ); } // --- Internal functions --- function _initializeWallet( address wallet, WalletConfig calldata config, uint feeAmount ) internal { ILoopringWalletV2(wallet).initialize( config.owner, config.guardians, config.quota, config.inheritor, config.feeRecipient, config.feeToken, feeAmount ); emit WalletCreated(wallet, config.owner); } function _validateConfig( WalletConfig calldata config ) private view { require(config.owner != address(0), "INVALID_OWNER"); bytes32 dataHash = keccak256( abi.encode( CREATE_WALLET_TYPEHASH, config.owner, keccak256(abi.encodePacked(config.guardians)), config.quota, config.inheritor, config.feeRecipient, config.feeToken, config.maxFeeAmount, config.salt ) ); bytes32 signHash = EIP712.hashPacked(DOMAIN_SEPARATOR, dataHash); require(signHash.verifySignature(config.owner, config.signature), "INVALID_SIGNATURE"); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "../thirdparty/Create2.sol"; import "../thirdparty/proxies/WalletProxy.sol"; /// @title WalletDeploymentLib /// @dev Functionality to compute wallet addresses and to deploy wallets /// @author Brecht Devos - <[email protected]> contract WalletDeploymentLib { address public immutable walletImplementation; string public constant WALLET_CREATION = "WALLET_CREATION"; constructor( address _walletImplementation ) { walletImplementation = _walletImplementation; } function getWalletCode() public view returns (bytes memory) { return abi.encodePacked( type(WalletProxy).creationCode, abi.encode(walletImplementation) ); } function computeWalletSalt( address owner, uint salt ) public pure returns (bytes32) { return keccak256( abi.encodePacked( WALLET_CREATION, owner, salt ) ); } function _deploy( address owner, uint salt ) internal returns (address payable wallet) { wallet = Create2.deploy( computeWalletSalt(owner, salt), getWalletCode() ); } function _computeWalletAddress( address owner, uint salt, address deployer ) internal view returns (address) { return Create2.computeAddress( computeWalletSalt(owner, salt), getWalletCode(), deployer ); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Loopring SmartWallet V2 interface /// @author Brecht Devos - <[email protected]> abstract contract ILoopringWalletV2 { /// @dev Initializes the smart wallet. /// @param owner The wallet owner address. /// @param guardians The initial wallet guardians. /// @param quota The initial wallet quota. /// @param inheritor The inheritor of the wallet. /// @param feeRecipient The address receiving the fee for creating the wallet. /// @param feeToken The token to use for the fee payment. /// @param feeAmount The amount of tokens paid to the fee recipient. function initialize( address owner, address[] calldata guardians, uint quota, address inheritor, address feeRecipient, address feeToken, uint feeAmount ) external virtual; /// @dev Returns the timestamp the wallet was created. /// @return The timestamp the wallet was created. function getCreationTimestamp() public view virtual returns (uint64); /// @dev Returns the current wallet owner. /// @return The current wallet owner. function getOwner() public view virtual returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title AddressSet /// @author Daniel Wang - <[email protected]> contract AddressSet { struct Set { address[] addresses; mapping (address => uint) positions; uint count; } mapping (bytes32 => Set) private sets; function addAddressToSet( bytes32 key, address addr, bool maintainList ) internal { Set storage set = sets[key]; require(set.positions[addr] == 0, "ALREADY_IN_SET"); if (maintainList) { require(set.addresses.length == set.count, "PREVIOUSLY_NOT_MAINTAILED"); set.addresses.push(addr); } else { require(set.addresses.length == 0, "MUST_MAINTAIN"); } set.count += 1; set.positions[addr] = set.count; } function removeAddressFromSet( bytes32 key, address addr ) internal { Set storage set = sets[key]; uint pos = set.positions[addr]; require(pos != 0, "NOT_IN_SET"); delete set.positions[addr]; set.count -= 1; if (set.addresses.length > 0) { address lastAddr = set.addresses[set.count]; if (lastAddr != addr) { set.addresses[pos - 1] = lastAddr; set.positions[lastAddr] = pos; } set.addresses.pop(); } } function removeSet(bytes32 key) internal { delete sets[key]; } function isAddressInSet( bytes32 key, address addr ) internal view returns (bool) { return sets[key].positions[addr] != 0; } function numAddressesInSet(bytes32 key) internal view returns (uint) { Set storage set = sets[key]; return set.count; } function addressesInSet(bytes32 key) internal view returns (address[] memory) { Set storage set = sets[key]; require(set.count == set.addresses.length, "NOT_MAINTAINED"); return sets[key].addresses; } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Utility Functions for addresses /// @author Daniel Wang - <[email protected]> /// @author Brecht Devos - <[email protected]> library AddressUtil { using AddressUtil for *; function isContract( address addr ) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(addr) } return (codehash != 0x0 && codehash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470); } function toPayable( address addr ) internal pure returns (address payable) { return payable(addr); } // Works like address.send but with a customizable gas limit // Make sure your code is safe for reentrancy when using this function! function sendETH( address to, uint amount, uint gasLimit ) internal returns (bool success) { if (amount == 0) { return true; } address payable recipient = to.toPayable(); /* solium-disable-next-line */ (success,) = recipient.call{value: amount, gas: gasLimit}(""); } // Works like address.transfer but with a customizable gas limit // Make sure your code is safe for reentrancy when using this function! function sendETHAndVerify( address to, uint amount, uint gasLimit ) internal returns (bool success) { success = to.sendETH(amount, gasLimit); require(success, "TRANSFER_FAILURE"); } // Works like call but is slightly more efficient when data // needs to be copied from memory to do the call. function fastCall( address to, uint gasLimit, uint value, bytes memory data ) internal returns (bool success, bytes memory returnData) { if (to != address(0)) { assembly { // Do the call success := call(gasLimit, to, value, add(data, 32), mload(data), 0, 0) // Copy the return data let size := returndatasize() returnData := mload(0x40) mstore(returnData, size) returndatacopy(add(returnData, 32), 0, size) // Update free memory pointer mstore(0x40, add(returnData, add(32, size))) } } } // Like fastCall, but throws when the call is unsuccessful. function fastCallAndVerify( address to, uint gasLimit, uint value, bytes memory data ) internal returns (bytes memory returnData) { bool success; (success, returnData) = fastCall(to, gasLimit, value, data); if (!success) { assembly { revert(add(returnData, 32), mload(returnData)) } } } }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; library EIP712 { struct Domain { string name; string version; address verifyingContract; } bytes32 constant internal EIP712_DOMAIN_TYPEHASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); string constant internal EIP191_HEADER = "\x19\x01"; function hash(Domain memory domain) internal pure returns (bytes32) { uint _chainid; assembly { _chainid := chainid() } return keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, keccak256(bytes(domain.name)), keccak256(bytes(domain.version)), _chainid, domain.verifyingContract ) ); } function hashPacked( bytes32 domainSeparator, bytes32 dataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( EIP191_HEADER, domainSeparator, dataHash ) ); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; abstract contract ERC1271 { // bytes4(keccak256("isValidSignature(bytes32,bytes)") bytes4 constant internal ERC1271_MAGICVALUE = 0x1626ba7e; function isValidSignature( bytes32 _hash, bytes memory _signature) public view virtual returns (bytes4 magicValue); }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Utility Functions for uint /// @author Daniel Wang - <[email protected]> library MathUint { function mul( uint a, uint b ) internal pure returns (uint c) { c = a * b; require(a == 0 || c / a == b, "MUL_OVERFLOW"); } function sub( uint a, uint b ) internal pure returns (uint) { require(b <= a, "SUB_UNDERFLOW"); return a - b; } function add( uint a, uint b ) internal pure returns (uint c) { c = a + b; require(c >= a, "ADD_OVERFLOW"); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; /// @title Ownable /// @author Brecht Devos - <[email protected]> /// @dev The Ownable contract has an owner address, and provides basic /// authorization control functions, this simplifies the implementation of /// "user permissions". contract Ownable { address public owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /// @dev The Ownable constructor sets the original `owner` of the contract /// to the sender. constructor() { owner = msg.sender; } /// @dev Throws if called by any account other than the owner. modifier onlyOwner() { require(msg.sender == owner, "UNAUTHORIZED"); _; } /// @dev Allows the current owner to transfer control of the contract to a /// new owner. /// @param newOwner The address to transfer ownership to. function transferOwnership( address newOwner ) public virtual onlyOwner { require(newOwner != address(0), "ZERO_ADDRESS"); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } function renounceOwnership() public onlyOwner { emit OwnershipTransferred(owner, address(0)); owner = address(0); } }
// SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2017 Loopring Technology Limited. pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "../thirdparty/BytesUtil.sol"; import "./AddressUtil.sol"; import "./ERC1271.sol"; import "./MathUint.sol"; /// @title SignatureUtil /// @author Daniel Wang - <[email protected]> /// @dev This method supports multihash standard. Each signature's last byte indicates /// the signature's type. library SignatureUtil { using BytesUtil for bytes; using MathUint for uint; using AddressUtil for address; enum SignatureType { ILLEGAL, INVALID, EIP_712, ETH_SIGN, WALLET // deprecated } bytes4 constant internal ERC1271_MAGICVALUE = 0x1626ba7e; function verifySignatures( bytes32 signHash, address[] memory signers, bytes[] memory signatures ) internal view returns (bool) { require(signers.length == signatures.length, "BAD_SIGNATURE_DATA"); address lastSigner; for (uint i = 0; i < signers.length; i++) { require(signers[i] > lastSigner, "INVALID_SIGNERS_ORDER"); lastSigner = signers[i]; if (!verifySignature(signHash, signers[i], signatures[i])) { return false; } } return true; } function verifySignature( bytes32 signHash, address signer, bytes memory signature ) internal view returns (bool) { if (signer == address(0)) { return false; } return signer.isContract()? verifyERC1271Signature(signHash, signer, signature): verifyEOASignature(signHash, signer, signature); } function recoverECDSASigner( bytes32 signHash, bytes memory signature ) internal pure returns (address) { if (signature.length != 65) { return address(0); } bytes32 r; bytes32 s; uint8 v; // 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 assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := and(mload(add(signature, 0x41)), 0xff) } // See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return address(0); } if (v == 27 || v == 28) { return ecrecover(signHash, v, r, s); } else { return address(0); } } function verifyEOASignature( bytes32 signHash, address signer, bytes memory signature ) private pure returns (bool success) { if (signer == address(0)) { return false; } require(signature.length == 65 || signature.length == 66, "INVALID_SIGNATURE_LENGTH"); bool trimmed = false; if (signature.length == 66) { // Strip off the last byte of the signature by updating the length assembly { mstore(signature, 65) } trimmed = true; } success = (signer == recoverECDSASigner(signHash, signature)); if (!success) { bytes32 hash = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", signHash) ); success = (signer == recoverECDSASigner(hash, signature)); } if (trimmed) { // Restore the signature length assembly { mstore(signature, 66) } } } function verifyERC1271Signature( bytes32 signHash, address signer, bytes memory signature ) private view returns (bool) { bytes memory callData = abi.encodeWithSelector( ERC1271.isValidSignature.selector, signHash, signature ); (bool success, bytes memory result) = signer.staticcall(callData); return ( success && result.length == 32 && result.toBytes4(0) == ERC1271_MAGICVALUE ); } }
// SPDX-License-Identifier: UNLICENSED // Taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol pragma solidity ^0.7.0; library BytesUtil { function slice( bytes memory _bytes, uint _start, uint _length ) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length)); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= (_start + 20)); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) { require(_bytes.length >= (_start + 1)); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) { require(_bytes.length >= (_start + 2)); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint24(bytes memory _bytes, uint _start) internal pure returns (uint24) { require(_bytes.length >= (_start + 3)); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) { require(_bytes.length >= (_start + 4)); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) { require(_bytes.length >= (_start + 8)); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) { require(_bytes.length >= (_start + 12)); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) { require(_bytes.length >= (_start + 16)); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes4(bytes memory _bytes, uint _start) internal pure returns (bytes4) { require(_bytes.length >= (_start + 4)); bytes4 tempBytes4; assembly { tempBytes4 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes4; } function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) { require(_bytes.length >= (_start + 32)); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function fastSHA256( bytes memory data ) internal view returns (bytes32) { bytes32[] memory result = new bytes32[](1); bool success; assembly { let ptr := add(data, 32) success := staticcall(sub(gas(), 2000), 2, ptr, mload(data), add(result, 32), 32) } require(success, "SHA256_FAILED"); return result[0]; } }
// SPDX-License-Identifier: UNLICENSED // Taken from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/970f687f04d20e01138a3e8ccf9278b1d4b3997b/contracts/utils/Create2.sol pragma solidity ^0.7.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. Note that * a contract cannot be deployed twice using the same salt. */ function deploy(bytes32 salt, bytes memory bytecode) internal returns (address payable) { address payable addr; // solhint-disable-next-line no-inline-assembly assembly { addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "CREATE2_FAILED"); return addr; } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the `bytecode` * or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes memory bytecode) internal view returns (address) { return computeAddress(salt, bytecode, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes memory bytecodeHash, address deployer) internal pure returns (address) { bytes32 bytecodeHashHash = keccak256(bytecodeHash); bytes32 _data = keccak256( abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHashHash) ); return address(bytes20(_data << 96)); } }
// SPDX-License-Identifier: LGPL-3.0-or-later // Taken from: https://github.com/gnosis/safe-contracts/blob/development/contracts/proxies/GnosisSafeProxy.sol pragma solidity ^0.7.0; /// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain /// @author Richard Meissner - <[email protected]> interface IProxy { function masterCopy() external view returns (address); } /// @title WalletProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. /// @author Stefan George - <[email protected]> /// @author Richard Meissner - <[email protected]> contract WalletProxy { // masterCopy always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated. // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt` address internal masterCopy; /// @dev Constructor function sets address of master copy contract. /// @param _masterCopy Master copy address. constructor(address _masterCopy) { require(_masterCopy != address(0), "Invalid master copy address provided"); masterCopy = _masterCopy; } /// @dev Fallback function forwards all transactions and returns all received return data. fallback() payable external { // solium-disable-next-line security/no-inline-assembly assembly { let _masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff) // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) { mstore(0, _masterCopy) return(0, 0x20) } calldatacopy(0, 0, calldatasize()) let success := delegatecall(gas(), _masterCopy, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) if eq(success, 0) { revert(0, returndatasize()) } return(0, returndatasize()) } } receive() external payable { } }
{ "optimizer": { "enabled": true, "runs": 100000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_walletImplementation","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"OperatorRemoved","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"WalletCreated","type":"event"},{"inputs":[],"name":"CREATE_WALLET_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_CREATION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"computeWalletAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"computeWalletSalt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address[]","name":"guardians","type":"address[]"},{"internalType":"uint256","name":"quota","type":"uint256"},{"internalType":"address","name":"inheritor","type":"address"},{"internalType":"address","name":"feeRecipient","type":"address"},{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"maxFeeAmount","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct WalletFactory.WalletConfig","name":"config","type":"tuple"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"createWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"initOwner","type":"address"},{"internalType":"address[]","name":"guardians","type":"address[]"},{"internalType":"uint256","name":"quota","type":"uint256"},{"internalType":"address","name":"inheritor","type":"address"},{"internalType":"address","name":"feeRecipient","type":"address"},{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"maxFeeAmount","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"internalType":"struct WalletFactory.WalletConfigV2","name":"config","type":"tuple"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"createWalletByOperator","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getWalletCode","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numOperators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"walletImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b50604051620025633803806200256383398101604081905262000034916200014c565b606081811b6001600160601b031916608090815260008054336001600160a01b03199091161790556040805160a081018252600d9381019384526c57616c6c6574466163746f727960981b928101929092529181528151808301835260058152640322e302e360dc1b602080830191909152808301919091523092820192909252620000c991620000d3811b62000bb117901c565b60a05250620001a8565b6000804690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8360000151805190602001208460200151805190602001208386604001516040516020016200012e9594939291906200017c565b60405160208183030381529060405280519060200120915050919050565b6000602082840312156200015e578081fd5b81516001600160a01b038116811462000175578182fd5b9392505050565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b60805160601c60a05161238a620001d96000398061024e528061107d5250806105d352806108ca525061238a6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80639870d7fe116100b2578063ce15861211610081578063d92d1f5611610066578063d92d1f5614610211578063e673df8a14610224578063f2fde38b146102395761011b565b8063ce158612146101f6578063d70e2000146102095761011b565b80639870d7fe146101b5578063ac8a584a146101c8578063b6830d8f146101db578063bd820688146101ee5761011b565b8063715018a6116100ee578063715018a6146101865780638117abc1146101905780638da5cb5b1461019857806390610b0e146101a05761011b565b80633644e515146101205780634c30d6c91461013e5780635b29128f146101465780636d70f7ae14610166575b600080fd5b61012861024c565b6040516101359190611ec3565b60405180910390f35b610128610270565b610159610154366004611b8a565b610294565b6040516101359190611d73565b610179610174366004611b47565b6104a8565b6040516101359190611eb8565b61018e6104dc565b005b6101596105d1565b6101596105f5565b6101a8610611565b6040516101359190611f98565b61018e6101c3366004611b47565b61064a565b61018e6101d6366004611b47565b6106dc565b6101286101e9366004611b61565b6107d0565b61012861083b565b610159610204366004611b61565b61086b565b6101a861087f565b61015961021f366004611b8a565b610942565b61022c6109f1565b6040516101359190611e5e565b61018e610247366004611b47565b610a1c565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f4392cdd6c9d91e0896c5def13bad6473db5d21e2b0def85ab8c2475c3e60d14c81565b600061029f336104a8565b6102de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fe2565b60405180910390fd5b8260e0013582111561031c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fab565b600061032b6020850185611b47565b73ffffffffffffffffffffffffffffffffffffffff161415610379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590612076565b61039761038c6040850160208601611b47565b846101000135610c28565b905073ffffffffffffffffffffffffffffffffffffffff811663d6bb65c26103c26020860186611b47565b6103cf60408701876120e4565b60608801356103e460a08a0160808b01611b47565b6103f460c08b0160a08c01611b47565b61040460e08c0160c08d01611b47565b8a6040518963ffffffff1660e01b8152600401610428989796959493929190611dbb565b600060405180830381600087803b15801561044257600080fd5b505af1158015610456573d6000803e3d6000fd5b507f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081925083915061048c90506020860186611b47565b60405161049a929190611d94565b60405180910390a192915050565b60006104d47fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b0583610c44565b90505b919050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461056257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600f81526020017f57414c4c45545f4352454154494f4e000000000000000000000000000000000081525081565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b6106d981610c7e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b61078c7fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b0582610cee565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d90600090a250565b60006040518060400160405280600f81526020017f57414c4c45545f4352454154494f4e0000000000000000000000000000000000815250838360405160200161081c93929190611cc9565b6040516020818303038152906040528051906020012090505b92915050565b60006108667fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b05610f09565b905090565b6000610878838330610f1e565b9392505050565b60606040518060200161089190611afe565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f9091011660408190526108f2907f000000000000000000000000000000000000000000000000000000000000000090602001611d73565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261092e9291602001611c9a565b604051602081830303815290604052905090565b600061094d336104a8565b610983576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fe2565b8260c001358211156109c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fab565b6109ca83610f43565b6109e46109da6020850185611b47565b8460e00135610c28565b905061083581848461113b565b60606108667fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b05611249565b60005473ffffffffffffffffffffffffffffffffffffffff163314610aa257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610b2457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f414444524553530000000000000000000000000000000000000000604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000804690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f836000015180519060200120846020015180519060200120838660400151604051602001610c0a959493929190611f28565b60405160208183030381529060405280519060200120915050919050565b6000610878610c3784846107d0565b610c3f61087f565b611346565b600082815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529092019052902054151592915050565b610caa7fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b058260016113d7565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d90600090a250565b600082815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529283019091529091205480610d8e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f494e5f53455400000000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526001830160205260408120556002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055815415610f0357600082600001836002015481548110610dfc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff908116915084168114610e9e5780836000016001840381548110610e3d57fe5b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918316815260018501909152604090208290555b8254839080610ea957fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055505b50505050565b60009081526001602052604090206002015490565b6000610f3b610f2d85856107d0565b610f3561087f565b846115f2565b949350505050565b6000610f526020830183611b47565b73ffffffffffffffffffffffffffffffffffffffff161415610fa0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590612076565b60007f4392cdd6c9d91e0896c5def13bad6473db5d21e2b0def85ab8c2475c3e60d14c610fd06020840184611b47565b610fdd60208501856120e4565b604051602001610fee929190611c31565b60405160208183030381529060405280519060200120846040013585606001602081019061101c9190611b47565b61102c60a0880160808901611b47565b61103c60c0890160a08a01611b47565b8860c001358960e0013560405160200161105e99989796959493929190611ecc565b60405160208183030381529060405280519060200120905060006110a27f000000000000000000000000000000000000000000000000000000000000000083611691565b90506111006110b46020850185611b47565b6110c2610100860186612150565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508694939250506116dd9050565b611136576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d59061203f565b505050565b73ffffffffffffffffffffffffffffffffffffffff831663d6bb65c26111646020850185611b47565b61117160208601866120e4565b60408701356111866080890160608a01611b47565b61119660a08a0160808b01611b47565b6111a660c08b0160a08c01611b47565b896040518963ffffffff1660e01b81526004016111ca989796959493929190611dbb565b600060405180830381600087803b1580156111e457600080fd5b505af11580156111f8573d6000803e3d6000fd5b507f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081925085915061122e90506020850185611b47565b60405161123c929190611d94565b60405180910390a1505050565b60008181526001602052604090208054600282015460609291146112ce57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f4d41494e5441494e4544000000000000000000000000000000000000604482015290519081900360640190fd5b6000838152600160209081526040918290208054835181840281018401909452808452909183018282801561133957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161130e575b5050505050915050919050565b600080838351602085016000f5905073ffffffffffffffffffffffffffffffffffffffff811661087857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f435245415445325f4641494c4544000000000000000000000000000000000000604482015290519081900360640190fd5b600083815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff87168552928301909152909120541561147757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f494e5f534554000000000000000000000000000000000000604482015290519081900360640190fd5b81156115455760028101548154146114f057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f50524556494f55534c595f4e4f545f4d41494e5441494c454400000000000000604482015290519081900360640190fd5b80546001810182556000828152602090200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85161790556115b3565b8054156115b357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f4d5553545f4d41494e5441494e00000000000000000000000000000000000000604482015290519081900360640190fd5b60028101805460019081019182905573ffffffffffffffffffffffffffffffffffffffff90941660009081529190930160205260409020919091555050565b8151602092830120604080517fff000000000000000000000000000000000000000000000000000000000000008186015260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218401526035830194909452605580830191909152835180830390910181526075909101909252815191012073ffffffffffffffffffffffffffffffffffffffff1690565b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250838360405160200161081c93929190611d1b565b600073ffffffffffffffffffffffffffffffffffffffff831661170257506000610878565b6117218373ffffffffffffffffffffffffffffffffffffffff16611740565b61173557611730848484611777565b610f3b565b610f3b8484846118b0565b6000813f801580159061087857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b600073ffffffffffffffffffffffffffffffffffffffff831661179c57506000610878565b8151604114806117ad575081516042145b6117e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d5906120ad565b60008251604214156117f757506041825260015b6118018584611a0a565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161491508161189d576000856040516020016118499190611d42565b60405160208183030381529060405280519060200120905061186b8185611a0a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16149250505b80156118a857604283525b509392505050565b600080631626ba7e60e01b85846040516024016118ce929190611f61565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808573ffffffffffffffffffffffffffffffffffffffff16836040516119559190611c7e565b600060405180830381855afa9150503d8060008114611990576040519150601f19603f3d011682016040523d82523d6000602084013e611995565b606091505b50915091508180156119a8575080516020145b80156119ff57507f1626ba7e000000000000000000000000000000000000000000000000000000006119db826000611ae2565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b979650505050505050565b60008151604114611a1d57506000610835565b60208201516040830151604184015160ff167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115611a635760009350505050610835565b8060ff16601b1480611a7857508060ff16601c145b15611ad65760018682858560405160008152602001604052604051611aa09493929190611f7a565b6020604051602081039080840390855afa158015611ac2573d6000803e3d6000fd5b505050602060405103519350505050610835565b60009350505050610835565b60008160040183511015611af557600080fd5b50016020015190565b610175806121e083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146104d757600080fd5b60006101208284031215611b41578081fd5b50919050565b600060208284031215611b58578081fd5b61087882611b0b565b60008060408385031215611b73578081fd5b611b7c83611b0b565b946020939093013593505050565b60008060408385031215611b9c578182fd5b823567ffffffffffffffff811115611bb2578283fd5b611bbe85828601611b2f565b95602094909401359450505050565b73ffffffffffffffffffffffffffffffffffffffff169052565b60008151808452611bff8160208601602086016121b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008184825b85811015611c735773ffffffffffffffffffffffffffffffffffffffff611c5d83611b0b565b1683526020928301929190910190600101611c37565b509095945050505050565b60008251611c908184602087016121b3565b9190910192915050565b60008351611cac8184602088016121b3565b835190830190611cc08183602088016121b3565b01949350505050565b60008451611cdb8184602089016121b3565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b60008451611d2d8184602089016121b3565b91909101928352506020820152604001919050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff898116825260e060208084018290529083018990526000918a916101008501845b8c811015611e165783611e0386611b0b565b1682529382019390820190600101611df1565b5080945050505050866040830152611e316060830187611bcd565b611e3e6080830186611bcd565b611e4b60a0830185611bcd565b8260c08301529998505050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611eac57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611e7a565b50909695505050505050565b901515815260200190565b90815260200190565b98895273ffffffffffffffffffffffffffffffffffffffff97881660208a0152604089019690965260608801949094529185166080870152841660a086015290921660c084015260e08301919091526101008201526101200190565b94855260208501939093526040840191909152606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00190565b600083825260406020830152610f3b6040830184611be7565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526108786020830184611be7565b60208082526012908201527f494e56414c49445f4645455f414d4f554e540000000000000000000000000000604082015260600190565b60208082526025908201527f444953414c4c4f5745445f4f4e5f494d504c454d454e544154494f4e5f434f4e60408201527f5452414354000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f494e56414c49445f5349474e4154555245000000000000000000000000000000604082015260600190565b6020808252600d908201527f494e56414c49445f4f574e455200000000000000000000000000000000000000604082015260600190565b60208082526018908201527f494e56414c49445f5349474e41545552455f4c454e4754480000000000000000604082015260600190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612118578283fd5b83018035915067ffffffffffffffff821115612132578283fd5b602090810192508102360382131561214957600080fd5b9250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612184578283fd5b83018035915067ffffffffffffffff82111561219e578283fd5b60200191503681900382131561214957600080fd5b60005b838110156121ce5781810151838201526020016121b6565b83811115610f03575050600091015256fe608060405234801561001057600080fd5b506040516101753803806101758339818101604052602081101561003357600080fd5b50516001600160a01b03811661007a5760405162461bcd60e51b81526004018080602001828103825260248152602001806101516024913960400191505060405180910390fd5b600080546001600160a01b039092166001600160a01b031990921691909117905560a8806100a96000396000f3fe608060405236600a57005b600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e0000000000000000000000000000000000000000000000000000000082351415605457808252602082f35b3682833781823684845af490503d82833e80606d573d82fd5b503d81f3fea26469706673582212209b39db819970ade944325e6a1f180577f0bf51c0b1c93dcdcc13bc55d62dbddd64736f6c63430007060033496e76616c6964206d617374657220636f707920616464726573732070726f7669646564a26469706673582212207118399b829f084e3ffd4c75022f62be54a83224f5f660e1ea1f7f095902706d64736f6c6343000706003300000000000000000000000023a19a97a2da581e3d66ef5fd1eea15024f55611
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061011b5760003560e01c80639870d7fe116100b2578063ce15861211610081578063d92d1f5611610066578063d92d1f5614610211578063e673df8a14610224578063f2fde38b146102395761011b565b8063ce158612146101f6578063d70e2000146102095761011b565b80639870d7fe146101b5578063ac8a584a146101c8578063b6830d8f146101db578063bd820688146101ee5761011b565b8063715018a6116100ee578063715018a6146101865780638117abc1146101905780638da5cb5b1461019857806390610b0e146101a05761011b565b80633644e515146101205780634c30d6c91461013e5780635b29128f146101465780636d70f7ae14610166575b600080fd5b61012861024c565b6040516101359190611ec3565b60405180910390f35b610128610270565b610159610154366004611b8a565b610294565b6040516101359190611d73565b610179610174366004611b47565b6104a8565b6040516101359190611eb8565b61018e6104dc565b005b6101596105d1565b6101596105f5565b6101a8610611565b6040516101359190611f98565b61018e6101c3366004611b47565b61064a565b61018e6101d6366004611b47565b6106dc565b6101286101e9366004611b61565b6107d0565b61012861083b565b610159610204366004611b61565b61086b565b6101a861087f565b61015961021f366004611b8a565b610942565b61022c6109f1565b6040516101359190611e5e565b61018e610247366004611b47565b610a1c565b7fcc7a9834df85511f8da65d2817c8095b6027cec6b3fdf4b6fe0bd6b7d30d953781565b7f4392cdd6c9d91e0896c5def13bad6473db5d21e2b0def85ab8c2475c3e60d14c81565b600061029f336104a8565b6102de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fe2565b60405180910390fd5b8260e0013582111561031c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fab565b600061032b6020850185611b47565b73ffffffffffffffffffffffffffffffffffffffff161415610379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590612076565b61039761038c6040850160208601611b47565b846101000135610c28565b905073ffffffffffffffffffffffffffffffffffffffff811663d6bb65c26103c26020860186611b47565b6103cf60408701876120e4565b60608801356103e460a08a0160808b01611b47565b6103f460c08b0160a08c01611b47565b61040460e08c0160c08d01611b47565b8a6040518963ffffffff1660e01b8152600401610428989796959493929190611dbb565b600060405180830381600087803b15801561044257600080fd5b505af1158015610456573d6000803e3d6000fd5b507f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081925083915061048c90506020860186611b47565b60405161049a929190611d94565b60405180910390a192915050565b60006104d47fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b0583610c44565b90505b919050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461056257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b7f00000000000000000000000023a19a97a2da581e3d66ef5fd1eea15024f5561181565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600f81526020017f57414c4c45545f4352454154494f4e000000000000000000000000000000000081525081565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b6106d981610c7e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b61078c7fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b0582610cee565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d90600090a250565b60006040518060400160405280600f81526020017f57414c4c45545f4352454154494f4e0000000000000000000000000000000000815250838360405160200161081c93929190611cc9565b6040516020818303038152906040528051906020012090505b92915050565b60006108667fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b05610f09565b905090565b6000610878838330610f1e565b9392505050565b60606040518060200161089190611afe565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f9091011660408190526108f2907f00000000000000000000000023a19a97a2da581e3d66ef5fd1eea15024f5561190602001611d73565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261092e9291602001611c9a565b604051602081830303815290604052905090565b600061094d336104a8565b610983576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fe2565b8260c001358211156109c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590611fab565b6109ca83610f43565b6109e46109da6020850185611b47565b8460e00135610c28565b905061083581848461113b565b60606108667fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b05611249565b60005473ffffffffffffffffffffffffffffffffffffffff163314610aa257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610b2457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f414444524553530000000000000000000000000000000000000000604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000804690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f836000015180519060200120846020015180519060200120838660400151604051602001610c0a959493929190611f28565b60405160208183030381529060405280519060200120915050919050565b6000610878610c3784846107d0565b610c3f61087f565b611346565b600082815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529092019052902054151592915050565b610caa7fe63c388d4543ca9e94c981423c48d71e347af88fa97254eee172e5d43f973b058260016113d7565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d90600090a250565b600082815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529283019091529091205480610d8e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f494e5f53455400000000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526001830160205260408120556002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055815415610f0357600082600001836002015481548110610dfc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff908116915084168114610e9e5780836000016001840381548110610e3d57fe5b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918316815260018501909152604090208290555b8254839080610ea957fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055505b50505050565b60009081526001602052604090206002015490565b6000610f3b610f2d85856107d0565b610f3561087f565b846115f2565b949350505050565b6000610f526020830183611b47565b73ffffffffffffffffffffffffffffffffffffffff161415610fa0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d590612076565b60007f4392cdd6c9d91e0896c5def13bad6473db5d21e2b0def85ab8c2475c3e60d14c610fd06020840184611b47565b610fdd60208501856120e4565b604051602001610fee929190611c31565b60405160208183030381529060405280519060200120846040013585606001602081019061101c9190611b47565b61102c60a0880160808901611b47565b61103c60c0890160a08a01611b47565b8860c001358960e0013560405160200161105e99989796959493929190611ecc565b60405160208183030381529060405280519060200120905060006110a27fcc7a9834df85511f8da65d2817c8095b6027cec6b3fdf4b6fe0bd6b7d30d953783611691565b90506111006110b46020850185611b47565b6110c2610100860186612150565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508694939250506116dd9050565b611136576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d59061203f565b505050565b73ffffffffffffffffffffffffffffffffffffffff831663d6bb65c26111646020850185611b47565b61117160208601866120e4565b60408701356111866080890160608a01611b47565b61119660a08a0160808b01611b47565b6111a660c08b0160a08c01611b47565b896040518963ffffffff1660e01b81526004016111ca989796959493929190611dbb565b600060405180830381600087803b1580156111e457600080fd5b505af11580156111f8573d6000803e3d6000fd5b507f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081925085915061122e90506020850185611b47565b60405161123c929190611d94565b60405180910390a1505050565b60008181526001602052604090208054600282015460609291146112ce57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f4d41494e5441494e4544000000000000000000000000000000000000604482015290519081900360640190fd5b6000838152600160209081526040918290208054835181840281018401909452808452909183018282801561133957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161130e575b5050505050915050919050565b600080838351602085016000f5905073ffffffffffffffffffffffffffffffffffffffff811661087857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f435245415445325f4641494c4544000000000000000000000000000000000000604482015290519081900360640190fd5b600083815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff87168552928301909152909120541561147757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f494e5f534554000000000000000000000000000000000000604482015290519081900360640190fd5b81156115455760028101548154146114f057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f50524556494f55534c595f4e4f545f4d41494e5441494c454400000000000000604482015290519081900360640190fd5b80546001810182556000828152602090200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85161790556115b3565b8054156115b357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f4d5553545f4d41494e5441494e00000000000000000000000000000000000000604482015290519081900360640190fd5b60028101805460019081019182905573ffffffffffffffffffffffffffffffffffffffff90941660009081529190930160205260409020919091555050565b8151602092830120604080517fff000000000000000000000000000000000000000000000000000000000000008186015260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218401526035830194909452605580830191909152835180830390910181526075909101909252815191012073ffffffffffffffffffffffffffffffffffffffff1690565b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250838360405160200161081c93929190611d1b565b600073ffffffffffffffffffffffffffffffffffffffff831661170257506000610878565b6117218373ffffffffffffffffffffffffffffffffffffffff16611740565b61173557611730848484611777565b610f3b565b610f3b8484846118b0565b6000813f801580159061087857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b600073ffffffffffffffffffffffffffffffffffffffff831661179c57506000610878565b8151604114806117ad575081516042145b6117e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d5906120ad565b60008251604214156117f757506041825260015b6118018584611a0a565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161491508161189d576000856040516020016118499190611d42565b60405160208183030381529060405280519060200120905061186b8185611a0a565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16149250505b80156118a857604283525b509392505050565b600080631626ba7e60e01b85846040516024016118ce929190611f61565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808573ffffffffffffffffffffffffffffffffffffffff16836040516119559190611c7e565b600060405180830381855afa9150503d8060008114611990576040519150601f19603f3d011682016040523d82523d6000602084013e611995565b606091505b50915091508180156119a8575080516020145b80156119ff57507f1626ba7e000000000000000000000000000000000000000000000000000000006119db826000611ae2565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b979650505050505050565b60008151604114611a1d57506000610835565b60208201516040830151604184015160ff167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115611a635760009350505050610835565b8060ff16601b1480611a7857508060ff16601c145b15611ad65760018682858560405160008152602001604052604051611aa09493929190611f7a565b6020604051602081039080840390855afa158015611ac2573d6000803e3d6000fd5b505050602060405103519350505050610835565b60009350505050610835565b60008160040183511015611af557600080fd5b50016020015190565b610175806121e083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146104d757600080fd5b60006101208284031215611b41578081fd5b50919050565b600060208284031215611b58578081fd5b61087882611b0b565b60008060408385031215611b73578081fd5b611b7c83611b0b565b946020939093013593505050565b60008060408385031215611b9c578182fd5b823567ffffffffffffffff811115611bb2578283fd5b611bbe85828601611b2f565b95602094909401359450505050565b73ffffffffffffffffffffffffffffffffffffffff169052565b60008151808452611bff8160208601602086016121b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008184825b85811015611c735773ffffffffffffffffffffffffffffffffffffffff611c5d83611b0b565b1683526020928301929190910190600101611c37565b509095945050505050565b60008251611c908184602087016121b3565b9190910192915050565b60008351611cac8184602088016121b3565b835190830190611cc08183602088016121b3565b01949350505050565b60008451611cdb8184602089016121b3565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b60008451611d2d8184602089016121b3565b91909101928352506020820152604001919050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff898116825260e060208084018290529083018990526000918a916101008501845b8c811015611e165783611e0386611b0b565b1682529382019390820190600101611df1565b5080945050505050866040830152611e316060830187611bcd565b611e3e6080830186611bcd565b611e4b60a0830185611bcd565b8260c08301529998505050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611eac57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611e7a565b50909695505050505050565b901515815260200190565b90815260200190565b98895273ffffffffffffffffffffffffffffffffffffffff97881660208a0152604089019690965260608801949094529185166080870152841660a086015290921660c084015260e08301919091526101008201526101200190565b94855260208501939093526040840191909152606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00190565b600083825260406020830152610f3b6040830184611be7565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526108786020830184611be7565b60208082526012908201527f494e56414c49445f4645455f414d4f554e540000000000000000000000000000604082015260600190565b60208082526025908201527f444953414c4c4f5745445f4f4e5f494d504c454d454e544154494f4e5f434f4e60408201527f5452414354000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f494e56414c49445f5349474e4154555245000000000000000000000000000000604082015260600190565b6020808252600d908201527f494e56414c49445f4f574e455200000000000000000000000000000000000000604082015260600190565b60208082526018908201527f494e56414c49445f5349474e41545552455f4c454e4754480000000000000000604082015260600190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612118578283fd5b83018035915067ffffffffffffffff821115612132578283fd5b602090810192508102360382131561214957600080fd5b9250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612184578283fd5b83018035915067ffffffffffffffff82111561219e578283fd5b60200191503681900382131561214957600080fd5b60005b838110156121ce5781810151838201526020016121b6565b83811115610f03575050600091015256fe608060405234801561001057600080fd5b506040516101753803806101758339818101604052602081101561003357600080fd5b50516001600160a01b03811661007a5760405162461bcd60e51b81526004018080602001828103825260248152602001806101516024913960400191505060405180910390fd5b600080546001600160a01b039092166001600160a01b031990921691909117905560a8806100a96000396000f3fe608060405236600a57005b600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e0000000000000000000000000000000000000000000000000000000082351415605457808252602082f35b3682833781823684845af490503d82833e80606d573d82fd5b503d81f3fea26469706673582212209b39db819970ade944325e6a1f180577f0bf51c0b1c93dcdcc13bc55d62dbddd64736f6c63430007060033496e76616c6964206d617374657220636f707920616464726573732070726f7669646564a26469706673582212207118399b829f084e3ffd4c75022f62be54a83224f5f660e1ea1f7f095902706d64736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000023a19a97a2da581e3d66ef5fd1eea15024f55611
-----Decoded View---------------
Arg [0] : _walletImplementation (address): 0x23a19a97A2dA581e3d66Ef5Fd1eeA15024f55611
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000023a19a97a2da581e3d66ef5fd1eea15024f55611
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.