Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,300 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Cancel Account R... | 12430569 | 1309 days ago | IN | 0 ETH | 0.00332352 | ||||
Cancel Account R... | 11557206 | 1443 days ago | IN | 0 ETH | 0.00281473 | ||||
Cancel Account R... | 11321954 | 1479 days ago | IN | 0 ETH | 0.00370121 | ||||
Recover | 11224630 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224629 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224628 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224625 | 1494 days ago | IN | 0 ETH | 0.00300981 | ||||
Recover | 11224622 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224621 | 1494 days ago | IN | 0 ETH | 0.00300981 | ||||
Recover | 11224617 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224613 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224611 | 1494 days ago | IN | 0 ETH | 0.00300981 | ||||
Recover | 11224609 | 1494 days ago | IN | 0 ETH | 0.00300981 | ||||
Recover | 11224604 | 1494 days ago | IN | 0 ETH | 0.00222918 | ||||
Recover | 11224601 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224599 | 1494 days ago | IN | 0 ETH | 0.00231986 | ||||
Recover | 11224596 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224594 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224593 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224591 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224586 | 1494 days ago | IN | 0 ETH | 0.00300981 | ||||
Recover | 11224585 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224582 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224580 | 1494 days ago | IN | 0 ETH | 0.00222981 | ||||
Recover | 11224579 | 1494 days ago | IN | 0 ETH | 0.00300918 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
9078396 | 1830 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
DharmaAccountRecoveryManagerV2
Compiler Version
v0.5.11+commit.c082d0b4
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-12-09 */ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg interface DharmaAccountRecoveryManagerInterface { // Fires an event whenever a user signing key is recovered for an account. event Recovery( address indexed wallet, address oldUserSigningKey, address newUserSigningKey ); // Fire an event whenever account recovery is disabled for an account. event RecoveryDisabled(address wallet); function initiateAccountRecovery( address smartWallet, address userSigningKey, uint256 extraTime ) external; function initiateAccountRecoveryDisablement( address smartWallet, uint256 extraTime ) external; function recover(address wallet, address newUserSigningKey) external; function disableAccountRecovery(address wallet) external; function accountRecoveryDisabled( address wallet ) external view returns (bool hasDisabledAccountRecovery); } interface DharmaAccountRecoveryManagerV2Interface { // Fires an event whenever a pending account recovery is cancelled. event RecoveryCancelled( address indexed wallet, address cancelledUserSigningKey ); event RecoveryDisablementCancelled(address wallet); event RoleModified(Role indexed role, address account); event RolePaused(Role indexed role); event RoleUnpaused(Role indexed role); enum Role { OPERATOR, RECOVERER, CANCELLER, DISABLER, PAUSER } struct RoleStatus { address account; bool paused; } function cancelAccountRecovery( address smartWallet, address newUserSigningKey ) external; function cancelAccountRecoveryDisablement(address smartWallet) external; function setRole(Role role, address account) external; function removeRole(Role role) external; function pause(Role role) external; function unpause(Role role) external; function isPaused(Role role) external view returns (bool paused); function isRole(Role role) external view returns (bool hasRole); function getOperator() external view returns (address operator); function getRecoverer() external view returns (address recoverer); function getCanceller() external view returns (address canceller); function getDisabler() external view returns (address disabler); function getPauser() external view returns (address pauser); } interface TimelockerInterface { // Fire an event any time a timelock is initiated. event TimelockInitiated( bytes4 functionSelector, // selector of the function uint256 timeComplete, // timestamp at which the function can be called bytes arguments, // abi-encoded function arguments to call with uint256 timeExpired // timestamp where function can no longer be called ); // Fire an event any time a minimum timelock interval is modified. event TimelockIntervalModified( bytes4 functionSelector, // selector of the function uint256 oldInterval, // old minimum timelock interval for the function uint256 newInterval // new minimum timelock interval for the function ); // Fire an event any time a default timelock expiration is modified. event TimelockExpirationModified( bytes4 functionSelector, // selector of the function uint256 oldExpiration, // old default timelock expiration for the function uint256 newExpiration // new default timelock expiration for the function ); // Each timelock has timestamps for when it is complete and when it expires. struct Timelock { uint128 complete; uint128 expires; } // Functions have a timelock interval and time from completion to expiration. struct TimelockDefaults { uint128 interval; uint128 expiration; } function getTimelock( bytes4 functionSelector, bytes calldata arguments ) external view returns ( bool exists, bool completed, bool expired, uint256 completionTime, uint256 expirationTime ); function getDefaultTimelockInterval( bytes4 functionSelector ) external view returns (uint256 defaultTimelockInterval); function getDefaultTimelockExpiration( bytes4 functionSelector ) external view returns (uint256 defaultTimelockExpiration); } interface TimelockerModifiersInterface { function initiateModifyTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval, uint256 extraTime ) external; function modifyTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval ) external; function initiateModifyTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration, uint256 extraTime ) external; function modifyTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration ) external; } interface DharmaSmartWalletRecoveryInterface { function recover(address newUserSigningKey) external; function getUserSigningKey() external view returns (address userSigningKey); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be aplied to your functions to restrict their use to * the owner. * * In order to transfer ownership, a recipient must be specified, at which point * the specified recipient can call `acceptOwnership` and take ownership. */ contract TwoStepOwnable { address private _owner; address private _newPotentialOwner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initialize contract by setting transaction submitter as initial owner. */ constructor() internal { _owner = tx.origin; emit OwnershipTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "TwoStepOwnable: caller is not the owner."); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows a new account (`newOwner`) to accept ownership. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { require( newOwner != address(0), "TwoStepOwnable: new potential owner is the zero address." ); _newPotentialOwner = newOwner; } /** * @dev Cancel a transfer of ownership to a new account. * Can only be called by the current owner. */ function cancelOwnershipTransfer() public onlyOwner { delete _newPotentialOwner; } /** * @dev Transfers ownership of the contract to the caller. * Can only be called by a new potential owner set by the current owner. */ function acceptOwnership() public { require( msg.sender == _newPotentialOwner, "TwoStepOwnable: current owner must set caller as new potential owner." ); delete _newPotentialOwner; emit OwnershipTransferred(_owner, msg.sender); _owner = msg.sender; } } /** * @title TimelockerV2 * @author 0age * @notice This contract allows contracts that inherit it to implement timelocks * on functions, where the `_setTimelock` internal function must first be called * and passed the target function selector and arguments. Then, a given time * interval must first fully transpire before the timelock functions can be * successfully called. Furthermore, once a timelock is complete, it will expire * after a period of time. In order to change timelock intervals or expirations, * the inheriting contract needs to implement `modifyTimelockInterval` and * `modifyTimelockExpiration` functions, respectively, as well as functions that * call `_setTimelock` in order to initiate the timelocks for those functions. * To make a function timelocked, use the `_enforceTimelock` internal function. * To set initial defult minimum timelock intervals and expirations, use the * `_setInitialTimelockInterval` and `_setInitialTimelockExpiration` internal * functions - they can only be used during contract creation. Additionally, * there are three external getters (and internal equivalents): `getTimelock`, * `getDefaultTimelockInterval`, and `getDefaultTimelockExpiration`. Finally, * version two of the timelocker builds on version one by including an internal * `_expireTimelock` function for expiring an existing timelock, which can then * be reactivated as long as the completion time does not become shorter than * the original completion time. */ contract TimelockerV2 is TimelockerInterface { using SafeMath for uint256; // Implement a timelock for each function and set of arguments. mapping(bytes4 => mapping(bytes32 => Timelock)) private _timelocks; // Implement default timelock intervals and expirations for each function. mapping(bytes4 => TimelockDefaults) private _timelockDefaults; // Only allow one new interval or expiration change at a time per function. mapping(bytes4 => mapping(bytes4 => bytes32)) private _protectedTimelockIDs; // Store modifyTimelockInterval function selector as a constant. bytes4 private constant _MODIFY_TIMELOCK_INTERVAL_SELECTOR = bytes4( 0xe950c085 ); // Store modifyTimelockExpiration function selector as a constant. bytes4 private constant _MODIFY_TIMELOCK_EXPIRATION_SELECTOR = bytes4( 0xd7ce3c6f ); // Set a ridiculously high duration in order to protect against overflows. uint256 private constant _A_TRILLION_YEARS = 365000000000000 days; /** * @notice In the constructor, confirm that selectors specified as constants * are correct. */ constructor() internal { TimelockerModifiersInterface modifiers; bytes4 targetModifyInterval = modifiers.modifyTimelockInterval.selector; require( _MODIFY_TIMELOCK_INTERVAL_SELECTOR == targetModifyInterval, "Incorrect modify timelock interval selector supplied." ); bytes4 targetModifyExpiration = modifiers.modifyTimelockExpiration.selector; require( _MODIFY_TIMELOCK_EXPIRATION_SELECTOR == targetModifyExpiration, "Incorrect modify timelock expiration selector supplied." ); } /** * @notice View function to check if a timelock for the specified function and * arguments has completed. * @param functionSelector Function to be called. * @param arguments The abi-encoded arguments of the function to be called. * @return A boolean indicating if the timelock exists or not and the time at * which the timelock completes if it does exist. */ function getTimelock( bytes4 functionSelector, bytes memory arguments ) public view returns ( bool exists, bool completed, bool expired, uint256 completionTime, uint256 expirationTime ) { // Get information on the current timelock, if one exists. (exists, completed, expired, completionTime, expirationTime) = _getTimelock( functionSelector, arguments ); } /** * @notice View function to check the current minimum timelock interval on a * given function. * @param functionSelector Function to retrieve the timelock interval for. * @return The current minimum timelock interval for the given function. */ function getDefaultTimelockInterval( bytes4 functionSelector ) public view returns (uint256 defaultTimelockInterval) { defaultTimelockInterval = _getDefaultTimelockInterval(functionSelector); } /** * @notice View function to check the current default timelock expiration on a * given function. * @param functionSelector Function to retrieve the timelock expiration for. * @return The current default timelock expiration for the given function. */ function getDefaultTimelockExpiration( bytes4 functionSelector ) public view returns (uint256 defaultTimelockExpiration) { defaultTimelockExpiration = _getDefaultTimelockExpiration(functionSelector); } /** * @notice Internal function that sets a timelock so that the specified * function can be called with the specified arguments. Note that existing * timelocks may be extended, but not shortened - this can also be used as a * method for "cancelling" a function call by extending the timelock to an * arbitrarily long duration. Keep in mind that new timelocks may be created * with a shorter duration on functions that already have other timelocks on * them, but only if they have different arguments. * @param functionSelector Selector of the function to be called. * @param arguments The abi-encoded arguments of the function to be called. * @param extraTime Additional time in seconds to add to the minimum timelock * interval for the given function. */ function _setTimelock( bytes4 functionSelector, bytes memory arguments, uint256 extraTime ) internal { // Ensure that the specified extra time will not cause an overflow error. require(extraTime < _A_TRILLION_YEARS, "Supplied extra time is too large."); // Get timelock ID using the supplied function arguments. bytes32 timelockID = keccak256(abi.encodePacked(arguments)); // For timelock interval or expiration changes, first drop any existing // timelock for the function being modified if the argument has changed. if ( functionSelector == _MODIFY_TIMELOCK_INTERVAL_SELECTOR || functionSelector == _MODIFY_TIMELOCK_EXPIRATION_SELECTOR ) { // Determine the function that will be modified by the timelock. (bytes4 modifiedFunction, uint256 duration) = abi.decode( arguments, (bytes4, uint256) ); // Ensure that the new timelock duration will not cause an overflow error. require( duration < _A_TRILLION_YEARS, "Supplied default timelock duration to modify is too large." ); // Determine the current timelockID, if any, for the modified function. bytes32 currentTimelockID = ( _protectedTimelockIDs[functionSelector][modifiedFunction] ); // Determine if current timelockID differs from what is currently set. if (currentTimelockID != timelockID) { // Drop existing timelock if one exists and has a different timelockID. if (currentTimelockID != bytes32(0)) { delete _timelocks[functionSelector][currentTimelockID]; } // Register the new timelockID as the current protected timelockID. _protectedTimelockIDs[functionSelector][modifiedFunction] = timelockID; } } // Get timelock using current time, inverval for timelock ID, & extra time. uint256 timelock = uint256( _timelockDefaults[functionSelector].interval ).add(now).add(extraTime); // Get expiration time using timelock duration plus default expiration time. uint256 expiration = timelock.add( uint256(_timelockDefaults[functionSelector].expiration) ); // Get the current timelock, if one exists. Timelock storage timelockStorage = _timelocks[functionSelector][timelockID]; // Determine the duration of the current timelock. uint256 currentTimelock = uint256(timelockStorage.complete); // Ensure that the timelock duration does not decrease. Note that a new, // shorter timelock may still be set up on the same function in the event // that it is provided with different arguments. Also note that this can be // circumvented when modifying intervals or expirations by setting a new // timelock (removing the old one), then resetting the original timelock but // with a shorter duration. require( currentTimelock == 0 || timelock > currentTimelock, "Existing timelocks may only be extended." ); // Set timelock completion and expiration using timelock ID and extra time. timelockStorage.complete = uint128(timelock); timelockStorage.expires = uint128(expiration); // Emit an event with all of the relevant information. emit TimelockInitiated(functionSelector, timelock, arguments, expiration); } /** * @notice Internal function for setting a new timelock interval for a given * function selector. The default for this function may also be modified, but * excessive values will cause the `modifyTimelockInterval` function to become * unusable. * @param functionSelector The selector of the function to set the timelock * interval for. * @param newTimelockInterval the new minimum timelock interval to set for the * given function. */ function _modifyTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval ) internal { // Ensure that the timelock has been set and is completed. _enforceTimelockPrivate( _MODIFY_TIMELOCK_INTERVAL_SELECTOR, abi.encode(functionSelector, newTimelockInterval) ); // Clear out the existing timelockID protection for the given function. delete _protectedTimelockIDs[ _MODIFY_TIMELOCK_INTERVAL_SELECTOR ][functionSelector]; // Set new timelock interval and emit a `TimelockIntervalModified` event. _setTimelockIntervalPrivate(functionSelector, newTimelockInterval); } /** * @notice Internal function for setting a new timelock expiration for a given * function selector. Once the minimum interval has elapsed, the timelock will * expire once the specified expiration time has elapsed. Setting this value * too low will result in timelocks that are very difficult to execute * correctly. Be sure to override the public version of this function with * appropriate access controls. * @param functionSelector The selector of the function to set the timelock * expiration for. * @param newTimelockExpiration The new minimum timelock expiration to set for * the given function. */ function _modifyTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration ) internal { // Ensure that the timelock has been set and is completed. _enforceTimelockPrivate( _MODIFY_TIMELOCK_EXPIRATION_SELECTOR, abi.encode(functionSelector, newTimelockExpiration) ); // Clear out the existing timelockID protection for the given function. delete _protectedTimelockIDs[ _MODIFY_TIMELOCK_EXPIRATION_SELECTOR ][functionSelector]; // Set new default expiration and emit a `TimelockExpirationModified` event. _setTimelockExpirationPrivate(functionSelector, newTimelockExpiration); } /** * @notice Internal function to set an initial timelock interval for a given * function selector. Only callable during contract creation. * @param functionSelector The selector of the function to set the timelock * interval for. * @param newTimelockInterval The new minimum timelock interval to set for the * given function. */ function _setInitialTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval ) internal { // Ensure that this function is only callable during contract construction. assembly { if extcodesize(address) { revert(0, 0) } } // Set the timelock interval and emit a `TimelockIntervalModified` event. _setTimelockIntervalPrivate(functionSelector, newTimelockInterval); } /** * @notice Internal function to set an initial timelock expiration for a given * function selector. Only callable during contract creation. * @param functionSelector The selector of the function to set the timelock * expiration for. * @param newTimelockExpiration The new minimum timelock expiration to set for * the given function. */ function _setInitialTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration ) internal { // Ensure that this function is only callable during contract construction. assembly { if extcodesize(address) { revert(0, 0) } } // Set the timelock interval and emit a `TimelockExpirationModified` event. _setTimelockExpirationPrivate(functionSelector, newTimelockExpiration); } /** * @notice Internal function to expire or cancel a timelock so it is no longer * usable. Once it has been expired, the timelock in question will only be * reactivated if the timelock is reset, and this operation is only permitted * if the completion time is not shorter than the original completion time. * @param functionSelector The function that the timelock to expire is set on. * @param arguments The abi-encoded arguments of the timelocked function call * to be expired. */ function _expireTimelock( bytes4 functionSelector, bytes memory arguments ) internal { // Get timelock ID using the supplied function arguments. bytes32 timelockID = keccak256(abi.encodePacked(arguments)); // Get the current timelock, if one exists. Timelock storage timelock = _timelocks[functionSelector][timelockID]; uint256 currentTimelock = uint256(timelock.complete); uint256 expiration = uint256(timelock.expires); // Ensure a timelock is currently set for the given function and arguments. require(currentTimelock != 0, "No timelock found for the given arguments."); // Ensure that the timelock has not already expired. require(expiration > now, "Timelock has already expired."); // Mark the timelock as expired. timelock.expires = uint128(0); } /** * @notice Internal function to ensure that a timelock is complete or expired * and to clear the existing timelock if it is complete so it cannot later be * reused. The function to enforce the timelock on is inferred from `msg.sig`. * @param arguments The abi-encoded arguments of the function to be called. */ function _enforceTimelock(bytes memory arguments) internal { // Enforce the relevant timelock. _enforceTimelockPrivate(msg.sig, arguments); } /** * @notice Internal view function to check if a timelock for the specified * function and arguments has completed. * @param functionSelector Function to be called. * @param arguments The abi-encoded arguments of the function to be called. * @return A boolean indicating if the timelock exists or not and the time at * which the timelock completes if it does exist. */ function _getTimelock( bytes4 functionSelector, bytes memory arguments ) internal view returns ( bool exists, bool completed, bool expired, uint256 completionTime, uint256 expirationTime ) { // Get timelock ID using the supplied function arguments. bytes32 timelockID = keccak256(abi.encodePacked(arguments)); // Get information on the current timelock, if one exists. completionTime = uint256(_timelocks[functionSelector][timelockID].complete); exists = completionTime != 0; expirationTime = uint256(_timelocks[functionSelector][timelockID].expires); completed = exists && now > completionTime; expired = exists && now > expirationTime; } /** * @notice Internal view function to check the current minimum timelock * interval on a given function. * @param functionSelector Function to retrieve the timelock interval for. * @return The current minimum timelock interval for the given function. */ function _getDefaultTimelockInterval( bytes4 functionSelector ) internal view returns (uint256 defaultTimelockInterval) { defaultTimelockInterval = uint256( _timelockDefaults[functionSelector].interval ); } /** * @notice Internal view function to check the current default timelock * expiration on a given function. * @param functionSelector Function to retrieve the timelock expiration for. * @return The current default timelock expiration for the given function. */ function _getDefaultTimelockExpiration( bytes4 functionSelector ) internal view returns (uint256 defaultTimelockExpiration) { defaultTimelockExpiration = uint256( _timelockDefaults[functionSelector].expiration ); } /** * @notice Private function to ensure that a timelock is complete or expired * and to clear the existing timelock if it is complete so it cannot later be * reused. * @param functionSelector Function to be called. * @param arguments The abi-encoded arguments of the function to be called. */ function _enforceTimelockPrivate( bytes4 functionSelector, bytes memory arguments ) private { // Get timelock ID using the supplied function arguments. bytes32 timelockID = keccak256(abi.encodePacked(arguments)); // Get the current timelock, if one exists. Timelock memory timelock = _timelocks[functionSelector][timelockID]; uint256 currentTimelock = uint256(timelock.complete); uint256 expiration = uint256(timelock.expires); // Ensure that the timelock is set and has completed. require( currentTimelock != 0 && currentTimelock <= now, "Timelock is incomplete." ); // Ensure that the timelock has not expired. require(expiration > now, "Timelock has expired."); // Clear out the existing timelock so that it cannot be reused. delete _timelocks[functionSelector][timelockID]; } /** * @notice Private function for setting a new timelock interval for a given * function selector. * @param functionSelector the selector of the function to set the timelock * interval for. * @param newTimelockInterval the new minimum timelock interval to set for the * given function. */ function _setTimelockIntervalPrivate( bytes4 functionSelector, uint256 newTimelockInterval ) private { // Ensure that the new timelock interval will not cause an overflow error. require( newTimelockInterval < _A_TRILLION_YEARS, "Supplied minimum timelock interval is too large." ); // Get the existing timelock interval, if any. uint256 oldTimelockInterval = uint256( _timelockDefaults[functionSelector].interval ); // Update the timelock interval on the provided function. _timelockDefaults[functionSelector].interval = uint128(newTimelockInterval); // Emit a `TimelockIntervalModified` event with the appropriate arguments. emit TimelockIntervalModified( functionSelector, oldTimelockInterval, newTimelockInterval ); } /** * @notice Private function for setting a new timelock expiration for a given * function selector. * @param functionSelector the selector of the function to set the timelock * interval for. * @param newTimelockExpiration the new default timelock expiration to set for * the given function. */ function _setTimelockExpirationPrivate( bytes4 functionSelector, uint256 newTimelockExpiration ) private { // Ensure that the new timelock expiration will not cause an overflow error. require( newTimelockExpiration < _A_TRILLION_YEARS, "Supplied default timelock expiration is too large." ); // Ensure that the new timelock expiration is not too short. require( newTimelockExpiration > 1 minutes, "New timelock expiration is too short." ); // Get the existing timelock expiration, if any. uint256 oldTimelockExpiration = uint256( _timelockDefaults[functionSelector].expiration ); // Update the timelock expiration on the provided function. _timelockDefaults[functionSelector].expiration = uint128( newTimelockExpiration ); // Emit a `TimelockExpirationModified` event with the appropriate arguments. emit TimelockExpirationModified( functionSelector, oldTimelockExpiration, newTimelockExpiration ); } } /** * @title DharmaAccountRecoveryManagerV2 * @author 0age * @notice This contract is owned by an Account Recovery multisig and manages * resets to user signing keys when necessary. It implements a set of timelocked * functions, where the `setTimelock` function must first be called, with the * same arguments that the function will be supplied with. Then, a given time * interval must first fully transpire before the timelock functions can be * successfully called. * * The timelocked functions currently implemented include: * recover(address wallet, address newUserSigningKey) * disableAccountRecovery(address wallet) * modifyTimelockInterval(bytes4 functionSelector, uint256 newTimelockInterval) * modifyTimelockExpiration( * bytes4 functionSelector, uint256 newTimelockExpiration * ) * * Note that special care should be taken to differentiate between lost keys and * compromised keys, and that the danger of a user being impersonated is * extremely high. Account recovery should progress to a system where the user * builds their preferred account recovery procedure into a "key ring" smart * contract at their signing address, reserving this "hard reset" for extremely * unusual circumstances and eventually sunsetting it entirely. * * V2 of the Account Recovery Manager builds on V1 by introducing the concept of * "roles" - these are dedicated accounts that can be modified by the owner, and * that can trigger specific functionality on the manager. These roles are: * - operator: initiates timelocks for account recovery + disablement * - recoverer: triggers account recovery once timelock is complete * - disabler: triggers account recovery disablement once timelock is complete * - canceller: cancels account recovery and recovery disablement timelocks * - pauser: pauses any role (where only the owner is then able to unpause it) * * V2 also provides dedicated methods for cancelling timelocks related to * account recovery or the disablement of account recovery, as well as functions * for managing, pausing, and querying for the status of the various roles. */ contract DharmaAccountRecoveryManagerV2 is DharmaAccountRecoveryManagerInterface, DharmaAccountRecoveryManagerV2Interface, TimelockerModifiersInterface, TwoStepOwnable, TimelockerV2 { using SafeMath for uint256; // Maintain a role status mapping with assigned accounts and paused states. mapping(uint256 => RoleStatus) private _roles; // Maintain mapping of smart wallets that have opted out of account recovery. mapping(address => bool) private _accountRecoveryDisabled; /** * @notice In the constructor, set the initial owner to the transaction * submitter and initial minimum timelock interval and default timelock * expiration values. */ constructor() public { // Set initial minimum timelock interval values. _setInitialTimelockInterval(this.modifyTimelockInterval.selector, 2 weeks); _setInitialTimelockInterval( this.modifyTimelockExpiration.selector, 2 weeks ); _setInitialTimelockInterval(this.recover.selector, 3 days); _setInitialTimelockInterval(this.disableAccountRecovery.selector, 3 days); // Set initial default timelock expiration values. _setInitialTimelockExpiration(this.modifyTimelockInterval.selector, 7 days); _setInitialTimelockExpiration( this.modifyTimelockExpiration.selector, 7 days ); _setInitialTimelockExpiration(this.recover.selector, 3 days); _setInitialTimelockExpiration(this.disableAccountRecovery.selector, 3 days); } /** * @notice Initiates a timelocked account recovery process for a smart wallet * user signing key. Only the owner or the designated operator may call this * function. Once the timelock period is complete (and before it has expired) * the owner or the designated recoverer may call `recover` to complete the * process and reset the user's signing key. * @param smartWallet The smart wallet address. * @param userSigningKey The new user signing key. * @param extraTime Additional time in seconds to add to the timelock. */ function initiateAccountRecovery( address smartWallet, address userSigningKey, uint256 extraTime ) external onlyOwnerOr(Role.OPERATOR) { require(smartWallet != address(0), "No smart wallet address provided."); require(userSigningKey != address(0), "No new user signing key provided."); // Set the timelock and emit a `TimelockInitiated` event. _setTimelock( this.recover.selector, abi.encode(smartWallet, userSigningKey), extraTime ); } /** * @notice Timelocked function to set a new user signing key on a smart * wallet. Only the owner or the designated recoverer may call this function. * @param smartWallet Address of the smart wallet to recover a key on. * @param newUserSigningKey Address of the new signing key for the user. */ function recover( address smartWallet, address newUserSigningKey ) external onlyOwnerOr(Role.RECOVERER) { require(smartWallet != address(0), "No smart wallet address provided."); require( newUserSigningKey != address(0), "No new user signing key provided." ); // Ensure that the wallet in question has not opted out of account recovery. require( !_accountRecoveryDisabled[smartWallet], "This wallet has elected to opt out of account recovery functionality." ); // Ensure that the timelock has been set and is completed. _enforceTimelock(abi.encode(smartWallet, newUserSigningKey)); // Declare the proper interface for the smart wallet in question. DharmaSmartWalletRecoveryInterface walletInterface; // Attempt to get current signing key - a failure should not block recovery. address oldUserSigningKey; (bool ok, bytes memory data) = smartWallet.call.gas(gasleft() / 2)( abi.encodeWithSelector(walletInterface.getUserSigningKey.selector) ); if (ok && data.length == 32) { oldUserSigningKey = abi.decode(data, (address)); } // Call the specified smart wallet and supply the new user signing key. DharmaSmartWalletRecoveryInterface(smartWallet).recover(newUserSigningKey); // Emit an event to signify that the wallet in question was recovered. emit Recovery(smartWallet, oldUserSigningKey, newUserSigningKey); } /** * @notice Initiates a timelocked account recovery disablement process for a * smart wallet. Only the owner or the designated operator may call this * function. Once the timelock period is complete (and before it has expired) * the owner or the designated disabler may call `disableAccountRecovery` to * complete the process and opt a smart wallet out of account recovery. Once * account recovery has been disabled, it cannot be reenabled - the process is * irreversible. * @param smartWallet The smart wallet address. * @param extraTime Additional time in seconds to add to the timelock. */ function initiateAccountRecoveryDisablement( address smartWallet, uint256 extraTime ) external onlyOwnerOr(Role.OPERATOR) { require(smartWallet != address(0), "No smart wallet address provided."); // Set the timelock and emit a `TimelockInitiated` event. _setTimelock( this.disableAccountRecovery.selector, abi.encode(smartWallet), extraTime ); } /** * @notice Timelocked function to opt a given wallet out of account recovery. * This action cannot be undone - any future account recovery would require an * upgrade to the smart wallet implementation itself and is not likely to be * supported. Only the owner or the designated disabler may call this * function. * @param smartWallet Address of the smart wallet to disable account recovery * for. */ function disableAccountRecovery( address smartWallet ) external onlyOwnerOr(Role.DISABLER) { require(smartWallet != address(0), "No smart wallet address provided."); // Ensure that the timelock has been set and is completed. _enforceTimelock(abi.encode(smartWallet)); // Register the specified wallet as having opted out of account recovery. _accountRecoveryDisabled[smartWallet] = true; // Emit an event to signify the wallet in question is no longer recoverable. emit RecoveryDisabled(smartWallet); } /** * @notice Cancel a pending timelock for setting a new user signing key on a * smart wallet. Only the owner or the designated canceller may call this * function. * @param smartWallet Address of the smart wallet to cancel the recovery on. * @param userSigningKey Address of the signing key supplied for the user. */ function cancelAccountRecovery( address smartWallet, address userSigningKey ) external onlyOwnerOr(Role.CANCELLER) { require(smartWallet != address(0), "No smart wallet address provided."); require(userSigningKey != address(0), "No user signing key provided."); // Expire the timelock for the account recovery in question if one exists. _expireTimelock( this.recover.selector, abi.encode(smartWallet, userSigningKey) ); // Emit an event to signify that the recovery was cancelled. emit RecoveryCancelled(smartWallet, userSigningKey); } /** * @notice Cancel a pending timelock for disabling account recovery for a * smart wallet. Only the owner or the designated canceller may call this * function. * @param smartWallet Address of the smart wallet to cancel the recovery * disablement on. */ function cancelAccountRecoveryDisablement( address smartWallet ) external onlyOwnerOr(Role.CANCELLER) { require(smartWallet != address(0), "No smart wallet address provided."); // Expire account recovery disablement timelock in question if one exists. _expireTimelock( this.disableAccountRecovery.selector, abi.encode(smartWallet) ); // Emit an event to signify that the recovery disablement was cancelled. emit RecoveryDisablementCancelled(smartWallet); } /** * @notice Pause a currently unpaused role and emit a `RolePaused` event. Only * the owner or the designated pauser may call this function. Also, bear in * mind that only the owner may unpause a role once paused. * @param role The role to pause. Permitted roles are operator (0), * recoverer (1), canceller (2), disabler (3), and pauser (4). */ function pause(Role role) external onlyOwnerOr(Role.PAUSER) { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; require(!storedRoleStatus.paused, "Role in question is already paused."); storedRoleStatus.paused = true; emit RolePaused(role); } /** * @notice Unause a currently paused role and emit a `RoleUnpaused` event. * Only the owner may call this function. * @param role The role to pause. Permitted roles are operator (0), * recoverer (1), canceller (2), disabler (3), and pauser (4). */ function unpause(Role role) external onlyOwner { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; require(storedRoleStatus.paused, "Role in question is already unpaused."); storedRoleStatus.paused = false; emit RoleUnpaused(role); } /** * @notice Sets the timelock for a new timelock interval for a given function * selector. Only the owner may call this function. * @param functionSelector The selector of the function to set the timelock * interval for. * @param newTimelockInterval The new timelock interval to set for the given * function selector. * @param extraTime Additional time in seconds to add to the timelock. */ function initiateModifyTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval, uint256 extraTime ) external onlyOwner { // Ensure that a function selector is specified (no 0x00000000 selector). require( functionSelector != bytes4(0), "Function selector cannot be empty." ); // Ensure a timelock interval over eight weeks is not set on this function. if (functionSelector == this.modifyTimelockInterval.selector) { require( newTimelockInterval <= 8 weeks, "Timelock interval of modifyTimelockInterval cannot exceed eight weeks." ); } // Set the timelock and emit a `TimelockInitiated` event. _setTimelock( this.modifyTimelockInterval.selector, abi.encode(functionSelector, newTimelockInterval), extraTime ); } /** * @notice Sets a new timelock interval for a given function selector. The * default for this function may also be modified, but has a maximum allowable * value of eight weeks. Only the owner may call this function. * @param functionSelector The selector of the function to set the timelock * interval for. * @param newTimelockInterval The new timelock interval to set for the given * function selector. */ function modifyTimelockInterval( bytes4 functionSelector, uint256 newTimelockInterval ) external onlyOwner { // Ensure that a function selector is specified (no 0x00000000 selector). require( functionSelector != bytes4(0), "Function selector cannot be empty." ); // Continue via logic in the inherited `_modifyTimelockInterval` function. _modifyTimelockInterval(functionSelector, newTimelockInterval); } /** * @notice Sets a new timelock expiration for a given function selector. The * default Only the owner may call this function. New expiration durations may * not exceed one month. * @param functionSelector The selector of the function to set the timelock * expiration for. * @param newTimelockExpiration The new timelock expiration to set for the * given function selector. * @param extraTime Additional time in seconds to add to the timelock. */ function initiateModifyTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration, uint256 extraTime ) external onlyOwner { // Ensure that a function selector is specified (no 0x00000000 selector). require( functionSelector != bytes4(0), "Function selector cannot be empty." ); // Ensure that the supplied default expiration does not exceed 1 month. require( newTimelockExpiration <= 30 days, "New timelock expiration cannot exceed one month." ); // Ensure a timelock expiration under one hour is not set on this function. if (functionSelector == this.modifyTimelockExpiration.selector) { require( newTimelockExpiration >= 60 minutes, "Expiration of modifyTimelockExpiration must be at least an hour long." ); } // Set the timelock and emit a `TimelockInitiated` event. _setTimelock( this.modifyTimelockExpiration.selector, abi.encode(functionSelector, newTimelockExpiration), extraTime ); } /** * @notice Sets a new timelock expiration for a given function selector. The * default for this function may also be modified, but has a minimum allowable * value of one hour. Only the owner may call this function. * @param functionSelector The selector of the function to set the timelock * expiration for. * @param newTimelockExpiration The new timelock expiration to set for the * given function selector. */ function modifyTimelockExpiration( bytes4 functionSelector, uint256 newTimelockExpiration ) external onlyOwner { // Ensure that a function selector is specified (no 0x00000000 selector). require( functionSelector != bytes4(0), "Function selector cannot be empty." ); // Continue via logic in the inherited `_modifyTimelockExpiration` function. _modifyTimelockExpiration( functionSelector, newTimelockExpiration ); } /** * @notice Set a new account on a given role and emit a `RoleModified` event * if the role holder has changed. Only the owner may call this function. * @param role The role that the account will be set for. Permitted roles are * operator (0), recoverer (1), canceller (2), disabler (3), and pauser (4). * @param account The account to set as the designated role bearer. */ function setRole(Role role, address account) external onlyOwner { require(account != address(0), "Must supply an account."); _setRole(role, account); } /** * @notice Remove any current role bearer for a given role and emit a * `RoleModified` event if a role holder was previously set. Only the owner * may call this function. * @param role The role that the account will be removed from. Permitted roles * are operator (0), recoverer (1), canceller (2), disabler (3), and * pauser (4). */ function removeRole(Role role) external onlyOwner { _setRole(role, address(0)); } /** * @notice External view function to check whether a given smart wallet has * disabled account recovery by opting out. * @param smartWallet Address of the smart wallet to check. * @return A boolean indicating if account recovery has been disabled for the * wallet in question. */ function accountRecoveryDisabled( address smartWallet ) external view returns (bool hasDisabledAccountRecovery) { // Determine if the wallet in question has opted out of account recovery. hasDisabledAccountRecovery = _accountRecoveryDisabled[smartWallet]; } /** * @notice External view function to check whether or not the functionality * associated with a given role is currently paused or not. The owner or the * pauser may pause any given role (including the pauser itself), but only the * owner may unpause functionality. Additionally, the owner may call paused * functions directly. * @param role The role to check the pause status on. Permitted roles are * operator (0), recoverer (1), canceller (2), disabler (3), and pauser (4). * @return A boolean to indicate if the functionality associated with the role * in question is currently paused. */ function isPaused(Role role) external view returns (bool paused) { paused = _isPaused(role); } /** * @notice External view function to check whether the caller is the current * role holder. * @param role The role to check for. Permitted roles are operator (0), * recoverer (1), canceller (2), disabler (3), and pauser (4). * @return A boolean indicating if the caller has the specified role. */ function isRole(Role role) external view returns (bool hasRole) { hasRole = _isRole(role); } /** * @notice External view function to check the account currently holding the * operator role. The operator can initiate timelocks for account recovery and * account recovery disablement. * @return The address of the current operator, or the null address if none is * set. */ function getOperator() external view returns (address operator) { operator = _roles[uint256(Role.OPERATOR)].account; } /** * @notice External view function to check the account currently holding the * recoverer role. The recoverer can trigger smart wallet account recovery in * the event that a timelock has been initiated and is complete and not yet * expired. * @return The address of the current recoverer, or the null address if none * is set. */ function getRecoverer() external view returns (address recoverer) { recoverer = _roles[uint256(Role.RECOVERER)].account; } /** * @notice External view function to check the account currently holding the * canceller role. The canceller can expire a timelock related to account * recovery or account recovery disablement prior to its execution. * @return The address of the current canceller, or the null address if none * is set. */ function getCanceller() external view returns (address canceller) { canceller = _roles[uint256(Role.CANCELLER)].account; } /** * @notice External view function to check the account currently holding the * disabler role. The disabler can trigger permanent smart wallet account * recovery disablement in the event that a timelock has been initiated and is * complete and not yet expired. * @return The address of the current disabler, or the null address if none is * set. */ function getDisabler() external view returns (address disabler) { disabler = _roles[uint256(Role.DISABLER)].account; } /** * @notice External view function to check the account currently holding the * pauser role. The pauser can pause any role from taking its standard action, * though the owner will still be able to call the associated function in the * interim and is the only entity able to unpause the given role once paused. * @return The address of the current pauser, or the null address if none is * set. */ function getPauser() external view returns (address pauser) { pauser = _roles[uint256(Role.PAUSER)].account; } /** * @notice Internal function to set a new account on a given role and emit a * `RoleModified` event if the role holder has changed. * @param role The role that the account will be set for. Permitted roles are * operator (0), recoverer (1), canceller (2), disabler (3), and pauser (4). * @param account The account to set as the designated role bearer. */ function _setRole(Role role, address account) internal { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; if (account != storedRoleStatus.account) { storedRoleStatus.account = account; emit RoleModified(role, account); } } /** * @notice Internal view function to check whether the caller is the current * role holder. * @param role The role to check for. Permitted roles are operator (0), * recoverer (1), canceller (2), disabler (3), and pauser (4). * @return A boolean indicating if the caller has the specified role. */ function _isRole(Role role) internal view returns (bool hasRole) { hasRole = msg.sender == _roles[uint256(role)].account; } /** * @notice Internal view function to check whether the given role is paused or * not. * @param role The role to check for. Permitted roles are operator (0), * recoverer (1), canceller (2), disabler (3), and pauser (4). * @return A boolean indicating if the specified role is paused or not. */ function _isPaused(Role role) internal view returns (bool paused) { paused = _roles[uint256(role)].paused; } /** * @notice Modifier that throws if called by any account other than the owner * or the supplied role, or if the caller is not the owner and the role in * question is paused. * @param role The role to require unless the caller is the owner. Permitted * roles are operator (0), recoverer (1), canceller (2), disabler (3), and * pauser (4). */ modifier onlyOwnerOr(Role role) { if (!isOwner()) { require(_isRole(role), "Caller does not have a required role."); require(!_isPaused(role), "Role in question is currently paused."); } _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"address","name":"userSigningKey","type":"address"}],"name":"cancelAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"}],"name":"disableAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"cancelOwnershipTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"uint256","name":"extraTime","type":"uint256"}],"name":"initiateAccountRecoveryDisablement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"}],"name":"getDefaultTimelockInterval","outputs":[{"internalType":"uint256","name":"defaultTimelockInterval","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"uint256","name":"newTimelockInterval","type":"uint256"},{"internalType":"uint256","name":"extraTime","type":"uint256"}],"name":"initiateModifyTimelockInterval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"}],"name":"accountRecoveryDisabled","outputs":[{"internalType":"bool","name":"hasDisabledAccountRecovery","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"address","name":"newUserSigningKey","type":"address"}],"name":"recover","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"address","name":"userSigningKey","type":"address"},{"internalType":"uint256","name":"extraTime","type":"uint256"}],"name":"initiateAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPauser","outputs":[{"internalType":"address","name":"pauser","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCanceller","outputs":[{"internalType":"address","name":"canceller","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"}],"name":"getDefaultTimelockExpiration","outputs":[{"internalType":"uint256","name":"defaultTimelockExpiration","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDisabler","outputs":[{"internalType":"address","name":"disabler","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"isRole","outputs":[{"internalType":"bool","name":"hasRole","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"isPaused","outputs":[{"internalType":"bool","name":"paused","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"uint256","name":"newTimelockExpiration","type":"uint256"}],"name":"modifyTimelockExpiration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"removeRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOperator","outputs":[{"internalType":"address","name":"operator","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"uint256","name":"newTimelockInterval","type":"uint256"}],"name":"modifyTimelockInterval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"bytes","name":"arguments","type":"bytes"}],"name":"getTimelock","outputs":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"completed","type":"bool"},{"internalType":"bool","name":"expired","type":"bool"},{"internalType":"uint256","name":"completionTime","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"},{"internalType":"address","name":"account","type":"address"}],"name":"setRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"smartWallet","type":"address"}],"name":"cancelAccountRecoveryDisablement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"uint256","name":"newTimelockExpiration","type":"uint256"},{"internalType":"uint256","name":"extraTime","type":"uint256"}],"name":"initiateModifyTimelockExpiration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRecoverer","outputs":[{"internalType":"address","name":"recoverer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"indexed":false,"internalType":"uint256","name":"timeComplete","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"arguments","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"timeExpired","type":"uint256"}],"name":"TimelockInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"indexed":false,"internalType":"uint256","name":"oldInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newInterval","type":"uint256"}],"name":"TimelockIntervalModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"indexed":false,"internalType":"uint256","name":"oldExpiration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newExpiration","type":"uint256"}],"name":"TimelockExpirationModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"address","name":"cancelledUserSigningKey","type":"address"}],"name":"RecoveryCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"RecoveryDisablementCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RoleModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"RolePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaAccountRecoveryManagerV2Interface.Role","name":"role","type":"uint8"}],"name":"RoleUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"address","name":"oldUserSigningKey","type":"address"},{"indexed":false,"internalType":"address","name":"newUserSigningKey","type":"address"}],"name":"Recovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"RecoveryDisabled","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b50600080546001600160a01b03191632178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36200008a7fe950c085000000000000000000000000000000000000000000000000000000006212750062000218565b620000c27fd7ce3c6f00000000000000000000000000000000000000000000000000000000621275006001600160e01b036200021816565b620000fa7f648bf774000000000000000000000000000000000000000000000000000000006203f4806001600160e01b036200021816565b620001327f1e225a6e000000000000000000000000000000000000000000000000000000006203f4806001600160e01b036200021816565b6200016a7fe950c0850000000000000000000000000000000000000000000000000000000062093a806001600160e01b036200023e16565b620001a27fd7ce3c6f0000000000000000000000000000000000000000000000000000000062093a806001600160e01b036200023e16565b620001da7f648bf774000000000000000000000000000000000000000000000000000000006203f4806001600160e01b036200023e16565b620002127f1e225a6e000000000000000000000000000000000000000000000000000000006203f4806001600160e01b036200023e16565b620004bf565b303b156200022557600080fd5b6200023a82826001600160e01b036200026016565b5050565b303b156200024b57600080fd5b6200023a82826001600160e01b036200035a16565b6801b5a660ea44b800008110620002c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806200300a6030913960400191505060405180910390fd5b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181526003602090815260409182902080546001600160801b038681166001600160801b0319831617909255835194855216908301819052828201849052905190917f559d7dd60c597cca6d78f7577a0778cbe3d5fbd56636087e185037f260d83338919081900360600190a1505050565b6801b5a660ea44b800008110620003bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603281526020018062002fd86032913960400191505060405180910390fd5b603c811162000418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018062002fb36025913960400191505060405180910390fd5b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181526003602090815260409182902080546001600160801b0386811670010000000000000000000000000000000090810282841617909355845195865291900416908301819052828201849052905190917f63f1567641b865eea56986985cc3702d7040232ddf6fde052234a17e97cc5889919081900360600190a1505050565b612ae480620004cf6000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639d003e0411610104578063e950c085116100a2578063f2fde38b11610071578063f2fde38b146105fb578063f5d3b65114610621578063f6e6761e14610647578063fd717de21461067a576101da565b8063e950c0851461049b578063ec2cd043146104c8578063edf07f15146105ac578063f2e12a39146105cc576101da565b8063bc61e733116100de578063bc61e73314610426578063d7ce3c6f14610446578063dab41d0d14610473578063e7f43c6814610493576101da565b80639d003e04146103d7578063afb24ecf146103fe578063bb60332014610406576101da565b806363e0cf4a1161017c57806379ba50971161014b57806379ba5097146103b75780638613959a146103bf5780638da5cb5b146103c75780638f32d59b146103cf576101da565b806363e0cf4a146102f5578063648bf7741461032f57806368a477fc1461035d5780637008b54814610393576101da565b806329904232116101b8578063299042321461023d578063301c7e5d14610269578063336e73d0146102895780635f679530146102c2576101da565b80630f664e6c146101df5780631e225a6e1461020f57806323452b9c14610235575b600080fd5b61020d600480360360408110156101f557600080fd5b506001600160a01b0381358116916020013516610682565b005b61020d6004803603602081101561022557600080fd5b50356001600160a01b031661083c565b61020d6109ae565b61020d6004803603604081101561025357600080fd5b506001600160a01b038135169060200135610a03565b61020d6004803603602081101561027f57600080fd5b503560ff16610b27565b6102b06004803603602081101561029f57600080fd5b50356001600160e01b031916610c1a565b60408051918252519081900360200190f35b61020d600480360360608110156102d857600080fd5b506001600160e01b03198135169060208101359060400135610c2b565b61031b6004803603602081101561030b57600080fd5b50356001600160a01b0316610d4d565b604080519115158252519081900360200190f35b61020d6004803603604081101561034557600080fd5b506001600160a01b0381358116916020013516610d6b565b61020d6004803603606081101561037357600080fd5b506001600160a01b038135811691602081013590911690604001356110e9565b61039b61124e565b604080516001600160a01b039092168252519081900360200190f35b61020d611275565b61039b61131a565b61039b611326565b61031b611335565b6102b0600480360360208110156103ed57600080fd5b50356001600160e01b031916611346565b61039b611351565b61031b6004803603602081101561041c57600080fd5b503560ff1661135d565b61031b6004803603602081101561043c57600080fd5b503560ff16611368565b61020d6004803603604081101561045c57600080fd5b506001600160e01b03198135169060200135611373565b61020d6004803603602081101561048957600080fd5b503560ff1661140a565b61039b61145b565b61020d600480360360408110156104b157600080fd5b506001600160e01b03198135169060200135611466565b61057f600480360360408110156104de57600080fd5b6001600160e01b0319823516919081019060408101602082013564010000000081111561050a57600080fd5b82018360208201111561051c57600080fd5b8035906020019184600183028401116401000000008311171561053e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506114f9945050505050565b60408051951515865293151560208601529115158484015260608401526080830152519081900360a00190f35b61020d600480360360208110156105c257600080fd5b503560ff1661151e565b61020d600480360360408110156105e257600080fd5b50803560ff1690602001356001600160a01b031661166d565b61020d6004803603602081101561061157600080fd5b50356001600160a01b0316611715565b61020d6004803603602081101561063757600080fd5b50356001600160a01b03166117bf565b61020d6004803603606081101561065d57600080fd5b506001600160e01b0319813516906020810135906040013561191d565b61039b611a80565b600261068c611335565b6107195761069981611a8c565b6106d45760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b6106dd81611ac0565b156107195760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b03831661075e5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b0382166107b9576040805162461bcd60e51b815260206004820152601d60248201527f4e6f2075736572207369676e696e67206b65792070726f76696465642e000000604482015290519081900360640190fd5b604080516001600160a01b03808616602083015284168183015281518082038301815260609091019091526107f690631922fddd60e21b90611af3565b604080516001600160a01b0384811682529151918516917f8506b00cd2df941a18335b7afb79ee5c531dc5cce3972b1b7bdf0211f96d711b9181900360200190a2505050565b6003610846611335565b6108d35761085381611a8c565b61088e5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61089781611ac0565b156108d35760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b0382166109185760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6109528260405160200180826001600160a01b03166001600160a01b03168152602001915050604051602081830303815290604052611c40565b6001600160a01b038216600081815260066020908152604091829020805460ff19166001179055815192835290517fa6a1c7e9940e618f418f7c47c543aea6144e61d3e65fe63fd64e0edef19d9ac69281900390910190a15050565b6109b6611335565b6109f15760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b600180546001600160a01b0319169055565b6000610a0d611335565b610a9a57610a1a81611a8c565b610a555760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b610a5e81611ac0565b15610a9a5760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b038316610adf5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b610b22631e225a6e60e01b8460405160200180826001600160a01b03166001600160a01b0316815260200191505060405160208183030381529060405284611c56565b505050565b610b2f611335565b610b6a5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b600060056000836004811115610b7c57fe5b815260208101919091526040016000208054909150600160a01b900460ff16610bd65760405162461bcd60e51b81526004018080602001828103825260258152602001806129db6025913960400191505060405180910390fd5b805460ff60a01b19168155816004811115610bed57fe5b6040517fd9ff16dcccc040d408ddf47191ae2d5313510993b245b3a7ccfb0258a4401d7890600090a25050565b6000610c2582612026565b92915050565b610c33611335565b610c6e5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b03198316610cb45760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6001600160e01b0319831663e950c08560e01b1415610d0f576249d400821115610d0f5760405162461bcd60e51b815260040180806020018281038252604681526020018061277a6046913960600191505060405180910390fd5b604080516001600160e01b0319851660208201528082018490528151808203830181526060909101909152610b229063e950c08560e01b9083611c56565b6001600160a01b031660009081526006602052604090205460ff1690565b6001610d75611335565b610e0257610d8281611a8c565b610dbd5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b610dc681611ac0565b15610e025760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b038316610e475760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b038216610e8c5760405162461bcd60e51b81526004018080602001828103825260218152602001806129536021913960400191505060405180910390fd5b6001600160a01b03831660009081526006602052604090205460ff1615610ee45760405162461bcd60e51b81526004018080602001828103825260458152602001806128ac6045913960600191505060405180910390fd5b604080516001600160a01b0380861660208301528416818301528151808203830181526060909101909152610f1890611c40565b60008060006060866001600160a01b031660025a81610f3357fe5b60408051600481526024810182526020810180516001600160e01b031663081a078d60e41b17815291518151949093049390929182918083835b60208310610f8c5780518252601f199092019160209182019101610f6d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b5091509150818015611007575080516020145b156110265780806020019051602081101561102157600080fd5b505192505b866001600160a01b0316630cd865ec876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561107e57600080fd5b505af1158015611092573d6000803e3d6000fd5b5050604080516001600160a01b0387811682528a811660208301528251908c1694507f6c0468512076e943ed3d1c5aae1d6903c72162713d86aedd1381b3ac19e10cec93509081900390910190a250505050505050565b60006110f3611335565b6111805761110081611a8c565b61113b5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61114481611ac0565b156111805760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b0384166111c55760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b03831661120a5760405162461bcd60e51b81526004018080602001828103825260218152602001806129536021913960400191505060405180910390fd5b604080516001600160a01b038087166020830152851681830152815180820383018152606090910190915261124890631922fddd60e21b9084611c56565b50505050565b600060058160045b81526020810191909152604001600020546001600160a01b0316919050565b6001546001600160a01b031633146112be5760405162461bcd60e51b81526004018080602001828103825260458152602001806128676045913960600191505060405180910390fd5b600180546001600160a01b03191690556000805460405133926001600160a01b03909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b03191633179055565b60006005816002611256565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6000610c258261204b565b60006005816003611256565b6000610c2582611a8c565b6000610c2582611ac0565b61137b611335565b6113b65760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031982166113fc5760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6114068282612077565b5050565b611412611335565b61144d5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6114588160006120f7565b50565b600060058180611256565b61146e611335565b6114a95760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031982166114ef5760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6114068282612196565b600080600080600061150b8787612216565b939b929a50909850965090945092505050565b6004611528611335565b6115b55761153581611a8c565b6115705760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61157981611ac0565b156115b55760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6000600560008460048111156115c757fe5b815260208101919091526040016000208054909150600160a01b900460ff16156116225760405162461bcd60e51b8152600401808060200182810382526023815260200180612a256023913960400191505060405180910390fd5b805460ff60a01b1916600160a01b17815582600481111561163f57fe5b6040517fad75709c5a2559beeed6c59693a5ea8701185d51947d3eef38713bb0fe5891e990600090a2505050565b611675611335565b6116b05760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160a01b03811661170b576040805162461bcd60e51b815260206004820152601760248201527f4d75737420737570706c7920616e206163636f756e742e000000000000000000604482015290519081900360640190fd5b61140682826120f7565b61171d611335565b6117585760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160a01b03811661179d5760405162461bcd60e51b8152600401808060200182810382526038815260200180612a786038913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60026117c9611335565b611856576117d681611a8c565b6118115760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61181a81611ac0565b156118565760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b03821661189b5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6118dd631e225a6e60e01b8360405160200180826001600160a01b03166001600160a01b03168152602001915050604051602081830303815290604052611af3565b604080516001600160a01b038416815290517f170985b339d7db71b7658093224871db8b69f5728f1f0c45459af399728b54db9181900360200190a15050565b611925611335565b6119605760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031983166119a65760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b62278d008211156119e85760405162461bcd60e51b8152600401808060200182810382526030815260200180612a486030913960400191505060405180910390fd5b6001600160e01b0319831663d7ce3c6f60e01b1415611a4257610e10821015611a425760405162461bcd60e51b81526004018080602001828103825260458152602001806129966045913960600191505060405180910390fd5b604080516001600160e01b0319851660208201528082018490528151808203830181526060909101909152610b229063d7ce3c6f60e01b9083611c56565b60006005816001611256565b600060056000836004811115611a9e57fe5b81526020810191909152604001600020546001600160a01b0316331492915050565b600060056000836004811115611ad257fe5b8152602081019190915260400160002054600160a01b900460ff1692915050565b6000816040516020018082805190602001908083835b60208310611b285780518252601f199092019160209182019101611b09565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835284528151918101919091206001600160e01b0319891660009081526002835284812082825290925292902080549295509350506001600160801b038082169250600160801b9091041681611bd85760405162461bcd60e51b815260040180806020018281038252602a815260200180612818602a913960400191505060405180910390fd5b428111611c2c576040805162461bcd60e51b815260206004820152601d60248201527f54696d656c6f636b2068617320616c726561647920657870697265642e000000604482015290519081900360640190fd5b505080546001600160801b03169055505050565b6114586000356001600160e01b031916826122f7565b6801b5a660ea44b800008110611c9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806126e16021913960400191505060405180910390fd5b6000826040516020018082805190602001908083835b60208310611cd25780518252601f199092019160209182019101611cb3565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f19018352909352805192019190912093505063e950c08560e01b6001600160e01b03198716149150819050611d3e57506001600160e01b0319841663d7ce3c6f60e01b145b15611e3857600080848060200190516040811015611d5b57600080fd5b50805160209091015190925090506801b5a660ea44b800008110611db05760405162461bcd60e51b815260040180806020018281038252603a815260200180612919603a913960400191505060405180910390fd5b6001600160e01b0319808716600090815260046020908152604080832093861683529290522054838114611e34578015611e0a576001600160e01b0319871660009081526002602090815260408083208484529091528120555b6001600160e01b031980881660009081526004602090815260408083209387168352929052208490555b5050505b6001600160e01b03198416600090815260036020526040812054611e7d908490611e71906001600160801b03164263ffffffff61249a16565b9063ffffffff61249a16565b6001600160e01b0319861660009081526003602052604081205491925090611eb6908390600160801b90046001600160801b031661249a565b6001600160e01b03198716600090815260026020908152604080832087845290915290208054919250906001600160801b0316801580611ef557508084115b611f305760405162461bcd60e51b81526004018080602001828103825260288152602001806127c06028913960400191505060405180910390fd5b81546001600160801b03848116600160801b028187166001600160801b03199093169290921716178255604080516001600160e01b03198a16815260208082018790526060820186905260809282018381528a519383019390935289517fd7e6ea5d472293380587e80ee930aaf3dafcb4da900ef39840b525867bb220c4938c9389938d938a939160a08401919086019080838360005b83811015611fdf578181015183820152602001611fc7565b50505050905090810190601f16801561200c5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a15050505050505050565b6001600160e01b0319166000908152600360205260409020546001600160801b031690565b6001600160e01b031916600090815260036020526040902054600160801b90046001600160801b031690565b604080516001600160e01b03198416602082015280820183905281518082038301815260609091019091526120b49063d7ce3c6f60e01b906122f7565b6001600160e01b0319821660009081527f853c0ad41052a6382a89e0e283f5254589d89b8e221fb1b8e970f56802a9c3d8602052604081205561140682826124fb565b60006005600084600481111561210957fe5b8152602081019190915260400160002080549091506001600160a01b03838116911614610b225780546001600160a01b0319166001600160a01b03831617815582600481111561215557fe5b604080516001600160a01b038516815290517f40ab465936efb8324cf37e3a29170c60d9b81de43af89693ce9d92c761e42adc9181900360200190a2505050565b604080516001600160e01b03198416602082015280820183905281518082038301815260609091019091526121d39063e950c08560e01b906122f7565b6001600160e01b0319821660009081527fc62cd2b678eec090e28450ba4c449928bac817050d2c9f2aabe08e7a8043503160205260408120556114068282612603565b600080600080600080866040516020018082805190602001908083835b602083106122525780518252601f199092019160209182019101612233565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835284528151918101919091206001600160e01b03198e16600090815260028352848120828252909252929020546001600160801b03808216801580159d50909950600160801b9092041696509194508993509091506122dc905057508242115b94508580156122ea57508142115b9350509295509295909350565b6000816040516020018082805190602001908083835b6020831061232c5780518252601f19909201916020918201910161230d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012090506123716126c9565b506001600160e01b0319831660009081526002602090815260408083208484528252918290208251808401909352546001600160801b03808216808552600160801b909204169183018290529081158015906123cd5750428211155b61241e576040805162461bcd60e51b815260206004820152601760248201527f54696d656c6f636b20697320696e636f6d706c6574652e000000000000000000604482015290519081900360640190fd5b42811161246a576040805162461bcd60e51b81526020600482015260156024820152742a34b6b2b637b1b5903430b99032bc3834b932b21760591b604482015290519081900360640190fd5b5050506001600160e01b031990921660009081526002602090815260408083209483529390529182209190915550565b6000828201838110156124f4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6801b5a660ea44b8000081106125425760405162461bcd60e51b81526004018080602001828103825260328152602001806127486032913960400191505060405180910390fd5b603c81116125815760405162461bcd60e51b81526004018080602001828103825260258152602001806127026025913960400191505060405180910390fd5b6001600160e01b0319821660008181526003602090815260409182902080546001600160801b03868116600160801b90810282841617909355845195865291900416908301819052828201849052905190917f63f1567641b865eea56986985cc3702d7040232ddf6fde052234a17e97cc5889919081900360600190a1505050565b6801b5a660ea44b80000811061264a5760405162461bcd60e51b81526004018080602001828103825260308152602001806127e86030913960400191505060405180910390fd5b6001600160e01b0319821660008181526003602090815260409182902080546001600160801b038681166001600160801b0319831617909255835194855216908301819052828201849052905190917f559d7dd60c597cca6d78f7577a0778cbe3d5fbd56636087e185037f260d83338919081900360600190a1505050565b60408051808201909152600080825260208201529056fe537570706c6965642065787472612074696d6520697320746f6f206c617267652e4e65772074696d656c6f636b2065787069726174696f6e20697320746f6f2073686f72742e4e6f20736d6172742077616c6c657420616464726573732070726f76696465642e537570706c6965642064656661756c742074696d656c6f636b2065787069726174696f6e20697320746f6f206c617267652e54696d656c6f636b20696e74657276616c206f66206d6f6469667954696d656c6f636b496e74657276616c2063616e6e6f7420657863656564206569676874207765656b732e4578697374696e672074696d656c6f636b73206d6179206f6e6c7920626520657874656e6465642e537570706c696564206d696e696d756d2074696d656c6f636b20696e74657276616c20697320746f6f206c617267652e4e6f2074696d656c6f636b20666f756e6420666f722074686520676976656e20617267756d656e74732e43616c6c657220646f6573206e6f742068617665206120726571756972656420726f6c652e54776f537465704f776e61626c653a2063757272656e74206f776e6572206d757374207365742063616c6c6572206173206e657720706f74656e7469616c206f776e65722e546869732077616c6c65742068617320656c656374656420746f206f7074206f7574206f66206163636f756e74207265636f766572792066756e6374696f6e616c6974792e54776f537465704f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65722e537570706c6965642064656661756c742074696d656c6f636b206475726174696f6e20746f206d6f6469667920697320746f6f206c617267652e4e6f206e65772075736572207369676e696e67206b65792070726f76696465642e46756e6374696f6e2073656c6563746f722063616e6e6f7420626520656d7074792e45787069726174696f6e206f66206d6f6469667954696d656c6f636b45787069726174696f6e206d757374206265206174206c6561737420616e20686f7572206c6f6e672e526f6c6520696e207175657374696f6e20697320616c726561647920756e7061757365642e526f6c6520696e207175657374696f6e2069732063757272656e746c79207061757365642e526f6c6520696e207175657374696f6e20697320616c7265616479207061757365642e4e65772074696d656c6f636b2065787069726174696f6e2063616e6e6f7420657863656564206f6e65206d6f6e74682e54776f537465704f776e61626c653a206e657720706f74656e7469616c206f776e657220697320746865207a65726f20616464726573732ea265627a7a7231582020446861726d614163636f756e745265636f766572794d616e6167657256322064736f6c634300050b00324e65772074696d656c6f636b2065787069726174696f6e20697320746f6f2073686f72742e537570706c6965642064656661756c742074696d656c6f636b2065787069726174696f6e20697320746f6f206c617267652e537570706c696564206d696e696d756d2074696d656c6f636b20696e74657276616c20697320746f6f206c617267652e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80639d003e0411610104578063e950c085116100a2578063f2fde38b11610071578063f2fde38b146105fb578063f5d3b65114610621578063f6e6761e14610647578063fd717de21461067a576101da565b8063e950c0851461049b578063ec2cd043146104c8578063edf07f15146105ac578063f2e12a39146105cc576101da565b8063bc61e733116100de578063bc61e73314610426578063d7ce3c6f14610446578063dab41d0d14610473578063e7f43c6814610493576101da565b80639d003e04146103d7578063afb24ecf146103fe578063bb60332014610406576101da565b806363e0cf4a1161017c57806379ba50971161014b57806379ba5097146103b75780638613959a146103bf5780638da5cb5b146103c75780638f32d59b146103cf576101da565b806363e0cf4a146102f5578063648bf7741461032f57806368a477fc1461035d5780637008b54814610393576101da565b806329904232116101b8578063299042321461023d578063301c7e5d14610269578063336e73d0146102895780635f679530146102c2576101da565b80630f664e6c146101df5780631e225a6e1461020f57806323452b9c14610235575b600080fd5b61020d600480360360408110156101f557600080fd5b506001600160a01b0381358116916020013516610682565b005b61020d6004803603602081101561022557600080fd5b50356001600160a01b031661083c565b61020d6109ae565b61020d6004803603604081101561025357600080fd5b506001600160a01b038135169060200135610a03565b61020d6004803603602081101561027f57600080fd5b503560ff16610b27565b6102b06004803603602081101561029f57600080fd5b50356001600160e01b031916610c1a565b60408051918252519081900360200190f35b61020d600480360360608110156102d857600080fd5b506001600160e01b03198135169060208101359060400135610c2b565b61031b6004803603602081101561030b57600080fd5b50356001600160a01b0316610d4d565b604080519115158252519081900360200190f35b61020d6004803603604081101561034557600080fd5b506001600160a01b0381358116916020013516610d6b565b61020d6004803603606081101561037357600080fd5b506001600160a01b038135811691602081013590911690604001356110e9565b61039b61124e565b604080516001600160a01b039092168252519081900360200190f35b61020d611275565b61039b61131a565b61039b611326565b61031b611335565b6102b0600480360360208110156103ed57600080fd5b50356001600160e01b031916611346565b61039b611351565b61031b6004803603602081101561041c57600080fd5b503560ff1661135d565b61031b6004803603602081101561043c57600080fd5b503560ff16611368565b61020d6004803603604081101561045c57600080fd5b506001600160e01b03198135169060200135611373565b61020d6004803603602081101561048957600080fd5b503560ff1661140a565b61039b61145b565b61020d600480360360408110156104b157600080fd5b506001600160e01b03198135169060200135611466565b61057f600480360360408110156104de57600080fd5b6001600160e01b0319823516919081019060408101602082013564010000000081111561050a57600080fd5b82018360208201111561051c57600080fd5b8035906020019184600183028401116401000000008311171561053e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506114f9945050505050565b60408051951515865293151560208601529115158484015260608401526080830152519081900360a00190f35b61020d600480360360208110156105c257600080fd5b503560ff1661151e565b61020d600480360360408110156105e257600080fd5b50803560ff1690602001356001600160a01b031661166d565b61020d6004803603602081101561061157600080fd5b50356001600160a01b0316611715565b61020d6004803603602081101561063757600080fd5b50356001600160a01b03166117bf565b61020d6004803603606081101561065d57600080fd5b506001600160e01b0319813516906020810135906040013561191d565b61039b611a80565b600261068c611335565b6107195761069981611a8c565b6106d45760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b6106dd81611ac0565b156107195760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b03831661075e5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b0382166107b9576040805162461bcd60e51b815260206004820152601d60248201527f4e6f2075736572207369676e696e67206b65792070726f76696465642e000000604482015290519081900360640190fd5b604080516001600160a01b03808616602083015284168183015281518082038301815260609091019091526107f690631922fddd60e21b90611af3565b604080516001600160a01b0384811682529151918516917f8506b00cd2df941a18335b7afb79ee5c531dc5cce3972b1b7bdf0211f96d711b9181900360200190a2505050565b6003610846611335565b6108d35761085381611a8c565b61088e5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61089781611ac0565b156108d35760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b0382166109185760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6109528260405160200180826001600160a01b03166001600160a01b03168152602001915050604051602081830303815290604052611c40565b6001600160a01b038216600081815260066020908152604091829020805460ff19166001179055815192835290517fa6a1c7e9940e618f418f7c47c543aea6144e61d3e65fe63fd64e0edef19d9ac69281900390910190a15050565b6109b6611335565b6109f15760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b600180546001600160a01b0319169055565b6000610a0d611335565b610a9a57610a1a81611a8c565b610a555760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b610a5e81611ac0565b15610a9a5760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b038316610adf5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b610b22631e225a6e60e01b8460405160200180826001600160a01b03166001600160a01b0316815260200191505060405160208183030381529060405284611c56565b505050565b610b2f611335565b610b6a5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b600060056000836004811115610b7c57fe5b815260208101919091526040016000208054909150600160a01b900460ff16610bd65760405162461bcd60e51b81526004018080602001828103825260258152602001806129db6025913960400191505060405180910390fd5b805460ff60a01b19168155816004811115610bed57fe5b6040517fd9ff16dcccc040d408ddf47191ae2d5313510993b245b3a7ccfb0258a4401d7890600090a25050565b6000610c2582612026565b92915050565b610c33611335565b610c6e5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b03198316610cb45760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6001600160e01b0319831663e950c08560e01b1415610d0f576249d400821115610d0f5760405162461bcd60e51b815260040180806020018281038252604681526020018061277a6046913960600191505060405180910390fd5b604080516001600160e01b0319851660208201528082018490528151808203830181526060909101909152610b229063e950c08560e01b9083611c56565b6001600160a01b031660009081526006602052604090205460ff1690565b6001610d75611335565b610e0257610d8281611a8c565b610dbd5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b610dc681611ac0565b15610e025760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b038316610e475760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b038216610e8c5760405162461bcd60e51b81526004018080602001828103825260218152602001806129536021913960400191505060405180910390fd5b6001600160a01b03831660009081526006602052604090205460ff1615610ee45760405162461bcd60e51b81526004018080602001828103825260458152602001806128ac6045913960600191505060405180910390fd5b604080516001600160a01b0380861660208301528416818301528151808203830181526060909101909152610f1890611c40565b60008060006060866001600160a01b031660025a81610f3357fe5b60408051600481526024810182526020810180516001600160e01b031663081a078d60e41b17815291518151949093049390929182918083835b60208310610f8c5780518252601f199092019160209182019101610f6d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b5091509150818015611007575080516020145b156110265780806020019051602081101561102157600080fd5b505192505b866001600160a01b0316630cd865ec876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561107e57600080fd5b505af1158015611092573d6000803e3d6000fd5b5050604080516001600160a01b0387811682528a811660208301528251908c1694507f6c0468512076e943ed3d1c5aae1d6903c72162713d86aedd1381b3ac19e10cec93509081900390910190a250505050505050565b60006110f3611335565b6111805761110081611a8c565b61113b5760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61114481611ac0565b156111805760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b0384166111c55760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6001600160a01b03831661120a5760405162461bcd60e51b81526004018080602001828103825260218152602001806129536021913960400191505060405180910390fd5b604080516001600160a01b038087166020830152851681830152815180820383018152606090910190915261124890631922fddd60e21b9084611c56565b50505050565b600060058160045b81526020810191909152604001600020546001600160a01b0316919050565b6001546001600160a01b031633146112be5760405162461bcd60e51b81526004018080602001828103825260458152602001806128676045913960600191505060405180910390fd5b600180546001600160a01b03191690556000805460405133926001600160a01b03909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b03191633179055565b60006005816002611256565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6000610c258261204b565b60006005816003611256565b6000610c2582611a8c565b6000610c2582611ac0565b61137b611335565b6113b65760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031982166113fc5760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6114068282612077565b5050565b611412611335565b61144d5760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6114588160006120f7565b50565b600060058180611256565b61146e611335565b6114a95760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031982166114ef5760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b6114068282612196565b600080600080600061150b8787612216565b939b929a50909850965090945092505050565b6004611528611335565b6115b55761153581611a8c565b6115705760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61157981611ac0565b156115b55760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6000600560008460048111156115c757fe5b815260208101919091526040016000208054909150600160a01b900460ff16156116225760405162461bcd60e51b8152600401808060200182810382526023815260200180612a256023913960400191505060405180910390fd5b805460ff60a01b1916600160a01b17815582600481111561163f57fe5b6040517fad75709c5a2559beeed6c59693a5ea8701185d51947d3eef38713bb0fe5891e990600090a2505050565b611675611335565b6116b05760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160a01b03811661170b576040805162461bcd60e51b815260206004820152601760248201527f4d75737420737570706c7920616e206163636f756e742e000000000000000000604482015290519081900360640190fd5b61140682826120f7565b61171d611335565b6117585760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160a01b03811661179d5760405162461bcd60e51b8152600401808060200182810382526038815260200180612a786038913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60026117c9611335565b611856576117d681611a8c565b6118115760405162461bcd60e51b81526004018080602001828103825260258152602001806128426025913960400191505060405180910390fd5b61181a81611ac0565b156118565760405162461bcd60e51b8152600401808060200182810382526025815260200180612a006025913960400191505060405180910390fd5b6001600160a01b03821661189b5760405162461bcd60e51b81526004018080602001828103825260218152602001806127276021913960400191505060405180910390fd5b6118dd631e225a6e60e01b8360405160200180826001600160a01b03166001600160a01b03168152602001915050604051602081830303815290604052611af3565b604080516001600160a01b038416815290517f170985b339d7db71b7658093224871db8b69f5728f1f0c45459af399728b54db9181900360200190a15050565b611925611335565b6119605760405162461bcd60e51b81526004018080602001828103825260288152602001806128f16028913960400191505060405180910390fd5b6001600160e01b031983166119a65760405162461bcd60e51b81526004018080602001828103825260228152602001806129746022913960400191505060405180910390fd5b62278d008211156119e85760405162461bcd60e51b8152600401808060200182810382526030815260200180612a486030913960400191505060405180910390fd5b6001600160e01b0319831663d7ce3c6f60e01b1415611a4257610e10821015611a425760405162461bcd60e51b81526004018080602001828103825260458152602001806129966045913960600191505060405180910390fd5b604080516001600160e01b0319851660208201528082018490528151808203830181526060909101909152610b229063d7ce3c6f60e01b9083611c56565b60006005816001611256565b600060056000836004811115611a9e57fe5b81526020810191909152604001600020546001600160a01b0316331492915050565b600060056000836004811115611ad257fe5b8152602081019190915260400160002054600160a01b900460ff1692915050565b6000816040516020018082805190602001908083835b60208310611b285780518252601f199092019160209182019101611b09565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835284528151918101919091206001600160e01b0319891660009081526002835284812082825290925292902080549295509350506001600160801b038082169250600160801b9091041681611bd85760405162461bcd60e51b815260040180806020018281038252602a815260200180612818602a913960400191505060405180910390fd5b428111611c2c576040805162461bcd60e51b815260206004820152601d60248201527f54696d656c6f636b2068617320616c726561647920657870697265642e000000604482015290519081900360640190fd5b505080546001600160801b03169055505050565b6114586000356001600160e01b031916826122f7565b6801b5a660ea44b800008110611c9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806126e16021913960400191505060405180910390fd5b6000826040516020018082805190602001908083835b60208310611cd25780518252601f199092019160209182019101611cb3565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f19018352909352805192019190912093505063e950c08560e01b6001600160e01b03198716149150819050611d3e57506001600160e01b0319841663d7ce3c6f60e01b145b15611e3857600080848060200190516040811015611d5b57600080fd5b50805160209091015190925090506801b5a660ea44b800008110611db05760405162461bcd60e51b815260040180806020018281038252603a815260200180612919603a913960400191505060405180910390fd5b6001600160e01b0319808716600090815260046020908152604080832093861683529290522054838114611e34578015611e0a576001600160e01b0319871660009081526002602090815260408083208484529091528120555b6001600160e01b031980881660009081526004602090815260408083209387168352929052208490555b5050505b6001600160e01b03198416600090815260036020526040812054611e7d908490611e71906001600160801b03164263ffffffff61249a16565b9063ffffffff61249a16565b6001600160e01b0319861660009081526003602052604081205491925090611eb6908390600160801b90046001600160801b031661249a565b6001600160e01b03198716600090815260026020908152604080832087845290915290208054919250906001600160801b0316801580611ef557508084115b611f305760405162461bcd60e51b81526004018080602001828103825260288152602001806127c06028913960400191505060405180910390fd5b81546001600160801b03848116600160801b028187166001600160801b03199093169290921716178255604080516001600160e01b03198a16815260208082018790526060820186905260809282018381528a519383019390935289517fd7e6ea5d472293380587e80ee930aaf3dafcb4da900ef39840b525867bb220c4938c9389938d938a939160a08401919086019080838360005b83811015611fdf578181015183820152602001611fc7565b50505050905090810190601f16801561200c5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a15050505050505050565b6001600160e01b0319166000908152600360205260409020546001600160801b031690565b6001600160e01b031916600090815260036020526040902054600160801b90046001600160801b031690565b604080516001600160e01b03198416602082015280820183905281518082038301815260609091019091526120b49063d7ce3c6f60e01b906122f7565b6001600160e01b0319821660009081527f853c0ad41052a6382a89e0e283f5254589d89b8e221fb1b8e970f56802a9c3d8602052604081205561140682826124fb565b60006005600084600481111561210957fe5b8152602081019190915260400160002080549091506001600160a01b03838116911614610b225780546001600160a01b0319166001600160a01b03831617815582600481111561215557fe5b604080516001600160a01b038516815290517f40ab465936efb8324cf37e3a29170c60d9b81de43af89693ce9d92c761e42adc9181900360200190a2505050565b604080516001600160e01b03198416602082015280820183905281518082038301815260609091019091526121d39063e950c08560e01b906122f7565b6001600160e01b0319821660009081527fc62cd2b678eec090e28450ba4c449928bac817050d2c9f2aabe08e7a8043503160205260408120556114068282612603565b600080600080600080866040516020018082805190602001908083835b602083106122525780518252601f199092019160209182019101612233565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835284528151918101919091206001600160e01b03198e16600090815260028352848120828252909252929020546001600160801b03808216801580159d50909950600160801b9092041696509194508993509091506122dc905057508242115b94508580156122ea57508142115b9350509295509295909350565b6000816040516020018082805190602001908083835b6020831061232c5780518252601f19909201916020918201910161230d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012090506123716126c9565b506001600160e01b0319831660009081526002602090815260408083208484528252918290208251808401909352546001600160801b03808216808552600160801b909204169183018290529081158015906123cd5750428211155b61241e576040805162461bcd60e51b815260206004820152601760248201527f54696d656c6f636b20697320696e636f6d706c6574652e000000000000000000604482015290519081900360640190fd5b42811161246a576040805162461bcd60e51b81526020600482015260156024820152742a34b6b2b637b1b5903430b99032bc3834b932b21760591b604482015290519081900360640190fd5b5050506001600160e01b031990921660009081526002602090815260408083209483529390529182209190915550565b6000828201838110156124f4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6801b5a660ea44b8000081106125425760405162461bcd60e51b81526004018080602001828103825260328152602001806127486032913960400191505060405180910390fd5b603c81116125815760405162461bcd60e51b81526004018080602001828103825260258152602001806127026025913960400191505060405180910390fd5b6001600160e01b0319821660008181526003602090815260409182902080546001600160801b03868116600160801b90810282841617909355845195865291900416908301819052828201849052905190917f63f1567641b865eea56986985cc3702d7040232ddf6fde052234a17e97cc5889919081900360600190a1505050565b6801b5a660ea44b80000811061264a5760405162461bcd60e51b81526004018080602001828103825260308152602001806127e86030913960400191505060405180910390fd5b6001600160e01b0319821660008181526003602090815260409182902080546001600160801b038681166001600160801b0319831617909255835194855216908301819052828201849052905190917f559d7dd60c597cca6d78f7577a0778cbe3d5fbd56636087e185037f260d83338919081900360600190a1505050565b60408051808201909152600080825260208201529056fe537570706c6965642065787472612074696d6520697320746f6f206c617267652e4e65772074696d656c6f636b2065787069726174696f6e20697320746f6f2073686f72742e4e6f20736d6172742077616c6c657420616464726573732070726f76696465642e537570706c6965642064656661756c742074696d656c6f636b2065787069726174696f6e20697320746f6f206c617267652e54696d656c6f636b20696e74657276616c206f66206d6f6469667954696d656c6f636b496e74657276616c2063616e6e6f7420657863656564206569676874207765656b732e4578697374696e672074696d656c6f636b73206d6179206f6e6c7920626520657874656e6465642e537570706c696564206d696e696d756d2074696d656c6f636b20696e74657276616c20697320746f6f206c617267652e4e6f2074696d656c6f636b20666f756e6420666f722074686520676976656e20617267756d656e74732e43616c6c657220646f6573206e6f742068617665206120726571756972656420726f6c652e54776f537465704f776e61626c653a2063757272656e74206f776e6572206d757374207365742063616c6c6572206173206e657720706f74656e7469616c206f776e65722e546869732077616c6c65742068617320656c656374656420746f206f7074206f7574206f66206163636f756e74207265636f766572792066756e6374696f6e616c6974792e54776f537465704f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65722e537570706c6965642064656661756c742074696d656c6f636b206475726174696f6e20746f206d6f6469667920697320746f6f206c617267652e4e6f206e65772075736572207369676e696e67206b65792070726f76696465642e46756e6374696f6e2073656c6563746f722063616e6e6f7420626520656d7074792e45787069726174696f6e206f66206d6f6469667954696d656c6f636b45787069726174696f6e206d757374206265206174206c6561737420616e20686f7572206c6f6e672e526f6c6520696e207175657374696f6e20697320616c726561647920756e7061757365642e526f6c6520696e207175657374696f6e2069732063757272656e746c79207061757365642e526f6c6520696e207175657374696f6e20697320616c7265616479207061757365642e4e65772074696d656c6f636b2065787069726174696f6e2063616e6e6f7420657863656564206f6e65206d6f6e74682e54776f537465704f776e61626c653a206e657720706f74656e7469616c206f776e657220697320746865207a65726f20616464726573732ea265627a7a7231582020446861726d614163636f756e745265636f766572794d616e6167657256322064736f6c634300050b0032
Deployed Bytecode Sourcemap
31585:21456:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31585:21456:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38305:592;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;38305:592:0;;;;;;;;;;:::i;:::-;;37400:554;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37400:554:0;-1:-1:-1;;;;;37400:554:0;;:::i;7893:90::-;;;:::i;36570:386::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36570:386:0;;;;;;;;:::i;40630:267::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40630:267:0;;;;:::i;12735:209::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12735:209:0;-1:-1:-1;;;;;;12735:209:0;;:::i;:::-;;;;;;;;;;;;;;;;41331:851;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;;41331:851:0;;;;;;;;;;;;;:::i;46934:278::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;46934:278:0;-1:-1:-1;;;;;46934:278:0;;:::i;:::-;;;;;;;;;;;;;;;;;;34451:1475;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;34451:1475:0;;;;;;;;;;:::i;33644:481::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;33644:481:0;;;;;;;;;;;;;;;;;:::i;50748:118::-;;;:::i;:::-;;;;-1:-1:-1;;;;;50748:118:0;;;;;;;;;;;;;;8141:298;;;:::i;49669:130::-;;;:::i;6980:73::-;;;:::i;7322:86::-;;;:::i;13226:217::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13226:217:0;-1:-1:-1;;;;;;13226:217:0;;:::i;50187:126::-;;;:::i;48291:100::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48291:100:0;;;;:::i;47856:102::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47856:102:0;;;;:::i;45103:479::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;;45103:479:0;;;;;;;;:::i;46529:89::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;46529:89:0;;;;:::i;48702:126::-;;;:::i;42633:455::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;;42633:455:0;;;;;;;;:::i;12042:417::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;12042:417:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;12042:417:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;12042:417: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;12042:417:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;12042:417:0;;-1:-1:-1;12042:417:0;;-1:-1:-1;;;;;12042:417:0:i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40074:276;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40074:276:0;;;;:::i;45991:164::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45991:164:0;;;;;;;;-1:-1:-1;;;;;45991:164:0;;:::i;7541:225::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7541:225:0;-1:-1:-1;;;;;7541:225:0;;:::i;39185:508::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39185:508:0;-1:-1:-1;;;;;39185:508:0;;:::i;43582:1065::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;;43582:1065:0;;;;;;;;;;;;;:::i;49197:130::-;;;:::i;38305:592::-;38412:14;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38443:25:0;;38435:71;;;;-1:-1:-1;;;38435:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38521:28:0;;38513:70;;;;;-1:-1:-1;;;38513:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;38719:39;;;-1:-1:-1;;;;;38719:39:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;38719:39:0;;;;;;;38672:93;;-1:-1:-1;;;38696:21:0;38672:15;:93::i;:::-;38845:46;;;-1:-1:-1;;;;;38845:46:0;;;;;;;;;;;;;;;;;;;;38305:592;;;:::o;37400:554::-;37484:13;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37514:25:0;;37506:71;;;;-1:-1:-1;;;37506:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37650:41;37678:11;37667:23;;;;;;-1:-1:-1;;;;;37667:23:0;-1:-1:-1;;;;;37667:23:0;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;37667:23:0;;;37650:16;:41::i;:::-;-1:-1:-1;;;;;37779:37:0;;;;;;:24;:37;;;;;;;;;:44;;-1:-1:-1;;37779:44:0;37819:4;37779:44;;;37919:29;;;;;;;;;;;;;;;;;37400:554;;:::o;7893:90::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7959:18;7952:25;;-1:-1:-1;;;;;;7952:25:0;;;7893:90::o;36570:386::-;36685:13;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36715:25:0;;36707:71;;;;-1:-1:-1;;;36707:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36850:100;36871:36;;;36920:11;36909:23;;;;;;-1:-1:-1;;;;;36909:23:0;-1:-1:-1;;;;;36909:23:0;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36909:23:0;;;36934:9;36850:12;:100::i;:::-;36570:386;;;:::o;40630:267::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40684:35;40722:6;:21;40737:4;40729:13;;;;;;;;40722:21;;;;;;;;;;;-1:-1:-1;40722:21:0;40758:23;;40722:21;;-1:-1:-1;;;;40758:23:0;;;;40750:73;;;;-1:-1:-1;;;40750:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40830:31;;-1:-1:-1;;;;40830:31:0;;;40886:4;40873:18;;;;;;;;;;;;;;;7235:1;40630:267;:::o;12735:209::-;12827:31;12893:45;12921:16;12893:27;:45::i;:::-;12867:71;12735:209;-1:-1:-1;;12735:209:0:o;41331:851::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41575:29:0;;41559:97;;;;-1:-1:-1;;;41559:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41750:56:0;;-1:-1:-1;;;41750:56:0;41746:219;;;41858:7;41835:19;:30;;41817:140;;;;-1:-1:-1;;;41817:140:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42102:49;;;-1:-1:-1;;;;;;42102:49:0;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;42102::0;;;;;;;42036:140;;-1:-1:-1;;;42057:36:0;42160:9;42036:12;:140::i;46934:278::-;-1:-1:-1;;;;;47169:37:0;47021:31;47169:37;;;:24;:37;;;;;;;;;46934:278::o;34451:1475::-;34547:14;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34578:25:0;;34570:71;;;;-1:-1:-1;;;34570:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34664:31:0;;34648:98;;;;-1:-1:-1;;;34648:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34854:37:0;;;;;;:24;:37;;;;;;;;34853:38;34837:141;;;;-1:-1:-1;;;34837:141:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35068:42;;;-1:-1:-1;;;;;35068:42:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;35068:42:0;;;;;;;35051:60;;:16;:60::i;:::-;35191:50;35332:25;35365:7;35374:17;35395:11;-1:-1:-1;;;;;35395:16:0;35428:1;35416:9;:13;;;;;35439:66;;;22:32:-1;6:49;;35439:66:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;35395:117:0;;;;35416:13;;;;;35439:66;;35395:117;;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;35395:117:0;;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;35364:148:0;;;;35523:2;:23;;;;;35529:4;:11;35544:2;35529:17;35523:23;35519:93;;;35588:4;35577:27;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35577:27:0;;-1:-1:-1;35519:93:0;35732:11;-1:-1:-1;;;;;35697:55:0;;35753:17;35697:74;;;;;;;;;;;;;-1:-1:-1;;;;;35697:74:0;-1:-1:-1;;;;;35697:74:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35697:74:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;35861:59:0;;;-1:-1:-1;;;;;35861:59:0;;;;;;;;;;;;;;;;;;-1:-1:-1;35861:59:0;;-1:-1:-1;35861:59:0;;;;;;;;;53031:1;;;;34451:1475;;;:::o;33644:481::-;33772:13;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33802:25:0;;33794:71;;;;-1:-1:-1;;;33794:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33880:28:0;;33872:74;;;;-1:-1:-1;;;33872:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34062:39;;;-1:-1:-1;;;;;34062:39:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;34062:39:0;;;;;;;34018:101;;-1:-1:-1;;;34039:21:0;34103:9;34018:12;:101::i;:::-;33644:481;;;;:::o;50748:118::-;50792:14;50824:6;50792:14;50839:11;50831:20;50824:28;;;;;;;;;;;-1:-1:-1;50824:28:0;:36;-1:-1:-1;;;;;50824:36:0;;50748:118;-1:-1:-1;50748:118:0:o;8141:298::-;8212:18;;-1:-1:-1;;;;;8212:18:0;8198:10;:32;8182:135;;;;-1:-1:-1;;;8182:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8333:18;8326:25;;-1:-1:-1;;;;;;8326:25:0;;;-1:-1:-1;8386:6:0;;8365:40;;8394:10;;-1:-1:-1;;;;;8386:6:0;;;;8365:40;;;8414:6;:19;;-1:-1:-1;;;;;;8414:19:0;8423:10;8414:19;;;8141:298::o;49669:130::-;49716:17;49754:6;49716:17;49769:14;49761:23;;6980:73;7018:7;7041:6;-1:-1:-1;;;;;7041:6:0;6980:73;:::o;7322:86::-;7362:4;7396:6;-1:-1:-1;;;;;7396:6:0;7382:10;:20;;7322:86::o;13226:217::-;13320:33;13390:47;13420:16;13390:29;:47::i;50187:126::-;50233:16;50269:6;50233:16;50284:13;50276:22;;48291:100;48341:12;48372:13;48380:4;48372:7;:13::i;47856:102::-;47908:11;47937:15;47947:4;47937:9;:15::i;45103:479::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;45324:29:0;;45308:97;;;;-1:-1:-1;;;45308:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45496:80;45530:16;45548:21;45496:25;:80::i;:::-;45103:479;;:::o;46529:89::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46586:26;46595:4;46609:1;46586:8;:26::i;:::-;46529:89;:::o;48702:126::-;48748:16;48784:6;48748:16;;48791:22;;42633:455;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;42850:29:0;;42834:97;;;;-1:-1:-1;;;42834:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43020:62;43044:16;43062:19;43020:23;:62::i;12042:417::-;12149:11;12167:14;12188:12;12207:22;12236;12398:55;12419:16;12437:9;12398:12;:55::i;:::-;12335:118;;;;-1:-1:-1;12335:118:0;;-1:-1:-1;12335:118:0;-1:-1:-1;12335:118:0;;-1:-1:-1;12042:417:0;-1:-1:-1;;;12042:417:0:o;40074:276::-;40121:11;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40141:35;40179:6;:21;40194:4;40186:13;;;;;;;;40179:21;;;;;;;;;;;-1:-1:-1;40179:21:0;40216:23;;40179:21;;-1:-1:-1;;;;40216:23:0;;;;40215:24;40207:72;;;;-1:-1:-1;;;40207:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40286:30;;-1:-1:-1;;;;40286:30:0;-1:-1:-1;;;40286:30:0;;;40339:4;40328:16;;;;;;;;;;;;;;;53031:1;40074:276;;:::o;45991:164::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46070:21:0;;46062:57;;;;;-1:-1:-1;;;46062:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;46126:23;46135:4;46141:7;46126:8;:23::i;7541:225::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7626:22:0;;7610:112;;;;-1:-1:-1;;;7610:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7731:18;:29;;-1:-1:-1;;;;;;7731:29:0;-1:-1:-1;;;;;7731:29:0;;;;;;;;;;7541:225::o;39185:508::-;39279:14;52859:9;:7;:9::i;:::-;52854:171;;52887:13;52895:4;52887:7;:13::i;:::-;52879:63;;;;-1:-1:-1;;;52879:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52960:15;52970:4;52960:9;:15::i;:::-;52959:16;52951:66;;;;-1:-1:-1;;;52951:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39310:25:0;;39302:71;;;;-1:-1:-1;;;39302:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39462:92;39486:36;;;39535:11;39524:23;;;;;;-1:-1:-1;;;;;39524:23:0;-1:-1:-1;;;;;39524:23:0;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;39524:23:0;;;39462:15;:92::i;:::-;39646:41;;;-1:-1:-1;;;;;39646:41:0;;;;;;;;;;;;;;;39185:508;;:::o;43582:1065::-;7174:9;:7;:9::i;:::-;7166:62;;;;-1:-1:-1;;;7166:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;43830:29:0;;43814:97;;;;-1:-1:-1;;;43814:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44038:7;44013:21;:32;;43997:114;;;;-1:-1:-1;;;43997:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;44205:58:0;;-1:-1:-1;;;44205:58:0;44201:225;;;44317:10;44292:21;:35;;44274:144;;;;-1:-1:-1;;;44274:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44565:51;;;-1:-1:-1;;;;;;44565:51:0;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;44565:51:0;;;;;;;44497:144;;-1:-1:-1;;;44518:38:0;44625:9;44497:12;:144::i;49197:130::-;49244:17;49282:6;49244:17;49297:14;49289:23;;51858:131;51909:12;51954:6;:21;51969:4;51961:13;;;;;;;;51954:21;;;;;;;;;;;-1:-1:-1;51954:21:0;:29;-1:-1:-1;;;;;51954:29:0;51940:10;:43;;;-1:-1:-1;;51858:131:0:o;52318:116::-;52371:11;52400:6;:21;52415:4;52407:13;;;;;;;;52400:21;;;;;;;;;;;-1:-1:-1;52400:21:0;:28;-1:-1:-1;;;52400:28:0;;;;;;-1:-1:-1;;52318:116:0:o;22178:834::-;22341:18;22389:9;22372:27;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;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;;22372:27:0;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;22372:27:0;;22362:38;;;;;;;;;-1:-1:-1;;;;;;22486:28:0;;-1:-1:-1;22486:28:0;;;:10;:28;;;;;:40;;;;;;;;;22569:17;;22362:38;;-1:-1:-1;22486:40:0;-1:-1:-1;;;;;;;22569:17:0;;;;-1:-1:-1;;;;22623:16:0;;;;22569:17;22730:75;;;;-1:-1:-1;;;22730:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22893:3;22880:10;:16;22872:58;;;;;-1:-1:-1;;;22872:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;22977:29:0;;-1:-1:-1;;;;;22977:29:0;;;-1:-1:-1;;;22178:834:0:o;23355:154::-;23460:43;23484:7;;-1:-1:-1;;;;;;23484:7:0;23493:9;23460:23;:43::i;14257:3364::-;10955:20;14460:9;:29;14452:75;;;;-1:-1:-1;;;14452:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14599:18;14647:9;14630:27;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;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;;14630:27:0;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;14630:27:0;;;14620:38;;;;;;;;;-1:-1:-1;;;;;;;;;;;14834:54:0;;;;-1:-1:-1;14834:54:0;;-1:-1:-1;14834:121:0;;-1:-1:-1;;;;;;;14899:56:0;;-1:-1:-1;;;14899:56:0;14834:121;14822:1250;;;15045:23;15070:16;15111:9;15090:58;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15090:58:0;;;;;;;;;-1:-1:-1;15090:58:0;-1:-1:-1;10955:20:0;15259:28;;15241:126;;;;-1:-1:-1;;;15241:126:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15496:39:0;;;15457:25;15496:39;;;:21;:39;;;;;;;;:57;;;;;;;;;;15655:31;;;15651:414;;15784:31;;15780:116;;-1:-1:-1;;;;;;15837:28:0;;;;;;:10;:28;;;;;;;;:47;;;;;;;;15830:54;15780:116;-1:-1:-1;;;;;;15985:39:0;;;;;;;:21;:39;;;;;;;;:57;;;;;;;;;:70;;;15651:414;14822:1250;;;;-1:-1:-1;;;;;;16196:35:0;;16161:16;16196:35;;;:17;:35;;;;;:44;16180:91;;16261:9;;16180:76;;-1:-1:-1;;;;;16196:44:0;16252:3;16180:76;:71;:76;:::i;:::-;:80;:91;:80;:91;:::i;:::-;-1:-1:-1;;;;;;16412:35:0;;16362:18;16412:35;;;:17;:35;;;;;:46;16161:110;;-1:-1:-1;16362:18:0;16383:83;;16161:110;;-1:-1:-1;;;16412:46:0;;-1:-1:-1;;;;;16412:46:0;16383:12;:83::i;:::-;-1:-1:-1;;;;;;16559:28:0;;16524:32;16559:28;;;:10;:28;;;;;;;;:40;;;;;;;;16698:24;;16362:104;;-1:-1:-1;16559:40:0;-1:-1:-1;;;;;16698:24:0;17179:20;;;:50;;;17214:15;17203:8;:26;17179:50;17163:124;;;;-1:-1:-1;;;17163:124:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17377:44;;-1:-1:-1;;;;;17428:45:0;;;-1:-1:-1;;;17428:45:0;17377:44;;;-1:-1:-1;;;;;;17377:44:0;;;;;;;17428:45;;;;17547:68;;;-1:-1:-1;;;;;;17547:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17565:16;;17412:8;;17593:9;;17462:10;;17547:68;;;;;;;;;;;;17377:24;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;17547:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14257:3364;;;;;;;;:::o;24922:234::-;-1:-1:-1;;;;;;25099:35:0;25017:31;25099:35;;;:17;:35;;;;;:44;-1:-1:-1;;;;;25099:44:0;;24922:234::o;25447:242::-;-1:-1:-1;;;;;;25630:35:0;25544:33;25630:35;;;:17;:35;;;;;:46;-1:-1:-1;;;25630:46:0;;-1:-1:-1;;;;;25630:46:0;;25447:242::o;19413:667::-;19671:51;;;-1:-1:-1;;;;;;19671:51:0;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;19671:51:0;;;;;;;19594:135;;-1:-1:-1;;;10797:28:0;19594:23;:135::i;:::-;-1:-1:-1;;;;;;19822:91:0;;:73;:91;;;:73;;:91;:73;:91;;19815:98;20004:70;19896:16;20052:21;20004:29;:70::i;51257:268::-;51319:35;51357:6;:21;51372:4;51364:13;;;;;;;;51357:21;;;;;;;;;;;-1:-1:-1;51357:21:0;51402:24;;51357:21;;-1:-1:-1;;;;;;51391:35:0;;;51402:24;;51391:35;51387:133;;51437:34;;-1:-1:-1;;;;;;51437:34:0;-1:-1:-1;;;;;51437:34:0;;;;;51498:4;51485:27;;;;;;;;;;;-1:-1:-1;;;;;51485:27:0;;;;;;;;;;;;;;;51257:268;;;:::o;18103:650::-;18355:49;;;-1:-1:-1;;;;;;18355:49:0;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;18355::0;;;;;;;18280:131;;-1:-1:-1;;;10629:28:0;18280:23;:131::i;:::-;-1:-1:-1;;;;;;18504:89:0;;:71;:89;;;:71;;:89;:71;:89;;18497:96;18681:66;18576:16;18727:19;18681:27;:66::i;23917:720::-;24027:11;24045:14;24066:12;24085:22;24114;24212:18;24260:9;24243:27;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;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;;24243:27:0;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;24243:27:0;;24233:38;;;;;;;;;-1:-1:-1;;;;;;24369:28:0;;-1:-1:-1;24369:28:0;;;:10;:28;;;;;:40;;;;;;;;;:49;-1:-1:-1;;;;;24369:49:0;;;24435:19;;;;;-1:-1:-1;24369:49:0;;-1:-1:-1;;;;24486:48:0;;;;;-1:-1:-1;24233:38:0;;-1:-1:-1;24435:19:0;;-1:-1:-1;24435:19:0;;-1:-1:-1;24554:30:0;;-1:-1:-1;24554:30:0;;24570:14;24564:3;:20;24554:30;24542:42;;24601:6;:30;;;;;24617:14;24611:3;:20;24601:30;24591:40;;23917:720;;;;;;;;;:::o;26016:872::-;26186:18;26234:9;26217:27;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;26217:27:0;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;26217:27:0;;;26207:38;;;;;;26186:59;;26303:24;;:::i;:::-;-1:-1:-1;;;;;;;26330:28:0;;;;;;:10;:28;;;;;;;;:40;;;;;;;;;26303:67;;;;;;;;;-1:-1:-1;;;;;26303:67:0;;;;;;-1:-1:-1;;;26303:67:0;;;;;;;;;;;26568:20;;;;;:46;;;26611:3;26592:15;:22;;26568:46;26552:96;;;;;-1:-1:-1;;;26552:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;26728:3;26715:10;:16;26707:50;;;;;-1:-1:-1;;;26707:50:0;;;;;;;;;;;;-1:-1:-1;;;26707:50:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;26842:28:0;;;;;;;:10;:28;;;;;;;;:40;;;;;;;;;26835:47;;;;-1:-1:-1;26016:872:0:o;5072:167::-;5130:7;5158:5;;;5178:6;;;;5170:46;;;;;-1:-1:-1;;;5170:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5232:1;5072:167;-1:-1:-1;;;5072:167:0:o;28368:1043::-;10955:20;28586:21;:41;28570:125;;;;-1:-1:-1;;;28570:125:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28810:9;28786:21;:33;28770:104;;;;-1:-1:-1;;;28770:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;28985:35:0;;28937:29;28985:35;;;:17;:35;;;;;;;;;:46;;-1:-1:-1;;;;;29112:93:0;;;-1:-1:-1;;;29112:93:0;;;;;;;;;;29301:104;;;;;28985:46;;;;29301:104;;;;;;;;;;;;;;28985:46;;29301:104;;;;;;;;;;28368:1043;;;:::o;27215:820::-;10955:20;27427:19;:39;27411:121;;;;-1:-1:-1;;;27411:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;27639:35:0;;27593:27;27639:35;;;:17;:35;;;;;;;;;:44;;-1:-1:-1;;;;;27762:75:0;;;-1:-1:-1;;;;;;27762:75:0;;;;;;27931:98;;;;;27639:44;27931:98;;;;;;;;;;;;;;27639:44;;27931:98;;;;;;;;;;27215:820;;;:::o;31585:21456::-;;;;;;;;;;-1:-1:-1;31585:21456:0;;;;;;;;:::o
Swarm Source
bzzr://20446861726d614163636f756e745265636f766572794d616e61676572563220
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.