Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 895 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Counterfa... | 11802436 | 1409 days ago | IN | 0 ETH | 0.06756269 | ||||
Create Counterfa... | 11569471 | 1445 days ago | IN | 0 ETH | 0.04521503 | ||||
Create Counterfa... | 11536932 | 1450 days ago | IN | 0 ETH | 0.11395993 | ||||
Create Counterfa... | 11329228 | 1481 days ago | IN | 0 ETH | 0.0161111 | ||||
Create Counterfa... | 11327871 | 1482 days ago | IN | 0 ETH | 0.02979754 | ||||
Create Counterfa... | 11226403 | 1497 days ago | IN | 0 ETH | 0.00815011 | ||||
Create Counterfa... | 11226389 | 1497 days ago | IN | 0 ETH | 0.00779569 | ||||
Create Counterfa... | 11199852 | 1501 days ago | IN | 0 ETH | 0.0094068 | ||||
Create Counterfa... | 11194688 | 1502 days ago | IN | 0 ETH | 0.01309451 | ||||
Create Counterfa... | 11194613 | 1502 days ago | IN | 0 ETH | 0.01411462 | ||||
Create Counterfa... | 11185244 | 1504 days ago | IN | 0 ETH | 0.03205711 | ||||
Create Counterfa... | 11185222 | 1504 days ago | IN | 0 ETH | 0.03066235 | ||||
Create Counterfa... | 11149366 | 1509 days ago | IN | 0 ETH | 0.02143332 | ||||
Create Counterfa... | 11145922 | 1510 days ago | IN | 0 ETH | 0.06756269 | ||||
Create Counterfa... | 11140765 | 1510 days ago | IN | 0 ETH | 0.01091397 | ||||
Create Counterfa... | 11139337 | 1511 days ago | IN | 0 ETH | 0.02227595 | ||||
Create Counterfa... | 11139325 | 1511 days ago | IN | 0 ETH | 0.02281927 | ||||
Create Counterfa... | 11139305 | 1511 days ago | IN | 0 ETH | 0.02159401 | ||||
Create Counterfa... | 11137139 | 1511 days ago | IN | 0 ETH | 0.00930519 | ||||
Create Counterfa... | 11133868 | 1511 days ago | IN | 0 ETH | 0.01205734 | ||||
Create Counterfa... | 10775838 | 1567 days ago | IN | 0 ETH | 0.25482692 | ||||
Create Counterfa... | 10775819 | 1567 days ago | IN | 0 ETH | 0.25482692 | ||||
Create Counterfa... | 10770018 | 1568 days ago | IN | 0 ETH | 0.15643361 | ||||
Create Counterfa... | 10768627 | 1568 days ago | IN | 0 ETH | 0.11844833 | ||||
Create Counterfa... | 10768625 | 1568 days ago | IN | 0 ETH | 0.11844833 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11802436 | 1409 days ago | Contract Creation | 0 ETH | |||
11569471 | 1445 days ago | Contract Creation | 0 ETH | |||
11536932 | 1450 days ago | Contract Creation | 0 ETH | |||
11329228 | 1481 days ago | Contract Creation | 0 ETH | |||
11327871 | 1482 days ago | Contract Creation | 0 ETH | |||
11226403 | 1497 days ago | Contract Creation | 0 ETH | |||
11226389 | 1497 days ago | Contract Creation | 0 ETH | |||
11199852 | 1501 days ago | Contract Creation | 0 ETH | |||
11194688 | 1502 days ago | Contract Creation | 0 ETH | |||
11194613 | 1502 days ago | Contract Creation | 0 ETH | |||
11185244 | 1504 days ago | Contract Creation | 0 ETH | |||
11185222 | 1504 days ago | Contract Creation | 0 ETH | |||
11149366 | 1509 days ago | Contract Creation | 0 ETH | |||
11145922 | 1510 days ago | Contract Creation | 0 ETH | |||
11140765 | 1510 days ago | Contract Creation | 0 ETH | |||
11139337 | 1511 days ago | Contract Creation | 0 ETH | |||
11139325 | 1511 days ago | Contract Creation | 0 ETH | |||
11139305 | 1511 days ago | Contract Creation | 0 ETH | |||
11137139 | 1511 days ago | Contract Creation | 0 ETH | |||
11133868 | 1511 days ago | Contract Creation | 0 ETH | |||
10775838 | 1567 days ago | Contract Creation | 0 ETH | |||
10775819 | 1567 days ago | Contract Creation | 0 ETH | |||
10770018 | 1568 days ago | Contract Creation | 0 ETH | |||
10768627 | 1568 days ago | Contract Creation | 0 ETH | |||
10768625 | 1568 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.5.4+commit.9549d8ff
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-05-28 */ pragma solidity ^0.5.4; /** * @title Proxy * @dev 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 implementation; event Received(uint indexed value, address indexed sender, bytes data); constructor(address _implementation) public { implementation = _implementation; } function() external payable { if(msg.data.length == 0 && msg.value > 0) { emit Received(msg.value, msg.sender, msg.data); } else { // solium-disable-next-line security/no-inline-assembly assembly { let target := sload(0) 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())} } } } } /** * @title Module * @dev Interface for a module. * A module MUST implement the addModule() method to ensure that a wallet with at least one module * can never end up in a "frozen" state. * @author Julien Niset - <[email protected]> */ interface Module { /** * @dev Inits a module for a wallet by e.g. setting some wallet specific parameters in storage. * @param _wallet The wallet. */ function init(BaseWallet _wallet) external; /** * @dev Adds a module to a wallet. * @param _wallet The target wallet. * @param _module The modules to authorise. */ function addModule(BaseWallet _wallet, Module _module) external; /** * @dev Utility method to recover any ERC20 token that was sent to the * module by mistake. * @param _token The token to recover. */ function recoverToken(address _token) external; } /** * @title BaseWallet * @dev Simple modular wallet that authorises modules to call its invoke() method. * Based on https://gist.github.com/Arachnid/a619d31f6d32757a4328a428286da186 by * @author Julien Niset - <[email protected]> */ contract BaseWallet { // The implementation of the proxy address public implementation; // The owner address public owner; // The authorised modules mapping (address => bool) public authorised; // The enabled static calls mapping (bytes4 => address) public enabled; // The number of modules uint public modules; event AuthorisedModule(address indexed module, bool value); event EnabledStaticCall(address indexed module, bytes4 indexed method); 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); /** * @dev Throws if the sender is not an authorised module. */ modifier moduleOnly { require(authorised[msg.sender], "BW: msg.sender not an authorized module"); _; } /** * @dev 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: construction requires at least 1 module"); 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; Module(_modules[i]).init(this); emit AuthorisedModule(_modules[i], true); } if (address(this).balance > 0) { emit Received(address(this).balance, address(0), ""); } } /** * @dev 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 moduleOnly { if (authorised[_module] != _value) { emit AuthorisedModule(_module, _value); if(_value == true) { modules += 1; authorised[_module] = true; Module(_module).init(this); } else { modules -= 1; require(modules > 0, "BW: wallet must have at least one module"); delete authorised[_module]; } } } /** * @dev 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 moduleOnly { require(authorised[_module], "BW: must be an authorised module for static call"); enabled[_method] = _module; emit EnabledStaticCall(_module, _method); } /** * @dev Sets a new owner for the wallet. * @param _newOwner The new owner. */ function setOwner(address _newOwner) external moduleOnly { require(_newOwner != address(0), "BW: address cannot be null"); owner = _newOwner; emit OwnerChanged(_newOwner); } /** * @dev 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; // solium-disable-next-line security/no-call-value (success, _result) = _target.call.value(_value)(_data); if(!success) { // solium-disable-next-line security/no-inline-assembly assembly { returndatacopy(0, 0, returndatasize) revert(0, returndatasize) } } emit Invoked(msg.sender, _target, _value, _data); } /** * @dev This method makes it possible for the wallet to comply to interfaces expecting the wallet to * implement specific static methods. It delegates the static call to a target contract if the data corresponds * to an enabled method, or logs the call otherwise. */ function() external payable { if(msg.data.length > 0) { address module = enabled[msg.sig]; if(module == address(0)) { emit Received(msg.value, msg.sender, msg.data); } else { require(authorised[module], "BW: must be an authorised module for static call"); // solium-disable-next-line security/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())} } } } } } /** * @title Owned * @dev Basic contract to define an owner. * @author Julien Niset - <[email protected]> */ contract Owned { // The owner address public owner; event OwnerChanged(address indexed _newOwner); /** * @dev Throws if the sender is not the owner. */ modifier onlyOwner { require(msg.sender == owner, "Must be owner"); _; } constructor() public { owner = msg.sender; } /** * @dev 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); } } /** * @title Managed * @dev Basic contract that defines a set of managers. Only the owner can add/remove managers. * @author Julien Niset - <[email protected]> */ contract Managed is Owned { // The managers mapping (address => bool) public managers; /** * @dev 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); /** * @dev 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); } } /** * @dev Revokes a manager. * @param _manager The address of the manager. */ function revokeManager(address _manager) external onlyOwner { require(managers[_manager] == true, "M: Target must be an existing manager"); delete managers[_manager]; emit ManagerRevoked(_manager); } } /** * ENS Registry interface. */ contract ENSRegistry { function owner(bytes32 _node) public view returns (address); function resolver(bytes32 _node) public view returns (address); function ttl(bytes32 _node) public view returns (uint64); function setOwner(bytes32 _node, address _owner) public; function setSubnodeOwner(bytes32 _node, bytes32 _label, address _owner) public; function setResolver(bytes32 _node, address _resolver) public; function setTTL(bytes32 _node, uint64 _ttl) public; } /** * ENS Resolver interface. */ contract ENSResolver { function addr(bytes32 _node) public view returns (address); function setAddr(bytes32 _node, address _addr) public; function name(bytes32 _node) public view returns (string memory); function setName(bytes32 _node, string memory _name) public; } /** * ENS Reverse Registrar interface. */ contract ENSReverseRegistrar { function claim(address _owner) public returns (bytes32 _node); function claimWithResolver(address _owner, address _resolver) public returns (bytes32); function setName(string memory _name) public returns (bytes32); function node(address _addr) public returns (bytes32); }/* * @title String & slice utility library for Solidity contracts. * @author Nick Johnson <[email protected]> * * @dev Functionality in this library is largely implemented using an * abstraction called a 'slice'. A slice represents a part of a string - * anything from the entire string to a single character, or even no * characters at all (a 0-length slice). Since a slice only has to specify * an offset and a length, copying and manipulating slices is a lot less * expensive than copying and manipulating the strings they reference. * * To further reduce gas costs, most functions on slice that need to return * a slice modify the original one instead of allocating a new one; for * instance, `s.split(".")` will return the text up to the first '.', * modifying s to only contain the remainder of the string after the '.'. * In situations where you do not want to modify the original slice, you * can make a copy first with `.copy()`, for example: * `s.copy().split(".")`. Try and avoid using this idiom in loops; since * Solidity has no memory management, it will result in allocating many * short-lived slices that are later discarded. * * Functions that return two slices come in two versions: a non-allocating * version that takes the second slice as an argument, modifying it in * place, and an allocating version that allocates and returns the second * slice; see `nextRune` for example. * * Functions that have to copy string data will return strings rather than * slices; these can be cast back to slices for further processing if * required. * * For convenience, some functions are provided with non-modifying * variants that create a new slice and return both; for instance, * `s.splitNew('.')` leaves s unmodified, and returns two values * corresponding to the left and right parts of the string. */ // pragma solidity ^0.5.4; /* solium-disable */ library strings { struct slice { uint _len; uint _ptr; } function memcpy(uint dest, uint src, uint len) private pure { // Copy word-length chunks while possible for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /* * @dev Returns a slice containing the entire string. * @param self The string to make a slice from. * @return A newly allocated slice containing the entire string. */ function toSlice(string memory self) internal pure returns (slice memory) { uint ptr; assembly { ptr := add(self, 0x20) } return slice(bytes(self).length, ptr); } /* * @dev Returns the length of a null-terminated bytes32 string. * @param self The value to find the length of. * @return The length of the string, from 0 to 32. */ function len(bytes32 self) internal pure returns (uint) { uint ret; if (self == 0) return 0; if (uint256(self) & 0xffffffffffffffffffffffffffffffff == 0) { ret += 16; self = bytes32(uint(self) / 0x100000000000000000000000000000000); } if (uint256(self) & 0xffffffffffffffff == 0) { ret += 8; self = bytes32(uint(self) / 0x10000000000000000); } if (uint256(self) & 0xffffffff == 0) { ret += 4; self = bytes32(uint(self) / 0x100000000); } if (uint256(self) & 0xffff == 0) { ret += 2; self = bytes32(uint(self) / 0x10000); } if (uint256(self) & 0xff == 0) { ret += 1; } return 32 - ret; } /* * @dev Returns a slice containing the entire bytes32, interpreted as a * null-terminated utf-8 string. * @param self The bytes32 value to convert to a slice. * @return A new slice containing the value of the input argument up to the * first null. */ function toSliceB32(bytes32 self) internal pure returns (slice memory ret) { // Allocate space for `self` in memory, copy it there, and point ret at it assembly { let ptr := mload(0x40) mstore(0x40, add(ptr, 0x20)) mstore(ptr, self) mstore(add(ret, 0x20), ptr) } ret._len = len(self); } /* * @dev Returns a new slice containing the same data as the current slice. * @param self The slice to copy. * @return A new slice containing the same data as `self`. */ function copy(slice memory self) internal pure returns (slice memory) { return slice(self._len, self._ptr); } /* * @dev Copies a slice to a new string. * @param self The slice to copy. * @return A newly allocated string containing the slice's text. */ function toString(slice memory self) internal pure returns (string memory) { string memory ret = new string(self._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); return ret; } /* * @dev Returns the length in runes of the slice. Note that this operation * takes time proportional to the length of the slice; avoid using it * in loops, and call `slice.empty()` if you only need to know whether * the slice is empty or not. * @param self The slice to operate on. * @return The length of the slice in runes. */ function len(slice memory self) internal pure returns (uint l) { // Starting at ptr-31 means the LSB will be the byte we care about uint ptr = self._ptr - 31; uint end = ptr + self._len; for (l = 0; ptr < end; l++) { uint8 b; assembly { b := and(mload(ptr), 0xFF) } if (b < 0x80) { ptr += 1; } else if(b < 0xE0) { ptr += 2; } else if(b < 0xF0) { ptr += 3; } else if(b < 0xF8) { ptr += 4; } else if(b < 0xFC) { ptr += 5; } else { ptr += 6; } } } /* * @dev Returns true if the slice is empty (has a length of 0). * @param self The slice to operate on. * @return True if the slice is empty, False otherwise. */ function empty(slice memory self) internal pure returns (bool) { return self._len == 0; } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two slices are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first slice to compare. * @param other The second slice to compare. * @return The result of the comparison. */ function compare(slice memory self, slice memory other) internal pure returns (int) { uint shortest = self._len; if (other._len < self._len) shortest = other._len; uint selfptr = self._ptr; uint otherptr = other._ptr; for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint256 mask = uint256(-1); // 0xffff... if(shortest < 32) { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } uint256 diff = (a & mask) - (b & mask); if (diff != 0) return int(diff); } selfptr += 32; otherptr += 32; } return int(self._len) - int(other._len); } /* * @dev Returns true if the two slices contain the same text. * @param self The first slice to compare. * @param self The second slice to compare. * @return True if the slices are equal, false otherwise. */ function equals(slice memory self, slice memory other) internal pure returns (bool) { return compare(self, other) == 0; } /* * @dev Extracts the first rune in the slice into `rune`, advancing the * slice to point to the next rune and returning `self`. * @param self The slice to operate on. * @param rune The slice that will contain the first rune. * @return `rune`. */ function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) { rune._ptr = self._ptr; if (self._len == 0) { rune._len = 0; return rune; } uint l; uint b; // Load the first byte of the rune into the LSBs of b assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) } if (b < 0x80) { l = 1; } else if(b < 0xE0) { l = 2; } else if(b < 0xF0) { l = 3; } else { l = 4; } // Check for truncated codepoints if (l > self._len) { rune._len = self._len; self._ptr += self._len; self._len = 0; return rune; } self._ptr += l; self._len -= l; rune._len = l; return rune; } /* * @dev Returns the first rune in the slice, advancing the slice to point * to the next rune. * @param self The slice to operate on. * @return A slice containing only the first rune from `self`. */ function nextRune(slice memory self) internal pure returns (slice memory ret) { nextRune(self, ret); } /* * @dev Returns the number of the first codepoint in the slice. * @param self The slice to operate on. * @return The number of the first codepoint in the slice. */ function ord(slice memory self) internal pure returns (uint ret) { if (self._len == 0) { return 0; } uint word; uint length; uint divisor = 2 ** 248; // Load the rune into the MSBs of b assembly { word:= mload(mload(add(self, 32))) } uint b = word / divisor; if (b < 0x80) { ret = b; length = 1; } else if(b < 0xE0) { ret = b & 0x1F; length = 2; } else if(b < 0xF0) { ret = b & 0x0F; length = 3; } else { ret = b & 0x07; length = 4; } // Check for truncated codepoints if (length > self._len) { return 0; } for (uint i = 1; i < length; i++) { divisor = divisor / 256; b = (word / divisor) & 0xFF; if (b & 0xC0 != 0x80) { // Invalid UTF-8 sequence return 0; } ret = (ret * 64) | (b & 0x3F); } return ret; } /* * @dev Returns the keccak-256 hash of the slice. * @param self The slice to hash. * @return The hash of the slice. */ function keccak(slice memory self) internal pure returns (bytes32 ret) { assembly { ret := keccak256(mload(add(self, 32)), mload(self)) } } /* * @dev Returns true if `self` starts with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function startsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } if (self._ptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` starts with `needle`, `needle` is removed from the * beginning of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } bool equal = true; if (self._ptr != needle._ptr) { assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; self._ptr += needle._len; } return self; } /* * @dev Returns true if the slice ends with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function endsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } uint selfptr = self._ptr + self._len - needle._len; if (selfptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` ends with `needle`, `needle` is removed from the * end of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function until(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } uint selfptr = self._ptr + self._len - needle._len; bool equal = true; if (selfptr != needle._ptr) { assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; } return self; } // Returns the memory address of the first byte of the first occurrence of // `needle` in `self`, or the first byte after `self` if not found. function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr = selfptr; uint idx; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } uint end = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr >= end) return selfptr + selflen; ptr++; assembly { ptrdata := and(mload(ptr), mask) } } return ptr; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } for (idx = 0; idx <= selflen - needlelen; idx++) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr; ptr += 1; } } } return selfptr + selflen; } // Returns the memory address of the first byte after the last occurrence of // `needle` in `self`, or the address of `self` if not found. function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } ptr = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr <= selfptr) return selfptr; ptr--; assembly { ptrdata := and(mload(ptr), mask) } } return ptr + needlelen; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } ptr = selfptr + (selflen - needlelen); while (ptr >= selfptr) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr + needlelen; ptr -= 1; } } } return selfptr; } /* * @dev Modifies `self` to contain everything from the first occurrence of * `needle` to the end of the slice. `self` is set to the empty slice * if `needle` is not found. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function find(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); self._len -= ptr - self._ptr; self._ptr = ptr; return self; } /* * @dev Modifies `self` to contain the part of the string from the start of * `self` to the end of the first occurrence of `needle`. If `needle` * is not found, `self` is set to the empty slice. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); self._len = ptr - self._ptr; return self; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and `token` to everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = self._ptr; token._len = ptr - self._ptr; if (ptr == self._ptr + self._len) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; self._ptr = ptr + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and returning everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` up to the first occurrence of `delim`. */ function split(slice memory self, slice memory needle) internal pure returns (slice memory token) { split(self, needle, token); } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and `token` to everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = ptr; token._len = self._len - (ptr - self._ptr); if (ptr == self._ptr) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and returning everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` after the last occurrence of `delim`. */ function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) { rsplit(self, needle, token); } /* * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return The number of occurrences of `needle` found in `self`. */ function count(slice memory self, slice memory needle) internal pure returns (uint cnt) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; while (ptr <= self._ptr + self._len) { cnt++; ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len; } } /* * @dev Returns True if `self` contains `needle`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return True if `needle` is found in `self`, false otherwise. */ function contains(slice memory self, slice memory needle) internal pure returns (bool) { return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; } /* * @dev Returns a newly allocated string containing the concatenation of * `self` and `other`. * @param self The first slice to concatenate. * @param other The second slice to concatenate. * @return The concatenation of the two strings. */ function concat(slice memory self, slice memory other) internal pure returns (string memory) { string memory ret = new string(self._len + other._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); memcpy(retptr + self._len, other._ptr, other._len); return ret; } /* * @dev Joins an array of slices, using `self` as a delimiter, returning a * newly allocated string. * @param self The delimiter to use. * @param parts A list of slices to join. * @return A newly allocated string containing all the slices in `parts`, * joined with `self`. */ function join(slice memory self, slice[] memory parts) internal pure returns (string memory) { if (parts.length == 0) return ""; uint length = self._len * (parts.length - 1); for(uint i = 0; i < parts.length; i++) length += parts[i]._len; string memory ret = new string(length); uint retptr; assembly { retptr := add(ret, 32) } for(uint i = 0; i < parts.length; i++) { memcpy(retptr, parts[i]._ptr, parts[i]._len); retptr += parts[i]._len; if (i < parts.length - 1) { memcpy(retptr, self._ptr, self._len); retptr += self._len; } } return ret; } } /** * @title ENSConsumer * @dev Helper contract to resolve ENS names. * @author Julien Niset - <[email protected]> */ contract ENSConsumer { using strings for *; // namehash('addr.reverse') bytes32 constant public ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; // the address of the ENS registry address ensRegistry; /** * @dev No address should be provided when deploying on Mainnet to avoid storage cost. The * contract will use the hardcoded value. */ constructor(address _ensRegistry) public { ensRegistry = _ensRegistry; } /** * @dev Resolves an ENS name to an address. * @param _node The namehash of the ENS name. */ function resolveEns(bytes32 _node) public view returns (address) { address resolver = getENSRegistry().resolver(_node); return ENSResolver(resolver).addr(_node); } /** * @dev Gets the official ENS registry. */ function getENSRegistry() public view returns (ENSRegistry) { return ENSRegistry(ensRegistry); } /** * @dev Gets the official ENS reverse registrar. */ function getENSReverseRegistrar() public view returns (ENSReverseRegistrar) { return ENSReverseRegistrar(getENSRegistry().owner(ADDR_REVERSE_NODE)); } } /** * @dev Interface for an ENS Mananger. */ interface IENSManager { function changeRootnodeOwner(address _newOwner) external; function register(string calldata _label, address _owner) external; function isAvailable(bytes32 _subnode) external view returns(bool); } /** * @title ArgentENSManager * @dev Implementation of an ENS manager that orchestrates the complete * registration of subdomains for a single root (e.g. argent.eth). * The contract defines a manager role who is the only role that can trigger the registration of * a new subdomain. * @author Julien Niset - <[email protected]> */ contract ArgentENSManager is IENSManager, Owned, Managed, ENSConsumer { using strings for *; // The managed root name string public rootName; // The managed root node bytes32 public rootNode; // The address of the ENS resolver address public ensResolver; // *************** Events *************************** // event RootnodeOwnerChange(bytes32 indexed _rootnode, address indexed _newOwner); event ENSResolverChanged(address addr); event Registered(address indexed _owner, string _ens); event Unregistered(string _ens); // *************** Constructor ********************** // /** * @dev Constructor that sets the ENS root name and root node to manage. * @param _rootName The root name (e.g. argentx.eth). * @param _rootNode The node of the root name (e.g. namehash(argentx.eth)). */ constructor(string memory _rootName, bytes32 _rootNode, address _ensRegistry, address _ensResolver) ENSConsumer(_ensRegistry) public { rootName = _rootName; rootNode = _rootNode; ensResolver = _ensResolver; } // *************** External Functions ********************* // /** * @dev This function must be called when the ENS Manager contract is replaced * and the address of the new Manager should be provided. * @param _newOwner The address of the new ENS manager that will manage the root node. */ function changeRootnodeOwner(address _newOwner) external onlyOwner { getENSRegistry().setOwner(rootNode, _newOwner); emit RootnodeOwnerChange(rootNode, _newOwner); } /** * @dev Lets the owner change the address of the ENS resolver contract. * @param _ensResolver The address of the ENS resolver contract. */ function changeENSResolver(address _ensResolver) external onlyOwner { require(_ensResolver != address(0), "WF: address cannot be null"); ensResolver = _ensResolver; emit ENSResolverChanged(_ensResolver); } /** * @dev Lets the manager assign an ENS subdomain of the root node to a target address. * Registers both the forward and reverse ENS. * @param _label The subdomain label. * @param _owner The owner of the subdomain. */ function register(string calldata _label, address _owner) external onlyManager { bytes32 labelNode = keccak256(abi.encodePacked(_label)); bytes32 node = keccak256(abi.encodePacked(rootNode, labelNode)); address currentOwner = getENSRegistry().owner(node); require(currentOwner == address(0), "AEM: _label is alrealdy owned"); // Forward ENS getENSRegistry().setSubnodeOwner(rootNode, labelNode, address(this)); getENSRegistry().setResolver(node, ensResolver); getENSRegistry().setOwner(node, _owner); ENSResolver(ensResolver).setAddr(node, _owner); // Reverse ENS strings.slice[] memory parts = new strings.slice[](2); parts[0] = _label.toSlice(); parts[1] = rootName.toSlice(); string memory name = ".".toSlice().join(parts); bytes32 reverseNode = getENSReverseRegistrar().node(_owner); ENSResolver(ensResolver).setName(reverseNode, name); emit Registered(_owner, name); } // *************** Public Functions ********************* // /** * @dev Returns true is a given subnode is available. * @param _subnode The target subnode. * @return true if the subnode is available. */ function isAvailable(bytes32 _subnode) public view returns (bool) { bytes32 node = keccak256(abi.encodePacked(rootNode, _subnode)); address currentOwner = getENSRegistry().owner(node); if(currentOwner == address(0)) { return true; } return false; } } /** * ERC20 contract interface. */ contract ERC20 { function totalSupply() public view returns (uint); function decimals() public view returns (uint); function balanceOf(address tokenOwner) public view returns (uint balance); function allowance(address tokenOwner, address spender) public view returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom(address from, address to, uint tokens) public returns (bool success); } /** * @title ModuleRegistry * @dev Registry of authorised modules. * Modules must be registered before they can be authorised on a wallet. * @author Julien Niset - <[email protected]> */ contract ModuleRegistry is Owned { mapping (address => Info) internal modules; mapping (address => Info) internal upgraders; event ModuleRegistered(address indexed module, bytes32 name); event ModuleDeRegistered(address module); event UpgraderRegistered(address indexed upgrader, bytes32 name); event UpgraderDeRegistered(address upgrader); struct Info { bool exists; bytes32 name; } /** * @dev Registers a module. * @param _module The module. * @param _name The unique name of the module. */ function registerModule(address _module, bytes32 _name) external onlyOwner { require(!modules[_module].exists, "MR: module already exists"); modules[_module] = Info({exists: true, name: _name}); emit ModuleRegistered(_module, _name); } /** * @dev Deregisters a module. * @param _module The module. */ function deregisterModule(address _module) external onlyOwner { require(modules[_module].exists, "MR: module does not exist"); delete modules[_module]; emit ModuleDeRegistered(_module); } /** * @dev Registers an upgrader. * @param _upgrader The upgrader. * @param _name The unique name of the upgrader. */ function registerUpgrader(address _upgrader, bytes32 _name) external onlyOwner { require(!upgraders[_upgrader].exists, "MR: upgrader already exists"); upgraders[_upgrader] = Info({exists: true, name: _name}); emit UpgraderRegistered(_upgrader, _name); } /** * @dev Deregisters an upgrader. * @param _upgrader The _upgrader. */ function deregisterUpgrader(address _upgrader) external onlyOwner { require(upgraders[_upgrader].exists, "MR: upgrader does not exist"); delete upgraders[_upgrader]; emit UpgraderDeRegistered(_upgrader); } /** * @dev Utility method enbaling the owner of the registry to claim any ERC20 token that was sent to the * registry. * @param _token The token to recover. */ function recoverToken(address _token) external onlyOwner { uint total = ERC20(_token).balanceOf(address(this)); ERC20(_token).transfer(msg.sender, total); } /** * @dev Gets the name of a module from its address. * @param _module The module address. * @return the name. */ function moduleInfo(address _module) external view returns (bytes32) { return modules[_module].name; } /** * @dev Gets the name of an upgrader from its address. * @param _upgrader The upgrader address. * @return the name. */ function upgraderInfo(address _upgrader) external view returns (bytes32) { return upgraders[_upgrader].name; } /** * @dev Checks if a module is registered. * @param _module The module address. * @return true if the module is registered. */ function isRegisteredModule(address _module) external view returns (bool) { return modules[_module].exists; } /** * @dev Checks if a list of modules are registered. * @param _modules The list of modules address. * @return true if all the modules are registered. */ function isRegisteredModule(address[] calldata _modules) external view returns (bool) { for(uint i = 0; i < _modules.length; i++) { if (!modules[_modules[i]].exists) { return false; } } return true; } /** * @dev Checks if an upgrader is registered. * @param _upgrader The upgrader address. * @return true if the upgrader is registered. */ function isRegisteredUpgrader(address _upgrader) external view returns (bool) { return upgraders[_upgrader].exists; } } /** * @title WalletFactory * @dev The WalletFactory contract creates and assigns wallets to accounts. * @author Julien Niset - <[email protected]> */ contract WalletFactory is Owned, Managed, ENSConsumer { // The address of the module dregistry address public moduleRegistry; // The address of the base wallet implementation address public walletImplementation; // The address of the ENS manager address public ensManager; // The address of the ENS resolver address public ensResolver; // *************** Events *************************** // event ModuleRegistryChanged(address addr); event WalletImplementationChanged(address addr); event ENSManagerChanged(address addr); event ENSResolverChanged(address addr); event WalletCreated(address indexed _wallet, address indexed _owner); // *************** Constructor ********************** // /** * @dev Default constructor. */ constructor( address _ensRegistry, address _moduleRegistry, address _walletImplementation, address _ensManager, address _ensResolver ) ENSConsumer(_ensRegistry) public { moduleRegistry = _moduleRegistry; walletImplementation = _walletImplementation; ensManager = _ensManager; ensResolver = _ensResolver; } // *************** External Functions ********************* // /** * @dev Lets the manager create a wallet for an account. The wallet is initialised with a list of modules. * @param _owner The account address. * @param _modules The list of modules. * @param _label Optional ENS label of the new wallet (e.g. franck). */ function createWallet( address _owner, address[] calldata _modules, string calldata _label ) external onlyManager { _validateInputs(_owner, _modules); // create the proxy Proxy proxy = new Proxy(walletImplementation); address payable wallet = address(proxy); // check for ENS bytes memory labelBytes = bytes(_label); if (labelBytes.length != 0) { // add the factory to the modules so it can claim the reverse ENS 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 BaseWallet(wallet).init(_owner, extendedModules); // register ENS registerWalletENS(wallet, _label); // remove the factory from the authorised modules BaseWallet(wallet).authoriseModule(address(this), false); } else { // initialise the wallet with the owner and the modules BaseWallet(wallet).init(_owner, _modules); } emit WalletCreated(wallet, _owner); } /** * @dev Gets the address of a counterfactual wallet. * @param _owner The account address. * @param _modules The list of modules. * @param _salt The salt. * @return the address that the wallet will have when created using CREATE2 and the same input parameters. */ function getAddressForCounterfactualWallet( address _owner, address[] calldata _modules, bytes32 _salt ) external view returns (address) { bytes32 newsalt = _newSalt(_salt, _owner, _modules); bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(walletImplementation)); bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), newsalt, keccak256(code))); return address(uint160(uint256(hash))); } /** * @dev Lets the manager create a wallet for an account at a specific address. * The wallet is initialised with a list of modules and salt. * The wallet is created using the CREATE2 opcode. * @param _owner The account address. * @param _modules The list of modules. * @param _label Optional ENS label of the new wallet (e.g. franck). * @param _salt The salt. */ function createCounterfactualWallet( address _owner, address[] calldata _modules, string calldata _label, bytes32 _salt ) external onlyManager { _validateInputs(_owner, _modules); // create the salt bytes32 newsalt = _newSalt(_salt, _owner, _modules); bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(walletImplementation)); address payable wallet; // solium-disable-next-line security/no-inline-assembly assembly { wallet := create2(0, add(code, 0x20), mload(code), newsalt) if iszero(extcodesize(wallet)) { revert(0, returndatasize) } } // check for ENS bytes memory labelBytes = bytes(_label); if (labelBytes.length != 0) { // add the factory to the modules so it can claim the reverse ENS 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 BaseWallet(wallet).init(_owner, extendedModules); // register ENS registerWalletENS(wallet, _label); // remove the factory from the authorised modules BaseWallet(wallet).authoriseModule(address(this), false); } else { // initialise the wallet with the owner and the modules BaseWallet(wallet).init(_owner, _modules); } emit WalletCreated(wallet, _owner); } /** * @dev Throws if the owner and the modules are not valid. * @param _owner The owner address. * @param _modules The list of modules. */ function _validateInputs(address _owner, address[] memory _modules) internal view { require(_owner != address(0), "WF: owner cannot be null"); require(_modules.length > 0, "WF: cannot assign with less than 1 module"); require(ModuleRegistry(moduleRegistry).isRegisteredModule(_modules), "WF: one or more modules are not registered"); } /** * @dev Generates a new salt based on a provided salt, an owner and a list of modules. * @param _salt The slat provided. * @param _owner The owner address. * @param _modules The list of modules. */ function _newSalt(bytes32 _salt, address _owner, address[] memory _modules) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_salt, _owner, _modules)); } /** * @dev Lets the owner change the address of the module registry contract. * @param _moduleRegistry The address of the module registry contract. */ function changeModuleRegistry(address _moduleRegistry) external onlyOwner { require(_moduleRegistry != address(0), "WF: address cannot be null"); moduleRegistry = _moduleRegistry; emit ModuleRegistryChanged(_moduleRegistry); } /** * @dev Lets the owner change the address of the implementing contract. * @param _walletImplementation The address of the implementing contract. */ function changeWalletImplementation(address _walletImplementation) external onlyOwner { require(_walletImplementation != address(0), "WF: address cannot be null"); walletImplementation = _walletImplementation; emit WalletImplementationChanged(_walletImplementation); } /** * @dev Lets the owner change the address of the ENS manager contract. * @param _ensManager The address of the ENS manager contract. */ function changeENSManager(address _ensManager) external onlyOwner { require(_ensManager != address(0), "WF: address cannot be null"); ensManager = _ensManager; emit ENSManagerChanged(_ensManager); } /** * @dev Lets the owner change the address of the ENS resolver contract. * @param _ensResolver The address of the ENS resolver contract. */ function changeENSResolver(address _ensResolver) external onlyOwner { require(_ensResolver != address(0), "WF: address cannot be null"); ensResolver = _ensResolver; emit ENSResolverChanged(_ensResolver); } /** * @dev Register an ENS subname to a wallet. * @param _wallet The wallet address. * @param _label ENS label of the new wallet (e.g. franck). */ function registerWalletENS(address payable _wallet, string memory _label) internal { // claim reverse bytes memory methodData = abi.encodeWithSignature("claimWithResolver(address,address)", ensManager, ensResolver); BaseWallet(_wallet).invoke(address(getENSReverseRegistrar()), 0, methodData); // register with ENS manager IENSManager(ensManager).register(_label, _wallet); } /** * @dev Inits the module for a wallet by logging an event. * The method can only be called by the wallet itself. * @param _wallet The wallet. */ function init(BaseWallet _wallet) external pure { //do nothing } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"_moduleRegistry","type":"address"}],"name":"changeModuleRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getENSReverseRegistrar","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_wallet","type":"address"}],"name":"init","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"}],"name":"addManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getENSRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_modules","type":"address[]"},{"name":"_label","type":"string"},{"name":"_salt","type":"bytes32"}],"name":"createCounterfactualWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"}],"name":"revokeManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ensManager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ADDR_REVERSE_NODE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"walletImplementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_ensManager","type":"address"}],"name":"changeENSManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_node","type":"bytes32"}],"name":"resolveEns","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ensResolver","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_modules","type":"address[]"},{"name":"_label","type":"string"}],"name":"createWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"moduleRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_modules","type":"address[]"},{"name":"_salt","type":"bytes32"}],"name":"getAddressForCounterfactualWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_walletImplementation","type":"address"}],"name":"changeWalletImplementation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_ensResolver","type":"address"}],"name":"changeENSResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"managers","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_ensRegistry","type":"address"},{"name":"_moduleRegistry","type":"address"},{"name":"_walletImplementation","type":"address"},{"name":"_ensManager","type":"address"},{"name":"_ensResolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"ModuleRegistryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"WalletImplementationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"ENSManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"ENSResolverChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_wallet","type":"address"},{"indexed":true,"name":"_owner","type":"address"}],"name":"WalletCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_manager","type":"address"}],"name":"ManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_manager","type":"address"}],"name":"ManagerRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_newOwner","type":"address"}],"name":"OwnerChanged","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405160a080612189833981018060405260a081101561003057600080fd5b50805160208201516040830151606084015160809094015160008054600160a060020a0319908116331790915560028054600160a060020a03968716908316179055600380549486169482169490941790935560048054928516928416929092179091556005805494841694831694909417909355600680549290931691161790556120c8806100c16000396000f3fe608060405234801561001057600080fd5b506004361061013b5760003560e060020a900480638da5cb5b116100bc578063aff1857511610080578063aff185751461037b578063b95459e41461044d578063b97ccf2f14610455578063c799cd11146104d5578063fb419999146104fb578063fdff9b4d146105215761013b565b80638da5cb5b1461030257806390ed991c1461030a5780639eb869c714610330578063a6f9dae11461034d578063adce1c5f146103735761013b565b8063350aaa9a11610103578063350aaa9a146101e0578063377e32e6146102b25780635a6971f9146102d85780637cf8a2eb146102e05780638117abc1146102fa5761013b565b806308d668bc1461014057806309d734421461016857806319ab453c1461018c5780632d06177a146101b25780632f680795146101d8575b600080fd5b6101666004803603602081101561015657600080fd5b5035600160a060020a031661055b565b005b61017061065a565b60408051600160a060020a039092168252519081900360200190f35b610166600480360360208110156101a257600080fd5b5035600160a060020a03166106fe565b610166600480360360208110156101c857600080fd5b5035600160a060020a0316610701565b610170610822565b610166600480360360808110156101f657600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561022157600080fd5b82018360208201111561023357600080fd5b8035906020019184602083028401116401000000008311171561025557600080fd5b91939092909160208101903564010000000081111561027357600080fd5b82018360208201111561028557600080fd5b803590602001918460018302840111640100000000831117156102a757600080fd5b919350915035610831565b610166600480360360208110156102c857600080fd5b5035600160a060020a0316610d41565b610170610e3a565b6102e8610e49565b60408051918252519081900360200190f35b610170610e6d565b610170610e7c565b6101666004803603602081101561032057600080fd5b5035600160a060020a0316610e8b565b6101706004803603602081101561034657600080fd5b5035610f8a565b6101666004803603602081101561036357600080fd5b5035600160a060020a031661109e565b6101706111a3565b6101666004803603606081101561039157600080fd5b600160a060020a0382351691908101906040810160208201356401000000008111156103bc57600080fd5b8201836020820111156103ce57600080fd5b803590602001918460208302840111640100000000831117156103f057600080fd5b91939092909160208101903564010000000081111561040e57600080fd5b82018360208201111561042057600080fd5b8035906020019184600183028401116401000000008311171561044257600080fd5b5090925090506111b2565b610170611622565b6101706004803603606081101561046b57600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460208302840111640100000000831117156104ca57600080fd5b919350915035611631565b610166600480360360208110156104eb57600080fd5b5035600160a060020a031661177f565b6101666004803603602081101561051157600080fd5b5035600160a060020a031661187e565b6105476004803603602081101561053757600080fd5b5035600160a060020a031661197d565b604080519115158252519081900360200190f35b600054600160a060020a031633146105ab576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811615156105f9576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60038054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f9bf4baeb20b6008af8dfd7fed5c50dce707a05623b022e5d61a00c7db7f90c729181900360200190a150565b6000610664610822565b600160a060020a03166302571be37f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26001026040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b1580156106cd57600080fd5b505afa1580156106e1573d6000803e3d6000fd5b505050506040513d60208110156106f757600080fd5b5051905090565b50565b600054600160a060020a03163314610751576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811615156107b1576040805160e560020a62461bcd02815260206004820152601b60248201527f4d3a2041646472657373206d757374206e6f74206265206e756c6c0000000000604482015290519081900360640190fd5b600160a060020a03811660009081526001602052604090205460ff1615156106fe57600160a060020a0381166000818152600160208190526040808320805460ff1916909217909155517f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a9190a250565b600254600160a060020a031690565b3360009081526001602081905260409091205460ff1615151461089e576040805160e560020a62461bcd02815260206004820152601260248201527f4d3a204d757374206265206d616e616765720000000000000000000000000000604482015290519081900360640190fd5b6108db8686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061199292505050565b600061091b8288888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611b4292505050565b905060606040518060200161092f90611e90565b601f1982820381018352601f9091011660408190526004548251600160a060020a039091169160209081019182918501908083835b602083106109835780518252601f199092019160209182019101610964565b51815160209384036101000a6000190180199092169116179052920193845250604080518085038152938201905282519294506000935085929150840183f59050803b15156109d1573d6000fd5b606086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505090159050610c42576040805160018a0180825260208082028301019092526060918015610a44578160200160208202803883390190505b50905030816000815181101515610a5757fe5b600160a060020a0390921660209283029091019091015260005b89811015610ac5578a8a82818110610a8557fe5b90506020020135600160a060020a03168282600101815181101515610aa657fe5b600160a060020a03909216602092830290910190910152600101610a71565b5082600160a060020a0316633c5a3cea8c836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015610b41578181015183820152602001610b29565b505050509050019350505050600060405180830381600087803b158015610b6757600080fd5b505af1158015610b7b573d6000803e3d6000fd5b50505050610bbf8389898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcf92505050565b604080517f1f17732d0000000000000000000000000000000000000000000000000000000081523060048201526000602482018190529151600160a060020a03861692631f17732d926044808201939182900301818387803b158015610c2457600080fd5b505af1158015610c38573d6000803e3d6000fd5b5050505050610cf5565b604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038c81166004830190815260248301938452604483018c905290851692633c5a3cea928e928e928e92606401846020850280828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b158015610cdc57600080fd5b505af1158015610cf0573d6000803e3d6000fd5b505050505b89600160a060020a031682600160a060020a03167f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f08160405160405180910390a350505050505050505050565b600054600160a060020a03163314610d91576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811660009081526001602081905260409091205460ff16151514610df15760405160e560020a62461bcd028152600401808060200182810382526025815260200180611fe56025913960400191505060405180910390fd5b600160a060020a038116600081815260016020526040808220805460ff19169055517fe5def11e0516f317f9c37b8835aec29fc01db4d4b6d6fecaca339d3596a29bc19190a250565b600554600160a060020a031681565b7f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e281565b600454600160a060020a031681565b600054600160a060020a031681565b600054600160a060020a03163314610edb576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a0381161515610f29576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60058054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f5b22021f5b1f5f8a744edb1f20f667875f22a1b29c4d9a46418ee25110c76cb89181900360200190a150565b600080610f95610822565b600160a060020a0316630178b8bf846040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b158015610fdb57600080fd5b505afa158015610fef573d6000803e3d6000fd5b505050506040513d602081101561100557600080fd5b5051604080517f3b3b57de000000000000000000000000000000000000000000000000000000008152600481018690529051919250600160a060020a03831691633b3b57de91602480820192602092909190829003018186803b15801561106b57600080fd5b505afa15801561107f573d6000803e3d6000fd5b505050506040513d602081101561109557600080fd5b50519392505050565b600054600160a060020a031633146110ee576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561114e576040805160e560020a62461bcd02815260206004820152601860248201527f41646472657373206d757374206e6f74206265206e756c6c0000000000000000604482015290519081900360640190fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038316908117825560405190917fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3691a250565b600654600160a060020a031681565b3360009081526001602081905260409091205460ff1615151461121f576040805160e560020a62461bcd02815260206004820152601260248201527f4d3a204d757374206265206d616e616765720000000000000000000000000000604482015290519081900360640190fd5b61125c8585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061199292505050565b600454604051600091600160a060020a03169061127890611e90565b600160a060020a03909116815260405190819003602001906000f0801580156112a5573d6000803e3d6000fd5b5090506000819050606084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508251929350509015905061152557604080516001880180825260208082028301019092526060918015611320578160200160208202803883390190505b5090503081600081518110151561133357fe5b600160a060020a0390921660209283029091019091015260005b878110156113a15788888281811061136157fe5b90506020020135600160a060020a0316828260010181518110151561138257fe5b600160a060020a0390921660209283029091019091015260010161134d565b50604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081526024830193845284516044840152845191871693633c5a3cea938e9387939291606401906020808601910280838360005b8381101561142457818101518382015260200161140c565b505050509050019350505050600060405180830381600087803b15801561144a57600080fd5b505af115801561145e573d6000803e3d6000fd5b505050506114a28387878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcf92505050565b604080517f1f17732d0000000000000000000000000000000000000000000000000000000081523060048201526000602482018190529151600160a060020a03861692631f17732d926044808201939182900301818387803b15801561150757600080fd5b505af115801561151b573d6000803e3d6000fd5b50505050506115d8565b604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830190815260248301938452604483018a905290851692633c5a3cea928c928c928c92606401846020850280828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b1580156115bf57600080fd5b505af11580156115d3573d6000803e3d6000fd5b505050505b87600160a060020a031682600160a060020a03167f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f08160405160405180910390a35050505050505050565b600354600160a060020a031681565b6000806116728387878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611b4292505050565b905060606040518060200161168690611e90565b601f1982820381018352601f9091011660408190526004548251600160a060020a039091169160209081019182918501908083835b602083106116da5780518252601f1990920191602091820191016116bb565b51815160209384036101000a600019018019909216911617905292019384525060408051808503815284830182528051908301207fff0000000000000000000000000000000000000000000000000000000000000082860152306c010000000000000000000000000260418601526055850197909752607580850197909752805180850390970187526095909301909252508351930192909220979650505050505050565b600054600160a060020a031633146117cf576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561181d576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60048054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f06b03978f7966b1fbddfcf29d0c63594e116380be51c99e25506cbc85d5bb1a19181900360200190a150565b600054600160a060020a031633146118ce576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561191c576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60068054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f8bd878c65101d815c50829c7b19270ff5c19e91bd1ad6ebaa282c4a65a5baa5f9181900360200190a150565b60016020526000908152604090205460ff1681565b600160a060020a03821615156119f2576040805160e560020a62461bcd02815260206004820152601860248201527f57463a206f776e65722063616e6e6f74206265206e756c6c0000000000000000604482015290519081900360640190fd5b8051600010611a355760405160e560020a62461bcd0281526004018080602001828103825260298152602001806120546029913960400191505060405180910390fd5b6003546040517f6bb18a54000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451600160a060020a0390941693636bb18a549386938392604490920191818601910280838360005b83811015611aaf578181015183820152602001611a97565b505050509050019250505060206040518083038186803b158015611ad257600080fd5b505afa158015611ae6573d6000803e3d6000fd5b505050506040513d6020811015611afc57600080fd5b50511515611b3e5760405160e560020a62461bcd02815260040180806020018281038252602a81526020018061200a602a913960400191505060405180910390fd5b5050565b60008383836040516020018084815260200183600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401828051906020019060200280838360005b83811015611ba4578181015183820152602001611b8c565b5050505090500193505050506040516020818303038152906040528051906020012090509392505050565b60055460065460408051600160a060020a03938416602482015291831660448084019190915281518084039091018152606490920190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0f5a546600000000000000000000000000000000000000000000000000000000179052908316638f6f0332611c5e61065a565b6000846040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611cce578181015183820152602001611cb6565b50505050905090810190601f168015611cfb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d1c57600080fd5b505af1158015611d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611d5957600080fd5b810190808051640100000000811115611d7157600080fd5b82016020810184811115611d8457600080fd5b8151640100000000811182820187101715611d9e57600080fd5b5050600554604080517f1e59c529000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660248301526004820192835289516044830152895193169650631e59c52995508894508993509091829160640190602086019080838360005b83811015611e26578181015183820152602001611e0e565b50505050905090810190601f168015611e535780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611e7357600080fd5b505af1158015611e87573d6000803e3d6000fd5b50505050505050565b61014780611e9e8339019056fe608060405234801561001057600080fd5b506040516020806101478339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a031990921691909117905560e6806100616000396000f3fe60806040523615801560115750600034115b156092573373ffffffffffffffffffffffffffffffffffffffff16347f606834f57405380c4fb88d1f4850326ad3885f014bab3b568dfbf7a041eef73860003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a360b8565b6000543660008037600080366000845af43d6000803e80801560b3573d6000f35b3d6000fd5b00fea165627a7a72305820e854f651916eca83c7706547ec8ad57ff7b894e3b683d0a5631d181baa718cf800294d3a20546172676574206d75737420626520616e206578697374696e67206d616e6167657257463a206f6e65206f72206d6f7265206d6f64756c657320617265206e6f7420726567697374657265644d757374206265206f776e65720000000000000000000000000000000000000057463a2063616e6e6f742061737369676e2077697468206c657373207468616e2031206d6f64756c6557463a20616464726573732063616e6e6f74206265206e756c6c000000000000a165627a7a7230582052a0317929288aa13f9b5ac288b8ac823e6e3acfc1a99344e3aba98c3938563d00290000000000000000000000003a013728cfcebaa433783a964408b3042e6ee065000000000000000000000000f8617805d3f9857f0be84d86a277eca815c13998000000000000000000000000811a7f70d12fbd29ec494edc75645e66f5fcccfc000000000000000000000000493faa052c622270192de1c68c3b988ca7b5100000000000000000000000000082ce4bad674d8d313f639d8f97bb2d43a1488248
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061013b5760003560e060020a900480638da5cb5b116100bc578063aff1857511610080578063aff185751461037b578063b95459e41461044d578063b97ccf2f14610455578063c799cd11146104d5578063fb419999146104fb578063fdff9b4d146105215761013b565b80638da5cb5b1461030257806390ed991c1461030a5780639eb869c714610330578063a6f9dae11461034d578063adce1c5f146103735761013b565b8063350aaa9a11610103578063350aaa9a146101e0578063377e32e6146102b25780635a6971f9146102d85780637cf8a2eb146102e05780638117abc1146102fa5761013b565b806308d668bc1461014057806309d734421461016857806319ab453c1461018c5780632d06177a146101b25780632f680795146101d8575b600080fd5b6101666004803603602081101561015657600080fd5b5035600160a060020a031661055b565b005b61017061065a565b60408051600160a060020a039092168252519081900360200190f35b610166600480360360208110156101a257600080fd5b5035600160a060020a03166106fe565b610166600480360360208110156101c857600080fd5b5035600160a060020a0316610701565b610170610822565b610166600480360360808110156101f657600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561022157600080fd5b82018360208201111561023357600080fd5b8035906020019184602083028401116401000000008311171561025557600080fd5b91939092909160208101903564010000000081111561027357600080fd5b82018360208201111561028557600080fd5b803590602001918460018302840111640100000000831117156102a757600080fd5b919350915035610831565b610166600480360360208110156102c857600080fd5b5035600160a060020a0316610d41565b610170610e3a565b6102e8610e49565b60408051918252519081900360200190f35b610170610e6d565b610170610e7c565b6101666004803603602081101561032057600080fd5b5035600160a060020a0316610e8b565b6101706004803603602081101561034657600080fd5b5035610f8a565b6101666004803603602081101561036357600080fd5b5035600160a060020a031661109e565b6101706111a3565b6101666004803603606081101561039157600080fd5b600160a060020a0382351691908101906040810160208201356401000000008111156103bc57600080fd5b8201836020820111156103ce57600080fd5b803590602001918460208302840111640100000000831117156103f057600080fd5b91939092909160208101903564010000000081111561040e57600080fd5b82018360208201111561042057600080fd5b8035906020019184600183028401116401000000008311171561044257600080fd5b5090925090506111b2565b610170611622565b6101706004803603606081101561046b57600080fd5b600160a060020a03823516919081019060408101602082013564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460208302840111640100000000831117156104ca57600080fd5b919350915035611631565b610166600480360360208110156104eb57600080fd5b5035600160a060020a031661177f565b6101666004803603602081101561051157600080fd5b5035600160a060020a031661187e565b6105476004803603602081101561053757600080fd5b5035600160a060020a031661197d565b604080519115158252519081900360200190f35b600054600160a060020a031633146105ab576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811615156105f9576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60038054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f9bf4baeb20b6008af8dfd7fed5c50dce707a05623b022e5d61a00c7db7f90c729181900360200190a150565b6000610664610822565b600160a060020a03166302571be37f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26001026040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b1580156106cd57600080fd5b505afa1580156106e1573d6000803e3d6000fd5b505050506040513d60208110156106f757600080fd5b5051905090565b50565b600054600160a060020a03163314610751576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811615156107b1576040805160e560020a62461bcd02815260206004820152601b60248201527f4d3a2041646472657373206d757374206e6f74206265206e756c6c0000000000604482015290519081900360640190fd5b600160a060020a03811660009081526001602052604090205460ff1615156106fe57600160a060020a0381166000818152600160208190526040808320805460ff1916909217909155517f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a9190a250565b600254600160a060020a031690565b3360009081526001602081905260409091205460ff1615151461089e576040805160e560020a62461bcd02815260206004820152601260248201527f4d3a204d757374206265206d616e616765720000000000000000000000000000604482015290519081900360640190fd5b6108db8686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061199292505050565b600061091b8288888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611b4292505050565b905060606040518060200161092f90611e90565b601f1982820381018352601f9091011660408190526004548251600160a060020a039091169160209081019182918501908083835b602083106109835780518252601f199092019160209182019101610964565b51815160209384036101000a6000190180199092169116179052920193845250604080518085038152938201905282519294506000935085929150840183f59050803b15156109d1573d6000fd5b606086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505090159050610c42576040805160018a0180825260208082028301019092526060918015610a44578160200160208202803883390190505b50905030816000815181101515610a5757fe5b600160a060020a0390921660209283029091019091015260005b89811015610ac5578a8a82818110610a8557fe5b90506020020135600160a060020a03168282600101815181101515610aa657fe5b600160a060020a03909216602092830290910190910152600101610a71565b5082600160a060020a0316633c5a3cea8c836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015610b41578181015183820152602001610b29565b505050509050019350505050600060405180830381600087803b158015610b6757600080fd5b505af1158015610b7b573d6000803e3d6000fd5b50505050610bbf8389898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcf92505050565b604080517f1f17732d0000000000000000000000000000000000000000000000000000000081523060048201526000602482018190529151600160a060020a03861692631f17732d926044808201939182900301818387803b158015610c2457600080fd5b505af1158015610c38573d6000803e3d6000fd5b5050505050610cf5565b604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038c81166004830190815260248301938452604483018c905290851692633c5a3cea928e928e928e92606401846020850280828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b158015610cdc57600080fd5b505af1158015610cf0573d6000803e3d6000fd5b505050505b89600160a060020a031682600160a060020a03167f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f08160405160405180910390a350505050505050505050565b600054600160a060020a03163314610d91576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a03811660009081526001602081905260409091205460ff16151514610df15760405160e560020a62461bcd028152600401808060200182810382526025815260200180611fe56025913960400191505060405180910390fd5b600160a060020a038116600081815260016020526040808220805460ff19169055517fe5def11e0516f317f9c37b8835aec29fc01db4d4b6d6fecaca339d3596a29bc19190a250565b600554600160a060020a031681565b7f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e281565b600454600160a060020a031681565b600054600160a060020a031681565b600054600160a060020a03163314610edb576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a0381161515610f29576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60058054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f5b22021f5b1f5f8a744edb1f20f667875f22a1b29c4d9a46418ee25110c76cb89181900360200190a150565b600080610f95610822565b600160a060020a0316630178b8bf846040518263ffffffff1660e060020a0281526004018082815260200191505060206040518083038186803b158015610fdb57600080fd5b505afa158015610fef573d6000803e3d6000fd5b505050506040513d602081101561100557600080fd5b5051604080517f3b3b57de000000000000000000000000000000000000000000000000000000008152600481018690529051919250600160a060020a03831691633b3b57de91602480820192602092909190829003018186803b15801561106b57600080fd5b505afa15801561107f573d6000803e3d6000fd5b505050506040513d602081101561109557600080fd5b50519392505050565b600054600160a060020a031633146110ee576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561114e576040805160e560020a62461bcd02815260206004820152601860248201527f41646472657373206d757374206e6f74206265206e756c6c0000000000000000604482015290519081900360640190fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038316908117825560405190917fa2ea9883a321a3e97b8266c2b078bfeec6d50c711ed71f874a90d500ae2eaf3691a250565b600654600160a060020a031681565b3360009081526001602081905260409091205460ff1615151461121f576040805160e560020a62461bcd02815260206004820152601260248201527f4d3a204d757374206265206d616e616765720000000000000000000000000000604482015290519081900360640190fd5b61125c8585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061199292505050565b600454604051600091600160a060020a03169061127890611e90565b600160a060020a03909116815260405190819003602001906000f0801580156112a5573d6000803e3d6000fd5b5090506000819050606084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508251929350509015905061152557604080516001880180825260208082028301019092526060918015611320578160200160208202803883390190505b5090503081600081518110151561133357fe5b600160a060020a0390921660209283029091019091015260005b878110156113a15788888281811061136157fe5b90506020020135600160a060020a0316828260010181518110151561138257fe5b600160a060020a0390921660209283029091019091015260010161134d565b50604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081526024830193845284516044840152845191871693633c5a3cea938e9387939291606401906020808601910280838360005b8381101561142457818101518382015260200161140c565b505050509050019350505050600060405180830381600087803b15801561144a57600080fd5b505af115801561145e573d6000803e3d6000fd5b505050506114a28387878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcf92505050565b604080517f1f17732d0000000000000000000000000000000000000000000000000000000081523060048201526000602482018190529151600160a060020a03861692631f17732d926044808201939182900301818387803b15801561150757600080fd5b505af115801561151b573d6000803e3d6000fd5b50505050506115d8565b604080517f3c5a3cea000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830190815260248301938452604483018a905290851692633c5a3cea928c928c928c92606401846020850280828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b1580156115bf57600080fd5b505af11580156115d3573d6000803e3d6000fd5b505050505b87600160a060020a031682600160a060020a03167f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f08160405160405180910390a35050505050505050565b600354600160a060020a031681565b6000806116728387878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611b4292505050565b905060606040518060200161168690611e90565b601f1982820381018352601f9091011660408190526004548251600160a060020a039091169160209081019182918501908083835b602083106116da5780518252601f1990920191602091820191016116bb565b51815160209384036101000a600019018019909216911617905292019384525060408051808503815284830182528051908301207fff0000000000000000000000000000000000000000000000000000000000000082860152306c010000000000000000000000000260418601526055850197909752607580850197909752805180850390970187526095909301909252508351930192909220979650505050505050565b600054600160a060020a031633146117cf576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561181d576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60048054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f06b03978f7966b1fbddfcf29d0c63594e116380be51c99e25506cbc85d5bb1a19181900360200190a150565b600054600160a060020a031633146118ce576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020612034833981519152604482015290519081900360640190fd5b600160a060020a038116151561191c576040805160e560020a62461bcd02815260206004820152601a602482015260008051602061207d833981519152604482015290519081900360640190fd5b60068054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f8bd878c65101d815c50829c7b19270ff5c19e91bd1ad6ebaa282c4a65a5baa5f9181900360200190a150565b60016020526000908152604090205460ff1681565b600160a060020a03821615156119f2576040805160e560020a62461bcd02815260206004820152601860248201527f57463a206f776e65722063616e6e6f74206265206e756c6c0000000000000000604482015290519081900360640190fd5b8051600010611a355760405160e560020a62461bcd0281526004018080602001828103825260298152602001806120546029913960400191505060405180910390fd5b6003546040517f6bb18a54000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451600160a060020a0390941693636bb18a549386938392604490920191818601910280838360005b83811015611aaf578181015183820152602001611a97565b505050509050019250505060206040518083038186803b158015611ad257600080fd5b505afa158015611ae6573d6000803e3d6000fd5b505050506040513d6020811015611afc57600080fd5b50511515611b3e5760405160e560020a62461bcd02815260040180806020018281038252602a81526020018061200a602a913960400191505060405180910390fd5b5050565b60008383836040516020018084815260200183600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401828051906020019060200280838360005b83811015611ba4578181015183820152602001611b8c565b5050505090500193505050506040516020818303038152906040528051906020012090509392505050565b60055460065460408051600160a060020a03938416602482015291831660448084019190915281518084039091018152606490920190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0f5a546600000000000000000000000000000000000000000000000000000000179052908316638f6f0332611c5e61065a565b6000846040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611cce578181015183820152602001611cb6565b50505050905090810190601f168015611cfb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d1c57600080fd5b505af1158015611d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611d5957600080fd5b810190808051640100000000811115611d7157600080fd5b82016020810184811115611d8457600080fd5b8151640100000000811182820187101715611d9e57600080fd5b5050600554604080517f1e59c529000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660248301526004820192835289516044830152895193169650631e59c52995508894508993509091829160640190602086019080838360005b83811015611e26578181015183820152602001611e0e565b50505050905090810190601f168015611e535780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611e7357600080fd5b505af1158015611e87573d6000803e3d6000fd5b50505050505050565b61014780611e9e8339019056fe608060405234801561001057600080fd5b506040516020806101478339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a031990921691909117905560e6806100616000396000f3fe60806040523615801560115750600034115b156092573373ffffffffffffffffffffffffffffffffffffffff16347f606834f57405380c4fb88d1f4850326ad3885f014bab3b568dfbf7a041eef73860003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a360b8565b6000543660008037600080366000845af43d6000803e80801560b3573d6000f35b3d6000fd5b00fea165627a7a72305820e854f651916eca83c7706547ec8ad57ff7b894e3b683d0a5631d181baa718cf800294d3a20546172676574206d75737420626520616e206578697374696e67206d616e6167657257463a206f6e65206f72206d6f7265206d6f64756c657320617265206e6f7420726567697374657265644d757374206265206f776e65720000000000000000000000000000000000000057463a2063616e6e6f742061737369676e2077697468206c657373207468616e2031206d6f64756c6557463a20616464726573732063616e6e6f74206265206e756c6c000000000000a165627a7a7230582052a0317929288aa13f9b5ac288b8ac823e6e3acfc1a99344e3aba98c3938563d0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003a013728cfcebaa433783a964408b3042e6ee065000000000000000000000000f8617805d3f9857f0be84d86a277eca815c13998000000000000000000000000811a7f70d12fbd29ec494edc75645e66f5fcccfc000000000000000000000000493faa052c622270192de1c68c3b988ca7b5100000000000000000000000000082ce4bad674d8d313f639d8f97bb2d43a1488248
-----Decoded View---------------
Arg [0] : _ensRegistry (address): 0x3a013728cFCEbaA433783A964408B3042E6EE065
Arg [1] : _moduleRegistry (address): 0xf8617805d3f9857f0Be84D86a277eca815C13998
Arg [2] : _walletImplementation (address): 0x811A7F70d12fbd29Ec494eDc75645E66f5fCcCFc
Arg [3] : _ensManager (address): 0x493fAa052C622270192dE1C68C3B988Ca7b51000
Arg [4] : _ensResolver (address): 0x82cE4baD674D8D313f639d8F97Bb2d43a1488248
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000003a013728cfcebaa433783a964408b3042e6ee065
Arg [1] : 000000000000000000000000f8617805d3f9857f0be84d86a277eca815c13998
Arg [2] : 000000000000000000000000811a7f70d12fbd29ec494edc75645e66f5fcccfc
Arg [3] : 000000000000000000000000493faa052c622270192de1c68c3b988ca7b51000
Arg [4] : 00000000000000000000000082ce4bad674d8d313f639d8f97bb2d43a1488248
Deployed Bytecode Sourcemap
48124:9553:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48124:9553:0;;;;;;;;-1:-1:-1;;;48124:9553:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55252:258;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55252:258:0;-1:-1:-1;;;;;55252:258:0;;:::i;:::-;;38437:164;;;:::i;:::-;;;;-1:-1:-1;;;;;38437:164:0;;;;;;;;;;;;;;57596:78;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57596:78:0;-1:-1:-1;;;;;57596:78:0;;:::i;9202:282::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9202:282:0;-1:-1:-1;;;;;9202:282:0;;:::i;38248:110::-;;;:::i;52363:1734::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;52363:1734:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;52363:1734:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;52363:1734:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;52363:1734:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;52363:1734:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;52363:1734:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;52363:1734:0;;-1:-1:-1;52363:1734:0;-1:-1:-1;52363:1734:0;;:::i;9591:231::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9591:231:0;-1:-1:-1;;;;;9591:231:0;;:::i;48402:25::-;;;:::i;37437:110::-;;;:::i;:::-;;;;;;;;;;;;;;;;48321:35;;;:::i;7862:20::-;;;:::i;56162:230::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56162:230:0;-1:-1:-1;;;;;56162:230:0;;:::i;37993:186::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37993:186:0;;:::i;8321:205::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8321:205:0;-1:-1:-1;;;;;8321:205:0;;:::i;48474:26::-;;;:::i;49752:1338::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;49752:1338:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;49752:1338:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49752:1338:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;49752:1338:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;49752:1338:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49752:1338:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;49752:1338:0;;-1:-1:-1;49752:1338:0;-1:-1:-1;49752:1338:0;:::i;48231:29::-;;;:::i;51405:532::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;51405:532:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;51405:532:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;51405:532:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;51405:532:0;;-1:-1:-1;51405:532:0;-1:-1:-1;51405:532:0;;:::i;55692:300::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55692:300:0;-1:-1:-1;;;;;55692:300:0;;:::i;56565:237::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56565:237:0;-1:-1:-1;;;;;56565:237:0;;:::i;8760:41::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8760:41:0;-1:-1:-1;;;;;8760:41:0;;:::i;:::-;;;;;;;;;;;;;;;;;;55252:258;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;55345:29:0;;;;55337:68;;;;;-1:-1:-1;;;;;55337:68:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;55337:68:0;;;;;;;;;;;;;;;55416:14;:32;;-1:-1:-1;;;;;55416:32:0;;-1:-1:-1;;55416:32:0;;;;;;;;55464:38;;;;;;;;;;;;;;;;55252:258;:::o;38437:164::-;38492:19;38551:16;:14;:16::i;:::-;-1:-1:-1;;;;;38551:22:0;;37481:66;38574:17;;38551:41;;;;;-1:-1:-1;;;38551:41:0;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38551:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38551:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38551:41:0;;-1:-1:-1;38437:164:0;:::o;57596:78::-;;:::o;9202:282::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;9278:22:0;;;;9270:62;;;;;-1:-1:-1;;;;;9270:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9346:18:0;;;;;;:8;:18;;;;;;;;:27;;9343:126;;-1:-1:-1;;;;;9390:18:0;;;;;;9411:4;9390:18;;;;;;;;:25;;-1:-1:-1;;9390:25:0;;;;;;;9435:22;;;9390:18;9435:22;9202:282;:::o;38248:110::-;38338:11;;-1:-1:-1;;;;;38338:11:0;38248:110;:::o;52363:1734::-;8929:10;8920:20;;;;:8;:20;;;;;;;;;;;:28;;;8912:59;;;;;-1:-1:-1;;;;;8912:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52581:33;52597:6;52605:8;;52581:33;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;52581:15:0;;-1:-1:-1;;;52581:33:0:i;:::-;52653:15;52671:33;52680:5;52687:6;52695:8;;52671:33;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;52671:8:0;;-1:-1:-1;;;52671:33:0:i;:::-;52653:51;;52715:17;52752:24;;;;;;;;:::i;:::-;-1:-1:-1;;21:26;;;;;7:41;;87:2;69:12;;;65:26;61:2;54:38;;;52786:20:0;;52735:73;;-1:-1:-1;;;;;52786:20:0;;;;41:4:-1;52735:73:0;;;;;;30:16:-1;;;52735:73:0;;30:16:-1;36:153;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;52735:73:0;;;;;-1:-1:-1;52735:73:0;;;26:21:-1;;;6:49;;52735:73:0;;;;;52979:11;;52735:73;;-1:-1:-1;;;;52992:7:0;;52979:11;-1:-1:-1;52962:15:0;;-1:-1:-1;52951:49:0;52941:59;;53036:6;53024:19;53017:27;53014:2;;;53057:14;53054:1;53047:25;53014:2;53121:23;53153:6;;53121:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;53175:17:0;;53121:39;;-1:-1:-1;;53175:22:0;;;-1:-1:-1;53171:874:0;;53328:34;;;53360:1;53342:19;;53328:34;;;;;;;;;;;;;53293:32;;53328:34;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;53328:34:0;;53293:69;;53406:4;53377:15;53393:1;53377:18;;;;;;;;;;-1:-1:-1;;;;;53377:34:0;;;:18;;;;;;;;;;:34;53430:6;53426:113;53442:19;;;53426:113;;;53512:8;;53521:1;53512:11;;;;;;;;;;;;;-1:-1:-1;;;;;53512:11:0;53487:15;53503:1;53507;53503:5;53487:22;;;;;;;;;;-1:-1:-1;;;;;53487:36:0;;;:22;;;;;;;;;;:36;53463:3;;53426:113;;;;53642:6;-1:-1:-1;;;;;53631:23:0;;53655:6;53663:15;53631:48;;;;;-1:-1:-1;;;53631:48:0;;;;;;;-1:-1:-1;;;;;53631:48:0;-1:-1:-1;;;;;53631:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;53631:48:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53631:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53631:48:0;;;;53723:33;53741:6;53749;;53723:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;53723:17:0;;-1:-1:-1;;;53723:33:0:i;:::-;53834:56;;;;;;53877:4;53834:56;;;;53884:5;53834:56;;;;;;;;-1:-1:-1;;;;;53834:34:0;;;;;:56;;;;;;;;;;;53884:5;53834:34;:56;;;5:2:-1;;;;30:1;27;20:12;5:2;53834:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53834:56:0;;;;53171:874;;;;53992:41;;;;;;-1:-1:-1;;;;;53992:41:0;;;;;;;;;;;;;;;;;;;;;:23;;;;;;54016:6;;54024:8;;;;53992:41;;54024:8;53992:41;;;;54024:8;53992:41;1:33:-1;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;53992:41:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53992:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53992:41:0;;;;53171:874;54082:6;-1:-1:-1;;;;;54060:29:0;54074:6;-1:-1:-1;;;;;54060:29:0;;;;;;;;;;;8982:1;;;;52363:1734;;;;;;:::o;9591:231::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;9670:18:0;;;;;;:8;:18;;;;;;;;;;;:26;;;9662:76;;;;-1:-1:-1;;;;;9662:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9756:18:0;;;;;;:8;:18;;;;;;9749:25;;-1:-1:-1;;9749:25:0;;;9790:24;;;9756:18;9790:24;9591:231;:::o;48402:25::-;;;-1:-1:-1;;;;;48402:25:0;;:::o;37437:110::-;37481:66;37437:110;:::o;48321:35::-;;;-1:-1:-1;;;;;48321:35:0;;:::o;7862:20::-;;;-1:-1:-1;;;;;7862:20:0;;:::o;56162:230::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;56247:25:0;;;;56239:64;;;;;-1:-1:-1;;;;;56239:64:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56239:64:0;;;;;;;;;;;;;;;56314:10;:24;;-1:-1:-1;;;;;56314:24:0;;-1:-1:-1;;56314:24:0;;;;;;;;56354:30;;;;;;;;;;;;;;;;56162:230;:::o;37993:186::-;38049:7;38069:16;38088;:14;:16::i;:::-;-1:-1:-1;;;;;38088:25:0;;38114:5;38088:32;;;;;-1:-1:-1;;;38088:32:0;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38088:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38088:32:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38088:32:0;38138:33;;;;;;;;;;;;;;38088:32;;-1:-1:-1;;;;;;38138:26:0;;;;;:33;;;;;38088:32;;38138:33;;;;;;;;:26;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;38138:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38138:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38138:33:0;;37993:186;-1:-1:-1;;;37993:186:0:o;8321:205::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;8399:23:0;;;;8391:60;;;;;-1:-1:-1;;;;;8391:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8462:5;:17;;-1:-1:-1;;8462:17:0;-1:-1:-1;;;;;8462:17:0;;;;;;;8495:23;;8462:17;;8495:23;;;8321:205;:::o;48474:26::-;;;-1:-1:-1;;;;;48474:26:0;;:::o;49752:1338::-;8929:10;8920:20;;;;:8;:20;;;;;;;;;;;:28;;;8912:59;;;;;-1:-1:-1;;;;;8912:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49909:33;49925:6;49933:8;;49909:33;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;49909:15:0;;-1:-1:-1;;;49909:33:0:i;:::-;50006:20;;49996:31;;49982:11;;-1:-1:-1;;;;;50006:20:0;;49996:31;;;:::i;:::-;-1:-1:-1;;;;;49996:31:0;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49996:31:0;49982:45;;50038:22;50071:5;50038:39;;50114:23;50146:6;;50114:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;50168:17:0;;50114:39;;-1:-1:-1;;50168:22:0;;;-1:-1:-1;50164:874:0;;50321:34;;;50353:1;50335:19;;50321:34;;;;;;;;;;;;;50286:32;;50321:34;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;50321:34:0;;50286:69;;50399:4;50370:15;50386:1;50370:18;;;;;;;;;;-1:-1:-1;;;;;50370:34:0;;;:18;;;;;;;;;;:34;50423:6;50419:113;50435:19;;;50419:113;;;50505:8;;50514:1;50505:11;;;;;;;;;;;;;-1:-1:-1;;;;;50505:11:0;50480:15;50496:1;50500;50496:5;50480:22;;;;;;;;;;-1:-1:-1;;;;;50480:36:0;;;:22;;;;;;;;;;:36;50456:3;;50419:113;;;-1:-1:-1;50624:48:0;;;;;;-1:-1:-1;;;;;50624:48:0;;;;;;;;;;;;;;;;;;;;;;;:23;;;;;;50648:6;;50656:15;;50624:48;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;50624:48:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50624:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50624:48:0;;;;50716:33;50734:6;50742;;50716:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;50716:17:0;;-1:-1:-1;;;50716:33:0:i;:::-;50827:56;;;;;;50870:4;50827:56;;;;50877:5;50827:56;;;;;;;;-1:-1:-1;;;;;50827:34:0;;;;;:56;;;;;;;;;;;50877:5;50827:34;:56;;;5:2:-1;;;;30:1;27;20:12;5:2;50827:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50827:56:0;;;;50164:874;;;;50985:41;;;;;;-1:-1:-1;;;;;50985:41:0;;;;;;;;;;;;;;;;;;;;;:23;;;;;;51009:6;;51017:8;;;;50985:41;;51017:8;50985:41;;;;51017:8;50985:41;1:33:-1;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;50985:41:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50985:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50985:41:0;;;;50164:874;51075:6;-1:-1:-1;;;;;51053:29:0;51067:6;-1:-1:-1;;;;;51053:29:0;;;;;;;;;;;8982:1;;;49752:1338;;;;;:::o;48231:29::-;;;-1:-1:-1;;;;;48231:29:0;;:::o;51405:532::-;51592:7;51617:15;51635:33;51644:5;51651:6;51659:8;;51635:33;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;51635:8:0;;-1:-1:-1;;;51635:33:0:i;:::-;51617:51;;51679:17;51716:24;;;;;;;;:::i;:::-;-1:-1:-1;;21:26;;;;;7:41;;87:2;69:12;;;65:26;61:2;54:38;;;51750:20:0;;51699:73;;-1:-1:-1;;;;;51750:20:0;;;;41:4:-1;51699:73:0;;;;;;30:16:-1;;;51699:73:0;;30:16:-1;36:153;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;51699:73:0;;;;;-1:-1:-1;51699:73:0;;;26:21:-1;;;6:49;;51699:73:0;;;;;51863:15;;;;;;51825:12;51808:71;;;;51847:4;51808:71;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;51808:71:0;;;;;;;-1:-1:-1;51798:82:0;;;;;;;;;51405:532;-1:-1:-1;;;;;;;51405:532:0:o;55692:300::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;55797:35:0;;;;55789:74;;;;;-1:-1:-1;;;;;55789:74:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;55789:74:0;;;;;;;;;;;;;;;55874:20;:44;;-1:-1:-1;;;;;55874:44:0;;-1:-1:-1;;55874:44:0;;;;;;;;55934:50;;;;;;;;;;;;;;;;55692:300;:::o;56565:237::-;8067:5;;-1:-1:-1;;;;;8067:5:0;8053:10;:19;8045:45;;;;;-1:-1:-1;;;;;8045:45:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;8045:45:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;56652:26:0;;;;56644:65;;;;;-1:-1:-1;;;;;56644:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56644:65:0;;;;;;;;;;;;;;;56720:11;:26;;-1:-1:-1;;;;;56720:26:0;;-1:-1:-1;;56720:26:0;;;;;;;;56762:32;;;;;;;;;;;;;;;;56565:237;:::o;8760:41::-;;;;;;;;;;;;;;;:::o;54273:367::-;-1:-1:-1;;;;;54374:20:0;;;;54366:57;;;;;-1:-1:-1;;;;;54366:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54442:15;;54460:1;-1:-1:-1;54434:73:0;;;;-1:-1:-1;;;;;54434:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54541:14;;54526:59;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54541:14:0;;;;54526:49;;54576:8;;54526:59;;;;;;;;;;;;;;;54541:14;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;54526:59:0;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54526:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54526:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54526:59:0;54518:114;;;;;;-1:-1:-1;;;;;54518:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54273:367;;:::o;54884:186::-;54983:7;55037:5;55044:6;55052:8;55020:41;;;;;;;;;;;-1:-1:-1;;;;;55020:41:0;-1:-1:-1;;;;;55020:41:0;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;55020:41:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;55020:41:0;;;55010:52;;;;;;55003:59;;54884:186;;;;;:::o;56986:425::-;57194:10;;57206:11;;57132:86;;;-1:-1:-1;;;;;57194:10:0;;;57132:86;;;;57206:11;;;57132:86;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;57132:86:0;;;;;;;25:18:-1;;61:17;;57132:86:0;182:15:-1;57132:86:0;179:29:-1;160:49;;57132:86:0;57229:26;;;57264:24;:22;:24::i;:::-;57291:1;57294:10;57229:76;;;;;-1:-1:-1;;;57229:76:0;;;;;;;-1:-1:-1;;;;;57229:76:0;-1:-1:-1;;;;;57229:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57229:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57229:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57229:76:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;57229:76:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;57229:76:0;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;261:11;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;-1:-1;;57366:10:0;;57354:49;;;;;;-1:-1:-1;;;;;57354:49:0;;;;;;;;;;;;;;;;;;;;;57366:10;;;-1:-1:-1;57354:32:0;;-1:-1:-1;57387:6:0;;-1:-1:-1;57395:7:0;;-1:-1:-1;57354:49:0;;;;;;;;;;;;;;57366:10;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57354:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57354:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57354:49:0;;;;56986:425;;;:::o;48124:9553::-;;;;;;;;:::o
Swarm Source
bzzr://52a0317929288aa13f9b5ac288b8ac823e6e3acfc1a99344e3aba98c3938563d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.