Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 895 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Create Counterfa... | 11802436 | 1843 days ago | IN | 0 ETH | 0.06756269 | ||||
| Create Counterfa... | 11569471 | 1879 days ago | IN | 0 ETH | 0.04521503 | ||||
| Create Counterfa... | 11536932 | 1884 days ago | IN | 0 ETH | 0.11395993 | ||||
| Create Counterfa... | 11329228 | 1916 days ago | IN | 0 ETH | 0.0161111 | ||||
| Create Counterfa... | 11327871 | 1916 days ago | IN | 0 ETH | 0.02979754 | ||||
| Create Counterfa... | 11226403 | 1932 days ago | IN | 0 ETH | 0.00815011 | ||||
| Create Counterfa... | 11226389 | 1932 days ago | IN | 0 ETH | 0.00779569 | ||||
| Create Counterfa... | 11199852 | 1936 days ago | IN | 0 ETH | 0.0094068 | ||||
| Create Counterfa... | 11194688 | 1936 days ago | IN | 0 ETH | 0.01309451 | ||||
| Create Counterfa... | 11194613 | 1936 days ago | IN | 0 ETH | 0.01411462 | ||||
| Create Counterfa... | 11185244 | 1938 days ago | IN | 0 ETH | 0.03205711 | ||||
| Create Counterfa... | 11185222 | 1938 days ago | IN | 0 ETH | 0.03066235 | ||||
| Create Counterfa... | 11149366 | 1943 days ago | IN | 0 ETH | 0.02143332 | ||||
| Create Counterfa... | 11145922 | 1944 days ago | IN | 0 ETH | 0.06756269 | ||||
| Create Counterfa... | 11140765 | 1945 days ago | IN | 0 ETH | 0.01091397 | ||||
| Create Counterfa... | 11139337 | 1945 days ago | IN | 0 ETH | 0.02227595 | ||||
| Create Counterfa... | 11139325 | 1945 days ago | IN | 0 ETH | 0.02281927 | ||||
| Create Counterfa... | 11139305 | 1945 days ago | IN | 0 ETH | 0.02159401 | ||||
| Create Counterfa... | 11137139 | 1945 days ago | IN | 0 ETH | 0.00930519 | ||||
| Create Counterfa... | 11133868 | 1946 days ago | IN | 0 ETH | 0.01205734 | ||||
| Create Counterfa... | 10775838 | 2001 days ago | IN | 0 ETH | 0.25482692 | ||||
| Create Counterfa... | 10775819 | 2001 days ago | IN | 0 ETH | 0.25482692 | ||||
| Create Counterfa... | 10770018 | 2002 days ago | IN | 0 ETH | 0.15643361 | ||||
| Create Counterfa... | 10768627 | 2002 days ago | IN | 0 ETH | 0.11844833 | ||||
| Create Counterfa... | 10768625 | 2002 days ago | IN | 0 ETH | 0.11844833 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 11802436 | 1843 days ago | Contract Creation | 0 ETH | |||
| - | 11569471 | 1879 days ago | Contract Creation | 0 ETH | |||
| - | 11536932 | 1884 days ago | Contract Creation | 0 ETH | |||
| - | 11329228 | 1916 days ago | Contract Creation | 0 ETH | |||
| - | 11327871 | 1916 days ago | Contract Creation | 0 ETH | |||
| - | 11226403 | 1932 days ago | Contract Creation | 0 ETH | |||
| - | 11226389 | 1932 days ago | Contract Creation | 0 ETH | |||
| - | 11199852 | 1936 days ago | Contract Creation | 0 ETH | |||
| - | 11194688 | 1936 days ago | Contract Creation | 0 ETH | |||
| - | 11194613 | 1936 days ago | Contract Creation | 0 ETH | |||
| - | 11185244 | 1938 days ago | Contract Creation | 0 ETH | |||
| - | 11185222 | 1938 days ago | Contract Creation | 0 ETH | |||
| - | 11149366 | 1943 days ago | Contract Creation | 0 ETH | |||
| - | 11145922 | 1944 days ago | Contract Creation | 0 ETH | |||
| - | 11140765 | 1945 days ago | Contract Creation | 0 ETH | |||
| - | 11139337 | 1945 days ago | Contract Creation | 0 ETH | |||
| - | 11139325 | 1945 days ago | Contract Creation | 0 ETH | |||
| - | 11139305 | 1945 days ago | Contract Creation | 0 ETH | |||
| - | 11137139 | 1945 days ago | Contract Creation | 0 ETH | |||
| - | 11133868 | 1946 days ago | Contract Creation | 0 ETH | |||
| - | 10775838 | 2001 days ago | Contract Creation | 0 ETH | |||
| - | 10775819 | 2001 days ago | Contract Creation | 0 ETH | |||
| - | 10770018 | 2002 days ago | Contract Creation | 0 ETH | |||
| - | 10768627 | 2002 days ago | Contract Creation | 0 ETH | |||
| - | 10768625 | 2002 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
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 - <julien@argent.im>
*/
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 - <julien@argent.xyz>
*/
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 - <julien@argent.im>
*/
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 - <julien@argent.im>
*/
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 - <julien@argent.im>
*/
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 <arachnid@notdot.net>
*
* @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 - <julien@argent.im>
*/
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 - <julien@argent.im>
*/
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 - <julien@argent.im>
*/
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 - <julien@argent.im>
*/
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
Contract ABI
API[{"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
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.