Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,026 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Delegate | 21283552 | 2 days ago | IN | 0 ETH | 0.0019278 | ||||
Delegate | 21268431 | 4 days ago | IN | 0 ETH | 0.002178 | ||||
Delegate | 21268417 | 4 days ago | IN | 0 ETH | 0.00183056 | ||||
Delegate | 21256233 | 5 days ago | IN | 0 ETH | 0.00194455 | ||||
Delegate | 21252150 | 6 days ago | IN | 0 ETH | 0.00051264 | ||||
Delegate | 21252047 | 6 days ago | IN | 0 ETH | 0.00089696 | ||||
Delegate | 21216250 | 11 days ago | IN | 0 ETH | 0.00096139 | ||||
Delegate | 21017913 | 39 days ago | IN | 0 ETH | 0.00027734 | ||||
Delegate | 21000959 | 41 days ago | IN | 0 ETH | 0.00089679 | ||||
Delegate | 20990377 | 42 days ago | IN | 0 ETH | 0.00133179 | ||||
Delegate | 20985907 | 43 days ago | IN | 0 ETH | 0.00132518 | ||||
Delegate | 20868591 | 59 days ago | IN | 0 ETH | 0.00058287 | ||||
Delegate | 20833428 | 64 days ago | IN | 0 ETH | 0.00339504 | ||||
Delegate | 20833296 | 64 days ago | IN | 0 ETH | 0.00117485 | ||||
Delegate | 20739132 | 78 days ago | IN | 0 ETH | 0.00011032 | ||||
Delegate | 20731831 | 79 days ago | IN | 0 ETH | 0.0009418 | ||||
Delegate | 20711553 | 81 days ago | IN | 0 ETH | 0.00007149 | ||||
Delegate | 20577558 | 100 days ago | IN | 0 ETH | 0.00081956 | ||||
Delegate | 20548965 | 104 days ago | IN | 0 ETH | 0.00008041 | ||||
Delegate | 20532749 | 106 days ago | IN | 0 ETH | 0.00009563 | ||||
Delegate | 20339563 | 133 days ago | IN | 0 ETH | 0.00036646 | ||||
Delegate | 20311449 | 137 days ago | IN | 0 ETH | 0.00025611 | ||||
Delegate | 20298824 | 139 days ago | IN | 0 ETH | 0.00006373 | ||||
Delegate | 20298824 | 139 days ago | IN | 0 ETH | 0.00007287 | ||||
Delegate | 20298824 | 139 days ago | IN | 0 ETH | 0.00005951 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Delegations
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-11-04 */ // File: @openzeppelin/contracts/math/SafeMath.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/SafeMath96.sol pragma solidity 0.6.12; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath96 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint96 a, uint256 b) internal pure returns (uint96) { require(uint256(uint96(b)) == b, "SafeMath: addition overflow"); uint96 c = a + uint96(b); require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint96 a, uint256 b) internal pure returns (uint96) { require(uint256(uint96(b)) == b, "SafeMath: subtraction overflow"); return sub(a, uint96(b), "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) { require(b <= a, errorMessage); uint96 c = a - b; return c; } } // File: contracts/spec_interfaces/IElections.sol pragma solidity 0.6.12; /// @title Elections contract interface interface IElections { // Election state change events event StakeChanged(address indexed addr, uint256 selfDelegatedStake, uint256 delegatedStake, uint256 effectiveStake); event GuardianStatusUpdated(address indexed guardian, bool readyToSync, bool readyForCommittee); // Vote out / Vote unready event GuardianVotedUnready(address indexed guardian); event VoteUnreadyCasted(address indexed voter, address indexed subject, uint256 expiration); event GuardianVotedOut(address indexed guardian); event VoteOutCasted(address indexed voter, address indexed subject); /* * External functions */ /// Notifies that the guardian is ready to sync with other nodes /// @dev may be called with either the guardian address or the guardian's orbs address /// @dev ready to sync state is not managed in the contract that only emits an event /// @dev readyToSync clears the readyForCommittee state function readyToSync() external; /// Notifies that the guardian is ready to join the committee /// @dev may be called with either the guardian address or the guardian's orbs address /// @dev a qualified guardian calling readyForCommittee is added to the committee function readyForCommittee() external; /// Checks if a guardian is qualified to join the committee /// @dev when true, calling readyForCommittee() will result in adding the guardian to the committee /// @dev called periodically by guardians to check if they are qualified to join the committee /// @param guardian is the guardian to check /// @return canJoin indicating that the guardian can join the current committee function canJoinCommittee(address guardian) external view returns (bool); /// Returns an address effective stake /// The effective stake is derived from a guardian delegate stake and selfs stake /// @return effectiveStake is the guardian's effective stake function getEffectiveStake(address guardian) external view returns (uint effectiveStake); /// Returns the current committee along with the guardians' Orbs address and IP /// @return committee is a list of the committee members' guardian addresses /// @return weights is a list of the committee members' weight (effective stake) /// @return orbsAddrs is a list of the committee members' orbs address /// @return certification is a list of bool indicating the committee members certification /// @return ips is a list of the committee members' ip function getCommittee() external view returns (address[] memory committee, uint256[] memory weights, address[] memory orbsAddrs, bool[] memory certification, bytes4[] memory ips); // Vote-unready /// Casts an unready vote on a subject guardian /// @dev Called by a guardian as part of the automatic vote-unready flow /// @dev The transaction may be sent from the guardian or orbs address. /// @param subject is the subject guardian to vote out /// @param voteExpiration is the expiration time of the vote unready to prevent counting of a vote that is already irrelevant. function voteUnready(address subject, uint voteExpiration) external; /// Returns the current vote unready vote for a voter and a subject pair /// @param voter is the voting guardian address /// @param subject is the subject guardian address /// @return valid indicates whether there is a valid vote /// @return expiration returns the votes expiration time function getVoteUnreadyVote(address voter, address subject) external view returns (bool valid, uint256 expiration); /// Returns the current vote-unready status of a subject guardian. /// @dev the committee and certification data is used to check the certified and committee threshold /// @param subject is the subject guardian address /// @return committee is a list of the current committee members /// @return weights is a list of the current committee members weight /// @return certification is a list of bool indicating the committee members certification /// @return votes is a list of bool indicating the members that votes the subject unready /// @return subjectInCommittee indicates that the subject is in the committee /// @return subjectInCertifiedCommittee indicates that the subject is in the certified committee function getVoteUnreadyStatus(address subject) external view returns ( address[] memory committee, uint256[] memory weights, bool[] memory certification, bool[] memory votes, bool subjectInCommittee, bool subjectInCertifiedCommittee ); // Vote-out /// Casts a voteOut vote by the sender to the given address /// @dev the transaction is sent from the guardian address /// @param subject is the subject guardian address function voteOut(address subject) external; /// Returns the subject address the addr has voted-out against /// @param voter is the voting guardian address /// @return subject is the subject the voter has voted out function getVoteOutVote(address voter) external view returns (address); /// Returns the governance voteOut status of a guardian. /// @dev A guardian is voted out if votedStake / totalDelegatedStake (in percent mille) > threshold /// @param subject is the subject guardian address /// @return votedOut indicates whether the subject was voted out /// @return votedStake is the total stake voting against the subject /// @return totalDelegatedStake is the total delegated stake function getVoteOutStatus(address subject) external view returns (bool votedOut, uint votedStake, uint totalDelegatedStake); /* * Notification functions from other PoS contracts */ /// Notifies a delegated stake change event /// @dev Called by: delegation contract /// @param delegate is the delegate to update /// @param selfDelegatedStake is the delegate self stake (0 if not self-delegating) /// @param delegatedStake is the delegate delegated stake (0 if not self-delegating) /// @param totalDelegatedStake is the total delegated stake function delegatedStakeChange(address delegate, uint256 selfDelegatedStake, uint256 delegatedStake, uint256 totalDelegatedStake) external /* onlyDelegationsContract onlyWhenActive */; /// Notifies a new guardian was unregistered /// @dev Called by: guardian registration contract /// @dev when a guardian unregisters its status is updated to not ready to sync and is removed from the committee /// @param guardian is the address of the guardian that unregistered function guardianUnregistered(address guardian) external /* onlyGuardiansRegistrationContract */; /// Notifies on a guardian certification change /// @dev Called by: guardian registration contract /// @param guardian is the address of the guardian to update /// @param isCertified indicates whether the guardian is certified function guardianCertificationChanged(address guardian, bool isCertified) external /* onlyCertificationContract */; /* * Governance functions */ event VoteUnreadyTimeoutSecondsChanged(uint32 newValue, uint32 oldValue); event VoteOutPercentMilleThresholdChanged(uint32 newValue, uint32 oldValue); event VoteUnreadyPercentMilleThresholdChanged(uint32 newValue, uint32 oldValue); event MinSelfStakePercentMilleChanged(uint32 newValue, uint32 oldValue); /// Sets the minimum self stake requirement for the effective stake /// @dev governance function called only by the functional manager /// @param minSelfStakePercentMille is the minimum self stake in percent-mille (0-100,000) function setMinSelfStakePercentMille(uint32 minSelfStakePercentMille) external /* onlyFunctionalManager */; /// Returns the minimum self-stake required for the effective stake /// @return minSelfStakePercentMille is the minimum self stake in percent-mille function getMinSelfStakePercentMille() external view returns (uint32); /// Sets the vote-out threshold /// @dev governance function called only by the functional manager /// @param voteOutPercentMilleThreshold is the minimum threshold in percent-mille (0-100,000) function setVoteOutPercentMilleThreshold(uint32 voteOutPercentMilleThreshold) external /* onlyFunctionalManager */; /// Returns the vote-out threshold /// @return voteOutPercentMilleThreshold is the minimum threshold in percent-mille function getVoteOutPercentMilleThreshold() external view returns (uint32); /// Sets the vote-unready threshold /// @dev governance function called only by the functional manager /// @param voteUnreadyPercentMilleThreshold is the minimum threshold in percent-mille (0-100,000) function setVoteUnreadyPercentMilleThreshold(uint32 voteUnreadyPercentMilleThreshold) external /* onlyFunctionalManager */; /// Returns the vote-unready threshold /// @return voteUnreadyPercentMilleThreshold is the minimum threshold in percent-mille function getVoteUnreadyPercentMilleThreshold() external view returns (uint32); /// Returns the contract's settings /// @return minSelfStakePercentMille is the minimum self stake in percent-mille /// @return voteUnreadyPercentMilleThreshold is the minimum threshold in percent-mille /// @return voteOutPercentMilleThreshold is the minimum threshold in percent-mille function getSettings() external view returns ( uint32 minSelfStakePercentMille, uint32 voteUnreadyPercentMilleThreshold, uint32 voteOutPercentMilleThreshold ); /// Initializes the ready for committee notification for the committee guardians /// @dev governance function called only by the initialization admin during migration /// @dev identical behaviour as if each guardian sent readyForCommittee() /// @param guardians a list of guardians addresses to update function initReadyForCommittee(address[] calldata guardians) external /* onlyInitializationAdmin */; } // File: contracts/spec_interfaces/IDelegations.sol pragma solidity 0.6.12; /// @title Delegations contract interface interface IDelegations /* is IStakeChangeNotifier */ { // Delegation state change events event DelegatedStakeChanged(address indexed addr, uint256 selfDelegatedStake, uint256 delegatedStake, address indexed delegator, uint256 delegatorContributedStake); // Function calls event Delegated(address indexed from, address indexed to); /* * External functions */ /// Delegate your stake /// @dev updates the election contract on the changes in the delegated stake /// @dev updates the rewards contract on the upcoming change in the delegator's delegation state /// @param to is the address to delegate to function delegate(address to) external /* onlyWhenActive */; /// Refresh the address stake for delegation power based on the staking contract /// @dev Disabled stake change update notifications from the staking contract may create mismatches /// @dev refreshStake re-syncs the stake data with the staking contract /// @param addr is the address to refresh its stake function refreshStake(address addr) external /* onlyWhenActive */; /// Refresh the addresses stake for delegation power based on the staking contract /// @dev Batched version of refreshStake /// @dev Disabled stake change update notifications from the staking contract may create mismatches /// @dev refreshStakeBatch re-syncs the stake data with the staking contract /// @param addrs is the list of addresses to refresh their stake function refreshStakeBatch(address[] calldata addrs) external /* onlyWhenActive */; /// Returns the delegate address of the given address /// @param addr is the address to query /// @return delegation is the address the addr delegated to function getDelegation(address addr) external view returns (address); /// Returns a delegator info /// @param addr is the address to query /// @return delegation is the address the addr delegated to /// @return delegatorStake is the stake of the delegator as reflected in the delegation contract function getDelegationInfo(address addr) external view returns (address delegation, uint256 delegatorStake); /// Returns the delegated stake of an addr /// @dev an address that is not self delegating has a 0 delegated stake /// @param addr is the address to query /// @return delegatedStake is the address delegated stake function getDelegatedStake(address addr) external view returns (uint256); /// Returns the total delegated stake /// @dev delegatedStake - the total stake delegated to an address that is self delegating /// @dev the delegated stake of a non self-delegated address is 0 /// @return totalDelegatedStake is the total delegatedStake of all the addresses function getTotalDelegatedStake() external view returns (uint256) ; /* * Governance functions */ event DelegationsImported(address[] from, address indexed to); event DelegationInitialized(address indexed from, address indexed to); /// Imports delegations during initial migration /// @dev initialization function called only by the initializationManager /// @dev Does not update the Rewards or Election contracts /// @dev assumes deactivated Rewards /// @param from is a list of delegator addresses /// @param to is the address the delegators delegate to function importDelegations(address[] calldata from, address to) external /* onlyMigrationManager onlyDuringDelegationImport */; /// Initializes the delegation of an address during initial migration /// @dev initialization function called only by the initializationManager /// @dev behaves identically to a delegate transaction sent by the delegator /// @param from is the delegator addresses /// @param to is the delegator delegates to function initDelegation(address from, address to) external /* onlyInitializationAdmin */; } // File: contracts/IStakeChangeNotifier.sol pragma solidity 0.6.12; /// @title An interface for notifying of stake change events (e.g., stake, unstake, partial unstake, restate, etc.). interface IStakeChangeNotifier { /// @dev Notifies of stake change event. /// @param _stakeOwner address The address of the subject stake owner. /// @param _amount uint256 The difference in the total staked amount. /// @param _sign bool The sign of the added (true) or subtracted (false) amount. /// @param _updatedStake uint256 The updated total staked amount. function stakeChange(address _stakeOwner, uint256 _amount, bool _sign, uint256 _updatedStake) external; /// @dev Notifies of multiple stake change events. /// @param _stakeOwners address[] The addresses of subject stake owners. /// @param _amounts uint256[] The differences in total staked amounts. /// @param _signs bool[] The signs of the added (true) or subtracted (false) amounts. /// @param _updatedStakes uint256[] The updated total staked amounts. function stakeChangeBatch(address[] calldata _stakeOwners, uint256[] calldata _amounts, bool[] calldata _signs, uint256[] calldata _updatedStakes) external; /// @dev Notifies of stake migration event. /// @param _stakeOwner address The address of the subject stake owner. /// @param _amount uint256 The migrated amount. function stakeMigration(address _stakeOwner, uint256 _amount) external; } // File: contracts/spec_interfaces/IStakingContractHandler.sol pragma solidity 0.6.12; /// @title Staking contract handler contract interface in addition to IStakeChangeNotifier interface IStakingContractHandler { event StakeChangeNotificationSkipped(address indexed stakeOwner); event StakeChangeBatchNotificationSkipped(address[] stakeOwners); event StakeMigrationNotificationSkipped(address indexed stakeOwner); /* * External functions */ /// Returns the stake of the specified stake owner (excluding unstaked tokens). /// @param stakeOwner address The address to check. /// @return uint256 The total stake. function getStakeBalanceOf(address stakeOwner) external view returns (uint256); /// Returns the total amount staked tokens (excluding unstaked tokens). /// @return uint256 is the total staked tokens of all stake owners. function getTotalStakedTokens() external view returns (uint256); /* * Governance functions */ event NotifyDelegationsChanged(bool notifyDelegations); /// Sets notifications to the delegation contract /// @dev staking while notifications are disabled may lead to a discrepancy in the delegation data /// @dev governance function called only by the migration manager /// @param notifyDelegations is a bool indicating whether to notify the delegation contract function setNotifyDelegations(bool notifyDelegations) external; /* onlyMigrationManager */ /// Returns the notifications to the delegation contract status /// @return notifyDelegations is a bool indicating whether notifications are enabled function getNotifyDelegations() external view returns (bool); } // File: contracts/spec_interfaces/IStakingRewards.sol pragma solidity 0.6.12; /// @title Staking rewards contract interface interface IStakingRewards { event DelegatorStakingRewardsAssigned(address indexed delegator, uint256 amount, uint256 totalAwarded, address guardian, uint256 delegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta); event GuardianStakingRewardsAssigned(address indexed guardian, uint256 amount, uint256 totalAwarded, uint256 delegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta, uint256 stakingRewardsPerWeight, uint256 stakingRewardsPerWeightDelta); event StakingRewardsClaimed(address indexed addr, uint256 claimedDelegatorRewards, uint256 claimedGuardianRewards, uint256 totalClaimedDelegatorRewards, uint256 totalClaimedGuardianRewards); event StakingRewardsAllocated(uint256 allocatedRewards, uint256 stakingRewardsPerWeight); event GuardianDelegatorsStakingRewardsPercentMilleUpdated(address indexed guardian, uint256 delegatorsStakingRewardsPercentMille); /* * External functions */ /// Returns the current reward balance of the given address. /// @dev calculates the up to date balances (differ from the state) /// @param addr is the address to query /// @return delegatorStakingRewardsBalance the rewards awarded to the guardian role /// @return guardianStakingRewardsBalance the rewards awarded to the guardian role function getStakingRewardsBalance(address addr) external view returns (uint256 delegatorStakingRewardsBalance, uint256 guardianStakingRewardsBalance); /// Claims the staking rewards balance of an addr, staking the rewards /// @dev Claimed rewards are staked in the staking contract using the distributeRewards interface /// @dev includes the rewards for both the delegator and guardian roles /// @dev calculates the up to date rewards prior to distribute them to the staking contract /// @param addr is the address to claim rewards for function claimStakingRewards(address addr) external; /// Returns the current global staking rewards state /// @dev calculated to the latest block, may differ from the state read /// @return stakingRewardsPerWeight is the potential reward per 1E18 (TOKEN_BASE) committee weight assigned to a guardian was in the committee from day zero /// @return unclaimedStakingRewards is the of tokens that were assigned to participants and not claimed yet function getStakingRewardsState() external view returns ( uint96 stakingRewardsPerWeight, uint96 unclaimedStakingRewards ); /// Returns the current guardian staking rewards state /// @dev calculated to the latest block, may differ from the state read /// @dev notice that the guardian rewards are the rewards for the guardian role as guardian and do not include delegation rewards /// @dev use getDelegatorStakingRewardsData to get the guardian's rewards as delegator /// @param guardian is the guardian to query /// @return balance is the staking rewards balance for the guardian role /// @return claimed is the staking rewards for the guardian role that were claimed /// @return delegatorRewardsPerToken is the potential reward per token (1E18 units) assigned to a guardian's delegator that delegated from day zero /// @return delegatorRewardsPerTokenDelta is the increment in delegatorRewardsPerToken since the last guardian update /// @return lastStakingRewardsPerWeight is the up to date stakingRewardsPerWeight used for the guardian state calculation /// @return stakingRewardsPerWeightDelta is the increment in stakingRewardsPerWeight since the last guardian update function getGuardianStakingRewardsData(address guardian) external view returns ( uint256 balance, uint256 claimed, uint256 delegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta, uint256 lastStakingRewardsPerWeight, uint256 stakingRewardsPerWeightDelta ); /// Returns the current delegator staking rewards state /// @dev calculated to the latest block, may differ from the state read /// @param delegator is the delegator to query /// @return balance is the staking rewards balance for the delegator role /// @return claimed is the staking rewards for the delegator role that were claimed /// @return guardian is the guardian the delegator delegated to receiving a portion of the guardian staking rewards /// @return lastDelegatorRewardsPerToken is the up to date delegatorRewardsPerToken used for the delegator state calculation /// @return delegatorRewardsPerTokenDelta is the increment in delegatorRewardsPerToken since the last delegator update function getDelegatorStakingRewardsData(address delegator) external view returns ( uint256 balance, uint256 claimed, address guardian, uint256 lastDelegatorRewardsPerToken, uint256 delegatorRewardsPerTokenDelta ); /// Returns an estimation for the delegator and guardian staking rewards for a given duration /// @dev the returned value is an estimation, assuming no change in the PoS state /// @dev the period calculated for start from the current block time until the current time + duration. /// @param addr is the address to estimate rewards for /// @param duration is the duration to calculate for in seconds /// @return estimatedDelegatorStakingRewards is the estimated reward for the delegator role /// @return estimatedGuardianStakingRewards is the estimated reward for the guardian role function estimateFutureRewards(address addr, uint256 duration) external view returns ( uint256 estimatedDelegatorStakingRewards, uint256 estimatedGuardianStakingRewards ); /// Sets the guardian's delegators staking reward portion /// @dev by default uses the defaultDelegatorsStakingRewardsPercentMille /// @param delegatorRewardsPercentMille is the delegators portion in percent-mille (0 - maxDelegatorsStakingRewardsPercentMille) function setGuardianDelegatorsStakingRewardsPercentMille(uint32 delegatorRewardsPercentMille) external; /// Returns a guardian's delegators staking reward portion /// @dev If not explicitly set, returns the defaultDelegatorsStakingRewardsPercentMille /// @return delegatorRewardsRatioPercentMille is the delegators portion in percent-mille function getGuardianDelegatorsStakingRewardsPercentMille(address guardian) external view returns (uint256 delegatorRewardsRatioPercentMille); /// Returns the amount of ORBS tokens in the staking rewards wallet allocated to staking rewards /// @dev The staking wallet balance must always larger than the allocated value /// @return allocated is the amount of tokens allocated in the staking rewards wallet function getStakingRewardsWalletAllocatedTokens() external view returns (uint256 allocated); /// Returns the current annual staking reward rate /// @dev calculated based on the current total committee weight /// @return annualRate is the current staking reward rate in percent-mille function getCurrentStakingRewardsRatePercentMille() external view returns (uint256 annualRate); /// Notifies an expected change in the committee membership of the guardian /// @dev Called only by: the Committee contract /// @dev called upon expected change in the committee membership of the guardian /// @dev triggers update of the global rewards state and the guardian rewards state /// @dev updates the rewards state based on the committee state prior to the change /// @param guardian is the guardian who's committee membership is updated /// @param weight is the weight of the guardian prior to the change /// @param totalCommitteeWeight is the total committee weight prior to the change /// @param inCommittee indicates whether the guardian was in the committee prior to the change /// @param inCommitteeAfter indicates whether the guardian is in the committee after the change function committeeMembershipWillChange(address guardian, uint256 weight, uint256 totalCommitteeWeight, bool inCommittee, bool inCommitteeAfter) external /* onlyCommitteeContract */; /// Notifies an expected change in a delegator and his guardian delegation state /// @dev Called only by: the Delegation contract /// @dev called upon expected change in a delegator's delegation state /// @dev triggers update of the global rewards state, the guardian rewards state and the delegator rewards state /// @dev on delegation change, updates also the new guardian and the delegator's lastDelegatorRewardsPerToken accordingly /// @param guardian is the delegator's guardian prior to the change /// @param guardianDelegatedStake is the delegated stake of the delegator's guardian prior to the change /// @param delegator is the delegator about to change delegation state /// @param delegatorStake is the stake of the delegator /// @param nextGuardian is the delegator's guardian after to the change /// @param nextGuardianDelegatedStake is the delegated stake of the delegator's guardian after to the change function delegationWillChange(address guardian, uint256 guardianDelegatedStake, address delegator, uint256 delegatorStake, address nextGuardian, uint256 nextGuardianDelegatedStake) external /* onlyDelegationsContract */; /* * Governance functions */ event AnnualStakingRewardsRateChanged(uint256 annualRateInPercentMille, uint256 annualCap); event DefaultDelegatorsStakingRewardsChanged(uint32 defaultDelegatorsStakingRewardsPercentMille); event MaxDelegatorsStakingRewardsChanged(uint32 maxDelegatorsStakingRewardsPercentMille); event RewardDistributionActivated(uint256 startTime); event RewardDistributionDeactivated(); event StakingRewardsBalanceMigrated(address indexed addr, uint256 guardianStakingRewards, uint256 delegatorStakingRewards, address toRewardsContract); event StakingRewardsBalanceMigrationAccepted(address from, address indexed addr, uint256 guardianStakingRewards, uint256 delegatorStakingRewards); event EmergencyWithdrawal(address addr, address token); /// Activates staking rewards allocation /// @dev governance function called only by the initialization admin /// @dev On migrations, startTime should be set to the previous contract deactivation time /// @param startTime sets the last assignment time function activateRewardDistribution(uint startTime) external /* onlyInitializationAdmin */; /// Deactivates fees and bootstrap allocation /// @dev governance function called only by the migration manager /// @dev guardians updates remain active based on the current perMember value function deactivateRewardDistribution() external /* onlyMigrationManager */; /// Sets the default delegators staking reward portion /// @dev governance function called only by the functional manager /// @param defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille(0 - maxDelegatorsStakingRewardsPercentMille) function setDefaultDelegatorsStakingRewardsPercentMille(uint32 defaultDelegatorsStakingRewardsPercentMille) external /* onlyFunctionalManager */; /// Returns the default delegators staking reward portion /// @return defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille function getDefaultDelegatorsStakingRewardsPercentMille() external view returns (uint32); /// Sets the maximum delegators staking reward portion /// @dev governance function called only by the functional manager /// @param maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille(0 - 100,000) function setMaxDelegatorsStakingRewardsPercentMille(uint32 maxDelegatorsStakingRewardsPercentMille) external /* onlyFunctionalManager */; /// Returns the default delegators staking reward portion /// @return maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille function getMaxDelegatorsStakingRewardsPercentMille() external view returns (uint32); /// Sets the annual rate and cap for the staking reward /// @dev governance function called only by the functional manager /// @param annualRateInPercentMille is the annual rate in percent-mille /// @param annualCap is the annual staking rewards cap function setAnnualStakingRewardsRate(uint32 annualRateInPercentMille, uint96 annualCap) external /* onlyFunctionalManager */; /// Returns the annual staking reward rate /// @return annualStakingRewardsRatePercentMille is the annual rate in percent-mille function getAnnualStakingRewardsRatePercentMille() external view returns (uint32); /// Returns the annual staking rewards cap /// @return annualStakingRewardsCap is the annual rate in percent-mille function getAnnualStakingRewardsCap() external view returns (uint256); /// Checks if rewards allocation is active /// @return rewardAllocationActive is a bool that indicates that rewards allocation is active function isRewardAllocationActive() external view returns (bool); /// Returns the contract's settings /// @return annualStakingRewardsCap is the annual rate in percent-mille /// @return annualStakingRewardsRatePercentMille is the annual rate in percent-mille /// @return defaultDelegatorsStakingRewardsPercentMille is the default delegators portion in percent-mille /// @return maxDelegatorsStakingRewardsPercentMille is the maximum delegators portion in percent-mille /// @return rewardAllocationActive is a bool that indicates that rewards allocation is active function getSettings() external view returns ( uint annualStakingRewardsCap, uint32 annualStakingRewardsRatePercentMille, uint32 defaultDelegatorsStakingRewardsPercentMille, uint32 maxDelegatorsStakingRewardsPercentMille, bool rewardAllocationActive ); /// Migrates the staking rewards balance of the given addresses to a new staking rewards contract /// @dev The new rewards contract is determined according to the contracts registry /// @dev No impact of the calling contract if the currently configured contract in the registry /// @dev may be called also while the contract is locked /// @param addrs is the list of addresses to migrate function migrateRewardsBalance(address[] calldata addrs) external; /// Accepts addresses balance migration from a previous rewards contract /// @dev the function may be called by any caller that approves the amounts provided for transfer /// @param addrs is the list migrated addresses /// @param migratedGuardianStakingRewards is the list of received guardian rewards balance for each address /// @param migratedDelegatorStakingRewards is the list of received delegator rewards balance for each address /// @param totalAmount is the total amount of staking rewards migrated for all addresses in the list. Must match the sum of migratedGuardianStakingRewards and migratedDelegatorStakingRewards lists. function acceptRewardsBalanceMigration(address[] calldata addrs, uint256[] calldata migratedGuardianStakingRewards, uint256[] calldata migratedDelegatorStakingRewards, uint256 totalAmount) external; /// Performs emergency withdrawal of the contract balance /// @dev called with a token to withdraw, should be called twice with the fees and bootstrap tokens /// @dev governance function called only by the migration manager /// @param erc20 is the ERC20 token to withdraw function emergencyWithdraw(address erc20) external /* onlyMigrationManager */; } // File: contracts/spec_interfaces/IManagedContract.sol pragma solidity 0.6.12; /// @title managed contract interface, used by the contracts registry to notify the contract on updates interface IManagedContract /* is ILockable, IContractRegistryAccessor, Initializable */ { /// Refreshes the address of the other contracts the contract interacts with /// @dev called by the registry contract upon an update of a contract in the registry function refreshContracts() external; } // File: contracts/spec_interfaces/IContractRegistry.sol pragma solidity 0.6.12; /// @title Contract registry contract interface /// @dev The contract registry holds Orbs PoS contracts and managers lists /// @dev The contract registry updates the managed contracts on changes in the contract list /// @dev Governance functions restricted to managers access the registry to retrieve the manager address /// @dev The contract registry represents the source of truth for Orbs Ethereum contracts /// @dev By tracking the registry events or query before interaction, one can access the up to date contracts interface IContractRegistry { event ContractAddressUpdated(string contractName, address addr, bool managedContract); event ManagerChanged(string role, address newManager); event ContractRegistryUpdated(address newContractRegistry); /* * External functions */ /// Updates the contracts address and emits a corresponding event /// @dev governance function called only by the migrationManager or registryAdmin /// @param contractName is the contract name, used to identify it /// @param addr is the contract updated address /// @param managedContract indicates whether the contract is managed by the registry and notified on changes function setContract(string calldata contractName, address addr, bool managedContract) external /* onlyAdminOrMigrationManager */; /// Returns the current address of the given contracts /// @param contractName is the contract name, used to identify it /// @return addr is the contract updated address function getContract(string calldata contractName) external view returns (address); /// Returns the list of contract addresses managed by the registry /// @dev Managed contracts are updated on changes in the registry contracts addresses /// @return addrs is the list of managed contracts function getManagedContracts() external view returns (address[] memory); /// Locks all the managed contracts /// @dev governance function called only by the migrationManager or registryAdmin /// @dev When set all onlyWhenActive functions will revert function lockContracts() external /* onlyAdminOrMigrationManager */; /// Unlocks all the managed contracts /// @dev governance function called only by the migrationManager or registryAdmin function unlockContracts() external /* onlyAdminOrMigrationManager */; /// Updates a manager address and emits a corresponding event /// @dev governance function called only by the registryAdmin /// @dev the managers list is a flexible list of role to the manager's address /// @param role is the managers' role name, for example "functionalManager" /// @param manager is the manager updated address function setManager(string calldata role, address manager) external /* onlyAdmin */; /// Returns the current address of the given manager /// @param role is the manager name, used to identify it /// @return addr is the manager updated address function getManager(string calldata role) external view returns (address); /// Sets a new contract registry to migrate to /// @dev governance function called only by the registryAdmin /// @dev updates the registry address record in all the managed contracts /// @dev by tracking the emitted ContractRegistryUpdated, tools can track the up to date contracts /// @param newRegistry is the new registry contract function setNewContractRegistry(IContractRegistry newRegistry) external /* onlyAdmin */; /// Returns the previous contract registry address /// @dev used when the setting the contract as a new registry to assure a valid registry /// @return previousContractRegistry is the previous contract registry function getPreviousContractRegistry() external view returns (address); } // File: contracts/spec_interfaces/IContractRegistryAccessor.sol pragma solidity 0.6.12; interface IContractRegistryAccessor { /// Sets the contract registry address /// @dev governance function called only by an admin /// @param newRegistry is the new registry contract function setContractRegistry(IContractRegistry newRegistry) external /* onlyAdmin */; /// Returns the contract registry address /// @return contractRegistry is the contract registry address function getContractRegistry() external view returns (IContractRegistry contractRegistry); function setRegistryAdmin(address _registryAdmin) external /* onlyInitializationAdmin */; } // File: @openzeppelin/contracts/GSN/Context.sol pragma solidity ^0.6.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: contracts/WithClaimableRegistryManagement.sol pragma solidity 0.6.12; /** * @title Claimable * @dev Extension for the Ownable contract, where the ownership needs to be claimed. * This allows the new owner to accept the transfer. */ contract WithClaimableRegistryManagement is Context { address private _registryAdmin; address private _pendingRegistryAdmin; event RegistryManagementTransferred(address indexed previousRegistryAdmin, address indexed newRegistryAdmin); /** * @dev Initializes the contract setting the deployer as the initial registryRegistryAdmin. */ constructor () internal { address msgSender = _msgSender(); _registryAdmin = msgSender; emit RegistryManagementTransferred(address(0), msgSender); } /** * @dev Returns the address of the current registryAdmin. */ function registryAdmin() public view returns (address) { return _registryAdmin; } /** * @dev Throws if called by any account other than the registryAdmin. */ modifier onlyRegistryAdmin() { require(isRegistryAdmin(), "WithClaimableRegistryManagement: caller is not the registryAdmin"); _; } /** * @dev Returns true if the caller is the current registryAdmin. */ function isRegistryAdmin() public view returns (bool) { return _msgSender() == _registryAdmin; } /** * @dev Leaves the contract without registryAdmin. It will not be possible to call * `onlyManager` functions anymore. Can only be called by the current registryAdmin. * * NOTE: Renouncing registryManagement will leave the contract without an registryAdmin, * thereby removing any functionality that is only available to the registryAdmin. */ function renounceRegistryManagement() public onlyRegistryAdmin { emit RegistryManagementTransferred(_registryAdmin, address(0)); _registryAdmin = address(0); } /** * @dev Transfers registryManagement of the contract to a new account (`newManager`). */ function _transferRegistryManagement(address newRegistryAdmin) internal { require(newRegistryAdmin != address(0), "RegistryAdmin: new registryAdmin is the zero address"); emit RegistryManagementTransferred(_registryAdmin, newRegistryAdmin); _registryAdmin = newRegistryAdmin; } /** * @dev Modifier throws if called by any account other than the pendingManager. */ modifier onlyPendingRegistryAdmin() { require(msg.sender == _pendingRegistryAdmin, "Caller is not the pending registryAdmin"); _; } /** * @dev Allows the current registryAdmin to set the pendingManager address. * @param newRegistryAdmin The address to transfer registryManagement to. */ function transferRegistryManagement(address newRegistryAdmin) public onlyRegistryAdmin { _pendingRegistryAdmin = newRegistryAdmin; } /** * @dev Allows the _pendingRegistryAdmin address to finalize the transfer. */ function claimRegistryManagement() external onlyPendingRegistryAdmin { _transferRegistryManagement(_pendingRegistryAdmin); _pendingRegistryAdmin = address(0); } /** * @dev Returns the current pendingRegistryAdmin */ function pendingRegistryAdmin() public view returns (address) { return _pendingRegistryAdmin; } } // File: contracts/Initializable.sol pragma solidity 0.6.12; contract Initializable { address private _initializationAdmin; event InitializationComplete(); /// Constructor /// Sets the initializationAdmin to the contract deployer /// The initialization admin may call any manager only function until initializationComplete constructor() public{ _initializationAdmin = msg.sender; } modifier onlyInitializationAdmin() { require(msg.sender == initializationAdmin(), "sender is not the initialization admin"); _; } /* * External functions */ /// Returns the initializationAdmin address function initializationAdmin() public view returns (address) { return _initializationAdmin; } /// Finalizes the initialization and revokes the initializationAdmin role function initializationComplete() external onlyInitializationAdmin { _initializationAdmin = address(0); emit InitializationComplete(); } /// Checks if the initialization was completed function isInitializationComplete() public view returns (bool) { return _initializationAdmin == address(0); } } // File: contracts/ContractRegistryAccessor.sol pragma solidity 0.6.12; contract ContractRegistryAccessor is IContractRegistryAccessor, WithClaimableRegistryManagement, Initializable { IContractRegistry private contractRegistry; /// Constructor /// @param _contractRegistry is the contract registry address /// @param _registryAdmin is the registry admin address constructor(IContractRegistry _contractRegistry, address _registryAdmin) public { require(address(_contractRegistry) != address(0), "_contractRegistry cannot be 0"); setContractRegistry(_contractRegistry); _transferRegistryManagement(_registryAdmin); } modifier onlyAdmin { require(isAdmin(), "sender is not an admin (registryManger or initializationAdmin)"); _; } modifier onlyMigrationManager { require(isMigrationManager(), "sender is not the migration manager"); _; } modifier onlyFunctionalManager { require(isFunctionalManager(), "sender is not the functional manager"); _; } /// Checks whether the caller is Admin: either the contract registry, the registry admin, or the initialization admin function isAdmin() internal view returns (bool) { return msg.sender == address(contractRegistry) || msg.sender == registryAdmin() || msg.sender == initializationAdmin(); } /// Checks whether the caller is a specific manager role or and Admin /// @dev queries the registry contract for the up to date manager assignment function isManager(string memory role) internal view returns (bool) { IContractRegistry _contractRegistry = contractRegistry; return isAdmin() || _contractRegistry != IContractRegistry(0) && contractRegistry.getManager(role) == msg.sender; } /// Checks whether the caller is the migration manager function isMigrationManager() internal view returns (bool) { return isManager('migrationManager'); } /// Checks whether the caller is the functional manager function isFunctionalManager() internal view returns (bool) { return isManager('functionalManager'); } /* * Contract getters, return the address of a contract by calling the contract registry */ function getProtocolContract() internal view returns (address) { return contractRegistry.getContract("protocol"); } function getStakingRewardsContract() internal view returns (address) { return contractRegistry.getContract("stakingRewards"); } function getFeesAndBootstrapRewardsContract() internal view returns (address) { return contractRegistry.getContract("feesAndBootstrapRewards"); } function getCommitteeContract() internal view returns (address) { return contractRegistry.getContract("committee"); } function getElectionsContract() internal view returns (address) { return contractRegistry.getContract("elections"); } function getDelegationsContract() internal view returns (address) { return contractRegistry.getContract("delegations"); } function getGuardiansRegistrationContract() internal view returns (address) { return contractRegistry.getContract("guardiansRegistration"); } function getCertificationContract() internal view returns (address) { return contractRegistry.getContract("certification"); } function getStakingContract() internal view returns (address) { return contractRegistry.getContract("staking"); } function getSubscriptionsContract() internal view returns (address) { return contractRegistry.getContract("subscriptions"); } function getStakingRewardsWallet() internal view returns (address) { return contractRegistry.getContract("stakingRewardsWallet"); } function getBootstrapRewardsWallet() internal view returns (address) { return contractRegistry.getContract("bootstrapRewardsWallet"); } function getGeneralFeesWallet() internal view returns (address) { return contractRegistry.getContract("generalFeesWallet"); } function getCertifiedFeesWallet() internal view returns (address) { return contractRegistry.getContract("certifiedFeesWallet"); } function getStakingContractHandler() internal view returns (address) { return contractRegistry.getContract("stakingContractHandler"); } /* * Governance functions */ event ContractRegistryAddressUpdated(address addr); /// Sets the contract registry address /// @dev governance function called only by an admin /// @param newContractRegistry is the new registry contract function setContractRegistry(IContractRegistry newContractRegistry) public override onlyAdmin { require(newContractRegistry.getPreviousContractRegistry() == address(contractRegistry), "new contract registry must provide the previous contract registry"); contractRegistry = newContractRegistry; emit ContractRegistryAddressUpdated(address(newContractRegistry)); } /// Returns the contract registry that the contract is set to use /// @return contractRegistry is the registry contract address function getContractRegistry() public override view returns (IContractRegistry) { return contractRegistry; } function setRegistryAdmin(address _registryAdmin) external override onlyInitializationAdmin { _transferRegistryManagement(_registryAdmin); } } // File: contracts/spec_interfaces/ILockable.sol pragma solidity 0.6.12; /// @title lockable contract interface, allows to lock a contract interface ILockable { event Locked(); event Unlocked(); /// Locks the contract to external non-governance function calls /// @dev governance function called only by the migration manager or an admin /// @dev typically called by the registry contract upon locking all managed contracts /// @dev getters and migration functions remain active also for locked contracts /// @dev checked by the onlyWhenActive modifier function lock() external /* onlyMigrationManager */; /// Unlocks the contract /// @dev governance function called only by the migration manager or an admin /// @dev typically called by the registry contract upon unlocking all managed contracts function unlock() external /* onlyMigrationManager */; /// Returns the contract locking status /// @return isLocked is a bool indicating the contract is locked function isLocked() view external returns (bool); } // File: contracts/Lockable.sol pragma solidity 0.6.12; /// @title lockable contract contract Lockable is ILockable, ContractRegistryAccessor { bool public locked; /// Constructor /// @param _contractRegistry is the contract registry address /// @param _registryAdmin is the registry admin address constructor(IContractRegistry _contractRegistry, address _registryAdmin) ContractRegistryAccessor(_contractRegistry, _registryAdmin) public {} /// Locks the contract to external non-governance function calls /// @dev governance function called only by the migration manager or an admin /// @dev typically called by the registry contract upon locking all managed contracts /// @dev getters and migration functions remain active also for locked contracts /// @dev checked by the onlyWhenActive modifier function lock() external override onlyMigrationManager { locked = true; emit Locked(); } /// Unlocks the contract /// @dev governance function called only by the migration manager or an admin /// @dev typically called by the registry contract upon unlocking all managed contracts function unlock() external override onlyMigrationManager { locked = false; emit Unlocked(); } /// Returns the contract locking status /// @return isLocked is a bool indicating the contract is locked function isLocked() external override view returns (bool) { return locked; } modifier onlyWhenActive() { require(!locked, "contract is locked for this operation"); _; } } // File: contracts/ManagedContract.sol pragma solidity 0.6.12; /// @title managed contract contract ManagedContract is IManagedContract, Lockable { /// @param _contractRegistry is the contract registry address /// @param _registryAdmin is the registry admin address constructor(IContractRegistry _contractRegistry, address _registryAdmin) Lockable(_contractRegistry, _registryAdmin) public {} /// Refreshes the address of the other contracts the contract interacts with /// @dev called by the registry contract upon an update of a contract in the registry function refreshContracts() virtual override external {} } // File: contracts/Delegations.sol pragma solidity 0.6.12; /// @title Delegations contract contract Delegations is IDelegations, IStakeChangeNotifier, ManagedContract { using SafeMath for uint256; using SafeMath96 for uint96; address constant public VOID_ADDR = address(-1); struct StakeOwnerData { address delegation; uint96 stake; } mapping(address => StakeOwnerData) public stakeOwnersData; mapping(address => uint256) public uncappedDelegatedStake; uint256 totalDelegatedStake; struct DelegateStatus { address addr; uint256 uncappedDelegatedStake; bool isSelfDelegating; uint256 delegatedStake; uint96 selfDelegatedStake; } /// Constructor /// @param _contractRegistry is the contract registry address /// @param _registryAdmin is the registry admin address constructor(IContractRegistry _contractRegistry, address _registryAdmin) ManagedContract(_contractRegistry, _registryAdmin) public { address VOID_ADDRESS_DUMMY_DELEGATION = address(-2); assert(VOID_ADDR != VOID_ADDRESS_DUMMY_DELEGATION && VOID_ADDR != address(0) && VOID_ADDRESS_DUMMY_DELEGATION != address(0)); stakeOwnersData[VOID_ADDR].delegation = VOID_ADDRESS_DUMMY_DELEGATION; } modifier onlyStakingContractHandler() { require(msg.sender == address(stakingContractHandler), "caller is not the staking contract handler"); _; } /* * External functions */ /// Delegate your stake /// @dev updates the election contract on the changes in the delegated stake /// @dev updates the rewards contract on the upcoming change in the delegator's delegation state /// @param to is the address to delegate to function delegate(address to) external override onlyWhenActive { delegateFrom(msg.sender, to); } /// Refresh the address stake for delegation power based on the staking contract /// @dev Disabled stake change update notifications from the staking contract may create mismatches /// @dev refreshStake re-syncs the stake data with the staking contract /// @param addr is the address to refresh its stake function refreshStake(address addr) external override onlyWhenActive { _stakeChange(addr, stakingContractHandler.getStakeBalanceOf(addr)); } /// Refresh the addresses stake for delegation power based on the staking contract /// @dev Batched version of refreshStake /// @dev Disabled stake change update notifications from the staking contract may create mismatches /// @dev refreshStakeBatch re-syncs the stake data with the staking contract /// @param addrs is the list of addresses to refresh their stake function refreshStakeBatch(address[] calldata addrs) external override onlyWhenActive { for (uint i = 0; i < addrs.length; i++) { _stakeChange(addrs[i], stakingContractHandler.getStakeBalanceOf(addrs[i])); } } /// Returns the delegate address of the given address /// @param addr is the address to query /// @return delegation is the address the addr delegated to function getDelegation(address addr) external override view returns (address) { return getStakeOwnerData(addr).delegation; } /// Returns a delegator info /// @param addr is the address to query /// @return delegation is the address the addr delegated to /// @return delegatorStake is the stake of the delegator as reflected in the delegation contract function getDelegationInfo(address addr) external override view returns (address delegation, uint256 delegatorStake) { StakeOwnerData memory data = getStakeOwnerData(addr); return (data.delegation, data.stake); } /// Returns the delegated stake of an addr /// @dev an address that is not self delegating has a 0 delegated stake /// @param addr is the address to query /// @return delegatedStake is the address delegated stake function getDelegatedStake(address addr) external override view returns (uint256) { return getDelegateStatus(addr).delegatedStake; } /// Returns the total delegated stake /// @dev delegatedStake - the total stake delegated to an address that is self delegating /// @dev the delegated stake of a non self-delegated address is 0 /// @return totalDelegatedStake is the total delegatedStake of all the addresses function getTotalDelegatedStake() external override view returns (uint256) { return totalDelegatedStake; } /* * Notifications from staking contract (IStakeChangeNotifier) */ /// Notifies of stake change event. /// @param _stakeOwner is the address of the subject stake owner. /// @param _updatedStake is the updated total staked amount. function stakeChange(address _stakeOwner, uint256, bool, uint256 _updatedStake) external override onlyStakingContractHandler onlyWhenActive { _stakeChange(_stakeOwner, _updatedStake); } /// Notifies of multiple stake change events. /// @param _stakeOwners is the addresses of subject stake owners. /// @param _amounts is the differences in total staked amounts. /// @param _signs is the signs of the added (true) or subtracted (false) amounts. /// @param _updatedStakes is the updated total staked amounts. function stakeChangeBatch(address[] calldata _stakeOwners, uint256[] calldata _amounts, bool[] calldata _signs, uint256[] calldata _updatedStakes) external override onlyStakingContractHandler onlyWhenActive { uint batchLength = _stakeOwners.length; require(batchLength == _amounts.length, "_stakeOwners, _amounts - array length mismatch"); require(batchLength == _signs.length, "_stakeOwners, _signs - array length mismatch"); require(batchLength == _updatedStakes.length, "_stakeOwners, _updatedStakes - array length mismatch"); for (uint i = 0; i < _stakeOwners.length; i++) { _stakeChange(_stakeOwners[i], _updatedStakes[i]); } } /// Notifies of stake migration event. /// @dev Empty function. A staking contract migration may be handled in the future in the StakingContractHandler /// @param _stakeOwner address The address of the subject stake owner. /// @param _amount uint256 The migrated amount. function stakeMigration(address _stakeOwner, uint256 _amount) external override onlyStakingContractHandler onlyWhenActive {} /* * Governance functions */ /// Imports delegations during initial migration /// @dev initialization function called only by the initializationManager /// @dev Does not update the Rewards or Election contracts /// @dev assumes deactivated Rewards /// @param from is a list of delegator addresses /// @param to is the address the delegators delegate to function importDelegations(address[] calldata from, address to) external override onlyInitializationAdmin { require(to != address(0), "to must be a non zero address"); require(from.length > 0, "from array must contain at least one address"); (uint96 stakingRewardsPerWeight, ) = stakingRewardsContract.getStakingRewardsState(); require(stakingRewardsPerWeight == 0, "no rewards may be allocated prior to importing delegations"); uint256 uncappedDelegatedStakeDelta = 0; StakeOwnerData memory data; uint256 newTotalDelegatedStake = totalDelegatedStake; DelegateStatus memory delegateStatus = getDelegateStatus(to); IStakingContractHandler _stakingContractHandler = stakingContractHandler; uint256 delegatorUncapped; uint256[] memory delegatorsStakes = new uint256[](from.length); for (uint i = 0; i < from.length; i++) { data = stakeOwnersData[from[i]]; require(data.delegation == address(0), "import allowed only for uninitialized accounts. existing delegation detected"); require(from[i] != to, "import cannot be used for self-delegation (already self delegated)"); require(data.stake == 0 , "import allowed only for uninitialized accounts. existing stake detected"); // from[i] stops being self delegating. any uncappedDelegatedStake it has now stops being counted towards totalDelegatedStake delegatorUncapped = uncappedDelegatedStake[from[i]]; if (delegatorUncapped > 0) { newTotalDelegatedStake = newTotalDelegatedStake.sub(delegatorUncapped); emit DelegatedStakeChanged( from[i], 0, 0, from[i], 0 ); } // update state data.delegation = to; data.stake = uint96(_stakingContractHandler.getStakeBalanceOf(from[i])); stakeOwnersData[from[i]] = data; uncappedDelegatedStakeDelta = uncappedDelegatedStakeDelta.add(data.stake); // store individual stake for event delegatorsStakes[i] = data.stake; emit Delegated(from[i], to); emit DelegatedStakeChanged( to, delegateStatus.selfDelegatedStake, delegateStatus.isSelfDelegating ? delegateStatus.delegatedStake.add(uncappedDelegatedStakeDelta) : 0, from[i], data.stake ); } // update totals uncappedDelegatedStake[to] = uncappedDelegatedStake[to].add(uncappedDelegatedStakeDelta); if (delegateStatus.isSelfDelegating) { newTotalDelegatedStake = newTotalDelegatedStake.add(uncappedDelegatedStakeDelta); } totalDelegatedStake = newTotalDelegatedStake; // emit events emit DelegationsImported(from, to); } /// Initializes the delegation of an address during initial migration /// @dev initialization function called only by the initializationManager /// @dev behaves identically to a delegate transaction sent by the delegator /// @param from is the delegator addresses /// @param to is the delegator delegates to function initDelegation(address from, address to) external override onlyInitializationAdmin { delegateFrom(from, to); emit DelegationInitialized(from, to); } /* * Private functions */ /// Generates and returns an internal memory structure with a Delegate status /// @dev updated based on the up to date state /// @dev status.addr is the queried address /// @dev status.uncappedDelegatedStake is the amount delegated to address including self-delegated stake /// @dev status.isSelfDelegating indicates whether the address is self-delegated /// @dev status.selfDelegatedStake if the addr is self-delegated is the addr self stake. 0 if not self-delegated /// @dev status.delegatedStake if the addr is self-delegated is the mount delegated to address. 0 if not self-delegated function getDelegateStatus(address addr) private view returns (DelegateStatus memory status) { StakeOwnerData memory data = getStakeOwnerData(addr); status.addr = addr; status.uncappedDelegatedStake = uncappedDelegatedStake[addr]; status.isSelfDelegating = data.delegation == addr; status.selfDelegatedStake = status.isSelfDelegating ? data.stake : 0; status.delegatedStake = status.isSelfDelegating ? status.uncappedDelegatedStake : 0; return status; } /// Returns an address stake and delegation data. /// @dev implicitly self-delegated addresses (delegation = 0) return delegation to the address function getStakeOwnerData(address addr) private view returns (StakeOwnerData memory data) { data = stakeOwnersData[addr]; data.delegation = (data.delegation == address(0)) ? addr : data.delegation; return data; } struct DelegateFromVars { DelegateStatus prevDelegateStatusBefore; DelegateStatus newDelegateStatusBefore; DelegateStatus prevDelegateStatusAfter; DelegateStatus newDelegateStatusAfter; } /// Handles a delegation change /// @dev notifies the rewards contract on the expected change (with data prior to the change) /// @dev updates the impacted delegates delegated stake and the total stake /// @dev notifies the election contract on changes in the impacted delegates delegated stake /// @param from is the delegator address /// @param to is the delegate address function delegateFrom(address from, address to) private { require(to != address(0), "cannot delegate to a zero address"); DelegateFromVars memory vars; StakeOwnerData memory delegatorData = getStakeOwnerData(from); address prevDelegate = delegatorData.delegation; if (to == prevDelegate) return; // Delegation hasn't changed // Optimization - no need for the full flow in the case of a zero staked delegator with no delegations if (delegatorData.stake == 0 && uncappedDelegatedStake[from] == 0) { stakeOwnersData[from].delegation = to; emit Delegated(from, to); return; } vars.prevDelegateStatusBefore = getDelegateStatus(prevDelegate); vars.newDelegateStatusBefore = getDelegateStatus(to); stakingRewardsContract.delegationWillChange(prevDelegate, vars.prevDelegateStatusBefore.delegatedStake, from, delegatorData.stake, to, vars.newDelegateStatusBefore.delegatedStake); stakeOwnersData[from].delegation = to; uint256 delegatorStake = delegatorData.stake; uncappedDelegatedStake[prevDelegate] = vars.prevDelegateStatusBefore.uncappedDelegatedStake.sub(delegatorStake); uncappedDelegatedStake[to] = vars.newDelegateStatusBefore.uncappedDelegatedStake.add(delegatorStake); vars.prevDelegateStatusAfter = getDelegateStatus(prevDelegate); vars.newDelegateStatusAfter = getDelegateStatus(to); uint256 _totalDelegatedStake = totalDelegatedStake.sub( vars.prevDelegateStatusBefore.delegatedStake ).add( vars.prevDelegateStatusAfter.delegatedStake ).sub( vars.newDelegateStatusBefore.delegatedStake ).add( vars.newDelegateStatusAfter.delegatedStake ); totalDelegatedStake = _totalDelegatedStake; emit Delegated(from, to); IElections _electionsContract = electionsContract; if (vars.prevDelegateStatusBefore.delegatedStake != vars.prevDelegateStatusAfter.delegatedStake) { _electionsContract.delegatedStakeChange( prevDelegate, vars.prevDelegateStatusAfter.selfDelegatedStake, vars.prevDelegateStatusAfter.delegatedStake, _totalDelegatedStake ); emit DelegatedStakeChanged( prevDelegate, vars.prevDelegateStatusAfter.selfDelegatedStake, vars.prevDelegateStatusAfter.delegatedStake, from, 0 ); } if (vars.newDelegateStatusBefore.delegatedStake != vars.newDelegateStatusAfter.delegatedStake) { _electionsContract.delegatedStakeChange( to, vars.newDelegateStatusAfter.selfDelegatedStake, vars.newDelegateStatusAfter.delegatedStake, _totalDelegatedStake ); emit DelegatedStakeChanged( to, vars.newDelegateStatusAfter.selfDelegatedStake, vars.newDelegateStatusAfter.delegatedStake, from, delegatorStake ); } } /// Handles a change in a stake owner stake /// @dev notifies the rewards contract on the expected change (with data prior to the change) /// @dev updates the impacted delegate delegated stake and the total stake /// @dev notifies the election contract on changes in the impacted delegate delegated stake /// @param _stakeOwner is the stake owner /// @param _updatedStake is the stake owner stake after the change function _stakeChange(address _stakeOwner, uint256 _updatedStake) private { StakeOwnerData memory stakeOwnerDataBefore = getStakeOwnerData(_stakeOwner); DelegateStatus memory delegateStatusBefore = getDelegateStatus(stakeOwnerDataBefore.delegation); uint256 prevUncappedStake = delegateStatusBefore.uncappedDelegatedStake; uint256 newUncappedStake = prevUncappedStake.sub(stakeOwnerDataBefore.stake).add(_updatedStake); stakingRewardsContract.delegationWillChange(stakeOwnerDataBefore.delegation, delegateStatusBefore.delegatedStake, _stakeOwner, stakeOwnerDataBefore.stake, stakeOwnerDataBefore.delegation, delegateStatusBefore.delegatedStake); uncappedDelegatedStake[stakeOwnerDataBefore.delegation] = newUncappedStake; require(uint256(uint96(_updatedStake)) == _updatedStake, "Delegations::updatedStakes value too big (>96 bits)"); stakeOwnersData[_stakeOwner].stake = uint96(_updatedStake); uint256 _totalDelegatedStake = totalDelegatedStake; if (delegateStatusBefore.isSelfDelegating) { _totalDelegatedStake = _totalDelegatedStake.sub(stakeOwnerDataBefore.stake).add(_updatedStake); totalDelegatedStake = _totalDelegatedStake; } DelegateStatus memory delegateStatusAfter = getDelegateStatus(stakeOwnerDataBefore.delegation); electionsContract.delegatedStakeChange( stakeOwnerDataBefore.delegation, delegateStatusAfter.selfDelegatedStake, delegateStatusAfter.delegatedStake, _totalDelegatedStake ); if (_updatedStake != stakeOwnerDataBefore.stake) { emit DelegatedStakeChanged( stakeOwnerDataBefore.delegation, delegateStatusAfter.selfDelegatedStake, delegateStatusAfter.delegatedStake, _stakeOwner, _updatedStake ); } } /* * Contracts topology / registry interface */ IElections electionsContract; IStakingRewards stakingRewardsContract; IStakingContractHandler stakingContractHandler; /// Refreshes the address of the other contracts the contract interacts with /// @dev called by the registry contract upon an update of a contract in the registry function refreshContracts() external override { electionsContract = IElections(getElectionsContract()); stakingContractHandler = IStakingContractHandler(getStakingContractHandler()); stakingRewardsContract = IStakingRewards(getStakingRewardsContract()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IContractRegistry","name":"_contractRegistry","type":"address"},{"internalType":"address","name":"_registryAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"ContractRegistryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Delegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"selfDelegatedStake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"delegatedStake","type":"uint256"},{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"uint256","name":"delegatorContributedStake","type":"uint256"}],"name":"DelegatedStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"DelegationInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"from","type":"address[]"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"DelegationsImported","type":"event"},{"anonymous":false,"inputs":[],"name":"InitializationComplete","type":"event"},{"anonymous":false,"inputs":[],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousRegistryAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newRegistryAdmin","type":"address"}],"name":"RegistryManagementTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Unlocked","type":"event"},{"inputs":[],"name":"VOID_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRegistryManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getContractRegistry","outputs":[{"internalType":"contract IContractRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getDelegatedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getDelegation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getDelegationInfo","outputs":[{"internalType":"address","name":"delegation","type":"address"},{"internalType":"uint256","name":"delegatorStake","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDelegatedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"from","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"importDelegations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"initDelegation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializationAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initializationComplete","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitializationComplete","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRegistryAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingRegistryAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refreshContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"refreshStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"}],"name":"refreshStakeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registryAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceRegistryManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IContractRegistry","name":"newContractRegistry","type":"address"}],"name":"setContractRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_registryAdmin","type":"address"}],"name":"setRegistryAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakeOwner","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"_updatedStake","type":"uint256"}],"name":"stakeChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_stakeOwners","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bool[]","name":"_signs","type":"bool[]"},{"internalType":"uint256[]","name":"_updatedStakes","type":"uint256[]"}],"name":"stakeChangeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakeOwner","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakeOwnersData","outputs":[{"internalType":"address","name":"delegation","type":"address"},{"internalType":"uint96","name":"stake","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistryAdmin","type":"address"}],"name":"transferRegistryManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"uncappedDelegatedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200368238038062003682833981810160405260408110156200003757600080fd5b50805160209091015181818181818160006200005262000171565b600080546001600160a01b0319166001600160a01b03831690811782556040519293509160008051602062003662833981519152908290a350600280546001600160a01b031916331790556001600160a01b038216620000f9576040805162461bcd60e51b815260206004820152601d60248201527f5f636f6e747261637452656769737472792063616e6e6f742062652030000000604482015290519081900360640190fd5b620001048262000175565b6200010f81620002cd565b506001199450620001209350505050565b6001600160a01b03600081905260046020527f3569f564c44c2d85a381a1123e4afebef0204e2bb799b725ae533e5c15f0829d8054919092166001600160a01b031990911617905550620003de9050565b3390565b6200017f6200035e565b620001bc5760405162461bcd60e51b815260040180806020018281038252603e815260200180620035af603e913960400191505060405180910390fd5b600354604080516301e32edf60e21b815290516001600160a01b039283169284169163078cbb7c916004808301926020929190829003018186803b1580156200020457600080fd5b505afa15801562000219573d6000803e3d6000fd5b505050506040513d60208110156200023057600080fd5b50516001600160a01b031614620002795760405162461bcd60e51b8152600401808060200182810382526041815260200180620035ed6041913960600191505060405180910390fd5b600380546001600160a01b0383166001600160a01b0319909116811790915560408051918252517ffea2d033438b968078a6264409d0104b5f3d2ce7b795afc74918e70f3534f22b9181900360200190a150565b6001600160a01b038116620003145760405162461bcd60e51b81526004018080602001828103825260348152602001806200362e6034913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216916000805160206200366283398151915291a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6003546000906001600160a01b031633148062000395575062000380620003c0565b6001600160a01b0316336001600160a01b0316145b80620003bb5750620003a6620003cf565b6001600160a01b0316336001600160a01b0316145b905090565b6000546001600160a01b031690565b6002546001600160a01b031690565b6131c180620003ee6000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638faf2f061161010f578063cf3b670b116100a2578063efb47c7e11610071578063efb47c7e1461067b578063f83d08ba146106f4578063fab46d66146106fc578063fcd13d6514610745576101f0565b8063cf3b670b1461065b578063d252352614610663578063e4e992221461066b578063eec0701f14610673576101f0565b8063a69df4b5116100de578063a69df4b514610617578063acdb8e041461061f578063ce257ab814610627578063cf30901214610653576101f0565b80638faf2f061461044b57806390ef9d3f14610453578063a39539c6146105b9578063a4e2d6341461060f576101f0565b806339069d8c116101875780635c19a95c116101565780635c19a95c146103ef5780635f94cd9c1461041557806374c16b231461041d5780637c47c16d14610425576101f0565b806339069d8c1461036d5780633dee40571461039357806348106fe3146103c15780635605a4e5146103c9576101f0565b80632987cea0116101c35780632987cea0146102f55780632a1fac721461031b5780632b29376814610323578063333df15414610365576101f0565b806305efb9ed146101f5578063071880e8146102675780630e3b7c951461029f5780631a0b2c4f146102d9575b600080fd5b6102656004803603602081101561020b57600080fd5b81019060208101813564010000000081111561022657600080fd5b82018360208201111561023857600080fd5b8035906020019184602083028401116401000000008311171561025a57600080fd5b50909250905061076b565b005b61028d6004803603602081101561027d57600080fd5b50356001600160a01b0316610896565b60408051918252519081900360200190f35b610265600480360360808110156102b557600080fd5b506001600160a01b03813516906020810135906040810135151590606001356108a8565b6102e161095b565b604080519115158252519081900360200190f35b6102656004803603602081101561030b57600080fd5b50356001600160a01b031661097f565b6102656109fc565b6103496004803603602081101561033957600080fd5b50356001600160a01b0316610aa6565b604080516001600160a01b039092168252519081900360200190f35b610349610ab8565b6102656004803603602081101561038357600080fd5b50356001600160a01b0316610ac7565b610265600480360360408110156103a957600080fd5b506001600160a01b0381358116916020013516610b2a565b6102e1610bcf565b610265600480360360208110156103df57600080fd5b50356001600160a01b0316610bdf565b6102656004803603602081101561040557600080fd5b50356001600160a01b0316610ca2565b610349610d06565b610349610d15565b61028d6004803603602081101561043b57600080fd5b50356001600160a01b0316610d24565b610349610d39565b6102656004803603608081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460208302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184602083028401116401000000008311171561050a57600080fd5b91939092909160208101903564010000000081111561052857600080fd5b82018360208201111561053a57600080fd5b8035906020019184602083028401116401000000008311171561055c57600080fd5b91939092909160208101903564010000000081111561057a57600080fd5b82018360208201111561058c57600080fd5b803590602001918460208302840111640100000000831117156105ae57600080fd5b509092509050610d5d565b6105df600480360360208110156105cf57600080fd5b50356001600160a01b0316610f11565b604080516001600160a01b0390931683526bffffffffffffffffffffffff90911660208301528051918290030190f35b6102e1610f54565b610265610f75565b61026561100b565b6102656004803603604081101561063d57600080fd5b506001600160a01b0381351690602001356110b0565b6102e1611157565b61028d611178565b61026561117e565b610349611206565b610265611215565b6102656004803603604081101561069157600080fd5b8101906020810181356401000000008111156106ac57600080fd5b8201836020820111156106be57600080fd5b803590602001918460208302840111640100000000831117156106e057600080fd5b9193509150356001600160a01b03166112d7565b610265611afd565b6107226004803603602081101561071257600080fd5b50356001600160a01b0316611baa565b604080516001600160a01b03909316835260208301919091528051918290030190f35b6102656004803603602081101561075b57600080fd5b50356001600160a01b0316611bdf565b60035474010000000000000000000000000000000000000000900460ff16156107c55760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b60005b81811015610891576108898383838181106107df57fe5b6009546001600160a01b036020909202939093013581169216905063e9aea8c886868681811061080b57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561085857600080fd5b505afa15801561086c573d6000803e3d6000fd5b505050506040513d602081101561088257600080fd5b5051611d5f565b6001016107c8565b505050565b60056020526000908152604090205481565b6009546001600160a01b031633146108f15760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff161561094b5760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b6109558482611d5f565b50505050565b600080546001600160a01b03166109706120c3565b6001600160a01b031614905090565b61098761095b565b6109c25760405162461bcd60e51b815260040180806020018281038252604081526020018061311e6040913960400191505060405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b610a04610ab8565b6001600160a01b0316336001600160a01b031614610a535760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040517f2a2b3ea974fb057582c3b210ef8b5f81492d15673f49d4384bfa3b896a964c3c90600090a1565b6000610ab1826120c7565b5192915050565b6002546001600160a01b031690565b610acf610ab8565b6001600160a01b0316336001600160a01b031614610b1e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b610b2781612146565b50565b610b32610ab8565b6001600160a01b0316336001600160a01b031614610b815760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b610b8b82826121fe565b806001600160a01b0316826001600160a01b03167fcf1993798656f790fc10bf446b6c785f2df06395b16dbb876003a2b018a6465860405160405180910390a35050565b6002546001600160a01b03161590565b60035474010000000000000000000000000000000000000000900460ff1615610c395760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b600954604080517fe9aea8c80000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529151610b27938593169163e9aea8c8916024808301926020929190829003018186803b15801561085857600080fd5b60035474010000000000000000000000000000000000000000900460ff1615610cfc5760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b610b2733826121fe565b6001546001600160a01b031690565b6000546001600160a01b031690565b6000610d2f826127bd565b6060015192915050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b6009546001600160a01b03163314610da65760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff1615610e005760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b86858114610e3f5760405162461bcd60e51b815260040180806020018281038252602e81526020018061315e602e913960400191505060405180910390fd5b808414610e7d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612f1c602c913960400191505060405180910390fd5b808214610ebb5760405162461bcd60e51b8152600401808060200182810382526034815260200180612f726034913960400191505060405180910390fd5b60005b88811015610f0557610efd8a8a83818110610ed557fe5b905060200201356001600160a01b0316858584818110610ef157fe5b90506020020135611d5f565b600101610ebe565b50505050505050505050565b6004602052600090815260409020546001600160a01b038116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b60035474010000000000000000000000000000000000000000900460ff1690565b610f7d61284f565b610fb85760405162461bcd60e51b8152600401808060200182810382526023815260200180612fe06023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f19aad37188a1d3921e29eb3c66acf43d81975e107cb650d58cca878627955fd690600090a1565b61101361095b565b61104e5760405162461bcd60e51b815260040180806020018281038252604081526020018061311e6040913960400191505060405180910390fd5b600080546040516001600160a01b03909116907f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6009546001600160a01b031633146110f95760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff16156111535760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b5050565b60035474010000000000000000000000000000000000000000900460ff1681565b60065490565b6001546001600160a01b031633146111c75760405162461bcd60e51b8152600401808060200182810382526027815260200180612ecf6027913960400191505060405180910390fd5b6001546111dc906001600160a01b0316612146565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6003546001600160a01b031690565b61121d612894565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561125d612955565b600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561129d6129e5565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6112df610ab8565b6001600160a01b0316336001600160a01b03161461132e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601d60248201527f746f206d7573742062652061206e6f6e207a65726f2061646472657373000000604482015290519081900360640190fd5b816113c55760405162461bcd60e51b815260040180806020018281038252602c815260200180612ea3602c913960400191505060405180910390fd5b600854604080517fcfbe49f200000000000000000000000000000000000000000000000000000000815281516000936001600160a01b03169263cfbe49f29260048082019391829003018186803b15801561141f57600080fd5b505afa158015611433573d6000803e3d6000fd5b505050506040513d604081101561144957600080fd5b505190506bffffffffffffffffffffffff8116156114985760405162461bcd60e51b815260040180806020018281038252603a815260200180612fa6603a913960400191505060405180910390fd5b60006114a2612d38565b6006546114ad612d4f565b6114b6866127bd565b6009549091506001600160a01b0316600060608967ffffffffffffffff811180156114e057600080fd5b5060405190808252806020026020018201604052801561150a578160200160208202803683370190505b50905060005b8a811015611a0757600460008d8d8481811061152857fe5b602090810292909201356001600160a01b03908116845283830194909452506040918201600020825180840190935254928316808352740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff16908201529750156115c75760405162461bcd60e51b815260040180806020018281038252604c81526020018061307d604c913960600191505060405180910390fd5b896001600160a01b03168c8c838181106115dd57fe5b905060200201356001600160a01b03166001600160a01b031614156116335760405162461bcd60e51b8152600401808060200182810382526042815260200180612dbd6042913960600191505060405180910390fd5b60208701516bffffffffffffffffffffffff16156116825760405162461bcd60e51b81526004018080602001828103825260478152602001806130366047913960600191505060405180910390fd5b600560008d8d8481811061169257fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020549250600083111561176e576116d88684612a75565b95508b8b828181106116e657fe5b905060200201356001600160a01b03166001600160a01b03168c8c8381811061170b57fe5b905060200201356001600160a01b03166001600160a01b03167f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b600080600060405180848152602001838152602001828152602001935050505060405180910390a35b6001600160a01b03808b168852841663e9aea8c88d8d8481811061178e57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d602081101561180557600080fd5b50516bffffffffffffffffffffffff16602088015286600460008e8e8581811061182b57fe5b602090810292909201356001600160a01b0390811684528383019490945250604090910160002083518154948301517fffffffffffffffffffffffff000000000000000000000000000000000000000090951690841617909216740100000000000000000000000000000000000000006bffffffffffffffffffffffff94851602179091558801516118bf918a9116612abe565b975086602001516bffffffffffffffffffffffff168282815181106118e057fe5b602002602001018181525050896001600160a01b03168c8c8381811061190257fe5b905060200201356001600160a01b03166001600160a01b03167f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea260405160405180910390a38b8b8281811061195357fe5b905060200201356001600160a01b03166001600160a01b03168a6001600160a01b03167f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b876080015188604001516119ac5760006119bb565b60608901516119bb908d612abe565b8b6020015160405180846bffffffffffffffffffffffff168152602001838152602001826bffffffffffffffffffffffff168152602001935050505060405180910390a3600101611510565b506001600160a01b038916600090815260056020526040902054611a2b9088612abe565b6001600160a01b038a16600090815260056020526040908190209190915584015115611a5e57611a5b8588612abe565b94505b84600681905550886001600160a01b03167f7bedb97dca1b1ff98032eb6dad66e46016096d6341192dc7c3b1be79b0b1a93a8c8c60405180806020018281038252848482818152602001925060200280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039550909350505050a25050505050505050505050565b611b0561284f565b611b405760405162461bcd60e51b8152600401808060200182810382526023815260200180612fe06023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f0f2e5b6c72c6a4491efd919a9f9a409f324ef0708c11ee57d410c2cb06c0992b90600090a1565b600080611bb5612d38565b611bbe846120c7565b80516020909101519093506bffffffffffffffffffffffff16915050915091565b611be7612b18565b611c225760405162461bcd60e51b815260040180806020018281038252603e815260200180612e24603e913960400191505060405180910390fd5b600354604080517f078cbb7c00000000000000000000000000000000000000000000000000000000815290516001600160a01b039283169284169163078cbb7c916004808301926020929190829003018186803b158015611c8257600080fd5b505afa158015611c96573d6000803e3d6000fd5b505050506040513d6020811015611cac57600080fd5b50516001600160a01b031614611cf35760405162461bcd60e51b8152600401808060200182810382526041815260200180612e626041913960600191505060405180910390fd5b600380546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517ffea2d033438b968078a6264409d0104b5f3d2ce7b795afc74918e70f3534f22b9181900360200190a150565b611d67612d38565b611d70836120c7565b9050611d7a612d4f565b8151611d85906127bd565b90506000816020015190506000611dc185611dbb86602001516bffffffffffffffffffffffff1685612a7590919063ffffffff16565b90612abe565b600854855160608601516020880151604080517f8a1f3c020000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201819052602482018590528d861660448301526bffffffffffffffffffffffff9093166064820152608481019290925260a48201929092529051939450911691638a1f3c029160c48082019260009290919082900301818387803b158015611e6c57600080fd5b505af1158015611e80573d6000803e3d6000fd5b505085516001600160a01b0316600090815260056020526040902083905550506bffffffffffffffffffffffff85168514611eec5760405162461bcd60e51b81526004018080602001828103825260338152602001806130036033913960400191505060405180910390fd5b6001600160a01b03868116600090815260046020526040908190208054909216740100000000000000000000000000000000000000006bffffffffffffffffffffffff891602179091556006549084015115611f7357611f6b86611dbb87602001516bffffffffffffffffffffffff1684612a7590919063ffffffff16565b600681905590505b611f7b612d4f565b8551611f86906127bd565b600754875160808301516060840151604080517f61885df80000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201526bffffffffffffffffffffffff9093166024840152604483019190915260648201879052519394509116916361885df89160848082019260009290919082900301818387803b15801561201e57600080fd5b505af1158015612032573d6000803e3d6000fd5b5050505085602001516bffffffffffffffffffffffff1687146120b95785516080820151606080840151604080516bffffffffffffffffffffffff909416845260208401919091528281018b9052516001600160a01b03808d169416927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b92908290030190a35b5050505050505050565b3390565b6120cf612d38565b506001600160a01b03818116600090815260046020908152604091829020825180840190935254928316808352740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff16908201529015612134578051612136565b815b6001600160a01b03168152919050565b6001600160a01b03811661218b5760405162461bcd60e51b81526004018080602001828103825260348152602001806130c96034913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e91a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0381166122435760405162461bcd60e51b81526004018080602001828103825260218152602001806130fd6021913960400191505060405180910390fd5b61224b612d7d565b612253612d38565b61225c846120c7565b80519091506001600160a01b03848116908216141561227d57505050611153565b60208201516bffffffffffffffffffffffff161580156122b357506001600160a01b038516600090815260056020526040902054155b1561232b576001600160a01b0385811660008181526004602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169489169485179055517f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea29190a3505050611153565b612334816127bd565b835261233f846127bd565b6020808501829052600854855160609081015192860151930151604080517f8a1f3c020000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260248201959095528a851660448201526bffffffffffffffffffffffff9095166064860152888416608486015260a485019190915251911691638a1f3c029160c480830192600092919082900301818387803b1580156123ef57600080fd5b505af1158015612403573d6000803e3d6000fd5b505050506001600160a01b03858116600090815260046020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001692871692909217909155828101518451909101516bffffffffffffffffffffffff909116906124769082612a75565b6001600160a01b0383166000908152600560209081526040909120919091558481015101516124a59082612abe565b6001600160a01b0386166000908152600560205260409020556124c7826127bd565b60408501526124d5856127bd565b84606001819052506000612526856060015160600151611dbb876020015160600151612520896040015160600151611dbb8b6000015160600151600654612a7590919063ffffffff16565b90612a75565b60068190556040519091506001600160a01b0380881691908916907f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea290600090a360075460408601516060908101518751909101516001600160a01b03909216911461269457806001600160a01b03166361885df885886040015160800151896040015160600151866040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846bffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561261157600080fd5b505af1158015612625573d6000803e3d6000fd5b505050604080880151608081015160609182015183516bffffffffffffffffffffffff9092168252602082015260008184015291516001600160a01b03808d1694508816927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b92908290030190a35b856060015160600151866020015160600151146120b957806001600160a01b03166361885df888886060015160800151896060015160600151866040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846bffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561273057600080fd5b505af1158015612744573d6000803e3d6000fd5b505050606080880151608081015190820151604080516bffffffffffffffffffffffff90931683526020830191909152818101879052516001600160a01b03808d1694508b16927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b928290030190a35050505050505050565b6127c5612d4f565b6127cd612d38565b6127d6836120c7565b6001600160a01b03808516808552600081815260056020908152604091829020549087015283519092161490840181905290915061281557600061281b565b80602001515b6bffffffffffffffffffffffff166080830152604082015161283e576000612844565b81602001515b606083015250919050565b600061288f6040518060400160405280601081526020017f6d6967726174696f6e4d616e6167657200000000000000000000000000000000815250612b73565b905090565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600960248301527f656c656374696f6e730000000000000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b505afa158015612938573d6000803e3d6000fd5b505050506040513d602081101561294e57600080fd5b5051905090565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052601660248301527f7374616b696e67436f6e747261637448616e646c657200000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600e60248301527f7374616b696e6752657761726473000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b6000612ab783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612ca1565b9392505050565b600082820183811015612ab7576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6003546000906001600160a01b0316331480612b4c5750612b37610d15565b6001600160a01b0316336001600160a01b0316145b8061288f5750612b5a610ab8565b6001600160a01b0316336001600160a01b031614905090565b6003546000906001600160a01b0316612b8a612b18565b80612ab757506001600160a01b03811615801590612ab757506003546040517f1ee441e900000000000000000000000000000000000000000000000000000000815260206004820181815286516024840152865133946001600160a01b031693631ee441e99389939283926044019185019080838360005b83811015612c1a578181015183820152602001612c02565b50505050905090810190601f168015612c475780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612c6457600080fd5b505afa158015612c78573d6000803e3d6000fd5b505050506040513d6020811015612c8e57600080fd5b50516001600160a01b0316149392505050565b60008184841115612d305760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612cf5578181015183820152602001612cdd565b50505050905090810190601f168015612d225780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082019091526000808252602082015290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6040518060800160405280612d90612d4f565b8152602001612d9d612d4f565b8152602001612daa612d4f565b8152602001612db7612d4f565b90529056fe696d706f72742063616e6e6f74206265207573656420666f722073656c662d64656c65676174696f6e2028616c72656164792073656c662064656c65676174656429636f6e7472616374206973206c6f636b656420666f722074686973206f7065726174696f6e73656e646572206973206e6f7420616e2061646d696e202872656769737472794d616e676572206f7220696e697469616c697a6174696f6e41646d696e296e657720636f6e7472616374207265676973747279206d7573742070726f76696465207468652070726576696f757320636f6e747261637420726567697374727966726f6d206172726179206d75737420636f6e7461696e206174206c65617374206f6e65206164647265737343616c6c6572206973206e6f74207468652070656e64696e6720726567697374727941646d696e73656e646572206973206e6f742074686520696e697469616c697a6174696f6e2061646d696e5f7374616b654f776e6572732c205f7369676e73202d206172726179206c656e677468206d69736d6174636863616c6c6572206973206e6f7420746865207374616b696e6720636f6e74726163742068616e646c65725f7374616b654f776e6572732c205f757064617465645374616b6573202d206172726179206c656e677468206d69736d617463686e6f2072657761726473206d617920626520616c6c6f6361746564207072696f7220746f20696d706f7274696e672064656c65676174696f6e7373656e646572206973206e6f7420746865206d6967726174696f6e206d616e6167657244656c65676174696f6e733a3a757064617465645374616b65732076616c756520746f6f2062696720283e3936206269747329696d706f727420616c6c6f776564206f6e6c7920666f7220756e696e697469616c697a6564206163636f756e74732e206578697374696e67207374616b65206465746563746564696d706f727420616c6c6f776564206f6e6c7920666f7220756e696e697469616c697a6564206163636f756e74732e206578697374696e672064656c65676174696f6e206465746563746564526567697374727941646d696e3a206e657720726567697374727941646d696e20697320746865207a65726f206164647265737363616e6e6f742064656c656761746520746f2061207a65726f206164647265737357697468436c61696d61626c6552656769737472794d616e6167656d656e743a2063616c6c6572206973206e6f742074686520726567697374727941646d696e5f7374616b654f776e6572732c205f616d6f756e7473202d206172726179206c656e677468206d69736d61746368a2646970667358221220190f4d45b81ab198cc49e7d4a1fbb315f40402e0142e6481bfbe091e58ec836064736f6c634300060c003373656e646572206973206e6f7420616e2061646d696e202872656769737472794d616e676572206f7220696e697469616c697a6174696f6e41646d696e296e657720636f6e7472616374207265676973747279206d7573742070726f76696465207468652070726576696f757320636f6e7472616374207265676973747279526567697374727941646d696e3a206e657720726567697374727941646d696e20697320746865207a65726f20616464726573731f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e000000000000000000000000d859701c81119ab12a1e62af6270ad2ae05c7ab3000000000000000000000000f1fd5233e60e7ef797025fe9dd066d60d59bcb92
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80638faf2f061161010f578063cf3b670b116100a2578063efb47c7e11610071578063efb47c7e1461067b578063f83d08ba146106f4578063fab46d66146106fc578063fcd13d6514610745576101f0565b8063cf3b670b1461065b578063d252352614610663578063e4e992221461066b578063eec0701f14610673576101f0565b8063a69df4b5116100de578063a69df4b514610617578063acdb8e041461061f578063ce257ab814610627578063cf30901214610653576101f0565b80638faf2f061461044b57806390ef9d3f14610453578063a39539c6146105b9578063a4e2d6341461060f576101f0565b806339069d8c116101875780635c19a95c116101565780635c19a95c146103ef5780635f94cd9c1461041557806374c16b231461041d5780637c47c16d14610425576101f0565b806339069d8c1461036d5780633dee40571461039357806348106fe3146103c15780635605a4e5146103c9576101f0565b80632987cea0116101c35780632987cea0146102f55780632a1fac721461031b5780632b29376814610323578063333df15414610365576101f0565b806305efb9ed146101f5578063071880e8146102675780630e3b7c951461029f5780631a0b2c4f146102d9575b600080fd5b6102656004803603602081101561020b57600080fd5b81019060208101813564010000000081111561022657600080fd5b82018360208201111561023857600080fd5b8035906020019184602083028401116401000000008311171561025a57600080fd5b50909250905061076b565b005b61028d6004803603602081101561027d57600080fd5b50356001600160a01b0316610896565b60408051918252519081900360200190f35b610265600480360360808110156102b557600080fd5b506001600160a01b03813516906020810135906040810135151590606001356108a8565b6102e161095b565b604080519115158252519081900360200190f35b6102656004803603602081101561030b57600080fd5b50356001600160a01b031661097f565b6102656109fc565b6103496004803603602081101561033957600080fd5b50356001600160a01b0316610aa6565b604080516001600160a01b039092168252519081900360200190f35b610349610ab8565b6102656004803603602081101561038357600080fd5b50356001600160a01b0316610ac7565b610265600480360360408110156103a957600080fd5b506001600160a01b0381358116916020013516610b2a565b6102e1610bcf565b610265600480360360208110156103df57600080fd5b50356001600160a01b0316610bdf565b6102656004803603602081101561040557600080fd5b50356001600160a01b0316610ca2565b610349610d06565b610349610d15565b61028d6004803603602081101561043b57600080fd5b50356001600160a01b0316610d24565b610349610d39565b6102656004803603608081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460208302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184602083028401116401000000008311171561050a57600080fd5b91939092909160208101903564010000000081111561052857600080fd5b82018360208201111561053a57600080fd5b8035906020019184602083028401116401000000008311171561055c57600080fd5b91939092909160208101903564010000000081111561057a57600080fd5b82018360208201111561058c57600080fd5b803590602001918460208302840111640100000000831117156105ae57600080fd5b509092509050610d5d565b6105df600480360360208110156105cf57600080fd5b50356001600160a01b0316610f11565b604080516001600160a01b0390931683526bffffffffffffffffffffffff90911660208301528051918290030190f35b6102e1610f54565b610265610f75565b61026561100b565b6102656004803603604081101561063d57600080fd5b506001600160a01b0381351690602001356110b0565b6102e1611157565b61028d611178565b61026561117e565b610349611206565b610265611215565b6102656004803603604081101561069157600080fd5b8101906020810181356401000000008111156106ac57600080fd5b8201836020820111156106be57600080fd5b803590602001918460208302840111640100000000831117156106e057600080fd5b9193509150356001600160a01b03166112d7565b610265611afd565b6107226004803603602081101561071257600080fd5b50356001600160a01b0316611baa565b604080516001600160a01b03909316835260208301919091528051918290030190f35b6102656004803603602081101561075b57600080fd5b50356001600160a01b0316611bdf565b60035474010000000000000000000000000000000000000000900460ff16156107c55760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b60005b81811015610891576108898383838181106107df57fe5b6009546001600160a01b036020909202939093013581169216905063e9aea8c886868681811061080b57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561085857600080fd5b505afa15801561086c573d6000803e3d6000fd5b505050506040513d602081101561088257600080fd5b5051611d5f565b6001016107c8565b505050565b60056020526000908152604090205481565b6009546001600160a01b031633146108f15760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff161561094b5760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b6109558482611d5f565b50505050565b600080546001600160a01b03166109706120c3565b6001600160a01b031614905090565b61098761095b565b6109c25760405162461bcd60e51b815260040180806020018281038252604081526020018061311e6040913960400191505060405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b610a04610ab8565b6001600160a01b0316336001600160a01b031614610a535760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040517f2a2b3ea974fb057582c3b210ef8b5f81492d15673f49d4384bfa3b896a964c3c90600090a1565b6000610ab1826120c7565b5192915050565b6002546001600160a01b031690565b610acf610ab8565b6001600160a01b0316336001600160a01b031614610b1e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b610b2781612146565b50565b610b32610ab8565b6001600160a01b0316336001600160a01b031614610b815760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b610b8b82826121fe565b806001600160a01b0316826001600160a01b03167fcf1993798656f790fc10bf446b6c785f2df06395b16dbb876003a2b018a6465860405160405180910390a35050565b6002546001600160a01b03161590565b60035474010000000000000000000000000000000000000000900460ff1615610c395760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b600954604080517fe9aea8c80000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529151610b27938593169163e9aea8c8916024808301926020929190829003018186803b15801561085857600080fd5b60035474010000000000000000000000000000000000000000900460ff1615610cfc5760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b610b2733826121fe565b6001546001600160a01b031690565b6000546001600160a01b031690565b6000610d2f826127bd565b6060015192915050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b6009546001600160a01b03163314610da65760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff1615610e005760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b86858114610e3f5760405162461bcd60e51b815260040180806020018281038252602e81526020018061315e602e913960400191505060405180910390fd5b808414610e7d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612f1c602c913960400191505060405180910390fd5b808214610ebb5760405162461bcd60e51b8152600401808060200182810382526034815260200180612f726034913960400191505060405180910390fd5b60005b88811015610f0557610efd8a8a83818110610ed557fe5b905060200201356001600160a01b0316858584818110610ef157fe5b90506020020135611d5f565b600101610ebe565b50505050505050505050565b6004602052600090815260409020546001600160a01b038116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b60035474010000000000000000000000000000000000000000900460ff1690565b610f7d61284f565b610fb85760405162461bcd60e51b8152600401808060200182810382526023815260200180612fe06023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f19aad37188a1d3921e29eb3c66acf43d81975e107cb650d58cca878627955fd690600090a1565b61101361095b565b61104e5760405162461bcd60e51b815260040180806020018281038252604081526020018061311e6040913960400191505060405180910390fd5b600080546040516001600160a01b03909116907f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6009546001600160a01b031633146110f95760405162461bcd60e51b815260040180806020018281038252602a815260200180612f48602a913960400191505060405180910390fd5b60035474010000000000000000000000000000000000000000900460ff16156111535760405162461bcd60e51b8152600401808060200182810382526025815260200180612dff6025913960400191505060405180910390fd5b5050565b60035474010000000000000000000000000000000000000000900460ff1681565b60065490565b6001546001600160a01b031633146111c75760405162461bcd60e51b8152600401808060200182810382526027815260200180612ecf6027913960400191505060405180910390fd5b6001546111dc906001600160a01b0316612146565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6003546001600160a01b031690565b61121d612894565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561125d612955565b600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561129d6129e5565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6112df610ab8565b6001600160a01b0316336001600160a01b03161461132e5760405162461bcd60e51b8152600401808060200182810382526026815260200180612ef66026913960400191505060405180910390fd5b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601d60248201527f746f206d7573742062652061206e6f6e207a65726f2061646472657373000000604482015290519081900360640190fd5b816113c55760405162461bcd60e51b815260040180806020018281038252602c815260200180612ea3602c913960400191505060405180910390fd5b600854604080517fcfbe49f200000000000000000000000000000000000000000000000000000000815281516000936001600160a01b03169263cfbe49f29260048082019391829003018186803b15801561141f57600080fd5b505afa158015611433573d6000803e3d6000fd5b505050506040513d604081101561144957600080fd5b505190506bffffffffffffffffffffffff8116156114985760405162461bcd60e51b815260040180806020018281038252603a815260200180612fa6603a913960400191505060405180910390fd5b60006114a2612d38565b6006546114ad612d4f565b6114b6866127bd565b6009549091506001600160a01b0316600060608967ffffffffffffffff811180156114e057600080fd5b5060405190808252806020026020018201604052801561150a578160200160208202803683370190505b50905060005b8a811015611a0757600460008d8d8481811061152857fe5b602090810292909201356001600160a01b03908116845283830194909452506040918201600020825180840190935254928316808352740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff16908201529750156115c75760405162461bcd60e51b815260040180806020018281038252604c81526020018061307d604c913960600191505060405180910390fd5b896001600160a01b03168c8c838181106115dd57fe5b905060200201356001600160a01b03166001600160a01b031614156116335760405162461bcd60e51b8152600401808060200182810382526042815260200180612dbd6042913960600191505060405180910390fd5b60208701516bffffffffffffffffffffffff16156116825760405162461bcd60e51b81526004018080602001828103825260478152602001806130366047913960600191505060405180910390fd5b600560008d8d8481811061169257fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020549250600083111561176e576116d88684612a75565b95508b8b828181106116e657fe5b905060200201356001600160a01b03166001600160a01b03168c8c8381811061170b57fe5b905060200201356001600160a01b03166001600160a01b03167f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b600080600060405180848152602001838152602001828152602001935050505060405180910390a35b6001600160a01b03808b168852841663e9aea8c88d8d8481811061178e57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d602081101561180557600080fd5b50516bffffffffffffffffffffffff16602088015286600460008e8e8581811061182b57fe5b602090810292909201356001600160a01b0390811684528383019490945250604090910160002083518154948301517fffffffffffffffffffffffff000000000000000000000000000000000000000090951690841617909216740100000000000000000000000000000000000000006bffffffffffffffffffffffff94851602179091558801516118bf918a9116612abe565b975086602001516bffffffffffffffffffffffff168282815181106118e057fe5b602002602001018181525050896001600160a01b03168c8c8381811061190257fe5b905060200201356001600160a01b03166001600160a01b03167f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea260405160405180910390a38b8b8281811061195357fe5b905060200201356001600160a01b03166001600160a01b03168a6001600160a01b03167f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b876080015188604001516119ac5760006119bb565b60608901516119bb908d612abe565b8b6020015160405180846bffffffffffffffffffffffff168152602001838152602001826bffffffffffffffffffffffff168152602001935050505060405180910390a3600101611510565b506001600160a01b038916600090815260056020526040902054611a2b9088612abe565b6001600160a01b038a16600090815260056020526040908190209190915584015115611a5e57611a5b8588612abe565b94505b84600681905550886001600160a01b03167f7bedb97dca1b1ff98032eb6dad66e46016096d6341192dc7c3b1be79b0b1a93a8c8c60405180806020018281038252848482818152602001925060200280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039550909350505050a25050505050505050505050565b611b0561284f565b611b405760405162461bcd60e51b8152600401808060200182810382526023815260200180612fe06023913960400191505060405180910390fd5b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f0f2e5b6c72c6a4491efd919a9f9a409f324ef0708c11ee57d410c2cb06c0992b90600090a1565b600080611bb5612d38565b611bbe846120c7565b80516020909101519093506bffffffffffffffffffffffff16915050915091565b611be7612b18565b611c225760405162461bcd60e51b815260040180806020018281038252603e815260200180612e24603e913960400191505060405180910390fd5b600354604080517f078cbb7c00000000000000000000000000000000000000000000000000000000815290516001600160a01b039283169284169163078cbb7c916004808301926020929190829003018186803b158015611c8257600080fd5b505afa158015611c96573d6000803e3d6000fd5b505050506040513d6020811015611cac57600080fd5b50516001600160a01b031614611cf35760405162461bcd60e51b8152600401808060200182810382526041815260200180612e626041913960600191505060405180910390fd5b600380546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517ffea2d033438b968078a6264409d0104b5f3d2ce7b795afc74918e70f3534f22b9181900360200190a150565b611d67612d38565b611d70836120c7565b9050611d7a612d4f565b8151611d85906127bd565b90506000816020015190506000611dc185611dbb86602001516bffffffffffffffffffffffff1685612a7590919063ffffffff16565b90612abe565b600854855160608601516020880151604080517f8a1f3c020000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201819052602482018590528d861660448301526bffffffffffffffffffffffff9093166064820152608481019290925260a48201929092529051939450911691638a1f3c029160c48082019260009290919082900301818387803b158015611e6c57600080fd5b505af1158015611e80573d6000803e3d6000fd5b505085516001600160a01b0316600090815260056020526040902083905550506bffffffffffffffffffffffff85168514611eec5760405162461bcd60e51b81526004018080602001828103825260338152602001806130036033913960400191505060405180910390fd5b6001600160a01b03868116600090815260046020526040908190208054909216740100000000000000000000000000000000000000006bffffffffffffffffffffffff891602179091556006549084015115611f7357611f6b86611dbb87602001516bffffffffffffffffffffffff1684612a7590919063ffffffff16565b600681905590505b611f7b612d4f565b8551611f86906127bd565b600754875160808301516060840151604080517f61885df80000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201526bffffffffffffffffffffffff9093166024840152604483019190915260648201879052519394509116916361885df89160848082019260009290919082900301818387803b15801561201e57600080fd5b505af1158015612032573d6000803e3d6000fd5b5050505085602001516bffffffffffffffffffffffff1687146120b95785516080820151606080840151604080516bffffffffffffffffffffffff909416845260208401919091528281018b9052516001600160a01b03808d169416927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b92908290030190a35b5050505050505050565b3390565b6120cf612d38565b506001600160a01b03818116600090815260046020908152604091829020825180840190935254928316808352740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff16908201529015612134578051612136565b815b6001600160a01b03168152919050565b6001600160a01b03811661218b5760405162461bcd60e51b81526004018080602001828103825260348152602001806130c96034913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f1f5f028be638d6a0e3b8d56fd05b812ce325cc8dc73cdb0e16df94d6b2725c2e91a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0381166122435760405162461bcd60e51b81526004018080602001828103825260218152602001806130fd6021913960400191505060405180910390fd5b61224b612d7d565b612253612d38565b61225c846120c7565b80519091506001600160a01b03848116908216141561227d57505050611153565b60208201516bffffffffffffffffffffffff161580156122b357506001600160a01b038516600090815260056020526040902054155b1561232b576001600160a01b0385811660008181526004602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169489169485179055517f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea29190a3505050611153565b612334816127bd565b835261233f846127bd565b6020808501829052600854855160609081015192860151930151604080517f8a1f3c020000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260248201959095528a851660448201526bffffffffffffffffffffffff9095166064860152888416608486015260a485019190915251911691638a1f3c029160c480830192600092919082900301818387803b1580156123ef57600080fd5b505af1158015612403573d6000803e3d6000fd5b505050506001600160a01b03858116600090815260046020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001692871692909217909155828101518451909101516bffffffffffffffffffffffff909116906124769082612a75565b6001600160a01b0383166000908152600560209081526040909120919091558481015101516124a59082612abe565b6001600160a01b0386166000908152600560205260409020556124c7826127bd565b60408501526124d5856127bd565b84606001819052506000612526856060015160600151611dbb876020015160600151612520896040015160600151611dbb8b6000015160600151600654612a7590919063ffffffff16565b90612a75565b60068190556040519091506001600160a01b0380881691908916907f4bc154dd35d6a5cb9206482ecb473cdbf2473006d6bce728b9cc0741bcc59ea290600090a360075460408601516060908101518751909101516001600160a01b03909216911461269457806001600160a01b03166361885df885886040015160800151896040015160600151866040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846bffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561261157600080fd5b505af1158015612625573d6000803e3d6000fd5b505050604080880151608081015160609182015183516bffffffffffffffffffffffff9092168252602082015260008184015291516001600160a01b03808d1694508816927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b92908290030190a35b856060015160600151866020015160600151146120b957806001600160a01b03166361885df888886060015160800151896060015160600151866040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846bffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561273057600080fd5b505af1158015612744573d6000803e3d6000fd5b505050606080880151608081015190820151604080516bffffffffffffffffffffffff90931683526020830191909152818101879052516001600160a01b03808d1694508b16927f52db726bc1b1643b24886ed6f0194a41de9abac79d1c12108aca494e5b2bda6b928290030190a35050505050505050565b6127c5612d4f565b6127cd612d38565b6127d6836120c7565b6001600160a01b03808516808552600081815260056020908152604091829020549087015283519092161490840181905290915061281557600061281b565b80602001515b6bffffffffffffffffffffffff166080830152604082015161283e576000612844565b81602001515b606083015250919050565b600061288f6040518060400160405280601081526020017f6d6967726174696f6e4d616e6167657200000000000000000000000000000000815250612b73565b905090565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600960248301527f656c656374696f6e730000000000000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b505afa158015612938573d6000803e3d6000fd5b505050506040513d602081101561294e57600080fd5b5051905090565b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052601660248301527f7374616b696e67436f6e747261637448616e646c657200000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b600354604080517f35817773000000000000000000000000000000000000000000000000000000008152602060048201819052600e60248301527f7374616b696e6752657761726473000000000000000000000000000000000000604483015291516000936001600160a01b03169263358177739260648082019391829003018186803b15801561292457600080fd5b6000612ab783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612ca1565b9392505050565b600082820183811015612ab7576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6003546000906001600160a01b0316331480612b4c5750612b37610d15565b6001600160a01b0316336001600160a01b0316145b8061288f5750612b5a610ab8565b6001600160a01b0316336001600160a01b031614905090565b6003546000906001600160a01b0316612b8a612b18565b80612ab757506001600160a01b03811615801590612ab757506003546040517f1ee441e900000000000000000000000000000000000000000000000000000000815260206004820181815286516024840152865133946001600160a01b031693631ee441e99389939283926044019185019080838360005b83811015612c1a578181015183820152602001612c02565b50505050905090810190601f168015612c475780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612c6457600080fd5b505afa158015612c78573d6000803e3d6000fd5b505050506040513d6020811015612c8e57600080fd5b50516001600160a01b0316149392505050565b60008184841115612d305760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612cf5578181015183820152602001612cdd565b50505050905090810190601f168015612d225780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082019091526000808252602082015290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6040518060800160405280612d90612d4f565b8152602001612d9d612d4f565b8152602001612daa612d4f565b8152602001612db7612d4f565b90529056fe696d706f72742063616e6e6f74206265207573656420666f722073656c662d64656c65676174696f6e2028616c72656164792073656c662064656c65676174656429636f6e7472616374206973206c6f636b656420666f722074686973206f7065726174696f6e73656e646572206973206e6f7420616e2061646d696e202872656769737472794d616e676572206f7220696e697469616c697a6174696f6e41646d696e296e657720636f6e7472616374207265676973747279206d7573742070726f76696465207468652070726576696f757320636f6e747261637420726567697374727966726f6d206172726179206d75737420636f6e7461696e206174206c65617374206f6e65206164647265737343616c6c6572206973206e6f74207468652070656e64696e6720726567697374727941646d696e73656e646572206973206e6f742074686520696e697469616c697a6174696f6e2061646d696e5f7374616b654f776e6572732c205f7369676e73202d206172726179206c656e677468206d69736d6174636863616c6c6572206973206e6f7420746865207374616b696e6720636f6e74726163742068616e646c65725f7374616b654f776e6572732c205f757064617465645374616b6573202d206172726179206c656e677468206d69736d617463686e6f2072657761726473206d617920626520616c6c6f6361746564207072696f7220746f20696d706f7274696e672064656c65676174696f6e7373656e646572206973206e6f7420746865206d6967726174696f6e206d616e6167657244656c65676174696f6e733a3a757064617465645374616b65732076616c756520746f6f2062696720283e3936206269747329696d706f727420616c6c6f776564206f6e6c7920666f7220756e696e697469616c697a6564206163636f756e74732e206578697374696e67207374616b65206465746563746564696d706f727420616c6c6f776564206f6e6c7920666f7220756e696e697469616c697a6564206163636f756e74732e206578697374696e672064656c65676174696f6e206465746563746564526567697374727941646d696e3a206e657720726567697374727941646d696e20697320746865207a65726f206164647265737363616e6e6f742064656c656761746520746f2061207a65726f206164647265737357697468436c61696d61626c6552656769737472794d616e6167656d656e743a2063616c6c6572206973206e6f742074686520726567697374727941646d696e5f7374616b654f776e6572732c205f616d6f756e7473202d206172726179206c656e677468206d69736d61746368a2646970667358221220190f4d45b81ab198cc49e7d4a1fbb315f40402e0142e6481bfbe091e58ec836064736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d859701c81119ab12a1e62af6270ad2ae05c7ab3000000000000000000000000f1fd5233e60e7ef797025fe9dd066d60d59bcb92
-----Decoded View---------------
Arg [0] : _contractRegistry (address): 0xD859701C81119aB12A1e62AF6270aD2AE05c7AB3
Arg [1] : _registryAdmin (address): 0xf1fD5233E60E7Ef797025FE9DD066d60d59BcB92
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000d859701c81119ab12a1e62af6270ad2ae05c7ab3
Arg [1] : 000000000000000000000000f1fd5233e60e7ef797025fe9dd066d60d59bcb92
Deployed Bytecode Sourcemap
61371:17455:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63940:221;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63940:221:0;;-1:-1:-1;63940:221:0;-1:-1:-1;63940:221:0;:::i;:::-;;61698:57;;;;;;;;;;;;;;;;-1:-1:-1;61698:57:0;-1:-1:-1;;;;;61698:57:0;;:::i;:::-;;;;;;;;;;;;;;;;65980:190;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;65980:190:0;;;;;;;;;;;;;;;;;;;;:::i;48702:110::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;50263:146;;;;;;;;;;;;;;;;-1:-1:-1;50263:146:0;-1:-1:-1;;;;;50263:146:0;;:::i;51789:159::-;;;:::i;64335:129::-;;;;;;;;;;;;;;;;-1:-1:-1;64335:129:0;-1:-1:-1;;;;;64335:129:0;;:::i;:::-;;;;-1:-1:-1;;;;;64335:129:0;;;;;;;;;;;;;;51594:107;;;:::i;57663:154::-;;;;;;;;;;;;;;;;-1:-1:-1;57663:154:0;-1:-1:-1;;;;;57663:154:0;;:::i;70911:165::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;70911:165:0;;;;;;;;;;:::i;52008:123::-;;;:::i;63399:145::-;;;;;;;;;;;;;;;;-1:-1:-1;63399:145:0;-1:-1:-1;;;;;63399:145:0;;:::i;62968:101::-;;;;;;;;;;;;;;;;-1:-1:-1;62968:101:0;-1:-1:-1;;;;;62968:101:0;;:::i;50777:110::-;;;:::i;48256:95::-;;;:::i;65174:137::-;;;;;;;;;;;;;;;;-1:-1:-1;65174:137:0;-1:-1:-1;;;;;65174:137:0;;:::i;61514:47::-;;;:::i;66521:658::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66521:658:0;;-1:-1:-1;66521:658:0;-1:-1:-1;66521:658:0;:::i;61637:57::-;;;;;;;;;;;;;;;;-1:-1:-1;61637:57:0;-1:-1:-1;;;;;61637:57:0;;:::i;:::-;;;;-1:-1:-1;;;;;61637:57:0;;;;;;;;;;;;;;;;;;;;;;60370:90;;;:::i;60130:116::-;;;:::i;49206:182::-;;;:::i;67476:124::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67476:124:0;;;;;;;;:::i;59095:18::-;;;:::i;65611:111::-;;;:::i;50515:183::-;;;:::i;57533:122::-;;;:::i;78555:266::-;;;:::i;67996:2576::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67996:2576:0;-1:-1:-1;67996:2576:0;-1:-1:-1;;;;;67996:2576:0;;:::i;59804:111::-;;;:::i;64715:220::-;;;;;;;;;;;;;;;;-1:-1:-1;64715:220:0;-1:-1:-1;;;;;64715:220:0;;:::i;:::-;;;;-1:-1:-1;;;;;64715:220:0;;;;;;;;;;;;;;;;;;;;;56993:394;;;;;;;;;;;;;;;;-1:-1:-1;56993:394:0;-1:-1:-1;;;;;56993:394:0;;:::i;63940:221::-;60514:6;;;;;;;60513:7;60505:57;;;;-1:-1:-1;;;60505:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64036:6:::1;64031:126;64048:16:::0;;::::1;64031:126;;;64077:74;64090:5;;64096:1;64090:8;;;;;;;64100:22;::::0;-1:-1:-1;;;;;64090:8:0::1;::::0;;::::1;::::0;;;::::1;;::::0;::::1;::::0;64100:22:::1;::::0;-1:-1:-1;64100:40:0::1;64141:5:::0;;64147:1;64141:8;;::::1;;;;;;;;;;;-1:-1:-1::0;;;;;64141:8:0::1;64100:50;;;;;;;;;;;;;-1:-1:-1::0;;;;;64100:50:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;64100:50:0;64077:12:::1;:74::i;:::-;64066:3;;64031:126;;;;63940:221:::0;;:::o;61698:57::-;;;;;;;;;;;;;:::o;65980:190::-;62583:22;;-1:-1:-1;;;;;62583:22:0;62561:10;:45;62553:100;;;;-1:-1:-1;;;62553:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60514:6:::1;::::0;;;::::1;;;60513:7;60505:57;;;;-1:-1:-1::0;;;60505:57:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66125:40:::2;66138:11;66151:13;66125:12;:40::i;:::-;65980:190:::0;;;;:::o;48702:110::-;48750:4;48790:14;;-1:-1:-1;;;;;48790:14:0;48774:12;:10;:12::i;:::-;-1:-1:-1;;;;;48774:30:0;;48767:37;;48702:110;:::o;50263:146::-;48500:17;:15;:17::i;:::-;48492:94;;;;-1:-1:-1;;;48492:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50361:21:::1;:40:::0;;;::::1;-1:-1:-1::0;;;;;50361:40:0;;;::::1;::::0;;;::::1;::::0;;50263:146::o;51789:159::-;51407:21;:19;:21::i;:::-;-1:-1:-1;;;;;51393:35:0;:10;-1:-1:-1;;;;;51393:35:0;;51385:86;;;;-1:-1:-1;;;51385:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51867:20:::1;:33:::0;;;::::1;::::0;;51916:24:::1;::::0;::::1;::::0;51898:1:::1;::::0;51916:24:::1;51789:159::o:0;64335:129::-;64404:7;64425:23;64443:4;64425:17;:23::i;:::-;:34;;64335:129;-1:-1:-1;;64335:129:0:o;51594:107::-;51673:20;;-1:-1:-1;;;;;51673:20:0;51594:107;:::o;57663:154::-;51407:21;:19;:21::i;:::-;-1:-1:-1;;;;;51393:35:0;:10;-1:-1:-1;;;;;51393:35:0;;51385:86;;;;-1:-1:-1;;;51385:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57766:43:::1;57794:14;57766:27;:43::i;:::-;57663:154:::0;:::o;70911:165::-;51407:21;:19;:21::i;:::-;-1:-1:-1;;;;;51393:35:0;:10;-1:-1:-1;;;;;51393:35:0;;51385:86;;;;-1:-1:-1;;;51385:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71008:22:::1;71021:4;71027:2;71008:12;:22::i;:::-;71068:2;-1:-1:-1::0;;;;;71040:31:0::1;71062:4;-1:-1:-1::0;;;;;71040:31:0::1;;;;;;;;;;;70911:165:::0;;:::o;52008:123::-;52089:20;;-1:-1:-1;;;;;52089:20:0;:34;52008:123;:::o;63399:145::-;60514:6;;;;;;;60513:7;60505:57;;;;-1:-1:-1;;;60505:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63492:22:::1;::::0;:46:::1;::::0;;;;;-1:-1:-1;;;;;63492:46:0;;::::1;;::::0;::::1;::::0;;;63473:66:::1;::::0;63486:4;;63492:22:::1;::::0;:40:::1;::::0;:46;;;;;::::1;::::0;;;;;;;;:22;:46;::::1;;::::0;::::1;;;;::::0;::::1;62968:101:::0;60514:6;;;;;;;60513:7;60505:57;;;;-1:-1:-1;;;60505:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63036:28:::1;63049:10;63061:2;63036:12;:28::i;50777:110::-:0;50856:21;;-1:-1:-1;;;;;50856:21:0;50777:110;:::o;48256:95::-;48302:7;48329:14;-1:-1:-1;;;;;48329:14:0;48256:95;:::o;65174:137::-;65247:7;65268:23;65286:4;65268:17;:23::i;:::-;:38;;;;65174:137;-1:-1:-1;;65174:137:0:o;61514:47::-;61558:2;61514:47;:::o;66521:658::-;62583:22;;-1:-1:-1;;;;;62583:22:0;62561:10;:45;62553:100;;;;-1:-1:-1;;;62553:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60514:6:::1;::::0;;;::::1;;;60513:7;60505:57;;;;-1:-1:-1::0;;;60505:57:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66752:12:::0;66784:30;;::::2;66776:89;;;;-1:-1:-1::0;;;66776:89:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66878:28:::0;;::::2;66870:85;;;;-1:-1:-1::0;;;66870:85:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66968:36:::0;;::::2;66960:101;;;;-1:-1:-1::0;;;66960:101:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67073:6;67068:107;67085:23:::0;;::::2;67068:107;;;67121:48;67134:12;;67147:1;67134:15;;;;;;;;;;;;;-1:-1:-1::0;;;;;67134:15:0::2;67151:14;;67166:1;67151:17;;;;;;;;;;;;;67121:12;:48::i;:::-;67110:3;;67068:107;;;;60575:1;66521:658:::0;;;;;;;;:::o;61637:57::-;;;;;;;;;;;;-1:-1:-1;;;;;61637:57:0;;;;;;;;;:::o;60370:90::-;60446:6;;;;;;;;60370:90::o;60130:116::-;53031:20;:18;:20::i;:::-;53023:68;;;;-1:-1:-1;;;53023:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60198:6:::1;:14:::0;;;::::1;::::0;;60228:10:::1;::::0;::::1;::::0;60207:5:::1;::::0;60228:10:::1;60130:116::o:0;49206:182::-;48500:17;:15;:17::i;:::-;48492:94;;;;-1:-1:-1;;;48492:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49339:1:::1;49315:14:::0;;49285:57:::1;::::0;-1:-1:-1;;;;;49315:14:0;;::::1;::::0;49285:57:::1;::::0;49339:1;;49285:57:::1;49378:1;49353:27:::0;;;::::1;::::0;;49206:182::o;67476:124::-;62583:22;;-1:-1:-1;;;;;62583:22:0;62561:10;:45;62553:100;;;;-1:-1:-1;;;62553:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60514:6:::1;::::0;;;::::1;;;60513:7;60505:57;;;;-1:-1:-1::0;;;60505:57:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67476:124:::0;;:::o;59095:18::-;;;;;;;;;:::o;65611:111::-;65698:19;;65611:111;:::o;50515:183::-;49994:21;;-1:-1:-1;;;;;49994:21:0;49980:10;:35;49972:87;;;;-1:-1:-1;;;49972:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50623:21:::1;::::0;50595:50:::1;::::0;-1:-1:-1;;;;;50623:21:0::1;50595:27;:50::i;:::-;50656:21;:34:::0;;;::::1;::::0;;50515:183::o;57533:122::-;57631:16;;-1:-1:-1;;;;;57631:16:0;57533:122;:::o;78555:266::-;78637:22;:20;:22::i;:::-;78606:17;:54;;;;-1:-1:-1;;;;;78606:54:0;;;;;;;;;;78714:27;:25;:27::i;:::-;78665:22;:77;;;;-1:-1:-1;;;;;78665:77:0;;;;;;;;;;78788:27;:25;:27::i;:::-;78747:22;:69;;;;-1:-1:-1;;;;;78747:69:0;;;;;;;;;;78555:266::o;67996:2576::-;51407:21;:19;:21::i;:::-;-1:-1:-1;;;;;51393:35:0;:10;-1:-1:-1;;;;;51393:35:0;;51385:86;;;;-1:-1:-1;;;51385:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68115:16:0;::::1;68107:58;;;::::0;;-1:-1:-1;;;68107:58:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;68178:15:::0;68170:72:::1;;;;-1:-1:-1::0;;;68170:72:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68284:22;::::0;:47:::1;::::0;;;;;;;68248:30:::1;::::0;-1:-1:-1;;;;;68284:22:0::1;::::0;:45:::1;::::0;:47:::1;::::0;;::::1;::::0;;;;;;;:22;:47;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;68284:47:0;;-1:-1:-1;68344:28:0::1;::::0;::::1;::::0;68336:99:::1;;;;-1:-1:-1::0;;;68336:99:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68442:35;68486:26;;:::i;:::-;68550:19;::::0;68574:36:::1;;:::i;:::-;68613:21;68631:2;68613:17;:21::i;:::-;68689:22;::::0;68574:60;;-1:-1:-1;;;;;;68689:22:0::1;68639:47;68746:33;68796:4:::0;68782:26:::1;::::0;::::1;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;68782:26:0::1;;68746:62;;68818:6;68813:1397;68830:15:::0;;::::1;68813:1397;;;68865:15;:24;68881:4;;68886:1;68881:7;;;;;;;;::::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;;;;68881:7:0;;::::1;68865:24:::0;;;;::::1;::::0;;;;-1:-1:-1;68865:24:0;;;;-1:-1:-1;68865:24:0;68858:31;;;;::::1;::::0;;;;;;::::1;::::0;;;;;;::::1;;;::::0;;::::1;::::0;;-1:-1:-1;68903:29:0;68895:118:::1;;;;-1:-1:-1::0;;;68895:118:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69038:2;-1:-1:-1::0;;;;;69027:13:0::1;:4;;69032:1;69027:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;69027:7:0::1;-1:-1:-1::0;;;;;69027:13:0::1;;;69019:92;;;;-1:-1:-1::0;;;69019:92:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69125:10;::::0;::::1;::::0;:15:::1;;::::0;69117:100:::1;;;;-1:-1:-1::0;;;69117:100:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69375:22;:31;69398:4;;69403:1;69398:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;69398:7:0::1;-1:-1:-1::0;;;;;69375:31:0::1;-1:-1:-1::0;;;;;69375:31:0::1;;;;;;;;;;;;;69355:51;;69436:1;69416:17;:21;69412:208;;;69471:45;:22:::0;69498:17;69471:26:::1;:45::i;:::-;69446:70;;69590:4;;69595:1;69590:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;69590:7:0::1;-1:-1:-1::0;;;;;69528:85:0::1;69557:4;;69562:1;69557:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;69557:7:0::1;-1:-1:-1::0;;;;;69528:85:0::1;;69572:1;69581::::0;69605::::1;69528:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69412:208;-1:-1:-1::0;;;;;69647:20:0;;::::1;::::0;;69693:41;::::1;;69735:4:::0;;69740:1;69735:7;;::::1;;;;;;;;;;;-1:-1:-1::0;;;;;69735:7:0::1;69693:50;;;;;;;;;;;;;-1:-1:-1::0;;;;;69693:50:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;69693:50:0;69673:71:::1;;69693:50;69673:10:::0;::::1;:71:::0;:4;69750:15:::1;:24;69766:4:::0;;69771:1;69766:7;;::::1;;;;;;::::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;;;;69766:7:0;;::::1;69750:24:::0;;;;::::1;::::0;;;;-1:-1:-1;69750:24:0;;;;-1:-1:-1;69750:24:0;:31;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;;::::1;::::0;::::1;::::0;;::::1;;;::::0;;;69851:10;::::1;::::0;69819:43:::1;::::0;:27;;:43:::1;:31;:43::i;:::-;69789:73;;69932:4;:10;;;69910:32;;:16;69927:1;69910:19;;;;;;;;;;;;;:32;;;::::0;::::1;69974:2;-1:-1:-1::0;;;;;69955:22:0::1;69965:4;;69970:1;69965:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;69965:7:0::1;-1:-1:-1::0;;;;;69955:22:0::1;;;;;;;;;;;70174:4;;70179:1;70174:7;;;;;;;;;;;;;-1:-1:-1::0;;;;;70174:7:0::1;-1:-1:-1::0;;;;;69990:214:0::1;70018:2;-1:-1:-1::0;;;;;69990:214:0::1;;70027:14;:33;;;70067:14;:31;;;:100;;70166:1;70067:100;;;70101:29;::::0;::::1;::::0;:62:::1;::::0;70135:27;70101:33:::1;:62::i;:::-;70188:4;:10;;;69990:214;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68847:3;;68813:1397;;;-1:-1:-1::0;;;;;;70265:26:0;::::1;;::::0;;;:22:::1;:26;::::0;;;;;:59:::1;::::0;70296:27;70265:30:::1;:59::i;:::-;-1:-1:-1::0;;;;;70236:26:0;::::1;;::::0;;;:22:::1;:26;::::0;;;;;;:88;;;;70335:31;::::1;::::0;70331:129:::1;;;70399:55;:22:::0;70426:27;70399:26:::1;:55::i;:::-;70374:80;;70331:129;70486:22;70464:19;:44;;;;70564:2;-1:-1:-1::0;;;;;70538:29:0::1;;70558:4;;70538:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;70538:29:0;;-1:-1:-1;;;;70538:29:0::1;51484:1;;;;;;;;67996:2576:::0;;;:::o;59804:111::-;53031:20;:18;:20::i;:::-;53023:68;;;;-1:-1:-1;;;53023:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59870:6:::1;:13:::0;;;::::1;::::0;::::1;::::0;;59899:8:::1;::::0;::::1;::::0;59870:13;;59899:8:::1;59804:111::o:0;64715:220::-;64788:18;64808:22;64837:26;;:::i;:::-;64866:23;64884:4;64866:17;:23::i;:::-;64902:15;;64919:10;;;;;64902:15;;-1:-1:-1;64894:36:0;;;-1:-1:-1;;64715:220:0;;;:::o;56993:394::-;52876:9;:7;:9::i;:::-;52868:84;;;;-1:-1:-1;;;52868:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57167:16:::1;::::0;57106:49:::1;::::0;;;;;;;-1:-1:-1;;;;;57167:16:0;;::::1;::::0;57106:47;::::1;::::0;::::1;::::0;:49:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:47;:49;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;57106:49:0;-1:-1:-1;;;;;57106:78:0::1;;57098:156;;;;-1:-1:-1::0;;;57098:156:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57265:16;:38:::0;;-1:-1:-1;;;;;57265:38:0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;57319:60:::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;56993:394:::0;:::o;76440:1747::-;76519:42;;:::i;:::-;76564:30;76582:11;76564:17;:30::i;:::-;76519:75;;76599:42;;:::i;:::-;76662:31;;76644:50;;:17;:50::i;:::-;76599:95;;76701:25;76729:20;:43;;;76701:71;;76777:24;76804:68;76858:13;76804:49;76826:20;:26;;;76804:49;;:17;:21;;:49;;;;:::i;:::-;:53;;:68::i;:::-;76879:22;;76923:31;;76956:35;;;;77006:26;;;;76879:224;;;;;;-1:-1:-1;;;;;76879:224:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76777:95;;-1:-1:-1;76879:22:0;;;:43;;:224;;;;;:22;;:224;;;;;;;;:22;;:224;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;77133:31:0;;-1:-1:-1;;;;;77110:55:0;;;;;:22;:55;;;;;:74;;;-1:-1:-1;;77199:30:0;;;:47;;77191:111;;;;-1:-1:-1;;;77191:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;77307:28:0;;;;;;;:15;:28;;;;;;;:58;;;;;;;;;;;;;;77403:19;;77431:37;;;;77427:197;;;77499:71;77556:13;77499:52;77524:20;:26;;;77499:52;;:20;:24;;:52;;;;:::i;:71::-;77576:19;:42;;;77476:94;-1:-1:-1;77427:197:0;77630:41;;:::i;:::-;77692:31;;77674:50;;:17;:50::i;:::-;77731:17;;77775:31;;77812:38;;;;77856:34;;;;77731:190;;;;;;-1:-1:-1;;;;;77731:190:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77630:94;;-1:-1:-1;77731:17:0;;;:38;;:190;;;;;:17;;:190;;;;;;;;:17;;:190;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77949:20;:26;;;77932:43;;:13;:43;77928:255;;78016:31;;78054:38;;;;78099:34;;;;;77988:189;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;77988:189:0;;;;;;;;;;;;;;;77928:255;76440:1747;;;;;;;;:::o;47001:106::-;47089:10;47001:106;:::o;72380:224::-;72443:26;;:::i;:::-;-1:-1:-1;;;;;;72483:21:0;;;;;;;:15;:21;;;;;;;;;72476:28;;;;;;;;;;;;;;;;;;;;;;;;;;72528:29;72527:56;;72568:15;;72527:56;;;72561:4;72527:56;-1:-1:-1;;;;;72509:74:0;;;72380:224;;;:::o;49505:309::-;-1:-1:-1;;;;;49596:30:0;;49588:95;;;;-1:-1:-1;;;49588:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49729:14;;;49699:63;;-1:-1:-1;;;;;49699:63:0;;;;49729:14;;;49699:63;;;49773:14;:33;;;;-1:-1:-1;;;;;49773:33:0;;;;;;;;;;49505:309::o;73220:2771::-;-1:-1:-1;;;;;73289:16:0;;73281:62;;;;-1:-1:-1;;;73281:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73350:28;;:::i;:::-;73385:35;;:::i;:::-;73423:23;73441:4;73423:17;:23::i;:::-;73474:24;;73385:61;;-1:-1:-1;;;;;;73509:18:0;;;;;;;73505:31;;;73529:7;;;;;73505:31;73681:19;;;;:24;;;:61;;;;-1:-1:-1;;;;;;73709:28:0;;;;;;:22;:28;;;;;;:33;73681:61;73677:158;;;-1:-1:-1;;;;;73750:21:0;;;;;;;:15;:21;;;;;;:37;;;;;;;;;;;;73798:19;;;73750:21;73798:19;73823:7;;;;;73677:158;73873:31;73891:12;73873:17;:31::i;:::-;73841:63;;73940:21;73958:2;73940:17;:21::i;:::-;73909:28;;;;:52;;;73968:22;;74026:29;;:44;;;;;74078:19;;;;74103:43;;;73968:179;;;;;;-1:-1:-1;;;;;73968:179:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;;;:43;;:179;;;;;:22;;:179;;;;;;;:22;;:179;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;74154:21:0;;;;;;;:15;:21;;;;;;;;:37;;;;;;;;;;;;;;74223:19;;;;74288:29;;:52;;;;74198:44;;;;;74288:72;;74198:44;74288:56;:72::i;:::-;-1:-1:-1;;;;;74249:36:0;;;;;;:22;:36;;;;;;;;:111;;;;74394:28;;;;:51;;:71;;74450:14;74394:55;:71::i;:::-;-1:-1:-1;;;;;74365:26:0;;;;;;:22;:26;;;;;:100;74503:31;74521:12;74503:17;:31::i;:::-;74472:28;;;:62;74569:21;74587:2;74569:17;:21::i;:::-;74539:4;:27;;:51;;;;74597:28;74628:251;74832:4;:27;;;:42;;;74628:194;74774:4;:28;;;:43;;;74628:136;74716:4;:28;;;:43;;;74628:78;74657:4;:29;;;:44;;;74628:19;;:23;;:78;;;;:::i;:136::-;:140;;:194::i;:251::-;74886:19;:42;;;74940:19;;74597:282;;-1:-1:-1;;;;;;74940:19:0;;;;;;;;;;;;;74998:17;;75074:28;;;;:43;;;;;75026:29;;:44;;;;-1:-1:-1;;;;;74998:17:0;;;;75026:91;75022:486;;75125:18;-1:-1:-1;;;;;75125:39:0;;75171:12;75190:4;:28;;;:47;;;75244:4;:28;;;:43;;;75294:20;75125:195;;;;;;;;;;;;;-1:-1:-1;;;;;75125:195:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;75380:28:0;;;;;:47;;;;75434:43;;;;;75333:169;;;;;;;;;;;;75495:1;75333:169;;;;;;-1:-1:-1;;;;;75333:169:0;;;;-1:-1:-1;75333:169:0;;;;;;;;;;;;75022:486;75565:4;:27;;;:42;;;75518:4;:28;;;:43;;;:89;75514:473;;75615:18;-1:-1:-1;;;;;75615:39:0;;75661:2;75670:4;:27;;;:46;;;75723:4;:27;;;:42;;;75772:20;75615:183;;;;;;;;;;;;;-1:-1:-1;;;;;75615:183:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;75848:27:0;;;;;:46;;;;75901:42;;;;75811:170;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75811:170:0;;;;-1:-1:-1;75811:170:0;;;;;;;;;;;73220:2771;;;;;;;;:::o;71739:480::-;71802:28;;:::i;:::-;71837:26;;:::i;:::-;71866:23;71884:4;71866:17;:23::i;:::-;-1:-1:-1;;;;;71896:18:0;;;;;;:11;71951:28;;;:22;:28;;;;;;;;;;71919:29;;;:60;72010:15;;:23;;;;71984;;;:49;;;71837:52;;-1:-1:-1;72066:40:0;;72105:1;72066:40;;;72092:4;:10;;;72066:40;72038:68;;:25;;;:68;72135:23;;;;:59;;72193:1;72135:59;;;72161:6;:29;;;72135:59;72111:21;;;:83;-1:-1:-1;71739:480:0;;;:::o;54068:114::-;54121:4;54145:29;;;;;;;;;;;;;;;;;;:9;:29::i;:::-;54138:36;;54068:114;:::o;55081:131::-;55163:16;;:41;;;;;;;;;;;;;;;;;;;;;;;;;55136:7;;-1:-1:-1;;;;;55163:16:0;;:28;;:41;;;;;;;;;;;:16;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55163:41:0;;-1:-1:-1;55081:131:0;:::o;56563:149::-;56650:16;;:54;;;;;;;;;;;;;;;;;;;;;;;;;56623:7;;-1:-1:-1;;;;;56650:16:0;;:28;;:54;;;;;;;;;;;:16;:54;;;;;;;;;;54626:141;54713:16;;:46;;;;;;;;;;;;;;;;;;;;;;;;;54686:7;;-1:-1:-1;;;;;54713:16:0;;:28;;:46;;;;;;;;;;;:16;:46;;;;;;;;;;1420:136;1478:7;1505:43;1509:1;1512;1505:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1498:50;1420:136;-1:-1:-1;;;1420:136:0:o;956:181::-;1014:7;1046:5;;;1070:6;;;;1062:46;;;;;-1:-1:-1;;;1062:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;53386:185;53474:16;;53428:4;;-1:-1:-1;;;;;53474:16:0;53452:10;:39;;:72;;;53509:15;:13;:15::i;:::-;-1:-1:-1;;;;;53495:29:0;:10;-1:-1:-1;;;;;53495:29:0;;53452:72;:111;;;;53542:21;:19;:21::i;:::-;-1:-1:-1;;;;;53528:35:0;:10;-1:-1:-1;;;;;53528:35:0;;53445:118;;53386:185;:::o;53736:264::-;53853:16;;53798:4;;-1:-1:-1;;;;;53853:16:0;53887:9;:7;:9::i;:::-;:105;;;-1:-1:-1;;;;;;53900:41:0;;;;;;:92;;-1:-1:-1;53945:16:0;;:33;;;;;;;;;;;;;;;;;;;;53982:10;;-1:-1:-1;;;;;53945:16:0;;:27;;53973:4;;53945:33;;;;;;;;;;;;:16;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53945:33:0;-1:-1:-1;;;;;53945:47:0;;53880:112;53736:264;-1:-1:-1;;;53736:264:0:o;1859:192::-;1945:7;1981:12;1973:6;;;;1965:29;;;;-1:-1:-1;;;1965:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2017:5:0;;;1859:192::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o
Swarm Source
ipfs://190f4d45b81ab198cc49e7d4a1fbb315f40402e0142e6481bfbe091e58ec8360
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.