API3 DAO single staking pool. Submitted by Kleros Curate.
Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 34,247 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Schedule Unstake | 21462866 | 3 hrs ago | IN | 0 ETH | 0.00066788 | ||||
Schedule Unstake | 21462597 | 4 hrs ago | IN | 0 ETH | 0.00079385 | ||||
Unstake | 21462153 | 5 hrs ago | IN | 0 ETH | 0.0005193 | ||||
Withdraw Regular | 21461597 | 7 hrs ago | IN | 0 ETH | 0.00175163 | ||||
Schedule Unstake | 21461277 | 8 hrs ago | IN | 0 ETH | 0.00072273 | ||||
Withdraw Regular | 21461174 | 8 hrs ago | IN | 0 ETH | 0.00172663 | ||||
Unstake | 21461093 | 9 hrs ago | IN | 0 ETH | 0.00044592 | ||||
Withdraw Regular | 21461068 | 9 hrs ago | IN | 0 ETH | 0.00239602 | ||||
Schedule Unstake | 21460753 | 10 hrs ago | IN | 0 ETH | 0.00084873 | ||||
Deposit Regular | 21460324 | 11 hrs ago | IN | 0 ETH | 0.00067167 | ||||
Unstake And With... | 21459835 | 13 hrs ago | IN | 0 ETH | 0.00193989 | ||||
Withdraw Regular | 21459297 | 15 hrs ago | IN | 0 ETH | 0.00301972 | ||||
Unstake | 21458733 | 17 hrs ago | IN | 0 ETH | 0.00083406 | ||||
Schedule Unstake | 21458710 | 17 hrs ago | IN | 0 ETH | 0.00120224 | ||||
Unstake And With... | 21458706 | 17 hrs ago | IN | 0 ETH | 0.00246141 | ||||
Schedule Unstake | 21458644 | 17 hrs ago | IN | 0 ETH | 0.00122273 | ||||
Schedule Unstake | 21458559 | 17 hrs ago | IN | 0 ETH | 0.00100356 | ||||
Schedule Unstake | 21458377 | 18 hrs ago | IN | 0 ETH | 0.00097455 | ||||
Withdraw Regular | 21457492 | 21 hrs ago | IN | 0 ETH | 0.00222867 | ||||
Unstake | 21457472 | 21 hrs ago | IN | 0 ETH | 0.00045166 | ||||
Withdraw Regular | 21457170 | 22 hrs ago | IN | 0 ETH | 0.00189037 | ||||
Deposit And Stak... | 21455856 | 26 hrs ago | IN | 0 ETH | 0.00085823 | ||||
Deposit And Stak... | 21455607 | 27 hrs ago | IN | 0 ETH | 0.00064024 | ||||
Withdraw Regular | 21455592 | 27 hrs ago | IN | 0 ETH | 0.00193756 | ||||
Schedule Unstake | 21453567 | 34 hrs ago | IN | 0 ETH | 0.00119681 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Api3Pool
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-07-08 */ // Sources flattened with hardhat v2.4.0 https://hardhat.org // File contracts/auxiliary/interfaces/v0.8.4/IERC20Aux.sol pragma solidity 0.8.4; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Aux { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File contracts/auxiliary/interfaces/v0.8.4/IApi3Token.sol pragma solidity 0.8.4; interface IApi3Token is IERC20Aux { event MinterStatusUpdated( address indexed minterAddress, bool minterStatus ); event BurnerStatusUpdated( address indexed burnerAddress, bool burnerStatus ); function updateMinterStatus( address minterAddress, bool minterStatus ) external; function updateBurnerStatus(bool burnerStatus) external; function mint( address account, uint256 amount ) external; function burn(uint256 amount) external; function getMinterStatus(address minterAddress) external view returns (bool minterStatus); function getBurnerStatus(address burnerAddress) external view returns (bool burnerStatus); } // File contracts/interfaces/IStateUtils.sol pragma solidity 0.8.4; interface IStateUtils { event SetDaoApps( address agentAppPrimary, address agentAppSecondary, address votingAppPrimary, address votingAppSecondary ); event SetClaimsManagerStatus( address indexed claimsManager, bool indexed status ); event SetStakeTarget(uint256 stakeTarget); event SetMaxApr(uint256 maxApr); event SetMinApr(uint256 minApr); event SetUnstakeWaitPeriod(uint256 unstakeWaitPeriod); event SetAprUpdateStep(uint256 aprUpdateStep); event SetProposalVotingPowerThreshold(uint256 proposalVotingPowerThreshold); event UpdatedLastProposalTimestamp( address indexed user, uint256 lastProposalTimestamp, address votingApp ); function setDaoApps( address _agentAppPrimary, address _agentAppSecondary, address _votingAppPrimary, address _votingAppSecondary ) external; function setClaimsManagerStatus( address claimsManager, bool status ) external; function setStakeTarget(uint256 _stakeTarget) external; function setMaxApr(uint256 _maxApr) external; function setMinApr(uint256 _minApr) external; function setUnstakeWaitPeriod(uint256 _unstakeWaitPeriod) external; function setAprUpdateStep(uint256 _aprUpdateStep) external; function setProposalVotingPowerThreshold(uint256 _proposalVotingPowerThreshold) external; function updateLastProposalTimestamp(address userAddress) external; function isGenesisEpoch() external view returns (bool); } // File contracts/StateUtils.sol pragma solidity 0.8.4; /// @title Contract that keeps state variables contract StateUtils is IStateUtils { struct Checkpoint { uint32 fromBlock; uint224 value; } struct AddressCheckpoint { uint32 fromBlock; address _address; } struct Reward { uint32 atBlock; uint224 amount; uint256 totalSharesThen; uint256 totalStakeThen; } struct User { Checkpoint[] shares; Checkpoint[] delegatedTo; AddressCheckpoint[] delegates; uint256 unstaked; uint256 vesting; uint256 unstakeAmount; uint256 unstakeShares; uint256 unstakeScheduledFor; uint256 lastDelegationUpdateTimestamp; uint256 lastProposalTimestamp; } struct LockedCalculation { uint256 initialIndEpoch; uint256 nextIndEpoch; uint256 locked; } /// @notice Length of the epoch in which the staking reward is paid out /// once. It is hardcoded as 7 days. /// @dev In addition to regulating reward payments, this variable is used /// for two additional things: /// (1) After a user makes a proposal, they cannot make a second one /// before `EPOCH_LENGTH` has passed /// (2) After a user updates their delegation status, they have to wait /// `EPOCH_LENGTH` before updating it again uint256 public constant EPOCH_LENGTH = 1 weeks; /// @notice Number of epochs before the staking rewards get unlocked. /// Hardcoded as 52 epochs, which approximately corresponds to a year with /// an `EPOCH_LENGTH` of 1 week. uint256 public constant REWARD_VESTING_PERIOD = 52; // All percentage values are represented as 1e18 = 100% uint256 internal constant ONE_PERCENT = 1e18 / 100; uint256 internal constant HUNDRED_PERCENT = 1e18; // To assert that typecasts do not overflow uint256 internal constant MAX_UINT32 = 2**32 - 1; uint256 internal constant MAX_UINT224 = 2**224 - 1; /// @notice Epochs are indexed as `block.timestamp / EPOCH_LENGTH`. /// `genesisEpoch` is the index of the epoch in which the pool is deployed. /// @dev No reward gets paid and proposals are not allowed in the genesis /// epoch uint256 public immutable genesisEpoch; /// @notice API3 token contract IApi3Token public immutable api3Token; /// @notice TimelockManager contract address public immutable timelockManager; /// @notice Address of the primary Agent app of the API3 DAO /// @dev Primary Agent can be operated through the primary Api3Voting app. /// The primary Api3Voting app requires a higher quorum by default, and the /// primary Agent is more privileged. address public agentAppPrimary; /// @notice Address of the secondary Agent app of the API3 DAO /// @dev Secondary Agent can be operated through the secondary Api3Voting /// app. The secondary Api3Voting app requires a lower quorum by default, /// and the primary Agent is less privileged. address public agentAppSecondary; /// @notice Address of the primary Api3Voting app of the API3 DAO /// @dev Used to operate the primary Agent address public votingAppPrimary; /// @notice Address of the secondary Api3Voting app of the API3 DAO /// @dev Used to operate the secondary Agent address public votingAppSecondary; /// @notice Mapping that keeps the claims manager statuses of addresses /// @dev A claims manager is a contract that is authorized to pay out /// claims from the staking pool, effectively slashing the stakers. The /// statuses are kept as a mapping to support multiple claims managers. mapping(address => bool) public claimsManagerStatus; /// @notice Records of rewards paid in each epoch /// @dev `.atBlock` of a past epoch's reward record being `0` means no /// reward was paid for that epoch mapping(uint256 => Reward) public epochIndexToReward; /// @notice Epoch index of the most recent reward uint256 public epochIndexOfLastReward; /// @notice Total number of tokens staked at the pool uint256 public totalStake; /// @notice Stake target the pool will aim to meet in percentages of the /// total token supply. The staking rewards increase if the total staked /// amount is below this, and vice versa. /// @dev Default value is 50% of the total API3 token supply. This /// parameter is governable by the DAO. uint256 public stakeTarget = ONE_PERCENT * 50; /// @notice Minimum APR (annual percentage rate) the pool will pay as /// staking rewards in percentages /// @dev Default value is 2.5%. This parameter is governable by the DAO. uint256 public minApr = ONE_PERCENT * 25 / 10; /// @notice Maximum APR (annual percentage rate) the pool will pay as /// staking rewards in percentages /// @dev Default value is 75%. This parameter is governable by the DAO. uint256 public maxApr = ONE_PERCENT * 75; /// @notice Steps in which APR will be updated in percentages /// @dev Default value is 1%. This parameter is governable by the DAO. uint256 public aprUpdateStep = ONE_PERCENT; /// @notice Users need to schedule an unstake and wait for /// `unstakeWaitPeriod` before being able to unstake. This is to prevent /// the stakers from frontrunning insurance claims by unstaking to evade /// them, or repeatedly unstake/stake to work around the proposal spam /// protection. The tokens awaiting to be unstaked during this period do /// not grant voting power or rewards. /// @dev This parameter is governable by the DAO, and the DAO is expected /// to set this to a value that is large enough to allow insurance claims /// to be resolved. uint256 public unstakeWaitPeriod = EPOCH_LENGTH; /// @notice Minimum voting power the users must have to be able to make /// proposals (in percentages) /// @dev Delegations count towards voting power. /// Default value is 0.1%. This parameter is governable by the DAO. uint256 public proposalVotingPowerThreshold = ONE_PERCENT / 10; /// @notice APR that will be paid next epoch /// @dev This value will reach an equilibrium based on the stake target. /// Every epoch (week), APR/52 of the total staked tokens will be added to /// the pool, effectively distributing them to the stakers. uint256 public apr = (maxApr + minApr) / 2; /// @notice User records mapping(address => User) public users; // Keeps the total number of shares of the pool Checkpoint[] public poolShares; // Keeps user states used in `withdrawPrecalculated()` calls mapping(address => LockedCalculation) public userToLockedCalculation; // Kept to prevent third parties from frontrunning the initialization // `setDaoApps()` call and grief the deployment address private deployer; /// @dev Reverts if the caller is not an API3 DAO Agent modifier onlyAgentApp() { require( msg.sender == agentAppPrimary || msg.sender == agentAppSecondary, "Pool: Caller not agent" ); _; } /// @dev Reverts if the caller is not the primary API3 DAO Agent modifier onlyAgentAppPrimary() { require( msg.sender == agentAppPrimary, "Pool: Caller not primary agent" ); _; } /// @dev Reverts if the caller is not an API3 DAO Api3Voting app modifier onlyVotingApp() { require( msg.sender == votingAppPrimary || msg.sender == votingAppSecondary, "Pool: Caller not voting app" ); _; } /// @param api3TokenAddress API3 token contract address /// @param timelockManagerAddress Timelock manager contract address constructor( address api3TokenAddress, address timelockManagerAddress ) { require( api3TokenAddress != address(0), "Pool: Invalid Api3Token" ); require( timelockManagerAddress != address(0), "Pool: Invalid TimelockManager" ); deployer = msg.sender; api3Token = IApi3Token(api3TokenAddress); timelockManager = timelockManagerAddress; // Initialize the share price at 1 updateCheckpointArray(poolShares, 1); totalStake = 1; // Set the current epoch as the genesis epoch and skip its reward // payment uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; genesisEpoch = currentEpoch; epochIndexOfLastReward = currentEpoch; } /// @notice Called after deployment to set the addresses of the DAO apps /// @dev This can also be called later on by the primary Agent to update /// all app addresses as a means of an upgrade /// @param _agentAppPrimary Address of the primary Agent /// @param _agentAppSecondary Address of the secondary Agent /// @param _votingAppPrimary Address of the primary Api3Voting app /// @param _votingAppSecondary Address of the secondary Api3Voting app function setDaoApps( address _agentAppPrimary, address _agentAppSecondary, address _votingAppPrimary, address _votingAppSecondary ) external override { // solhint-disable-next-line reason-string require( msg.sender == agentAppPrimary || (agentAppPrimary == address(0) && msg.sender == deployer), "Pool: Caller not primary agent or deployer initializing values" ); require( _agentAppPrimary != address(0) && _agentAppSecondary != address(0) && _votingAppPrimary != address(0) && _votingAppSecondary != address(0), "Pool: Invalid DAO apps" ); agentAppPrimary = _agentAppPrimary; agentAppSecondary = _agentAppSecondary; votingAppPrimary = _votingAppPrimary; votingAppSecondary = _votingAppSecondary; emit SetDaoApps( agentAppPrimary, agentAppSecondary, votingAppPrimary, votingAppSecondary ); } /// @notice Called by the primary DAO Agent to set the authorization status /// of a claims manager contract /// @dev The claims manager is a trusted contract that is allowed to /// withdraw as many tokens as it wants from the pool to pay out insurance /// claims. /// Only the primary Agent can do this because it is a critical operation. /// WARNING: A compromised contract being given claims manager status may /// result in loss of staked funds. If a proposal has been made to call /// this method to set a contract as a claims manager, you are recommended /// to review the contract yourself and/or refer to the audit reports to /// understand the implications. /// @param claimsManager Claims manager contract address /// @param status Authorization status function setClaimsManagerStatus( address claimsManager, bool status ) external override onlyAgentAppPrimary() { claimsManagerStatus[claimsManager] = status; emit SetClaimsManagerStatus( claimsManager, status ); } /// @notice Called by the DAO Agent to set the stake target /// @param _stakeTarget Stake target function setStakeTarget(uint256 _stakeTarget) external override onlyAgentApp() { require( _stakeTarget <= HUNDRED_PERCENT, "Pool: Invalid percentage value" ); stakeTarget = _stakeTarget; emit SetStakeTarget(_stakeTarget); } /// @notice Called by the DAO Agent to set the maximum APR /// @param _maxApr Maximum APR function setMaxApr(uint256 _maxApr) external override onlyAgentApp() { require( _maxApr >= minApr, "Pool: Max APR smaller than min" ); maxApr = _maxApr; emit SetMaxApr(_maxApr); } /// @notice Called by the DAO Agent to set the minimum APR /// @param _minApr Minimum APR function setMinApr(uint256 _minApr) external override onlyAgentApp() { require( _minApr <= maxApr, "Pool: Min APR larger than max" ); minApr = _minApr; emit SetMinApr(_minApr); } /// @notice Called by the primary DAO Agent to set the unstake waiting /// period /// @dev This may want to be increased to provide more time for insurance /// claims to be resolved. /// Even when the insurance functionality is not implemented, the minimum /// valid value is `EPOCH_LENGTH` to prevent users from unstaking, /// withdrawing and staking with another address to work around the /// proposal spam protection. /// Only the primary Agent can do this because it is a critical operation. /// @param _unstakeWaitPeriod Unstake waiting period function setUnstakeWaitPeriod(uint256 _unstakeWaitPeriod) external override onlyAgentAppPrimary() { require( _unstakeWaitPeriod >= EPOCH_LENGTH, "Pool: Period shorter than epoch" ); unstakeWaitPeriod = _unstakeWaitPeriod; emit SetUnstakeWaitPeriod(_unstakeWaitPeriod); } /// @notice Called by the primary DAO Agent to set the APR update steps /// @dev aprUpdateStep can be 0% or 100%+. /// Only the primary Agent can do this because it is a critical operation. /// @param _aprUpdateStep APR update steps function setAprUpdateStep(uint256 _aprUpdateStep) external override onlyAgentAppPrimary() { aprUpdateStep = _aprUpdateStep; emit SetAprUpdateStep(_aprUpdateStep); } /// @notice Called by the primary DAO Agent to set the voting power /// threshold for proposals /// @dev Only the primary Agent can do this because it is a critical /// operation. /// @param _proposalVotingPowerThreshold Voting power threshold for /// proposals function setProposalVotingPowerThreshold(uint256 _proposalVotingPowerThreshold) external override onlyAgentAppPrimary() { require( _proposalVotingPowerThreshold >= ONE_PERCENT / 10 && _proposalVotingPowerThreshold <= ONE_PERCENT * 10, "Pool: Threshold outside limits"); proposalVotingPowerThreshold = _proposalVotingPowerThreshold; emit SetProposalVotingPowerThreshold(_proposalVotingPowerThreshold); } /// @notice Called by a DAO Api3Voting app at proposal creation-time to /// update the timestamp of the user's last proposal /// @param userAddress User address function updateLastProposalTimestamp(address userAddress) external override onlyVotingApp() { users[userAddress].lastProposalTimestamp = block.timestamp; emit UpdatedLastProposalTimestamp( userAddress, block.timestamp, msg.sender ); } /// @notice Called to check if we are in the genesis epoch /// @dev Voting apps use this to prevent proposals from being made in the /// genesis epoch /// @return If the current epoch is the genesis epoch function isGenesisEpoch() external view override returns (bool) { return block.timestamp / EPOCH_LENGTH == genesisEpoch; } /// @notice Called internally to update a checkpoint array by pushing a new /// checkpoint /// @dev We assume `block.number` will always fit in a uint32 and `value` /// will always fit in a uint224. `value` will either be a raw token amount /// or a raw pool share amount so this assumption will be correct in /// practice with a token with 18 decimals, 1e8 initial total supply and no /// hyperinflation. /// @param checkpointArray Checkpoint array /// @param value Value to be used to create the new checkpoint function updateCheckpointArray( Checkpoint[] storage checkpointArray, uint256 value ) internal { assert(block.number <= MAX_UINT32); assert(value <= MAX_UINT224); checkpointArray.push(Checkpoint({ fromBlock: uint32(block.number), value: uint224(value) })); } /// @notice Called internally to update an address-checkpoint array by /// pushing a new checkpoint /// @dev We assume `block.number` will always fit in a uint32 /// @param addressCheckpointArray Address-checkpoint array /// @param _address Address to be used to create the new checkpoint function updateAddressCheckpointArray( AddressCheckpoint[] storage addressCheckpointArray, address _address ) internal { assert(block.number <= MAX_UINT32); addressCheckpointArray.push(AddressCheckpoint({ fromBlock: uint32(block.number), _address: _address })); } } // File contracts/interfaces/IGetterUtils.sol pragma solidity 0.8.4; interface IGetterUtils is IStateUtils { function userVotingPowerAt( address userAddress, uint256 _block ) external view returns (uint256); function userVotingPower(address userAddress) external view returns (uint256); function totalSharesAt(uint256 _block) external view returns (uint256); function totalShares() external view returns (uint256); function userSharesAt( address userAddress, uint256 _block ) external view returns (uint256); function userShares(address userAddress) external view returns (uint256); function userStake(address userAddress) external view returns (uint256); function delegatedToUserAt( address userAddress, uint256 _block ) external view returns (uint256); function delegatedToUser(address userAddress) external view returns (uint256); function userDelegateAt( address userAddress, uint256 _block ) external view returns (address); function userDelegate(address userAddress) external view returns (address); function userLocked(address userAddress) external view returns (uint256); function getUser(address userAddress) external view returns ( uint256 unstaked, uint256 vesting, uint256 unstakeShares, uint256 unstakeAmount, uint256 unstakeScheduledFor, uint256 lastDelegationUpdateTimestamp, uint256 lastProposalTimestamp ); } // File contracts/GetterUtils.sol pragma solidity 0.8.4; /// @title Contract that implements getters abstract contract GetterUtils is StateUtils, IGetterUtils { /// @notice Called to get the voting power of a user at a specific block /// @param userAddress User address /// @param _block Block number for which the query is being made for /// @return Voting power of the user at the block function userVotingPowerAt( address userAddress, uint256 _block ) public view override returns (uint256) { // Users that have a delegate have no voting power if (userDelegateAt(userAddress, _block) != address(0)) { return 0; } return userSharesAt(userAddress, _block) + delegatedToUserAt(userAddress, _block); } /// @notice Called to get the current voting power of a user /// @param userAddress User address /// @return Current voting power of the user function userVotingPower(address userAddress) external view override returns (uint256) { return userVotingPowerAt(userAddress, block.number); } /// @notice Called to get the total pool shares at a specific block /// @dev Total pool shares also corresponds to total voting power /// @param _block Block number for which the query is being made for /// @return Total pool shares at the block function totalSharesAt(uint256 _block) public view override returns (uint256) { return getValueAt(poolShares, _block); } /// @notice Called to get the current total pool shares /// @dev Total pool shares also corresponds to total voting power /// @return Current total pool shares function totalShares() public view override returns (uint256) { return totalSharesAt(block.number); } /// @notice Called to get the pool shares of a user at a specific block /// @param userAddress User address /// @param _block Block number for which the query is being made for /// @return Pool shares of the user at the block function userSharesAt( address userAddress, uint256 _block ) public view override returns (uint256) { return getValueAt(users[userAddress].shares, _block); } /// @notice Called to get the current pool shares of a user /// @param userAddress User address /// @return Current pool shares of the user function userShares(address userAddress) public view override returns (uint256) { return userSharesAt(userAddress, block.number); } /// @notice Called to get the current staked tokens of the user /// @param userAddress User address /// @return Current staked tokens of the user function userStake(address userAddress) public view override returns (uint256) { return userShares(userAddress) * totalStake / totalShares(); } /// @notice Called to get the voting power delegated to a user at a /// specific block /// @param userAddress User address /// @param _block Block number for which the query is being made for /// @return Voting power delegated to the user at the block function delegatedToUserAt( address userAddress, uint256 _block ) public view override returns (uint256) { return getValueAt(users[userAddress].delegatedTo, _block); } /// @notice Called to get the current voting power delegated to a user /// @param userAddress User address /// @return Current voting power delegated to the user function delegatedToUser(address userAddress) public view override returns (uint256) { return delegatedToUserAt(userAddress, block.number); } /// @notice Called to get the delegate of the user at a specific block /// @param userAddress User address /// @param _block Block number /// @return Delegate of the user at the specific block function userDelegateAt( address userAddress, uint256 _block ) public view override returns (address) { return getAddressAt(users[userAddress].delegates, _block); } /// @notice Called to get the current delegate of the user /// @param userAddress User address /// @return Current delegate of the user function userDelegate(address userAddress) public view override returns (address) { return userDelegateAt(userAddress, block.number); } /// @notice Called to get the current locked tokens of the user /// @param userAddress User address /// @return locked Current locked tokens of the user function userLocked(address userAddress) public view override returns (uint256 locked) { Checkpoint[] storage _userShares = users[userAddress].shares; uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; uint256 oldestLockedEpoch = getOldestLockedEpoch(); uint256 indUserShares = _userShares.length; for ( uint256 indEpoch = currentEpoch; indEpoch >= oldestLockedEpoch; indEpoch-- ) { // The user has never staked at this point, we can exit early if (indUserShares == 0) { break; } Reward storage lockedReward = epochIndexToReward[indEpoch]; if (lockedReward.atBlock != 0) { for (; indUserShares > 0; indUserShares--) { Checkpoint storage userShare = _userShares[indUserShares - 1]; if (userShare.fromBlock <= lockedReward.atBlock) { locked += lockedReward.amount * userShare.value / lockedReward.totalSharesThen; break; } } } } } /// @notice Called to get the details of a user /// @param userAddress User address /// @return unstaked Amount of unstaked API3 tokens /// @return vesting Amount of API3 tokens locked by vesting /// @return unstakeAmount Amount scheduled to unstake /// @return unstakeShares Shares revoked to unstake /// @return unstakeScheduledFor Time unstaking is scheduled for /// @return lastDelegationUpdateTimestamp Time of last delegation update /// @return lastProposalTimestamp Time when the user made their most /// recent proposal function getUser(address userAddress) external view override returns ( uint256 unstaked, uint256 vesting, uint256 unstakeAmount, uint256 unstakeShares, uint256 unstakeScheduledFor, uint256 lastDelegationUpdateTimestamp, uint256 lastProposalTimestamp ) { User storage user = users[userAddress]; unstaked = user.unstaked; vesting = user.vesting; unstakeAmount = user.unstakeAmount; unstakeShares = user.unstakeShares; unstakeScheduledFor = user.unstakeScheduledFor; lastDelegationUpdateTimestamp = user.lastDelegationUpdateTimestamp; lastProposalTimestamp = user.lastProposalTimestamp; } /// @notice Called to get the value of a checkpoint array at a specific /// block using binary search /// @dev Adapted from /// https://github.com/aragon/minime/blob/1d5251fc88eee5024ff318d95bc9f4c5de130430/contracts/MiniMeToken.sol#L431 /// @param checkpoints Checkpoints array /// @param _block Block number for which the query is being made /// @return Value of the checkpoint array at the block function getValueAt( Checkpoint[] storage checkpoints, uint256 _block ) internal view returns (uint256) { if (checkpoints.length == 0) return 0; // Shortcut for the actual value if (_block >= checkpoints[checkpoints.length -1].fromBlock) return checkpoints[checkpoints.length - 1].value; if (_block < checkpoints[0].fromBlock) return 0; // Limit the search to the last 1024 elements if the value being // searched falls within that window uint min = 0; if ( checkpoints.length > 1024 && checkpoints[checkpoints.length - 1024].fromBlock < _block ) { min = checkpoints.length - 1024; } // Binary search of the value in the array uint max = checkpoints.length - 1; while (max > min) { uint mid = (max + min + 1) / 2; if (checkpoints[mid].fromBlock <= _block) { min = mid; } else { max = mid - 1; } } return checkpoints[min].value; } /// @notice Called to get the value of an address-checkpoint array at a /// specific block using binary search /// @dev Adapted from /// https://github.com/aragon/minime/blob/1d5251fc88eee5024ff318d95bc9f4c5de130430/contracts/MiniMeToken.sol#L431 /// @param checkpoints Address-checkpoint array /// @param _block Block number for which the query is being made /// @return Value of the address-checkpoint array at the block function getAddressAt( AddressCheckpoint[] storage checkpoints, uint256 _block ) private view returns (address) { if (checkpoints.length == 0) return address(0); // Shortcut for the actual value if (_block >= checkpoints[checkpoints.length -1].fromBlock) return checkpoints[checkpoints.length - 1]._address; if (_block < checkpoints[0].fromBlock) return address(0); // Limit the search to the last 1024 elements if the value being // searched falls within that window uint min = 0; if ( checkpoints.length > 1024 && checkpoints[checkpoints.length - 1024].fromBlock < _block ) { min = checkpoints.length - 1024; } // Binary search of the value in the array uint max = checkpoints.length - 1; while (max > min) { uint mid = (max + min + 1) / 2; if (checkpoints[mid].fromBlock <= _block) { min = mid; } else { max = mid - 1; } } return checkpoints[min]._address; } /// @notice Called internally to get the index of the oldest epoch whose /// reward should be locked in the current epoch /// @return oldestLockedEpoch Index of the oldest epoch with locked rewards function getOldestLockedEpoch() internal view returns (uint256 oldestLockedEpoch) { uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; oldestLockedEpoch = currentEpoch - REWARD_VESTING_PERIOD + 1; if (oldestLockedEpoch < genesisEpoch + 1) { oldestLockedEpoch = genesisEpoch + 1; } } } // File contracts/interfaces/IRewardUtils.sol pragma solidity 0.8.4; interface IRewardUtils is IGetterUtils { event MintedReward( uint256 indexed epochIndex, uint256 amount, uint256 newApr, uint256 totalStake ); function mintReward() external; } // File contracts/RewardUtils.sol pragma solidity 0.8.4; /// @title Contract that implements reward payments abstract contract RewardUtils is GetterUtils, IRewardUtils { /// @notice Called to mint the staking reward /// @dev Skips past epochs for which rewards have not been paid for. /// Skips the reward payment if the pool is not authorized to mint tokens. /// Neither of these conditions will occur in practice. function mintReward() public override { uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; // This will be skipped in most cases because someone else will have // triggered the payment for this epoch if (epochIndexOfLastReward < currentEpoch) { if (api3Token.getMinterStatus(address(this))) { uint256 rewardAmount = totalStake * apr * EPOCH_LENGTH / 365 days / HUNDRED_PERCENT; assert(block.number <= MAX_UINT32); assert(rewardAmount <= MAX_UINT224); epochIndexToReward[currentEpoch] = Reward({ atBlock: uint32(block.number), amount: uint224(rewardAmount), totalSharesThen: totalShares(), totalStakeThen: totalStake }); api3Token.mint(address(this), rewardAmount); totalStake += rewardAmount; updateCurrentApr(); emit MintedReward( currentEpoch, rewardAmount, apr, totalStake ); } epochIndexOfLastReward = currentEpoch; } } /// @notice Updates the current APR /// @dev Called internally after paying out the reward function updateCurrentApr() internal { uint256 totalStakePercentage = totalStake * HUNDRED_PERCENT / api3Token.totalSupply(); if (totalStakePercentage > stakeTarget) { apr = apr > aprUpdateStep ? apr - aprUpdateStep : 0; } else { apr += aprUpdateStep; } if (apr > maxApr) { apr = maxApr; } else if (apr < minApr) { apr = minApr; } } } // File contracts/interfaces/IDelegationUtils.sol pragma solidity 0.8.4; interface IDelegationUtils is IRewardUtils { event Delegated( address indexed user, address indexed delegate, uint256 shares, uint256 totalDelegatedTo ); event Undelegated( address indexed user, address indexed delegate, uint256 shares, uint256 totalDelegatedTo ); event UpdatedDelegation( address indexed user, address indexed delegate, bool delta, uint256 shares, uint256 totalDelegatedTo ); function delegateVotingPower(address delegate) external; function undelegateVotingPower() external; } // File contracts/DelegationUtils.sol pragma solidity 0.8.4; /// @title Contract that implements voting power delegation abstract contract DelegationUtils is RewardUtils, IDelegationUtils { /// @notice Called by the user to delegate voting power /// @param delegate User address the voting power will be delegated to function delegateVotingPower(address delegate) external override { mintReward(); require( delegate != address(0) && delegate != msg.sender, "Pool: Invalid delegate" ); // Delegating users cannot use their voting power, so we are // verifying that the delegate is not currently delegating. However, // the delegate may delegate after they have been delegated to. require( userDelegate(delegate) == address(0), "Pool: Delegate is delegating" ); User storage user = users[msg.sender]; // Do not allow frequent delegation updates as that can be used to spam // proposals require( user.lastDelegationUpdateTimestamp + EPOCH_LENGTH < block.timestamp, "Pool: Updated delegate recently" ); user.lastDelegationUpdateTimestamp = block.timestamp; uint256 userShares = userShares(msg.sender); require( userShares != 0, "Pool: Have no shares to delegate" ); address previousDelegate = userDelegate(msg.sender); require( previousDelegate != delegate, "Pool: Already delegated" ); if (previousDelegate != address(0)) { // Need to revoke previous delegation updateCheckpointArray( users[previousDelegate].delegatedTo, delegatedToUser(previousDelegate) - userShares ); } // Assign the new delegation uint256 delegatedToUpdate = delegatedToUser(delegate) + userShares; updateCheckpointArray( users[delegate].delegatedTo, delegatedToUpdate ); // Record the new delegate for the user updateAddressCheckpointArray( user.delegates, delegate ); emit Delegated( msg.sender, delegate, userShares, delegatedToUpdate ); } /// @notice Called by the user to undelegate voting power function undelegateVotingPower() external override { mintReward(); User storage user = users[msg.sender]; address previousDelegate = userDelegate(msg.sender); require( previousDelegate != address(0), "Pool: Not delegated" ); require( user.lastDelegationUpdateTimestamp + EPOCH_LENGTH < block.timestamp, "Pool: Updated delegate recently" ); user.lastDelegationUpdateTimestamp = block.timestamp; uint256 userShares = userShares(msg.sender); uint256 delegatedToUpdate = delegatedToUser(previousDelegate) - userShares; updateCheckpointArray( users[previousDelegate].delegatedTo, delegatedToUpdate ); updateAddressCheckpointArray( user.delegates, address(0) ); emit Undelegated( msg.sender, previousDelegate, userShares, delegatedToUpdate ); } /// @notice Called internally when the user shares are updated to update /// the delegated voting power /// @dev User shares only get updated while staking or scheduling unstaking /// @param shares Amount of shares that will be added/removed /// @param delta Whether the shares will be added/removed (add for `true`, /// and vice versa) function updateDelegatedVotingPower( uint256 shares, bool delta ) internal { address delegate = userDelegate(msg.sender); if (delegate == address(0)) { return; } uint256 currentDelegatedTo = delegatedToUser(delegate); uint256 delegatedToUpdate = delta ? currentDelegatedTo + shares : currentDelegatedTo - shares; updateCheckpointArray( users[delegate].delegatedTo, delegatedToUpdate ); emit UpdatedDelegation( msg.sender, delegate, delta, shares, delegatedToUpdate ); } } // File contracts/interfaces/ITransferUtils.sol pragma solidity 0.8.4; interface ITransferUtils is IDelegationUtils{ event Deposited( address indexed user, uint256 amount, uint256 userUnstaked ); event Withdrawn( address indexed user, uint256 amount, uint256 userUnstaked ); event CalculatingUserLocked( address indexed user, uint256 nextIndEpoch, uint256 oldestLockedEpoch ); event CalculatedUserLocked( address indexed user, uint256 amount ); function depositRegular(uint256 amount) external; function withdrawRegular(uint256 amount) external; function precalculateUserLocked( address userAddress, uint256 noEpochsPerIteration ) external returns (bool finished); function withdrawPrecalculated(uint256 amount) external; } // File contracts/TransferUtils.sol pragma solidity 0.8.4; /// @title Contract that implements token transfer functionality abstract contract TransferUtils is DelegationUtils, ITransferUtils { /// @notice Called by the user to deposit tokens /// @dev The user should approve the pool to spend at least `amount` tokens /// before calling this. /// The method is named `depositRegular()` to prevent potential confusion. /// See `deposit()` for more context. /// @param amount Amount to be deposited function depositRegular(uint256 amount) public override { mintReward(); uint256 unstakedUpdate = users[msg.sender].unstaked + amount; users[msg.sender].unstaked = unstakedUpdate; // Should never return false because the API3 token uses the // OpenZeppelin implementation assert(api3Token.transferFrom(msg.sender, address(this), amount)); emit Deposited( msg.sender, amount, unstakedUpdate ); } /// @notice Called by the user to withdraw tokens to their wallet /// @dev The user should call `userLocked()` beforehand to ensure that /// they have at least `amount` unlocked tokens to withdraw. /// The method is named `withdrawRegular()` to be consistent with the name /// `depositRegular()`. See `depositRegular()` for more context. /// @param amount Amount to be withdrawn function withdrawRegular(uint256 amount) public override { mintReward(); withdraw(amount, userLocked(msg.sender)); } /// @notice Called to calculate the locked tokens of a user by making /// multiple transactions /// @dev If the user updates their `user.shares` by staking/unstaking too /// frequently (50+/week) in the last `REWARD_VESTING_PERIOD`, the /// `userLocked()` call gas cost may exceed the block gas limit. In that /// case, the user may call this method multiple times to have their locked /// tokens calculated and use `withdrawPrecalculated()` to withdraw. /// @param userAddress User address /// @param noEpochsPerIteration Number of epochs per iteration /// @return finished Calculation has finished in this call function precalculateUserLocked( address userAddress, uint256 noEpochsPerIteration ) external override returns (bool finished) { mintReward(); require( noEpochsPerIteration > 0, "Pool: Zero iteration window" ); uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; LockedCalculation storage lockedCalculation = userToLockedCalculation[userAddress]; // Reset the state if there was no calculation made in this epoch if (lockedCalculation.initialIndEpoch != currentEpoch) { lockedCalculation.initialIndEpoch = currentEpoch; lockedCalculation.nextIndEpoch = currentEpoch; lockedCalculation.locked = 0; } uint256 indEpoch = lockedCalculation.nextIndEpoch; uint256 locked = lockedCalculation.locked; uint256 oldestLockedEpoch = getOldestLockedEpoch(); for (; indEpoch >= oldestLockedEpoch; indEpoch--) { if (lockedCalculation.nextIndEpoch >= indEpoch + noEpochsPerIteration) { lockedCalculation.nextIndEpoch = indEpoch; lockedCalculation.locked = locked; emit CalculatingUserLocked( userAddress, indEpoch, oldestLockedEpoch ); return false; } Reward storage lockedReward = epochIndexToReward[indEpoch]; if (lockedReward.atBlock != 0) { uint256 userSharesThen = userSharesAt(userAddress, lockedReward.atBlock); locked += lockedReward.amount * userSharesThen / lockedReward.totalSharesThen; } } lockedCalculation.nextIndEpoch = indEpoch; lockedCalculation.locked = locked; emit CalculatedUserLocked(userAddress, locked); return true; } /// @notice Called by the user to withdraw after their locked token amount /// is calculated with repeated calls to `precalculateUserLocked()` /// @dev Only use `precalculateUserLocked()` and this method if /// `withdrawRegular()` hits the block gas limit /// @param amount Amount to be withdrawn function withdrawPrecalculated(uint256 amount) external override { mintReward(); uint256 currentEpoch = block.timestamp / EPOCH_LENGTH; LockedCalculation storage lockedCalculation = userToLockedCalculation[msg.sender]; require( lockedCalculation.initialIndEpoch == currentEpoch, "Pool: Calculation not up to date" ); require( lockedCalculation.nextIndEpoch < getOldestLockedEpoch(), "Pool: Calculation not complete" ); withdraw(amount, lockedCalculation.locked); } /// @notice Called internally after the amount of locked tokens of the user /// is determined /// @param amount Amount to be withdrawn /// @param userLocked Amount of locked tokens of the user function withdraw( uint256 amount, uint256 userLocked ) private { User storage user = users[msg.sender]; // Check if the user has `amount` unlocked tokens to withdraw uint256 lockedAndVesting = userLocked + user.vesting; uint256 userTotalFunds = user.unstaked + userStake(msg.sender); require( userTotalFunds >= lockedAndVesting + amount, "Pool: Not enough unlocked funds" ); require( user.unstaked >= amount, "Pool: Not enough unstaked funds" ); // Carry on with the withdrawal uint256 unstakedUpdate = user.unstaked - amount; user.unstaked = unstakedUpdate; // Should never return false because the API3 token uses the // OpenZeppelin implementation assert(api3Token.transfer(msg.sender, amount)); emit Withdrawn( msg.sender, amount, unstakedUpdate ); } } // File contracts/interfaces/IStakeUtils.sol pragma solidity 0.8.4; interface IStakeUtils is ITransferUtils{ event Staked( address indexed user, uint256 amount, uint256 mintedShares, uint256 userUnstaked, uint256 userShares, uint256 totalShares, uint256 totalStake ); event ScheduledUnstake( address indexed user, uint256 amount, uint256 shares, uint256 scheduledFor, uint256 userShares ); event Unstaked( address indexed user, uint256 amount, uint256 userUnstaked, uint256 totalShares, uint256 totalStake ); function stake(uint256 amount) external; function depositAndStake(uint256 amount) external; function scheduleUnstake(uint256 amount) external; function unstake(address userAddress) external returns (uint256); function unstakeAndWithdraw() external; } // File contracts/StakeUtils.sol pragma solidity 0.8.4; /// @title Contract that implements staking functionality abstract contract StakeUtils is TransferUtils, IStakeUtils { /// @notice Called to stake tokens to receive pools in the share /// @param amount Amount of tokens to stake function stake(uint256 amount) public override { mintReward(); User storage user = users[msg.sender]; require( user.unstaked >= amount, "Pool: Amount exceeds unstaked" ); uint256 userUnstakedUpdate = user.unstaked - amount; user.unstaked = userUnstakedUpdate; uint256 totalSharesNow = totalShares(); uint256 sharesToMint = amount * totalSharesNow / totalStake; uint256 userSharesUpdate = userShares(msg.sender) + sharesToMint; updateCheckpointArray( user.shares, userSharesUpdate ); uint256 totalSharesUpdate = totalSharesNow + sharesToMint; updateCheckpointArray( poolShares, totalSharesUpdate ); totalStake += amount; updateDelegatedVotingPower(sharesToMint, true); emit Staked( msg.sender, amount, sharesToMint, userUnstakedUpdate, userSharesUpdate, totalSharesUpdate, totalStake ); } /// @notice Convenience method to deposit and stake in a single transaction /// @param amount Amount to be deposited and staked function depositAndStake(uint256 amount) external override { depositRegular(amount); stake(amount); } /// @notice Called by the user to schedule unstaking of their tokens /// @dev While scheduling an unstake, `shares` get deducted from the user, /// meaning that they will not receive rewards or voting power for them any /// longer. /// At unstaking-time, the user unstakes either the amount of tokens /// scheduled to unstake, or the amount of tokens `shares` corresponds to /// at unstaking-time, whichever is smaller. This corresponds to tokens /// being scheduled to be unstaked not receiving any rewards, but being /// subject to claim payouts. /// In the instance that a claim has been paid out before an unstaking is /// executed, the user may potentially receive rewards during /// `unstakeWaitPeriod` (but not if there has not been a claim payout) but /// the amount of tokens that they can unstake will not be able to exceed /// the amount they scheduled the unstaking for. /// @param amount Amount of tokens scheduled to unstake function scheduleUnstake(uint256 amount) external override { mintReward(); uint256 userSharesNow = userShares(msg.sender); uint256 totalSharesNow = totalShares(); uint256 userStaked = userSharesNow * totalStake / totalSharesNow; require( userStaked >= amount, "Pool: Amount exceeds staked" ); User storage user = users[msg.sender]; require( user.unstakeScheduledFor == 0, "Pool: Unexecuted unstake exists" ); uint256 sharesToUnstake = amount * totalSharesNow / totalStake; // This will only happen if the user wants to schedule an unstake for a // few Wei require(sharesToUnstake > 0, "Pool: Unstake amount too small"); uint256 unstakeScheduledFor = block.timestamp + unstakeWaitPeriod; user.unstakeScheduledFor = unstakeScheduledFor; user.unstakeAmount = amount; user.unstakeShares = sharesToUnstake; uint256 userSharesUpdate = userSharesNow - sharesToUnstake; updateCheckpointArray( user.shares, userSharesUpdate ); updateDelegatedVotingPower(sharesToUnstake, false); emit ScheduledUnstake( msg.sender, amount, sharesToUnstake, unstakeScheduledFor, userSharesUpdate ); } /// @notice Called to execute a pre-scheduled unstake /// @dev Anyone can execute a matured unstake. This is to allow the user to /// use bots, etc. to execute their unstaking as soon as possible. /// @param userAddress User address /// @return Amount of tokens that are unstaked function unstake(address userAddress) public override returns (uint256) { mintReward(); User storage user = users[userAddress]; require( user.unstakeScheduledFor != 0, "Pool: No unstake scheduled" ); require( user.unstakeScheduledFor < block.timestamp, "Pool: Unstake not mature yet" ); uint256 totalShares = totalShares(); uint256 unstakeAmount = user.unstakeAmount; uint256 unstakeAmountByShares = user.unstakeShares * totalStake / totalShares; // If there was a claim payout in between the scheduling and the actual // unstake then the amount might be lower than expected at scheduling // time if (unstakeAmount > unstakeAmountByShares) { unstakeAmount = unstakeAmountByShares; } uint256 userUnstakedUpdate = user.unstaked + unstakeAmount; user.unstaked = userUnstakedUpdate; uint256 totalSharesUpdate = totalShares - user.unstakeShares; updateCheckpointArray( poolShares, totalSharesUpdate ); totalStake -= unstakeAmount; user.unstakeAmount = 0; user.unstakeShares = 0; user.unstakeScheduledFor = 0; emit Unstaked( userAddress, unstakeAmount, userUnstakedUpdate, totalSharesUpdate, totalStake ); return unstakeAmount; } /// @notice Convenience method to execute an unstake and withdraw to the /// user's wallet in a single transaction /// @dev The withdrawal will revert if the user has less than /// `unstakeAmount` tokens that are withdrawable function unstakeAndWithdraw() external override { withdrawRegular(unstake(msg.sender)); } } // File contracts/interfaces/IClaimUtils.sol pragma solidity 0.8.4; interface IClaimUtils is IStakeUtils { event PaidOutClaim( address indexed recipient, uint256 amount, uint256 totalStake ); function payOutClaim( address recipient, uint256 amount ) external; } // File contracts/ClaimUtils.sol pragma solidity 0.8.4; /// @title Contract that implements the insurance claim payout functionality abstract contract ClaimUtils is StakeUtils, IClaimUtils { /// @dev Reverts if the caller is not a claims manager modifier onlyClaimsManager() { require( claimsManagerStatus[msg.sender], "Pool: Caller not claims manager" ); _; } /// @notice Called by a claims manager to pay out an insurance claim /// @dev The claims manager is a trusted contract that is allowed to /// withdraw as many tokens as it wants from the pool to pay out insurance /// claims. Any kind of limiting logic (e.g., maximum amount of tokens that /// can be withdrawn) is implemented at its end and is out of the scope of /// this contract. /// This will revert if the pool does not have enough staked funds. /// @param recipient Recipient of the claim /// @param amount Amount of tokens that will be paid out function payOutClaim( address recipient, uint256 amount ) external override onlyClaimsManager() { mintReward(); // totalStake should not go lower than 1 require( totalStake > amount, "Pool: Amount exceeds total stake" ); totalStake -= amount; // Should never return false because the API3 token uses the // OpenZeppelin implementation assert(api3Token.transfer(recipient, amount)); emit PaidOutClaim( recipient, amount, totalStake ); } } // File contracts/interfaces/ITimelockUtils.sol pragma solidity 0.8.4; interface ITimelockUtils is IClaimUtils { event DepositedByTimelockManager( address indexed user, uint256 amount, uint256 userUnstaked ); event DepositedVesting( address indexed user, uint256 amount, uint256 start, uint256 end, uint256 userUnstaked, uint256 userVesting ); event VestedTimelock( address indexed user, uint256 amount, uint256 userVesting ); function deposit( address source, uint256 amount, address userAddress ) external; function depositWithVesting( address source, uint256 amount, address userAddress, uint256 releaseStart, uint256 releaseEnd ) external; function updateTimelockStatus(address userAddress) external; } // File contracts/TimelockUtils.sol pragma solidity 0.8.4; /// @title Contract that implements vesting functionality /// @dev The TimelockManager contract interfaces with this contract to transfer /// API3 tokens that are locked under a vesting schedule. /// This contract keeps its own type definitions, event declarations and state /// variables for them to be easier to remove for a subDAO where they will /// likely not be used. abstract contract TimelockUtils is ClaimUtils, ITimelockUtils { struct Timelock { uint256 totalAmount; uint256 remainingAmount; uint256 releaseStart; uint256 releaseEnd; } /// @notice Maps user addresses to timelocks /// @dev This implies that a user cannot have multiple timelocks /// transferred from the TimelockManager contract. This is acceptable /// because TimelockManager is implemented in a way to not allow multiple /// timelocks per user. mapping(address => Timelock) public userToTimelock; /// @notice Called by the TimelockManager contract to deposit tokens on /// behalf of a user /// @dev This method is only usable by `TimelockManager.sol`. /// It is named as `deposit()` and not `depositAsTimelockManager()` for /// example, because the TimelockManager is already deployed and expects /// the `deposit(address,uint256,address)` interface. /// @param source Token transfer source /// @param amount Amount to be deposited /// @param userAddress User that the tokens will be deposited for function deposit( address source, uint256 amount, address userAddress ) external override { require( msg.sender == timelockManager, "Pool: Caller not TimelockManager" ); uint256 unstakedUpdate = users[userAddress].unstaked + amount; users[userAddress].unstaked = unstakedUpdate; // Should never return false because the API3 token uses the // OpenZeppelin implementation assert(api3Token.transferFrom(source, address(this), amount)); emit DepositedByTimelockManager( userAddress, amount, unstakedUpdate ); } /// @notice Called by the TimelockManager contract to deposit tokens on /// behalf of a user on a linear vesting schedule /// @dev Refer to `TimelockManager.sol` to see how this is used /// @param source Token source /// @param amount Token amount /// @param userAddress Address of the user who will receive the tokens /// @param releaseStart Vesting schedule starting time /// @param releaseEnd Vesting schedule ending time function depositWithVesting( address source, uint256 amount, address userAddress, uint256 releaseStart, uint256 releaseEnd ) external override { require( msg.sender == timelockManager, "Pool: Caller not TimelockManager" ); require( userToTimelock[userAddress].remainingAmount == 0, "Pool: User has active timelock" ); require( releaseEnd > releaseStart, "Pool: Timelock start after end" ); require( amount != 0, "Pool: Timelock amount zero" ); uint256 unstakedUpdate = users[userAddress].unstaked + amount; users[userAddress].unstaked = unstakedUpdate; uint256 vestingUpdate = users[userAddress].vesting + amount; users[userAddress].vesting = vestingUpdate; userToTimelock[userAddress] = Timelock({ totalAmount: amount, remainingAmount: amount, releaseStart: releaseStart, releaseEnd: releaseEnd }); // Should never return false because the API3 token uses the // OpenZeppelin implementation assert(api3Token.transferFrom(source, address(this), amount)); emit DepositedVesting( userAddress, amount, releaseStart, releaseEnd, unstakedUpdate, vestingUpdate ); } /// @notice Called to release tokens vested by the timelock /// @param userAddress Address of the user whose timelock status will be /// updated function updateTimelockStatus(address userAddress) external override { Timelock storage timelock = userToTimelock[userAddress]; require( block.timestamp > timelock.releaseStart, "Pool: Release not started yet" ); require( timelock.remainingAmount > 0, "Pool: Timelock already released" ); uint256 totalUnlocked; if (block.timestamp >= timelock.releaseEnd) { totalUnlocked = timelock.totalAmount; } else { uint256 passedTime = block.timestamp - timelock.releaseStart; uint256 totalTime = timelock.releaseEnd - timelock.releaseStart; totalUnlocked = timelock.totalAmount * passedTime / totalTime; } uint256 previouslyUnlocked = timelock.totalAmount - timelock.remainingAmount; uint256 newlyUnlocked = totalUnlocked - previouslyUnlocked; User storage user = users[userAddress]; uint256 vestingUpdate = user.vesting - newlyUnlocked; user.vesting = vestingUpdate; timelock.remainingAmount -= newlyUnlocked; emit VestedTimelock( userAddress, newlyUnlocked, vestingUpdate ); } } // File contracts/interfaces/IApi3Pool.sol pragma solidity 0.8.4; interface IApi3Pool is ITimelockUtils { } // File contracts/Api3Pool.sol pragma solidity 0.8.4; /// @title API3 pool contract /// @notice Users can stake API3 tokens at the pool contract to be granted /// shares. These shares are exposed to the Aragon-based DAO, giving the user /// voting power at the DAO. Staking pays out weekly rewards that get unlocked /// after a year, and staked funds are used to collateralize an insurance /// product that is outside the scope of this contract. /// @dev Functionalities of the contract are distributed to files that form a /// chain of inheritance: /// (1) Api3Pool.sol /// (2) TimelockUtils.sol /// (3) ClaimUtils.sol /// (4) StakeUtils.sol /// (5) TransferUtils.sol /// (6) DelegationUtils.sol /// (7) RewardUtils.sol /// (8) GetterUtils.sol /// (9) StateUtils.sol contract Api3Pool is TimelockUtils, IApi3Pool { /// @param api3TokenAddress API3 token contract address /// @param timelockManagerAddress Timelock manager contract address constructor( address api3TokenAddress, address timelockManagerAddress ) StateUtils( api3TokenAddress, timelockManagerAddress ) {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"api3TokenAddress","type":"address"},{"internalType":"address","name":"timelockManagerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CalculatedUserLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"nextIndEpoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldestLockedEpoch","type":"uint256"}],"name":"CalculatingUserLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDelegatedTo","type":"uint256"}],"name":"Delegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"}],"name":"DepositedByTimelockManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"end","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userVesting","type":"uint256"}],"name":"DepositedVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epochIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newApr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStake","type":"uint256"}],"name":"MintedReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStake","type":"uint256"}],"name":"PaidOutClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scheduledFor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userShares","type":"uint256"}],"name":"ScheduledUnstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"aprUpdateStep","type":"uint256"}],"name":"SetAprUpdateStep","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimsManager","type":"address"},{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"SetClaimsManagerStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"agentAppPrimary","type":"address"},{"indexed":false,"internalType":"address","name":"agentAppSecondary","type":"address"},{"indexed":false,"internalType":"address","name":"votingAppPrimary","type":"address"},{"indexed":false,"internalType":"address","name":"votingAppSecondary","type":"address"}],"name":"SetDaoApps","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxApr","type":"uint256"}],"name":"SetMaxApr","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minApr","type":"uint256"}],"name":"SetMinApr","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalVotingPowerThreshold","type":"uint256"}],"name":"SetProposalVotingPowerThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stakeTarget","type":"uint256"}],"name":"SetStakeTarget","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"unstakeWaitPeriod","type":"uint256"}],"name":"SetUnstakeWaitPeriod","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintedShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStake","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDelegatedTo","type":"uint256"}],"name":"Undelegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStake","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"bool","name":"delta","type":"bool"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDelegatedTo","type":"uint256"}],"name":"UpdatedDelegation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lastProposalTimestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"votingApp","type":"address"}],"name":"UpdatedLastProposalTimestamp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userVesting","type":"uint256"}],"name":"VestedTimelock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userUnstaked","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"EPOCH_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_VESTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentAppPrimary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentAppSecondary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"api3Token","outputs":[{"internalType":"contract IApi3Token","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aprUpdateStep","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimsManagerStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegate","type":"address"}],"name":"delegateVotingPower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"delegatedToUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"delegatedToUserAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositAndStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositRegular","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"releaseStart","type":"uint256"},{"internalType":"uint256","name":"releaseEnd","type":"uint256"}],"name":"depositWithVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochIndexOfLastReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochIndexToReward","outputs":[{"internalType":"uint32","name":"atBlock","type":"uint32"},{"internalType":"uint224","name":"amount","type":"uint224"},{"internalType":"uint256","name":"totalSharesThen","type":"uint256"},{"internalType":"uint256","name":"totalStakeThen","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUser","outputs":[{"internalType":"uint256","name":"unstaked","type":"uint256"},{"internalType":"uint256","name":"vesting","type":"uint256"},{"internalType":"uint256","name":"unstakeAmount","type":"uint256"},{"internalType":"uint256","name":"unstakeShares","type":"uint256"},{"internalType":"uint256","name":"unstakeScheduledFor","type":"uint256"},{"internalType":"uint256","name":"lastDelegationUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastProposalTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGenesisEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"payOutClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolShares","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"value","type":"uint224"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"noEpochsPerIteration","type":"uint256"}],"name":"precalculateUserLocked","outputs":[{"internalType":"bool","name":"finished","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposalVotingPowerThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"scheduleUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_aprUpdateStep","type":"uint256"}],"name":"setAprUpdateStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimsManager","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setClaimsManagerStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_agentAppPrimary","type":"address"},{"internalType":"address","name":"_agentAppSecondary","type":"address"},{"internalType":"address","name":"_votingAppPrimary","type":"address"},{"internalType":"address","name":"_votingAppSecondary","type":"address"}],"name":"setDaoApps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxApr","type":"uint256"}],"name":"setMaxApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minApr","type":"uint256"}],"name":"setMinApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalVotingPowerThreshold","type":"uint256"}],"name":"setProposalVotingPowerThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakeTarget","type":"uint256"}],"name":"setStakeTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unstakeWaitPeriod","type":"uint256"}],"name":"setUnstakeWaitPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"totalSharesAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"undelegateVotingPower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"unstake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeAndWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeWaitPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"updateLastProposalTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"updateTimelockStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"userDelegate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"userDelegateAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"userLocked","outputs":[{"internalType":"uint256","name":"locked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"userShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"userSharesAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"userStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userToLockedCalculation","outputs":[{"internalType":"uint256","name":"initialIndEpoch","type":"uint256"},{"internalType":"uint256","name":"nextIndEpoch","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userToTimelock","outputs":[{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"remainingAmount","type":"uint256"},{"internalType":"uint256","name":"releaseStart","type":"uint256"},{"internalType":"uint256","name":"releaseEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"userVotingPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"userVotingPowerAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"unstaked","type":"uint256"},{"internalType":"uint256","name":"vesting","type":"uint256"},{"internalType":"uint256","name":"unstakeAmount","type":"uint256"},{"internalType":"uint256","name":"unstakeShares","type":"uint256"},{"internalType":"uint256","name":"unstakeScheduledFor","type":"uint256"},{"internalType":"uint256","name":"lastDelegationUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastProposalTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingAppPrimary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingAppSecondary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawPrecalculated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawRegular","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405262000018662386f26fc10000603262000317565b600855600a62000031662386f26fc10000601962000317565b6200003d9190620002f6565b60095562000054662386f26fc10000604b62000317565b600a55662386f26fc10000600b5562093a80600c55600a662386f26fc100006200007f9190620002f6565b600d556002600954600a54620000969190620002db565b620000a29190620002f6565b600e55348015620000b257600080fd5b5060405162003eef38038062003eef833981016040819052620000d591620002a4565b81816001600160a01b038216620001335760405162461bcd60e51b815260206004820152601760248201527f506f6f6c3a20496e76616c69642041706933546f6b656e00000000000000000060448201526064015b60405180910390fd5b6001600160a01b0381166200018b5760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a20496e76616c69642054696d656c6f636b4d616e6167657200000060448201526064016200012a565b601280546001600160a01b031916331790556001600160601b0319606083811b821660a05282901b1660c052620001c560106001620001ef565b60016007556000620001db62093a8042620002f6565b6080819052600655506200034f9350505050565b63ffffffff4311156200021257634e487b7160e01b600052600160045260246000fd5b6001600160e01b038111156200023857634e487b7160e01b600052600160045260246000fd5b6040805180820190915263ffffffff43811682526001600160e01b0392831660208084019182528554600181018755600096875295209251905190931664010000000002921691909117910155565b80516001600160a01b03811681146200029f57600080fd5b919050565b60008060408385031215620002b7578182fd5b620002c28362000287565b9150620002d26020840162000287565b90509250929050565b60008219821115620002f157620002f162000339565b500190565b6000826200031257634e487b7160e01b81526012600452602481fd5b500490565b600081600019048311821515161562000334576200033462000339565b500290565b634e487b7160e01b600052601160045260246000fd5b60805160a05160601c60c05160601c613b0f620003e0600039600081816108b6015281816114df01526128cc0152600081816105be01528181610c3e01528181610df2015281816111fa0152818161173d01528181611b7a015281816129a601528181612f4001526136fd01526000818161087c01528181611c4c0152818161334a015261337c0152613b0f6000f3fe608060405234801561001057600080fd5b50600436106103c45760003560e01c80638b8e39d6116101ff578063cd3bde951161011a578063ea26afd7116100ad578063f68308c71161007c578063f68308c7146109c4578063f6a485c1146109d7578063fc5da2aa146109ea578063fcde28cc146109fd57600080fd5b8063ea26afd714610978578063f2888dbb1461098b578063f3ff955a1461099e578063f45346dc146109b157600080fd5b8063e3b34174116100e9578063e3b3417414610936578063e67729b714610949578063e685dee01461095c578063e7460a521461096f57600080fd5b8063cd3bde95146108fe578063db6f162e14610911578063de69b3aa1461091a578063df60d8041461092d57600080fd5b8063ac4746ab11610192578063bba0538411610161578063bba053841461089e578063bf5669bd146108b1578063bf577a00146108d8578063cad2ab25146108eb57600080fd5b8063ac4746ab14610851578063b330fc531461085b578063b3609b531461086e578063b70e6be61461087757600080fd5b8063a4fb6ff7116101ce578063a4fb6ff7146107c8578063a694fc3a146107db578063a78c6ddc146107ee578063a87430ba1461080157600080fd5b80638b8e39d61461073f5780638dd04faa1461079457806392093b361461079c5780639745f563146107a557600080fd5b806356d4a7fe116102ef5780636f77926b116102825780637fd63875116102515780637fd63875146106f85780637fd75f261461070b5780638794eb4f1461071e5780638b0e9f3f1461073657600080fd5b80636f77926b14610619578063756b2a8b146106a557806375c385d6146106b8578063784b3c5d146106ef57600080fd5b8063613d517d116102be578063613d517d146105b9578063634cc198146105e0578063681a9ad7146105f357806368e5585d1461060657600080fd5b806356d4a7fe1461058257806357ded9c9146105955780635856130a1461059e57806359fe8539146105a657600080fd5b8063344965e2116103675780633c37d05a116103365780633c37d05a146104e85780634091fd3f146104f05780634eb05c47146105665780634f8a137f1461056f57600080fd5b8063344965e21461049957806336b1b6a4146104ac5780633a98ef39146104cd5780633b490a5d146104d557600080fd5b8063174f57af116103a3578063174f57af146104585780632304f24a146104605780632b2c2262146104735780632cacc0cb1461048657600080fd5b8062609187146103c95780630825af75146103f9578063106d08df14610443575b600080fd5b6002546103dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6104286104073660046137fa565b60116020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060016103f0565b61045661045136600461396a565b610a10565b005b610456610c0e565b61045661046e3660046137fa565b610ec0565b61045661048136600461396a565b61109f565b61045661049436600461389d565b611105565b6001546103dc906001600160a01b031681565b6104bf6104ba3660046137fa565b6112e2565b6040519081526020016103f0565b6104bf6112f4565b6104bf6104e336600461396a565b611304565b610456611311565b6105376104fe36600461396a565b60056020526000908152604090208054600182015460029092015463ffffffff821692600160201b9092046001600160e01b0316919084565b6040805163ffffffff90951685526001600160e01b0390931660208501529183015260608201526080016103f0565b6104bf60085481565b6104bf61057d36600461389d565b61148c565b610456610590366004613901565b6114d4565b6104bf600e5481565b6104bf603481565b6104566105b436600461396a565b61182a565b6103dc7f000000000000000000000000000000000000000000000000000000000000000081565b6104566105ee3660046137fa565b61183c565b6000546103dc906001600160a01b031681565b6104bf6106143660046137fa565b61190b565b6106706106273660046137fa565b6001600160a01b03166000908152600f60205260409020600381015460048201546005830154600684015460078501546008860154600990960154949693959294919390929190565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103f0565b6104566106b336600461396a565b611935565b6106cb6106c636600461396a565b6119fb565b6040805163ffffffff90931683526001600160e01b039091166020830152016103f0565b6104bf60095481565b61045661070636600461396a565b611a33565b61045661071936600461396a565b611b10565b610726611c48565b60405190151581526020016103f0565b6104bf60075481565b61077461074d3660046137fa565b60136020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103f0565b610456611c7e565b6104bf600a5481565b6107266107b33660046137fa565b60046020526000908152604090205460ff1681565b6104bf6107d63660046137fa565b611c8c565b6104566107e936600461396a565b611c98565b6104566107fc366004613814565b611dfe565b61067061080f3660046137fa565b600f6020528060005260406000206000915090508060030154908060040154908060050154908060060154908060070154908060080154908060090154905087565b6104bf62093a8081565b6103dc6108693660046137fa565b611fcf565b6104bf600d5481565b6104bf7f000000000000000000000000000000000000000000000000000000000000000081565b6104bf6108ac3660046137fa565b611fdb565b6103dc7f000000000000000000000000000000000000000000000000000000000000000081565b6104bf6108e636600461389d565b612115565b6103dc6108f936600461389d565b61213a565b61045661090c36600461396a565b61215f565b6104bf600b5481565b6104bf6109283660046137fa565b612246565b6104bf60065481565b61045661094436600461396a565b612252565b61045661095736600461396a565b612318565b6003546103dc906001600160a01b031681565b6104bf600c5481565b61045661098636600461396a565b612332565b6104bf6109993660046137fa565b6123fe565b6104566109ac3660046137fa565b6125d2565b6104566109bf3660046138c6565b6128c1565b6104566109d2366004613867565b612a86565b6107266109e536600461389d565b612b04565b6104bf6109f836600461389d565b612d11565b610456610a0b36600461396a565b612d33565b610a18610c0e565b6000610a2333612246565b90506000610a2f6112f4565b905060008160075484610a429190613a68565b610a4c9190613a19565b905083811015610aa35760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a20416d6f756e742065786365656473207374616b6564000000000060448201526064015b60405180910390fd5b336000908152600f60205260409020600781015415610b045760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20556e657865637574656420756e7374616b6520657869737473006044820152606401610a9a565b600754600090610b148588613a68565b610b1e9190613a19565b905060008111610b705760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a20556e7374616b6520616d6f756e7420746f6f20736d616c6c00006044820152606401610a9a565b6000600c5442610b809190613a01565b60078401819055600584018890556006840183905590506000610ba38388613a87565b9050610baf8482612de5565b610bba836000612e7a565b60408051898152602081018590529081018390526060810182905233907f251830cd12788c7474148132132ab205112e7b9bba739f0e69c8d4a6a54e21599060800160405180910390a25050505050505050565b6000610c1d62093a8042613a19565b9050806006541015610ebd5760405163bbb30c5d60e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bbb30c5d9060240160206040518083038186803b158015610c8857600080fd5b505afa158015610c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc0919061394e565b15610eb7576000670de0b6b3a76400006301e1338062093a80600e54600754610ce99190613a68565b610cf39190613a68565b610cfd9190613a19565b610d079190613a19565b905063ffffffff431115610d2b57634e487b7160e01b600052600160045260246000fd5b6001600160e01b03811115610d5057634e487b7160e01b600052600160045260246000fd5b60405180608001604052804363ffffffff168152602001826001600160e01b03168152602001610d7e6112f4565b81526007546020918201526000848152600582526040908190208351928401516001600160e01b0316600160201b0263ffffffff909316929092178255828101516001830155606090920151600290910155516340c10f1960e01b8152306004820152602481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b505050508060076000828254610e609190613a01565b90915550610e6e9050612f3c565b600e5460075460408051848152602081019390935282015282907f6e0fc10bac330e97bc2fd6c13cbb1c1189ddb48a8ce96395650ba8f2bd28f6fc9060600160405180910390a2505b60068190555b50565b6001600160a01b038116600090815260136020526040902060028101544211610f2b5760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a2052656c65617365206e6f742073746172746564207965740000006044820152606401610a9a565b6000816001015411610f7f5760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a2054696d656c6f636b20616c72656164792072656c6561736564006044820152606401610a9a565b600081600301544210610f9457508054610fe0565b6000826002015442610fa69190613a87565b9050600083600201548460030154610fbe9190613a87565b905080828560000154610fd19190613a68565b610fdb9190613a19565b925050505b60018201548254600091610ff391613a87565b905060006110018284613a87565b6001600160a01b0386166000908152600f6020526040812060048101549293509161102d908490613a87565b90508082600401819055508286600101600082825461104c9190613a87565b909155505060408051848152602081018390526001600160a01b038916917fdd8c2c092b990b8e3ae25447982d1c2f7f08c6b9bf7303986a4279f946ebd2ea91015b60405180910390a250505050505050565b6000546001600160a01b031633146110c95760405162461bcd60e51b8152600401610a9a906139ca565b600b8190556040518181527f9825cec2fb9b95eff07739ba941019e5f162bb5d2e266f53583f485282c5ea96906020015b60405180910390a150565b3360009081526004602052604090205460ff166111645760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a2043616c6c6572206e6f7420636c61696d73206d616e61676572006044820152606401610a9a565b61116c610c0e565b80600754116111bd5760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a20416d6f756e74206578636565647320746f74616c207374616b656044820152606401610a9a565b80600760008282546111cf9190613a87565b909155505060405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561123e57600080fd5b505af1158015611252573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611276919061394e565b61129057634e487b7160e01b600052600160045260246000fd5b816001600160a01b03167f330aad591dd914c6baddcfa6d34f5c8f8a16996d7e0c1c203e4345cb445adfbd826007546040516112d6929190918252602082015260400190565b60405180910390a25050565b60006112ee824361148c565b92915050565b60006112ff43611304565b905090565b60006112ee601083613069565b611319610c0e565b336000818152600f602052604081209161133290611fcf565b90506001600160a01b0381166113805760405162461bcd60e51b8152602060048201526013602482015272141bdbdb0e88139bdd0819195b1959d85d1959606a1b6044820152606401610a9a565b4262093a8083600801546113949190613a01565b106113e15760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20557064617465642064656c656761746520726563656e746c79006044820152606401610a9a565b42600883015560006113f233612246565b905060008161140084611c8c565b61140a9190613a87565b6001600160a01b0384166000908152600f602052604090209091506114329060010182612de5565b611440846002016000613299565b60408051838152602081018390526001600160a01b0385169133917f3aace7340547de7b9156593a7652dc07ee900cea3fd8f82cb6c9d38b40829802910160405180910390a350505050565b600080611499848461213a565b6001600160a01b0316146114af575060006112ee565b6114b98383612115565b6114c38484612d11565b6114cd9190613a01565b9392505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461154c5760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c6c6572206e6f742054696d656c6f636b4d616e616765726044820152606401610a9a565b6001600160a01b038316600090815260136020526040902060010154156115b55760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a205573657220686173206163746976652074696d656c6f636b00006044820152606401610a9a565b8181116116045760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a2054696d656c6f636b20737461727420616674657220656e6400006044820152606401610a9a565b836116515760405162461bcd60e51b815260206004820152601a60248201527f506f6f6c3a2054696d656c6f636b20616d6f756e74207a65726f0000000000006044820152606401610a9a565b6001600160a01b0383166000908152600f6020526040812060030154611678908690613a01565b6001600160a01b0385166000908152600f602052604081206003810183905560040154919250906116aa908790613a01565b6001600160a01b038681166000818152600f60209081526040808320600490810187905581516080810183528d81528084018e81528184018d8152606083018d8152978752601390955294839020905181559351600185015591516002840155925160039092019190915590516323b872dd60e01b81528a831691810191909152306024820152604481018990529192507f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401602060405180830381600087803b15801561178157600080fd5b505af1158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b9919061394e565b6117d357634e487b7160e01b600052600160045260246000fd5b604080518781526020810186905290810184905260608101839052608081018290526001600160a01b038616907f14ab87851ecf43dc38c282e0307cd24257a3d01d0265ae2ba28764befac8c6cc9060a00161108e565b61183381611b10565b610ebd81611c98565b6002546001600160a01b031633148061185f57506003546001600160a01b031633145b6118ab5760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a2043616c6c6572206e6f7420766f74696e672061707000000000006044820152606401610a9a565b6001600160a01b0381166000818152600f6020908152604091829020426009909101819055825190815233918101919091527fceaef3a8d9336089c649bcf1ea9dd1ae52f5c42ea01f8707ecdd57ea773aa3ee910160405180910390a250565b60006119156112f4565b60075461192184612246565b61192b9190613a68565b6112ee9190613a19565b6000546001600160a01b031633148061195857506001546001600160a01b031633145b6119745760405162461bcd60e51b8152600401610a9a9061399a565b600a548111156119c65760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a204d696e20415052206c6172676572207468616e206d61780000006044820152606401610a9a565b60098190556040518181527f73b1a5670aa918e2286672e7dd760a6710d209683665bd8843a04f8710a2be24906020016110fa565b60108181548110611a0b57600080fd5b60009182526020909120015463ffffffff81169150600160201b90046001600160e01b031682565b6000546001600160a01b03163314611a5d5760405162461bcd60e51b8152600401610a9a906139ca565b611a6f600a662386f26fc10000613a19565b8110158015611a8f5750611a8b662386f26fc10000600a613a68565b8111155b611adb5760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a205468726573686f6c64206f757473696465206c696d69747300006044820152606401610a9a565b600d8190556040518181527f3658b89a2695dcc4dd2433dc2d79647860cf037c444e112eeddd04063abfb3b6906020016110fa565b611b18610c0e565b336000908152600f6020526040812060030154611b36908390613a01565b336000818152600f602052604090819020600301839055516323b872dd60e01b81526004810191909152306024820152604481018490529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401602060405180830381600087803b158015611bbe57600080fd5b505af1158015611bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf6919061394e565b611c1057634e487b7160e01b600052600160045260246000fd5b604080518381526020810183905233917f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca91016112d6565b60007f0000000000000000000000000000000000000000000000000000000000000000611c7862093a8042613a19565b14905090565b611c8a610957336123fe565b565b60006112ee8243612115565b611ca0610c0e565b336000908152600f602052604090206003810154821115611d035760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a20416d6f756e74206578636565647320756e7374616b65640000006044820152606401610a9a565b6000828260030154611d159190613a87565b6003830181905590506000611d286112f4565b905060006007548286611d3b9190613a68565b611d459190613a19565b9050600081611d5333612246565b611d5d9190613a01565b9050611d698582612de5565b6000611d758385613a01565b9050611d82601082612de5565b8660076000828254611d949190613a01565b90915550611da59050836001612e7a565b6007546040805189815260208101869052908101879052606081018490526080810183905260a081019190915233907fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf559060c00161108e565b6000546001600160a01b0316331480611e3557506000546001600160a01b0316158015611e3557506012546001600160a01b031633145b611ea75760405162461bcd60e51b815260206004820152603e60248201527f506f6f6c3a2043616c6c6572206e6f74207072696d617279206167656e74206f60448201527f72206465706c6f79657220696e697469616c697a696e672076616c75657300006064820152608401610a9a565b6001600160a01b03841615801590611ec757506001600160a01b03831615155b8015611edb57506001600160a01b03821615155b8015611eef57506001600160a01b03811615155b611f345760405162461bcd60e51b8152602060048201526016602482015275506f6f6c3a20496e76616c69642044414f206170707360501b6044820152606401610a9a565b600080546001600160a01b038681166001600160a01b031992831681179093556001805487831690841681179091556002805487841690851681179091556003805493871693909416831790935560408051948552602085019190915283019190915260608201527f71b1ce304e98c2a645f0c32f4c9e3ae4d5dbe6717a8c17ccefb0083635afdc159060800160405180910390a150505050565b60006112ee824361213a565b6001600160a01b0381166000908152600f602052604081208161200162093a8042613a19565b9050600061200d61331b565b8354909150825b82811061210b57816120255761210b565b6000818152600560205260409020805463ffffffff16156120f8575b82156120f857600086612055600186613a87565b8154811061207357634e487b7160e01b600052603260045260246000fd5b6000918252602090912083549101805490925063ffffffff9182169116116120e5576001820154815483546120c0916001600160e01b03600160201b918290048116929190910416613a39565b6001600160e01b03166120d39190613a19565b6120dd9089613a01565b9750506120f8565b50826120f081613a9e565b935050612041565b508061210381613a9e565b915050612014565b5050505050919050565b6001600160a01b0382166000908152600f602052604081206114cd9060010183613069565b6001600160a01b0382166000908152600f602052604081206114cd90600201836133a9565b612167610c0e565b600061217662093a8042613a19565b33600090815260116020526040902080549192509082146121d95760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c63756c6174696f6e206e6f7420757020746f20646174656044820152606401610a9a565b6121e161331b565b8160010154106122335760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a2043616c63756c6174696f6e206e6f7420636f6d706c65746500006044820152606401610a9a565b6122418382600201546135d9565b505050565b60006112ee8243612d11565b6000546001600160a01b031633148061227557506001546001600160a01b031633145b6122915760405162461bcd60e51b8152600401610a9a9061399a565b6009548110156122e35760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a204d61782041505220736d616c6c6572207468616e206d696e00006044820152606401610a9a565b600a8190556040518181527f9bfee4483872bc31d94cf9864f4992fdbe3b588515c9f98f952c41a46720bc11906020016110fa565b612320610c0e565b610ebd8161232d33611fdb565b6135d9565b6000546001600160a01b031633148061235557506001546001600160a01b031633145b6123715760405162461bcd60e51b8152600401610a9a9061399a565b670de0b6b3a76400008111156123c95760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a20496e76616c69642070657263656e746167652076616c756500006044820152606401610a9a565b60088190556040518181527f30df07121af80c9a50a8fcfddf8aa9f537a550edb930294c6370d4c05632ba15906020016110fa565b6000612408610c0e565b6001600160a01b0382166000908152600f6020526040902060078101546124715760405162461bcd60e51b815260206004820152601a60248201527f506f6f6c3a204e6f20756e7374616b65207363686564756c65640000000000006044820152606401610a9a565b428160070154106124c45760405162461bcd60e51b815260206004820152601c60248201527f506f6f6c3a20556e7374616b65206e6f74206d617475726520796574000000006044820152606401610a9a565b60006124ce6112f4565b905060008260050154905060008260075485600601546124ee9190613a68565b6124f89190613a19565b905080821115612506578091505b60008285600301546125189190613a01565b6003860181905560068601549091506000906125349086613a87565b9050612541601082612de5565b83600760008282546125539190613a87565b90915550506000600587018190556006870181905560078088019190915554604080518681526020810185905290810183905260608101919091526001600160a01b038916907fdcfd2b4017d03f7e541021db793b2f9b31e4acdee005f789e52853c390e3e9629060800160405180910390a250919695505050505050565b6125da610c0e565b6001600160a01b038116158015906125fb57506001600160a01b0381163314155b6126405760405162461bcd60e51b8152602060048201526016602482015275506f6f6c3a20496e76616c69642064656c656761746560501b6044820152606401610a9a565b600061264b82611fcf565b6001600160a01b0316146126a15760405162461bcd60e51b815260206004820152601c60248201527f506f6f6c3a2044656c65676174652069732064656c65676174696e67000000006044820152606401610a9a565b336000908152600f60205260409020600881015442906126c59062093a8090613a01565b106127125760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20557064617465642064656c656761746520726563656e746c79006044820152606401610a9a565b426008820155600061272333612246565b9050806127725760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2048617665206e6f2073686172657320746f2064656c65676174656044820152606401610a9a565b600061277d33611fcf565b9050836001600160a01b0316816001600160a01b031614156127e15760405162461bcd60e51b815260206004820152601760248201527f506f6f6c3a20416c72656164792064656c6567617465640000000000000000006044820152606401610a9a565b6001600160a01b03811615612828576001600160a01b0381166000908152600f60205260409020612828906001018361281984611c8c565b6128239190613a87565b612de5565b60008261283486611c8c565b61283e9190613a01565b6001600160a01b0386166000908152600f602052604090209091506128669060010182612de5565b6128738460020186613299565b60408051848152602081018390526001600160a01b0387169133917f24d7bda8602b916d64417f0dbfe2e2e88ec9b1157bd9f596dfdb91ba26624e0491015b60405180910390a35050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146129395760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c6c6572206e6f742054696d656c6f636b4d616e616765726044820152606401610a9a565b6001600160a01b0381166000908152600f6020526040812060030154612960908490613a01565b6001600160a01b038381166000908152600f602052604090819020600301839055516323b872dd60e01b81528682166004820152306024820152604481018690529192507f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401602060405180830381600087803b1580156129ea57600080fd5b505af11580156129fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a22919061394e565b612a3c57634e487b7160e01b600052600160045260246000fd5b60408051848152602081018390526001600160a01b038416917fd0d7fef3966369afd08c0683ee833a06f6b91787b85a26fa3ef3004ae37484c2910160405180910390a250505050565b6000546001600160a01b03163314612ab05760405162461bcd60e51b8152600401610a9a906139ca565b6001600160a01b038216600081815260046020526040808220805460ff191685151590811790915590519092917fbf0d659300b2b4f4ddd43c45c5f2a7deafbf3e8bc8617173b6ef8937b19ca32191a35050565b6000612b0e610c0e565b60008211612b5e5760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a205a65726f20697465726174696f6e2077696e646f7700000000006044820152606401610a9a565b6000612b6d62093a8042613a19565b6001600160a01b03851660009081526011602052604090208054919250908214612ba35781815560018101829055600060028201555b600181015460028201546000612bb761331b565b90505b808310612cb757612bcb8784613a01565b846001015410612c3557600184018390556002840182905560408051848152602081018390526001600160a01b038a16917f6fc96dcc266501f61e68f71d8d27031f9c1a0122e03a723bc967b4163465f971910160405180910390a26000955050505050506112ee565b6000838152600560205260409020805463ffffffff1615612ca4578054600090612c66908b9063ffffffff16612d11565b6001830154835491925090612c8c908390600160201b90046001600160e01b0316613a68565b612c969190613a19565b612ca09085613a01565b9350505b5082612caf81613a9e565b935050612bba565b60018401839055600284018290556040518281526001600160a01b038916907fc348e77597c15c5ce7cb14e48ad08c01b889caf1d1fc2958cf3e6e1dd96836ee9060200160405180910390a2506001979650505050505050565b6001600160a01b0382166000908152600f602052604081206114cd9083613069565b6000546001600160a01b03163314612d5d5760405162461bcd60e51b8152600401610a9a906139ca565b62093a80811015612db05760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20506572696f642073686f72746572207468616e2065706f6368006044820152606401610a9a565b600c8190556040518181527f74c87fa8b1e9d1840c40ff666c878e91e081cb2b15fa68a62e584f07fd4ebff2906020016110fa565b63ffffffff431115612e0757634e487b7160e01b600052600160045260246000fd5b6001600160e01b03811115612e2c57634e487b7160e01b600052600160045260246000fd5b6040805180820190915263ffffffff43811682526001600160e01b03928316602080840191825285546001810187556000968752952092519051909316600160201b02921691909117910155565b6000612e8533611fcf565b90506001600160a01b038116612e9a57505050565b6000612ea582611c8c565b9050600083612ebd57612eb88583613a87565b612ec7565b612ec78583613a01565b6001600160a01b0384166000908152600f60205260409020909150612eef9060010182612de5565b604080518515158152602081018790529081018290526001600160a01b0384169033907ff310def5b4718cefe3603eb46259d8061fd58003695cf952de94c53e14dbb309906060016128b2565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f9757600080fd5b505afa158015612fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcf9190613982565b670de0b6b3a7640000600754612fe59190613a68565b612fef9190613a19565b905060085481111561302557600b54600e541161300d57600061301d565b600b54600e5461301d9190613a87565b600e5561303f565b600b54600e60008282546130399190613a01565b90915550505b600a54600e54111561305457600a54600e5550565b600954600e541015610ebd57600954600e5550565b815460009061307a575060006112ee565b8254839061308a90600190613a87565b815481106130a857634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821061311157825483906130d090600190613a87565b815481106130ee57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160e01b031690506112ee565b8260008154811061313257634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821015613153575060006112ee565b82546000906104001080156131a857508354839085906131769061040090613a87565b8154811061319457634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16105b156131bf5783546131bc9061040090613a87565b90505b83546000906131d090600190613a87565b90505b8181111561325457600060026131e98484613a01565b6131f4906001613a01565b6131fe9190613a19565b90508486828154811061322157634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16116132405780925061324e565b61324b600182613a87565b91505b506131d3565b84828154811061327457634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160e01b031695945050505050565b63ffffffff4311156132bb57634e487b7160e01b600052600160045260246000fd5b6040805180820190915263ffffffff43811682526001600160a01b03928316602080840191825285546001810187556000968752952092519290940180549451909316600160201b026001600160c01b0319909416911617919091179055565b60008061332b62093a8042613a19565b9050613338603482613a87565b613343906001613a01565b91506133707f00000000000000000000000000000000000000000000000000000000000000006001613a01565b8210156133a5576133a27f00000000000000000000000000000000000000000000000000000000000000006001613a01565b91505b5090565b81546000906133ba575060006112ee565b825483906133ca90600190613a87565b815481106133e857634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff168210613451578254839061341090600190613a87565b8154811061342e57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160a01b031690506112ee565b8260008154811061347257634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821015613493575060006112ee565b82546000906104001080156134e857508354839085906134b69061040090613a87565b815481106134d457634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16105b156134ff5783546134fc9061040090613a87565b90505b835460009061351090600190613a87565b90505b8181111561359457600060026135298484613a01565b613534906001613a01565b61353e9190613a19565b90508486828154811061356157634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16116135805780925061358e565b61358b600182613a87565b91505b50613513565b8482815481106135b457634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160a01b031695945050505050565b336000908152600f6020526040812060048101549091906135fa9084613a01565b905060006136073361190b565b83600301546136169190613a01565b90506136228583613a01565b8110156136715760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a204e6f7420656e6f75676820756e6c6f636b65642066756e6473006044820152606401610a9a565b84836003015410156136c55760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a204e6f7420656e6f75676820756e7374616b65642066756e6473006044820152606401610a9a565b60008584600301546136d79190613a87565b6003850181905560405163a9059cbb60e01b8152336004820152602481018890529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561374957600080fd5b505af115801561375d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613781919061394e565b61379b57634e487b7160e01b600052600160045260246000fd5b604080518781526020810183905233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a2505050505050565b80356001600160a01b03811681146137f557600080fd5b919050565b60006020828403121561380b578081fd5b6114cd826137de565b60008060008060808587031215613829578283fd5b613832856137de565b9350613840602086016137de565b925061384e604086016137de565b915061385c606086016137de565b905092959194509250565b60008060408385031215613879578182fd5b613882836137de565b9150602083013561389281613acb565b809150509250929050565b600080604083850312156138af578182fd5b6138b8836137de565b946020939093013593505050565b6000806000606084860312156138da578283fd5b6138e3846137de565b9250602084013591506138f8604085016137de565b90509250925092565b600080600080600060a08688031215613918578081fd5b613921866137de565b945060208601359350613936604087016137de565b94979396509394606081013594506080013592915050565b60006020828403121561395f578081fd5b81516114cd81613acb565b60006020828403121561397b578081fd5b5035919050565b600060208284031215613993578081fd5b5051919050565b602080825260169082015275141bdbdb0e8810d85b1b195c881b9bdd081859d95b9d60521b604082015260600190565b6020808252601e908201527f506f6f6c3a2043616c6c6572206e6f74207072696d617279206167656e740000604082015260600190565b60008219821115613a1457613a14613ab5565b500190565b600082613a3457634e487b7160e01b81526012600452602481fd5b500490565b60006001600160e01b0382811684821681151582840482111615613a5f57613a5f613ab5565b02949350505050565b6000816000190483118215151615613a8257613a82613ab5565b500290565b600082821015613a9957613a99613ab5565b500390565b600081613aad57613aad613ab5565b506000190190565b634e487b7160e01b600052601160045260246000fd5b8015158114610ebd57600080fdfea2646970667358221220dab22d0b89f8e4222d6d396b8e9eff20e527eeba97d049ec9d7bf982050a7ce564736f6c634300080400330000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103c45760003560e01c80638b8e39d6116101ff578063cd3bde951161011a578063ea26afd7116100ad578063f68308c71161007c578063f68308c7146109c4578063f6a485c1146109d7578063fc5da2aa146109ea578063fcde28cc146109fd57600080fd5b8063ea26afd714610978578063f2888dbb1461098b578063f3ff955a1461099e578063f45346dc146109b157600080fd5b8063e3b34174116100e9578063e3b3417414610936578063e67729b714610949578063e685dee01461095c578063e7460a521461096f57600080fd5b8063cd3bde95146108fe578063db6f162e14610911578063de69b3aa1461091a578063df60d8041461092d57600080fd5b8063ac4746ab11610192578063bba0538411610161578063bba053841461089e578063bf5669bd146108b1578063bf577a00146108d8578063cad2ab25146108eb57600080fd5b8063ac4746ab14610851578063b330fc531461085b578063b3609b531461086e578063b70e6be61461087757600080fd5b8063a4fb6ff7116101ce578063a4fb6ff7146107c8578063a694fc3a146107db578063a78c6ddc146107ee578063a87430ba1461080157600080fd5b80638b8e39d61461073f5780638dd04faa1461079457806392093b361461079c5780639745f563146107a557600080fd5b806356d4a7fe116102ef5780636f77926b116102825780637fd63875116102515780637fd63875146106f85780637fd75f261461070b5780638794eb4f1461071e5780638b0e9f3f1461073657600080fd5b80636f77926b14610619578063756b2a8b146106a557806375c385d6146106b8578063784b3c5d146106ef57600080fd5b8063613d517d116102be578063613d517d146105b9578063634cc198146105e0578063681a9ad7146105f357806368e5585d1461060657600080fd5b806356d4a7fe1461058257806357ded9c9146105955780635856130a1461059e57806359fe8539146105a657600080fd5b8063344965e2116103675780633c37d05a116103365780633c37d05a146104e85780634091fd3f146104f05780634eb05c47146105665780634f8a137f1461056f57600080fd5b8063344965e21461049957806336b1b6a4146104ac5780633a98ef39146104cd5780633b490a5d146104d557600080fd5b8063174f57af116103a3578063174f57af146104585780632304f24a146104605780632b2c2262146104735780632cacc0cb1461048657600080fd5b8062609187146103c95780630825af75146103f9578063106d08df14610443575b600080fd5b6002546103dc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6104286104073660046137fa565b60116020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060016103f0565b61045661045136600461396a565b610a10565b005b610456610c0e565b61045661046e3660046137fa565b610ec0565b61045661048136600461396a565b61109f565b61045661049436600461389d565b611105565b6001546103dc906001600160a01b031681565b6104bf6104ba3660046137fa565b6112e2565b6040519081526020016103f0565b6104bf6112f4565b6104bf6104e336600461396a565b611304565b610456611311565b6105376104fe36600461396a565b60056020526000908152604090208054600182015460029092015463ffffffff821692600160201b9092046001600160e01b0316919084565b6040805163ffffffff90951685526001600160e01b0390931660208501529183015260608201526080016103f0565b6104bf60085481565b6104bf61057d36600461389d565b61148c565b610456610590366004613901565b6114d4565b6104bf600e5481565b6104bf603481565b6104566105b436600461396a565b61182a565b6103dc7f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a81565b6104566105ee3660046137fa565b61183c565b6000546103dc906001600160a01b031681565b6104bf6106143660046137fa565b61190b565b6106706106273660046137fa565b6001600160a01b03166000908152600f60205260409020600381015460048201546005830154600684015460078501546008860154600990960154949693959294919390929190565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103f0565b6104566106b336600461396a565b611935565b6106cb6106c636600461396a565b6119fb565b6040805163ffffffff90931683526001600160e01b039091166020830152016103f0565b6104bf60095481565b61045661070636600461396a565b611a33565b61045661071936600461396a565b611b10565b610726611c48565b60405190151581526020016103f0565b6104bf60075481565b61077461074d3660046137fa565b60136020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103f0565b610456611c7e565b6104bf600a5481565b6107266107b33660046137fa565b60046020526000908152604090205460ff1681565b6104bf6107d63660046137fa565b611c8c565b6104566107e936600461396a565b611c98565b6104566107fc366004613814565b611dfe565b61067061080f3660046137fa565b600f6020528060005260406000206000915090508060030154908060040154908060050154908060060154908060070154908060080154908060090154905087565b6104bf62093a8081565b6103dc6108693660046137fa565b611fcf565b6104bf600d5481565b6104bf7f0000000000000000000000000000000000000000000000000000000000000a8081565b6104bf6108ac3660046137fa565b611fdb565b6103dc7f000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa81565b6104bf6108e636600461389d565b612115565b6103dc6108f936600461389d565b61213a565b61045661090c36600461396a565b61215f565b6104bf600b5481565b6104bf6109283660046137fa565b612246565b6104bf60065481565b61045661094436600461396a565b612252565b61045661095736600461396a565b612318565b6003546103dc906001600160a01b031681565b6104bf600c5481565b61045661098636600461396a565b612332565b6104bf6109993660046137fa565b6123fe565b6104566109ac3660046137fa565b6125d2565b6104566109bf3660046138c6565b6128c1565b6104566109d2366004613867565b612a86565b6107266109e536600461389d565b612b04565b6104bf6109f836600461389d565b612d11565b610456610a0b36600461396a565b612d33565b610a18610c0e565b6000610a2333612246565b90506000610a2f6112f4565b905060008160075484610a429190613a68565b610a4c9190613a19565b905083811015610aa35760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a20416d6f756e742065786365656473207374616b6564000000000060448201526064015b60405180910390fd5b336000908152600f60205260409020600781015415610b045760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20556e657865637574656420756e7374616b6520657869737473006044820152606401610a9a565b600754600090610b148588613a68565b610b1e9190613a19565b905060008111610b705760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a20556e7374616b6520616d6f756e7420746f6f20736d616c6c00006044820152606401610a9a565b6000600c5442610b809190613a01565b60078401819055600584018890556006840183905590506000610ba38388613a87565b9050610baf8482612de5565b610bba836000612e7a565b60408051898152602081018590529081018390526060810182905233907f251830cd12788c7474148132132ab205112e7b9bba739f0e69c8d4a6a54e21599060800160405180910390a25050505050505050565b6000610c1d62093a8042613a19565b9050806006541015610ebd5760405163bbb30c5d60e01b81523060048201527f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a6001600160a01b03169063bbb30c5d9060240160206040518083038186803b158015610c8857600080fd5b505afa158015610c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc0919061394e565b15610eb7576000670de0b6b3a76400006301e1338062093a80600e54600754610ce99190613a68565b610cf39190613a68565b610cfd9190613a19565b610d079190613a19565b905063ffffffff431115610d2b57634e487b7160e01b600052600160045260246000fd5b6001600160e01b03811115610d5057634e487b7160e01b600052600160045260246000fd5b60405180608001604052804363ffffffff168152602001826001600160e01b03168152602001610d7e6112f4565b81526007546020918201526000848152600582526040908190208351928401516001600160e01b0316600160201b0263ffffffff909316929092178255828101516001830155606090920151600290910155516340c10f1960e01b8152306004820152602481018290526001600160a01b037f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a16906340c10f1990604401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b505050508060076000828254610e609190613a01565b90915550610e6e9050612f3c565b600e5460075460408051848152602081019390935282015282907f6e0fc10bac330e97bc2fd6c13cbb1c1189ddb48a8ce96395650ba8f2bd28f6fc9060600160405180910390a2505b60068190555b50565b6001600160a01b038116600090815260136020526040902060028101544211610f2b5760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a2052656c65617365206e6f742073746172746564207965740000006044820152606401610a9a565b6000816001015411610f7f5760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a2054696d656c6f636b20616c72656164792072656c6561736564006044820152606401610a9a565b600081600301544210610f9457508054610fe0565b6000826002015442610fa69190613a87565b9050600083600201548460030154610fbe9190613a87565b905080828560000154610fd19190613a68565b610fdb9190613a19565b925050505b60018201548254600091610ff391613a87565b905060006110018284613a87565b6001600160a01b0386166000908152600f6020526040812060048101549293509161102d908490613a87565b90508082600401819055508286600101600082825461104c9190613a87565b909155505060408051848152602081018390526001600160a01b038916917fdd8c2c092b990b8e3ae25447982d1c2f7f08c6b9bf7303986a4279f946ebd2ea91015b60405180910390a250505050505050565b6000546001600160a01b031633146110c95760405162461bcd60e51b8152600401610a9a906139ca565b600b8190556040518181527f9825cec2fb9b95eff07739ba941019e5f162bb5d2e266f53583f485282c5ea96906020015b60405180910390a150565b3360009081526004602052604090205460ff166111645760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a2043616c6c6572206e6f7420636c61696d73206d616e61676572006044820152606401610a9a565b61116c610c0e565b80600754116111bd5760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a20416d6f756e74206578636565647320746f74616c207374616b656044820152606401610a9a565b80600760008282546111cf9190613a87565b909155505060405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a169063a9059cbb90604401602060405180830381600087803b15801561123e57600080fd5b505af1158015611252573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611276919061394e565b61129057634e487b7160e01b600052600160045260246000fd5b816001600160a01b03167f330aad591dd914c6baddcfa6d34f5c8f8a16996d7e0c1c203e4345cb445adfbd826007546040516112d6929190918252602082015260400190565b60405180910390a25050565b60006112ee824361148c565b92915050565b60006112ff43611304565b905090565b60006112ee601083613069565b611319610c0e565b336000818152600f602052604081209161133290611fcf565b90506001600160a01b0381166113805760405162461bcd60e51b8152602060048201526013602482015272141bdbdb0e88139bdd0819195b1959d85d1959606a1b6044820152606401610a9a565b4262093a8083600801546113949190613a01565b106113e15760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20557064617465642064656c656761746520726563656e746c79006044820152606401610a9a565b42600883015560006113f233612246565b905060008161140084611c8c565b61140a9190613a87565b6001600160a01b0384166000908152600f602052604090209091506114329060010182612de5565b611440846002016000613299565b60408051838152602081018390526001600160a01b0385169133917f3aace7340547de7b9156593a7652dc07ee900cea3fd8f82cb6c9d38b40829802910160405180910390a350505050565b600080611499848461213a565b6001600160a01b0316146114af575060006112ee565b6114b98383612115565b6114c38484612d11565b6114cd9190613a01565b9392505050565b336001600160a01b037f000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa161461154c5760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c6c6572206e6f742054696d656c6f636b4d616e616765726044820152606401610a9a565b6001600160a01b038316600090815260136020526040902060010154156115b55760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a205573657220686173206163746976652074696d656c6f636b00006044820152606401610a9a565b8181116116045760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a2054696d656c6f636b20737461727420616674657220656e6400006044820152606401610a9a565b836116515760405162461bcd60e51b815260206004820152601a60248201527f506f6f6c3a2054696d656c6f636b20616d6f756e74207a65726f0000000000006044820152606401610a9a565b6001600160a01b0383166000908152600f6020526040812060030154611678908690613a01565b6001600160a01b0385166000908152600f602052604081206003810183905560040154919250906116aa908790613a01565b6001600160a01b038681166000818152600f60209081526040808320600490810187905581516080810183528d81528084018e81528184018d8152606083018d8152978752601390955294839020905181559351600185015591516002840155925160039092019190915590516323b872dd60e01b81528a831691810191909152306024820152604481018990529192507f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a16906323b872dd90606401602060405180830381600087803b15801561178157600080fd5b505af1158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b9919061394e565b6117d357634e487b7160e01b600052600160045260246000fd5b604080518781526020810186905290810184905260608101839052608081018290526001600160a01b038616907f14ab87851ecf43dc38c282e0307cd24257a3d01d0265ae2ba28764befac8c6cc9060a00161108e565b61183381611b10565b610ebd81611c98565b6002546001600160a01b031633148061185f57506003546001600160a01b031633145b6118ab5760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a2043616c6c6572206e6f7420766f74696e672061707000000000006044820152606401610a9a565b6001600160a01b0381166000818152600f6020908152604091829020426009909101819055825190815233918101919091527fceaef3a8d9336089c649bcf1ea9dd1ae52f5c42ea01f8707ecdd57ea773aa3ee910160405180910390a250565b60006119156112f4565b60075461192184612246565b61192b9190613a68565b6112ee9190613a19565b6000546001600160a01b031633148061195857506001546001600160a01b031633145b6119745760405162461bcd60e51b8152600401610a9a9061399a565b600a548111156119c65760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a204d696e20415052206c6172676572207468616e206d61780000006044820152606401610a9a565b60098190556040518181527f73b1a5670aa918e2286672e7dd760a6710d209683665bd8843a04f8710a2be24906020016110fa565b60108181548110611a0b57600080fd5b60009182526020909120015463ffffffff81169150600160201b90046001600160e01b031682565b6000546001600160a01b03163314611a5d5760405162461bcd60e51b8152600401610a9a906139ca565b611a6f600a662386f26fc10000613a19565b8110158015611a8f5750611a8b662386f26fc10000600a613a68565b8111155b611adb5760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a205468726573686f6c64206f757473696465206c696d69747300006044820152606401610a9a565b600d8190556040518181527f3658b89a2695dcc4dd2433dc2d79647860cf037c444e112eeddd04063abfb3b6906020016110fa565b611b18610c0e565b336000908152600f6020526040812060030154611b36908390613a01565b336000818152600f602052604090819020600301839055516323b872dd60e01b81526004810191909152306024820152604481018490529091506001600160a01b037f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a16906323b872dd90606401602060405180830381600087803b158015611bbe57600080fd5b505af1158015611bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf6919061394e565b611c1057634e487b7160e01b600052600160045260246000fd5b604080518381526020810183905233917f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca91016112d6565b60007f0000000000000000000000000000000000000000000000000000000000000a80611c7862093a8042613a19565b14905090565b611c8a610957336123fe565b565b60006112ee8243612115565b611ca0610c0e565b336000908152600f602052604090206003810154821115611d035760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c3a20416d6f756e74206578636565647320756e7374616b65640000006044820152606401610a9a565b6000828260030154611d159190613a87565b6003830181905590506000611d286112f4565b905060006007548286611d3b9190613a68565b611d459190613a19565b9050600081611d5333612246565b611d5d9190613a01565b9050611d698582612de5565b6000611d758385613a01565b9050611d82601082612de5565b8660076000828254611d949190613a01565b90915550611da59050836001612e7a565b6007546040805189815260208101869052908101879052606081018490526080810183905260a081019190915233907fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf559060c00161108e565b6000546001600160a01b0316331480611e3557506000546001600160a01b0316158015611e3557506012546001600160a01b031633145b611ea75760405162461bcd60e51b815260206004820152603e60248201527f506f6f6c3a2043616c6c6572206e6f74207072696d617279206167656e74206f60448201527f72206465706c6f79657220696e697469616c697a696e672076616c75657300006064820152608401610a9a565b6001600160a01b03841615801590611ec757506001600160a01b03831615155b8015611edb57506001600160a01b03821615155b8015611eef57506001600160a01b03811615155b611f345760405162461bcd60e51b8152602060048201526016602482015275506f6f6c3a20496e76616c69642044414f206170707360501b6044820152606401610a9a565b600080546001600160a01b038681166001600160a01b031992831681179093556001805487831690841681179091556002805487841690851681179091556003805493871693909416831790935560408051948552602085019190915283019190915260608201527f71b1ce304e98c2a645f0c32f4c9e3ae4d5dbe6717a8c17ccefb0083635afdc159060800160405180910390a150505050565b60006112ee824361213a565b6001600160a01b0381166000908152600f602052604081208161200162093a8042613a19565b9050600061200d61331b565b8354909150825b82811061210b57816120255761210b565b6000818152600560205260409020805463ffffffff16156120f8575b82156120f857600086612055600186613a87565b8154811061207357634e487b7160e01b600052603260045260246000fd5b6000918252602090912083549101805490925063ffffffff9182169116116120e5576001820154815483546120c0916001600160e01b03600160201b918290048116929190910416613a39565b6001600160e01b03166120d39190613a19565b6120dd9089613a01565b9750506120f8565b50826120f081613a9e565b935050612041565b508061210381613a9e565b915050612014565b5050505050919050565b6001600160a01b0382166000908152600f602052604081206114cd9060010183613069565b6001600160a01b0382166000908152600f602052604081206114cd90600201836133a9565b612167610c0e565b600061217662093a8042613a19565b33600090815260116020526040902080549192509082146121d95760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c63756c6174696f6e206e6f7420757020746f20646174656044820152606401610a9a565b6121e161331b565b8160010154106122335760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a2043616c63756c6174696f6e206e6f7420636f6d706c65746500006044820152606401610a9a565b6122418382600201546135d9565b505050565b60006112ee8243612d11565b6000546001600160a01b031633148061227557506001546001600160a01b031633145b6122915760405162461bcd60e51b8152600401610a9a9061399a565b6009548110156122e35760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a204d61782041505220736d616c6c6572207468616e206d696e00006044820152606401610a9a565b600a8190556040518181527f9bfee4483872bc31d94cf9864f4992fdbe3b588515c9f98f952c41a46720bc11906020016110fa565b612320610c0e565b610ebd8161232d33611fdb565b6135d9565b6000546001600160a01b031633148061235557506001546001600160a01b031633145b6123715760405162461bcd60e51b8152600401610a9a9061399a565b670de0b6b3a76400008111156123c95760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c3a20496e76616c69642070657263656e746167652076616c756500006044820152606401610a9a565b60088190556040518181527f30df07121af80c9a50a8fcfddf8aa9f537a550edb930294c6370d4c05632ba15906020016110fa565b6000612408610c0e565b6001600160a01b0382166000908152600f6020526040902060078101546124715760405162461bcd60e51b815260206004820152601a60248201527f506f6f6c3a204e6f20756e7374616b65207363686564756c65640000000000006044820152606401610a9a565b428160070154106124c45760405162461bcd60e51b815260206004820152601c60248201527f506f6f6c3a20556e7374616b65206e6f74206d617475726520796574000000006044820152606401610a9a565b60006124ce6112f4565b905060008260050154905060008260075485600601546124ee9190613a68565b6124f89190613a19565b905080821115612506578091505b60008285600301546125189190613a01565b6003860181905560068601549091506000906125349086613a87565b9050612541601082612de5565b83600760008282546125539190613a87565b90915550506000600587018190556006870181905560078088019190915554604080518681526020810185905290810183905260608101919091526001600160a01b038916907fdcfd2b4017d03f7e541021db793b2f9b31e4acdee005f789e52853c390e3e9629060800160405180910390a250919695505050505050565b6125da610c0e565b6001600160a01b038116158015906125fb57506001600160a01b0381163314155b6126405760405162461bcd60e51b8152602060048201526016602482015275506f6f6c3a20496e76616c69642064656c656761746560501b6044820152606401610a9a565b600061264b82611fcf565b6001600160a01b0316146126a15760405162461bcd60e51b815260206004820152601c60248201527f506f6f6c3a2044656c65676174652069732064656c65676174696e67000000006044820152606401610a9a565b336000908152600f60205260409020600881015442906126c59062093a8090613a01565b106127125760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20557064617465642064656c656761746520726563656e746c79006044820152606401610a9a565b426008820155600061272333612246565b9050806127725760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2048617665206e6f2073686172657320746f2064656c65676174656044820152606401610a9a565b600061277d33611fcf565b9050836001600160a01b0316816001600160a01b031614156127e15760405162461bcd60e51b815260206004820152601760248201527f506f6f6c3a20416c72656164792064656c6567617465640000000000000000006044820152606401610a9a565b6001600160a01b03811615612828576001600160a01b0381166000908152600f60205260409020612828906001018361281984611c8c565b6128239190613a87565b612de5565b60008261283486611c8c565b61283e9190613a01565b6001600160a01b0386166000908152600f602052604090209091506128669060010182612de5565b6128738460020186613299565b60408051848152602081018390526001600160a01b0387169133917f24d7bda8602b916d64417f0dbfe2e2e88ec9b1157bd9f596dfdb91ba26624e0491015b60405180910390a35050505050565b336001600160a01b037f000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa16146129395760405162461bcd60e51b815260206004820181905260248201527f506f6f6c3a2043616c6c6572206e6f742054696d656c6f636b4d616e616765726044820152606401610a9a565b6001600160a01b0381166000908152600f6020526040812060030154612960908490613a01565b6001600160a01b038381166000908152600f602052604090819020600301839055516323b872dd60e01b81528682166004820152306024820152604481018690529192507f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a16906323b872dd90606401602060405180830381600087803b1580156129ea57600080fd5b505af11580156129fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a22919061394e565b612a3c57634e487b7160e01b600052600160045260246000fd5b60408051848152602081018390526001600160a01b038416917fd0d7fef3966369afd08c0683ee833a06f6b91787b85a26fa3ef3004ae37484c2910160405180910390a250505050565b6000546001600160a01b03163314612ab05760405162461bcd60e51b8152600401610a9a906139ca565b6001600160a01b038216600081815260046020526040808220805460ff191685151590811790915590519092917fbf0d659300b2b4f4ddd43c45c5f2a7deafbf3e8bc8617173b6ef8937b19ca32191a35050565b6000612b0e610c0e565b60008211612b5e5760405162461bcd60e51b815260206004820152601b60248201527f506f6f6c3a205a65726f20697465726174696f6e2077696e646f7700000000006044820152606401610a9a565b6000612b6d62093a8042613a19565b6001600160a01b03851660009081526011602052604090208054919250908214612ba35781815560018101829055600060028201555b600181015460028201546000612bb761331b565b90505b808310612cb757612bcb8784613a01565b846001015410612c3557600184018390556002840182905560408051848152602081018390526001600160a01b038a16917f6fc96dcc266501f61e68f71d8d27031f9c1a0122e03a723bc967b4163465f971910160405180910390a26000955050505050506112ee565b6000838152600560205260409020805463ffffffff1615612ca4578054600090612c66908b9063ffffffff16612d11565b6001830154835491925090612c8c908390600160201b90046001600160e01b0316613a68565b612c969190613a19565b612ca09085613a01565b9350505b5082612caf81613a9e565b935050612bba565b60018401839055600284018290556040518281526001600160a01b038916907fc348e77597c15c5ce7cb14e48ad08c01b889caf1d1fc2958cf3e6e1dd96836ee9060200160405180910390a2506001979650505050505050565b6001600160a01b0382166000908152600f602052604081206114cd9083613069565b6000546001600160a01b03163314612d5d5760405162461bcd60e51b8152600401610a9a906139ca565b62093a80811015612db05760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a20506572696f642073686f72746572207468616e2065706f6368006044820152606401610a9a565b600c8190556040518181527f74c87fa8b1e9d1840c40ff666c878e91e081cb2b15fa68a62e584f07fd4ebff2906020016110fa565b63ffffffff431115612e0757634e487b7160e01b600052600160045260246000fd5b6001600160e01b03811115612e2c57634e487b7160e01b600052600160045260246000fd5b6040805180820190915263ffffffff43811682526001600160e01b03928316602080840191825285546001810187556000968752952092519051909316600160201b02921691909117910155565b6000612e8533611fcf565b90506001600160a01b038116612e9a57505050565b6000612ea582611c8c565b9050600083612ebd57612eb88583613a87565b612ec7565b612ec78583613a01565b6001600160a01b0384166000908152600f60205260409020909150612eef9060010182612de5565b604080518515158152602081018790529081018290526001600160a01b0384169033907ff310def5b4718cefe3603eb46259d8061fd58003695cf952de94c53e14dbb309906060016128b2565b60007f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f9757600080fd5b505afa158015612fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcf9190613982565b670de0b6b3a7640000600754612fe59190613a68565b612fef9190613a19565b905060085481111561302557600b54600e541161300d57600061301d565b600b54600e5461301d9190613a87565b600e5561303f565b600b54600e60008282546130399190613a01565b90915550505b600a54600e54111561305457600a54600e5550565b600954600e541015610ebd57600954600e5550565b815460009061307a575060006112ee565b8254839061308a90600190613a87565b815481106130a857634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821061311157825483906130d090600190613a87565b815481106130ee57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160e01b031690506112ee565b8260008154811061313257634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821015613153575060006112ee565b82546000906104001080156131a857508354839085906131769061040090613a87565b8154811061319457634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16105b156131bf5783546131bc9061040090613a87565b90505b83546000906131d090600190613a87565b90505b8181111561325457600060026131e98484613a01565b6131f4906001613a01565b6131fe9190613a19565b90508486828154811061322157634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16116132405780925061324e565b61324b600182613a87565b91505b506131d3565b84828154811061327457634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160e01b031695945050505050565b63ffffffff4311156132bb57634e487b7160e01b600052600160045260246000fd5b6040805180820190915263ffffffff43811682526001600160a01b03928316602080840191825285546001810187556000968752952092519290940180549451909316600160201b026001600160c01b0319909416911617919091179055565b60008061332b62093a8042613a19565b9050613338603482613a87565b613343906001613a01565b91506133707f0000000000000000000000000000000000000000000000000000000000000a806001613a01565b8210156133a5576133a27f0000000000000000000000000000000000000000000000000000000000000a806001613a01565b91505b5090565b81546000906133ba575060006112ee565b825483906133ca90600190613a87565b815481106133e857634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff168210613451578254839061341090600190613a87565b8154811061342e57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160a01b031690506112ee565b8260008154811061347257634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16821015613493575060006112ee565b82546000906104001080156134e857508354839085906134b69061040090613a87565b815481106134d457634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16105b156134ff5783546134fc9061040090613a87565b90505b835460009061351090600190613a87565b90505b8181111561359457600060026135298484613a01565b613534906001613a01565b61353e9190613a19565b90508486828154811061356157634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16116135805780925061358e565b61358b600182613a87565b91505b50613513565b8482815481106135b457634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160201b90046001600160a01b031695945050505050565b336000908152600f6020526040812060048101549091906135fa9084613a01565b905060006136073361190b565b83600301546136169190613a01565b90506136228583613a01565b8110156136715760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a204e6f7420656e6f75676820756e6c6f636b65642066756e6473006044820152606401610a9a565b84836003015410156136c55760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c3a204e6f7420656e6f75676820756e7374616b65642066756e6473006044820152606401610a9a565b60008584600301546136d79190613a87565b6003850181905560405163a9059cbb60e01b8152336004820152602481018890529091507f0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a6001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561374957600080fd5b505af115801561375d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613781919061394e565b61379b57634e487b7160e01b600052600160045260246000fd5b604080518781526020810183905233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a2505050505050565b80356001600160a01b03811681146137f557600080fd5b919050565b60006020828403121561380b578081fd5b6114cd826137de565b60008060008060808587031215613829578283fd5b613832856137de565b9350613840602086016137de565b925061384e604086016137de565b915061385c606086016137de565b905092959194509250565b60008060408385031215613879578182fd5b613882836137de565b9150602083013561389281613acb565b809150509250929050565b600080604083850312156138af578182fd5b6138b8836137de565b946020939093013593505050565b6000806000606084860312156138da578283fd5b6138e3846137de565b9250602084013591506138f8604085016137de565b90509250925092565b600080600080600060a08688031215613918578081fd5b613921866137de565b945060208601359350613936604087016137de565b94979396509394606081013594506080013592915050565b60006020828403121561395f578081fd5b81516114cd81613acb565b60006020828403121561397b578081fd5b5035919050565b600060208284031215613993578081fd5b5051919050565b602080825260169082015275141bdbdb0e8810d85b1b195c881b9bdd081859d95b9d60521b604082015260600190565b6020808252601e908201527f506f6f6c3a2043616c6c6572206e6f74207072696d617279206167656e740000604082015260600190565b60008219821115613a1457613a14613ab5565b500190565b600082613a3457634e487b7160e01b81526012600452602481fd5b500490565b60006001600160e01b0382811684821681151582840482111615613a5f57613a5f613ab5565b02949350505050565b6000816000190483118215151615613a8257613a82613ab5565b500290565b600082821015613a9957613a99613ab5565b500390565b600081613aad57613aad613ab5565b506000190190565b634e487b7160e01b600052601160045260246000fd5b8015158114610ebd57600080fdfea2646970667358221220dab22d0b89f8e4222d6d396b8e9eff20e527eeba97d049ec9d7bf982050a7ce564736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa
-----Decoded View---------------
Arg [0] : api3TokenAddress (address): 0x0b38210ea11411557c13457D4dA7dC6ea731B88a
Arg [1] : timelockManagerAddress (address): 0xFaef86994a37F1c8b2A5c73648F07dd4eFF02baA
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000b38210ea11411557c13457d4da7dc6ea731b88a
Arg [1] : 000000000000000000000000faef86994a37f1c8b2a5c73648f07dd4eff02baa
Deployed Bytecode Sourcemap
70605:399:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9005:31;;;;;-1:-1:-1;;;;;9005:31:0;;;;;;-1:-1:-1;;;;;3058:32:1;;;3040:51;;3028:2;3013:18;9005:31:0;;;;;;;;12584:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18485:25:1;;;18541:2;18526:18;;18519:34;;;;18569:18;;;18562:34;18473:2;18458:18;12584:68:0;18440:162:1;56998:1470:0;;;;;;:::i;:::-;;:::i;:::-;;38069:1307;;;:::i;68351:1332::-;;;;;;:::i;:::-;;:::i;19879:219::-;;;;;;:::i;:::-;;:::i;62153:662::-;;;;;;:::i;:::-;;:::i;8845:32::-;;;;;-1:-1:-1;;;;;8845:32:0;;;26508:198;;;;;;:::i;:::-;;:::i;:::-;;;17715:25:1;;;17703:2;17688:18;26508:198:0;17670:76:1;27338:156:0;;;:::i;26980:175::-;;;;;;:::i;:::-;;:::i;43372:1088::-;;;:::i;9747:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9747:52:0;;;-1:-1:-1;;;;;9747:52:0;;;;;;;;;21176:10:1;21164:23;;;21146:42;;-1:-1:-1;;;;;21224:32:1;;;21219:2;21204:18;;21197:60;21273:18;;;21266:34;21331:2;21316:18;;21309:34;21133:3;21118:19;9747:52:0;21100:249:1;10322:45:0;;;;;;25888:455;;;;;;:::i;:::-;;:::i;66613:1570::-;;;;;;:::i;:::-;;:::i;12299:42::-;;;;;;7394:50;;7442:2;7394:50;;55829:147;;;;;;:::i;:::-;;:::i;8122:37::-;;;;;21091:341;;;;;;:::i;:::-;;:::i;8529:30::-;;;;;-1:-1:-1;;;;;8529:30:0;;;28505:198;;;;;;:::i;:::-;;:::i;32507:807::-;;;;;;:::i;:::-;-1:-1:-1;;;;;32935:18:0;32627:16;32935:18;;;:5;:18;;;;;32975:13;;;;33009:12;;;;33048:18;;;;33093;;;;33144:24;;;;33211:34;;;;33280:26;;;;;32975:13;;33009:12;;33048:18;;33093;;33144:24;;33211:34;33280:26;32507:807;;;;;20326:25:1;;;20382:2;20367:18;;20360:34;;;;20410:18;;;20403:34;;;;20468:2;20453:18;;20446:34;;;;20511:3;20496:19;;20489:35;20555:3;20540:19;;20533:35;20599:3;20584:19;;20577:35;20313:3;20298:19;32507:807:0;20280:338:1;18356:281:0;;;;;;:::i;:::-;;:::i;12479:30::-;;;;;;:::i;:::-;;:::i;:::-;;;;20825:10:1;20813:23;;;20795:42;;-1:-1:-1;;;;;20873:32:1;;;20868:2;20853:18;;20846:60;20768:18;12479:30:0;20750:162:1;10569:45:0;;;;;;20398:509;;;;;;:::i;:::-;;:::i;47125:536::-;;;;;;:::i;:::-;;:::i;21665:177::-;;;:::i;:::-;;;4396:14:1;;4389:22;4371:41;;4359:2;4344:18;21665:177:0;4326:92:1;9968:25:0;;;;;;64810:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18838:25:1;;;18894:2;18879:18;;18872:34;;;;18922:18;;;18915:34;18980:2;18965:18;;18958:34;18825:3;18810:19;64810:50:0;18792:206:1;60614:126:0;;;:::i;10815:40::-;;;;;;9516:51;;;;;;:::i;:::-;;;;;;;;;;;;;;;;29422:196;;;;;;:::i;:::-;;:::i;54521:1162::-;;;;;;:::i;:::-;;:::i;15101:1147::-;;;;;;:::i;:::-;;:::i;12380:37::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7146:46;;7185:7;7146:46;;30244:190;;;;;;:::i;:::-;;:::i;11955:62::-;;;;;;8039:37;;;;;30610:1311;;;;;;:::i;:::-;;:::i;8210:40::-;;;;;28988:249;;;;;;:::i;:::-;;:::i;29839:246::-;;;;;;:::i;:::-;;:::i;51251:624::-;;;;;;:::i;:::-;;:::i;11007:42::-;;;;;;28150:186;;;;;;:::i;:::-;;:::i;9863:37::-;;;;;;17966:282;;;;;;:::i;:::-;;:::i;48078:162::-;;;;;;:::i;:::-;;:::i;9168:33::-;;;;;-1:-1:-1;;;;;9168:33:0;;;11659:47;;;;;;17532:326;;;;;;:::i;:::-;;:::i;58781:1579::-;;;;;;:::i;:::-;;:::i;41148:2153::-;;;;;;:::i;:::-;;:::i;65415:725::-;;;;;;:::i;:::-;;:::i;17084:333::-;;;;;;:::i;:::-;;:::i;48911:2010::-;;;;;;:::i;:::-;;:::i;27748:239::-;;;;;;:::i;:::-;;:::i;19245:373::-;;;;;;:::i;:::-;;:::i;56998:1470::-;57091:12;:10;:12::i;:::-;57114:21;57138:22;57149:10;57138;:22::i;:::-;57114:46;;57171:22;57196:13;:11;:13::i;:::-;57171:38;;57220:18;57270:14;57257:10;;57241:13;:26;;;;:::i;:::-;:43;;;;:::i;:::-;57220:64;;57331:6;57317:10;:20;;57295:101;;;;-1:-1:-1;;;57295:101:0;;11335:2:1;57295:101:0;;;11317:21:1;11374:2;11354:18;;;11347:30;11413:29;11393:18;;;11386:57;11460:18;;57295:101:0;;;;;;;;;57435:10;57409:17;57429;;;:5;:17;;;;;57479:24;;;;:29;57457:114;;;;-1:-1:-1;;;57457:114:0;;15617:2:1;57457:114:0;;;15599:21:1;15656:2;15636:18;;;15629:30;15695:33;15675:18;;;15668:61;15746:18;;57457:114:0;15589:181:1;57457:114:0;57636:10;;57584:23;;57610;57619:14;57610:6;:23;:::i;:::-;:36;;;;:::i;:::-;57584:62;;57784:1;57766:15;:19;57758:62;;;;-1:-1:-1;;;57758:62:0;;14193:2:1;57758:62:0;;;14175:21:1;14232:2;14212:18;;;14205:30;14271:32;14251:18;;;14244:60;14321:18;;57758:62:0;14165:180:1;57758:62:0;57831:27;57879:17;;57861:15;:35;;;;:::i;:::-;57907:24;;;:46;;;57964:18;;;:27;;;58002:18;;;:36;;;57831:65;-1:-1:-1;;58076:31:0;58023:15;58076:13;:31;:::i;:::-;58049:58;-1:-1:-1;58118:93:0;58154:4;58049:58;58118:21;:93::i;:::-;58222:50;58249:15;58266:5;58222:26;:50::i;:::-;58288:172;;;18838:25:1;;;18894:2;18879:18;;18872:34;;;18922:18;;;18915:34;;;18980:2;18965:18;;18958:34;;;58319:10:0;;58288:172;;18825:3:1;18810:19;58288:172:0;;;;;;;56998:1470;;;;;;;;:::o;38069:1307::-;38141:20;38164:30;7185:7;38164:15;:30;:::i;:::-;38141:53;;38361:12;38336:22;;:37;38332:1037;;;38403:40;;-1:-1:-1;;;38403:40:0;;38437:4;38403:40;;;3040:51:1;38403:9:0;-1:-1:-1;;;;;38403:25:0;;;;3013:18:1;;38403:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38399:907;;;38477:20;7615:4;38534:8;7185:7;38513:3;;38500:10;;:16;;;;:::i;:::-;:31;;;;:::i;:::-;:42;;;;:::i;:::-;:60;;;;:::i;:::-;38477:83;;7716:9;38586:12;:26;;38579:34;;-1:-1:-1;;;38579:34:0;;;;;;;;;-1:-1:-1;;;;;38639:12:0;:27;;38632:35;;-1:-1:-1;;;38632:35:0;;;;;;;;;38721:237;;;;;;;;38767:12;38721:237;;;;;;38819:12;-1:-1:-1;;;;;38721:237:0;;;;;38872:13;:11;:13::i;:::-;38721:237;;38924:10;;38721:237;;;;;-1:-1:-1;38686:32:0;;;:18;:32;;;;;;;:272;;;;;;-1:-1:-1;;;;;38686:272:0;-1:-1:-1;;;38686:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38977:43;-1:-1:-1;;;38977:43:0;;39000:4;38686:272;38977:43;;4126:51:1;4193:18;;;4186:34;;;-1:-1:-1;;;;;38977:9:0;:14;;;;4099:18:1;;38977:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39053:12;39039:10;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;39084:18:0;;-1:-1:-1;39084:16:0;:18::i;:::-;39231:3;;39257:10;;39126:164;;;18485:25:1;;;18541:2;18526:18;;18519:34;;;;18569:18;;18562:34;39161:12:0;;39126:164;;18473:2:1;18458:18;39126:164:0;;;;;;;38399:907;;39320:22;:37;;;38332:1037;38069:1307;:::o;68351:1332::-;-1:-1:-1;;;;;68482:27:0;;68454:25;68482:27;;;:14;:27;;;;;68560:21;;;;68542:15;:39;68520:122;;;;-1:-1:-1;;;68520:122:0;;13126:2:1;68520:122:0;;;13108:21:1;13165:2;13145:18;;;13138:30;13204:31;13184:18;;;13177:59;13253:18;;68520:122:0;13098:179:1;68520:122:0;68702:1;68675:8;:24;;;:28;68653:113;;;;-1:-1:-1;;;68653:113:0;;7335:2:1;68653:113:0;;;7317:21:1;7374:2;7354:18;;;7347:30;7413:33;7393:18;;;7386:61;7464:18;;68653:113:0;7307:181:1;68653:113:0;68777:21;68832:8;:19;;;68813:15;:38;68809:381;;-1:-1:-1;68893:20:0;;68809:381;;;68964:18;69003:8;:21;;;68985:15;:39;;;;:::i;:::-;68964:60;;69039:17;69081:8;:21;;;69059:8;:19;;;:43;;;;:::i;:::-;69039:63;;69169:9;69156:10;69133:8;:20;;;:33;;;;:::i;:::-;:45;;;;:::i;:::-;69117:61;;68809:381;;;69252:24;;;;69229:20;;69200:26;;69229:47;;;:::i;:::-;69200:76;-1:-1:-1;69287:21:0;69311:34;69200:76;69311:13;:34;:::i;:::-;-1:-1:-1;;;;;69376:18:0;;69356:17;69376:18;;;:5;:18;;;;;69429:12;;;;69287:58;;-1:-1:-1;69376:18:0;69429:28;;69287:58;;69429:28;:::i;:::-;69405:52;;69483:13;69468:4;:12;;:28;;;;69535:13;69507:8;:24;;;:41;;;;;;;:::i;:::-;;;;-1:-1:-1;;69564:111:0;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;-1:-1:-1;;;;;69564:111:0;;;;;18177:18:1;69564:111:0;;;;;;;;68351:1332;;;;;;;:::o;19879:219::-;13234:15;;-1:-1:-1;;;;;13234:15:0;13220:10;:29;13198:113;;;;-1:-1:-1;;;13198:113:0;;;;;;;:::i;:::-;20012:13:::1;:30:::0;;;20058:32:::1;::::0;17715:25:1;;;20058:32:0::1;::::0;17703:2:1;17688:18;20058:32:0::1;;;;;;;;19879:219:::0;:::o;62153:662::-;61454:10;61434:31;;;;:19;:31;;;;;;;;61412:116;;;;-1:-1:-1;;;61412:116:0;;5536:2:1;61412:116:0;;;5518:21:1;5575:2;5555:18;;;5548:30;5614:33;5594:18;;;5587:61;5665:18;;61412:116:0;5508:181:1;61412:116:0;62319:12:::1;:10;:12::i;:::-;62427:6;62414:10;;:19;62392:105;;;::::0;-1:-1:-1;;;62392:105:0;;8050:2:1;62392:105:0::1;::::0;::::1;8032:21:1::0;;;8069:18;;;8062:30;8128:34;8108:18;;;8101:62;8180:18;;62392:105:0::1;8022:182:1::0;62392:105:0::1;62522:6;62508:10;;:20;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;62656:37:0::1;::::0;-1:-1:-1;;;62656:37:0;;-1:-1:-1;;;;;4144:32:1;;;62656:37:0::1;::::0;::::1;4126:51:1::0;4193:18;;;4186:34;;;62656:9:0::1;:18;::::0;::::1;::::0;4099::1;;62656:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62649:45;;-1:-1:-1::0;;;62649:45:0::1;;;;;;;;;62737:9;-1:-1:-1::0;;;;;62710:97:0::1;;62761:6;62782:10;;62710:97;;;;;;18204:25:1::0;;;18260:2;18245:18;;18238:34;18192:2;18177:18;;18159:119;62710:97:0::1;;;;;;;;62153:662:::0;;:::o;26508:198::-;26622:7;26654:44;26672:11;26685:12;26654:17;:44::i;:::-;26647:51;26508:198;-1:-1:-1;;26508:198:0:o;27338:156::-;27427:7;27459:27;27473:12;27459:13;:27::i;:::-;27452:34;;27338:156;:::o;26980:175::-;27085:7;27117:30;27128:10;27140:6;27117:10;:30::i;43372:1088::-;43457:12;:10;:12::i;:::-;43506:10;43480:17;43500;;;:5;:17;;;;;;43555:24;;:12;:24::i;:::-;43528:51;-1:-1:-1;;;;;;43612:30:0;;43590:103;;;;-1:-1:-1;;;43590:103:0;;8411:2:1;43590:103:0;;;8393:21:1;8450:2;8430:18;;;8423:30;-1:-1:-1;;;8469:18:1;;;8462:49;8528:18;;43590:103:0;8383:169:1;43590:103:0;43778:15;7185:7;43726:4;:34;;;:49;;;;:::i;:::-;:67;43704:152;;;;-1:-1:-1;;;43704:152:0;;16693:2:1;43704:152:0;;;16675:21:1;16732:2;16712:18;;;16705:30;16771:33;16751:18;;;16744:61;16822:18;;43704:152:0;16665:181:1;43704:152:0;43904:15;43867:34;;;:52;43932:18;43953:22;43964:10;43953;:22::i;:::-;43932:43;;43986:25;44050:10;44014:33;44030:16;44014:15;:33::i;:::-;:46;;;;:::i;:::-;-1:-1:-1;;;;;44107:23:0;;;;;;:5;:23;;;;;43986:74;;-1:-1:-1;44071:118:0;;44107:35;;43986:74;44071:21;:118::i;:::-;44200:97;44243:4;:14;;44280:1;44200:28;:97::i;:::-;44313:139;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;-1:-1:-1;;;;;44313:139:0;;;44339:10;;44313:139;;18177:18:1;44313:139:0;;;;;;;43372:1088;;;;:::o;25888:455::-;26047:7;;26136:35;26151:11;26164:6;26136:14;:35::i;:::-;-1:-1:-1;;;;;26136:49:0;;26132:99;;-1:-1:-1;26218:1:0;26211:8;;26132:99;26297:38;26315:11;26328:6;26297:17;:38::i;:::-;26248:33;26261:11;26274:6;26248:12;:33::i;:::-;:87;;;;:::i;:::-;26241:94;25888:455;-1:-1:-1;;;25888:455:0:o;66613:1570::-;66866:10;-1:-1:-1;;;;;66880:15:0;66866:29;;66844:115;;;;-1:-1:-1;;;66844:115:0;;10615:2:1;66844:115:0;;;10597:21:1;;;10634:18;;;10627:30;10693:34;10673:18;;;10666:62;10745:18;;66844:115:0;10587:182:1;66844:115:0;-1:-1:-1;;;;;66992:27:0;;;;;;:14;:27;;;;;:43;;;:48;66970:132;;;;-1:-1:-1;;;66970:132:0;;6615:2:1;66970:132:0;;;6597:21:1;6654:2;6634:18;;;6627:30;6693:32;6673:18;;;6666:60;6743:18;;66970:132:0;6587:180:1;66970:132:0;67148:12;67135:10;:25;67113:109;;;;-1:-1:-1;;;67113:109:0;;9900:2:1;67113:109:0;;;9882:21:1;9939:2;9919:18;;;9912:30;9978:32;9958:18;;;9951:60;10028:18;;67113:109:0;9872:180:1;67113:109:0;67255:11;67233:91;;;;-1:-1:-1;;;67233:91:0;;14903:2:1;67233:91:0;;;14885:21:1;14942:2;14922:18;;;14915:30;14981:28;14961:18;;;14954:56;15027:18;;67233:91:0;14875:176:1;67233:91:0;-1:-1:-1;;;;;67360:18:0;;67335:22;67360:18;;;:5;:18;;;;;:27;;;:36;;67390:6;;67360:36;:::i;:::-;-1:-1:-1;;;;;67407:18:0;;;;;;:5;:18;;;;;:27;;;:44;;;67486:26;;;67335:61;;-1:-1:-1;67407:18:0;67486:35;;67515:6;;67486:35;:::i;:::-;-1:-1:-1;;;;;67532:18:0;;;;;;;:5;:18;;;;;;;;:26;;;;:42;;;67615:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;67585:27;;;:14;:27;;;;;;;:205;;;;;;;;;;;;;;;;;;;;;;;;;;67918:53;;-1:-1:-1;;;67918:53:0;;3830:15:1;;;67918:53:0;;;3812:34:1;;;;67957:4:0;3862:18:1;;;3855:43;3914:18;;;3907:34;;;67532:42:0;;-1:-1:-1;67918:9:0;:22;;;;3747:18:1;;67918:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67911:61;;-1:-1:-1;;;67911:61:0;;;;;;;;;67988:187;;;19262:25:1;;;19318:2;19303:18;;19296:34;;;19346:18;;;19339:34;;;19404:2;19389:18;;19382:34;;;19447:3;19432:19;;19425:35;;;-1:-1:-1;;;;;67988:187:0;;;;;19249:3:1;19234:19;67988:187:0;19216:250:1;55829:147:0;55922:22;55937:6;55922:14;:22::i;:::-;55955:13;55961:6;55955:5;:13::i;21091:341::-;13481:16;;-1:-1:-1;;;;;13481:16:0;13467:10;:30;;:66;;-1:-1:-1;13515:18:0;;-1:-1:-1;;;;;13515:18:0;13501:10;:32;13467:66;13445:147;;;;-1:-1:-1;;;13445:147:0;;10259:2:1;13445:147:0;;;10241:21:1;10298:2;10278:18;;;10271:30;10337:29;10317:18;;;10310:57;10384:18;;13445:147:0;10231:177:1;13445:147:0;-1:-1:-1;;;;;21226:18:0;::::1;;::::0;;;:5:::1;:18;::::0;;;;;;;;21269:15:::1;21226:40;::::0;;::::1;:58:::0;;;21300:124;;17925:25:1;;;21399:10:0::1;17966:18:1::0;;;17959:60;;;;21300:124:0::1;::::0;17898:18:1;21300:124:0::1;;;;;;;21091:341:::0;:::o;28505:198::-;28611:7;28682:13;:11;:13::i;:::-;28669:10;;28643:23;28654:11;28643:10;:23::i;:::-;:36;;;;:::i;:::-;:52;;;;:::i;18356:281::-;12954:15;;-1:-1:-1;;;;;12954:15:0;12940:10;:29;;:64;;-1:-1:-1;12987:17:0;;-1:-1:-1;;;;;12987:17:0;12973:10;:31;12940:64;12918:140;;;;-1:-1:-1;;;12918:140:0;;;;;;;:::i;:::-;18501:6:::1;;18490:7;:17;;18468:100;;;::::0;-1:-1:-1;;;18468:100:0;;17053:2:1;18468:100:0::1;::::0;::::1;17035:21:1::0;17092:2;17072:18;;;17065:30;17131:31;17111:18;;;17104:59;17180:18;;18468:100:0::1;17025:179:1::0;18468:100:0::1;18579:6;:16:::0;;;18611:18:::1;::::0;17715:25:1;;;18611:18:0::1;::::0;17703:2:1;17688:18;18611::0::1;17670:76:1::0;12479:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;12479:30:0;;-1:-1:-1;;;;;12479:30:0;;:::o;20398:509::-;13234:15;;-1:-1:-1;;;;;13234:15:0;13220:10;:29;13198:113;;;;-1:-1:-1;;;13198:113:0;;;;;;;:::i;:::-;20616:16:::1;20630:2;7554:10;20616:16;:::i;:::-;20583:29;:49;;:119;;;;-1:-1:-1::0;20686:16:0::1;7554:10;20700:2;20686:16;:::i;:::-;20653:29;:49;;20583:119;20561:189;;;::::0;-1:-1:-1;;;20561:189:0;;12406:2:1;20561:189:0::1;::::0;::::1;12388:21:1::0;12445:2;12425:18;;;12418:30;12484:32;12464:18;;;12457:60;12534:18;;20561:189:0::1;12378:180:1::0;20561:189:0::1;20761:28;:60:::0;;;20837:62:::1;::::0;17715:25:1;;;20837:62:0::1;::::0;17703:2:1;17688:18;20837:62:0::1;17670:76:1::0;47125:536:0;47215:12;:10;:12::i;:::-;47269:10;47238:22;47263:17;;;:5;:17;;;;;:26;;;:35;;47292:6;;47263:35;:::i;:::-;47315:10;47309:17;;;;:5;:17;;;;;;;:26;;:43;;;47480:57;-1:-1:-1;;;47480:57:0;;;;;3812:34:1;;;;47523:4:0;3862:18:1;;;3855:43;3914:18;;;3907:34;;;47309:43:0;;-1:-1:-1;;;;;;47480:9:0;:22;;;;3747:18:1;;47480:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47473:65;;-1:-1:-1;;;47473:65:0;;;;;;;;;47554:99;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;47578:10:0;;47554:99;;18177:18:1;47554:99:0;18159:119:1;21665:177:0;21759:4;21822:12;21788:30;7185:7;21788:15;:30;:::i;:::-;:46;21781:53;;21665:177;:::o;60614:126::-;60696:36;60712:19;60720:10;60712:7;:19::i;60696:36::-;60614:126::o;29422:196::-;29534:7;29566:44;29584:11;29597:12;29566:17;:44::i;54521:1162::-;54602:12;:10;:12::i;:::-;54651:10;54625:17;54645;;;:5;:17;;;;;54695:13;;;;:23;-1:-1:-1;54695:23:0;54673:106;;;;-1:-1:-1;;;54673:106:0;;11691:2:1;54673:106:0;;;11673:21:1;11730:2;11710:18;;;11703:30;11769:31;11749:18;;;11742:59;11818:18;;54673:106:0;11663:179:1;54673:106:0;54790:26;54835:6;54819:4;:13;;;:22;;;;:::i;:::-;54852:13;;;:34;;;54790:51;-1:-1:-1;54897:22:0;54922:13;:11;:13::i;:::-;54897:38;;54946:20;54995:10;;54978:14;54969:6;:23;;;;:::i;:::-;:36;;;;:::i;:::-;54946:59;;55016:24;55068:12;55043:22;55054:10;55043;:22::i;:::-;:37;;;;:::i;:::-;55016:64;-1:-1:-1;55091:93:0;55127:4;55016:64;55091:21;:93::i;:::-;55195:25;55223:29;55240:12;55223:14;:29;:::i;:::-;55195:57;;55263:93;55299:10;55324:17;55263:21;:93::i;:::-;55381:6;55367:10;;:20;;;;;;;:::i;:::-;;;;-1:-1:-1;55398:46:0;;-1:-1:-1;55425:12:0;55439:4;55398:26;:46::i;:::-;55650:10;;55460:215;;;19758:25:1;;;19814:2;19799:18;;19792:34;;;19842:18;;;19835:34;;;19900:2;19885:18;;19878:34;;;19943:3;19928:19;;19921:35;;;19987:3;19972:19;;19965:35;;;;55481:10:0;;55460:215;;19745:3:1;19730:19;55460:215:0;19712:294:1;15101:1147:0;15418:15;;-1:-1:-1;;;;;15418:15:0;15404:10;:29;;:107;;-1:-1:-1;15482:1:0;15455:15;-1:-1:-1;;;;;15455:15:0;:29;:55;;;;-1:-1:-1;15502:8:0;;-1:-1:-1;;;;;15502:8:0;15488:10;:22;15455:55;15382:223;;;;-1:-1:-1;;;15382:223:0;;9469:2:1;15382:223:0;;;9451:21:1;9508:2;9488:18;;;9481:30;9547:34;9527:18;;;9520:62;9618:32;9598:18;;;9591:60;9668:19;;15382:223:0;9441:252:1;15382:223:0;-1:-1:-1;;;;;15638:30:0;;;;;;:83;;-1:-1:-1;;;;;;15689:32:0;;;;15638:83;:135;;;;-1:-1:-1;;;;;;15742:31:0;;;;15638:135;:189;;;;-1:-1:-1;;;;;;15794:33:0;;;;15638:189;15616:265;;;;-1:-1:-1;;;15616:265:0;;8759:2:1;15616:265:0;;;8741:21:1;8798:2;8778:18;;;8771:30;-1:-1:-1;;;8817:18:1;;;8810:52;8879:18;;15616:265:0;8731:172:1;15616:265:0;15892:15;:34;;-1:-1:-1;;;;;15892:34:0;;;-1:-1:-1;;;;;;15892:34:0;;;;;;;;-1:-1:-1;15937:38:0;;;;;;;;;;;;;15986:16;:36;;;;;;;;;;;;;16033:18;:40;;;;;;;;;;;;;;16089:151;;;3371:34:1;;;3436:2;3421:18;;3414:43;;;;3473:18;;3466:43;;;;3540:2;3525:18;;3518:43;16089:151:0;;3320:3:1;3305:19;16089:151:0;;;;;;;15101:1147;;;;:::o;30244:190::-;30353:7;30385:41;30400:11;30413:12;30385:14;:41::i;30610:1311::-;-1:-1:-1;;;;;30784:18:0;;30717:14;30784:18;;;:5;:18;;;;;30717:14;30843:30;7185:7;30843:15;:30;:::i;:::-;30820:53;;30884:25;30912:22;:20;:22::i;:::-;30969:18;;30884:50;;-1:-1:-1;31040:12:0;30998:916;31083:17;31071:8;:29;30998:916;;31248:18;31244:77;;31300:5;;31244:77;31335:27;31365:28;;;:18;:28;;;;;31412:20;;;;:25;31408:495;;31471:417;31478:17;;31471:417;;31554:28;31585:11;31597:17;31613:1;31597:13;:17;:::i;:::-;31585:30;;;;;;-1:-1:-1;;;31585:30:0;;;;;;;;;;;;;;;;;31665:20;;31585:30;;31642:19;;31585:30;;-1:-1:-1;31665:20:0;;;;31642:19;;:43;31638:231;;31785:28;;;;31767:15;;31745:19;;:37;;-1:-1:-1;;;;;;;;31767:15:0;;;;;;;31745:19;;;;;:37;:::i;:::-;-1:-1:-1;;;;;31745:68:0;;;;;:::i;:::-;31735:78;;;;:::i;:::-;;;31840:5;;;31638:231;-1:-1:-1;31497:15:0;;;;:::i;:::-;;;;31471:417;;;-1:-1:-1;31119:10:0;;;;:::i;:::-;;;;30998:916;;;;30610:1311;;;;;;;:::o;28988:249::-;-1:-1:-1;;;;;29190:18:0;;29147:7;29190:18;;;:5;:18;;;;;29179:50;;29190:30;;29222:6;29179:10;:50::i;29839:246::-;-1:-1:-1;;;;;30040:18:0;;29995:7;30040:18;;;:5;:18;;;;;30027:50;;30040:28;;30070:6;30027:12;:50::i;51251:624::-;51350:12;:10;:12::i;:::-;51373:20;51396:30;7185:7;51396:15;:30;:::i;:::-;51507:10;51437:43;51483:35;;;:23;:35;;;;;51551:33;;51373:53;;-1:-1:-1;51483:35:0;51551:49;;51529:135;;;;-1:-1:-1;;;51529:135:0;;6974:2:1;51529:135:0;;;6956:21:1;;;6993:18;;;6986:30;7052:34;7032:18;;;7025:62;7104:18;;51529:135:0;6946:182:1;51529:135:0;51730:22;:20;:22::i;:::-;51697:17;:30;;;:55;51675:139;;;;-1:-1:-1;;;51675:139:0;;10976:2:1;51675:139:0;;;10958:21:1;11015:2;10995:18;;;10988:30;11054:32;11034:18;;;11027:60;11104:18;;51675:139:0;10948:180:1;51675:139:0;51825:42;51834:6;51842:17;:24;;;51825:8;:42::i;:::-;51251:624;;;:::o;28150:186::-;28257:7;28289:39;28302:11;28315:12;28289;:39::i;17966:282::-;12954:15;;-1:-1:-1;;;;;12954:15:0;12940:10;:29;;:64;;-1:-1:-1;12987:17:0;;-1:-1:-1;;;;;12987:17:0;12973:10;:31;12940:64;12918:140;;;;-1:-1:-1;;;12918:140:0;;;;;;;:::i;:::-;18111:6:::1;;18100:7;:17;;18078:101;;;::::0;-1:-1:-1;;;18078:101:0;;5896:2:1;18078:101:0::1;::::0;::::1;5878:21:1::0;5935:2;5915:18;;;5908:30;5974:32;5954:18;;;5947:60;6024:18;;18078:101:0::1;5868:180:1::0;18078:101:0::1;18190:6;:16:::0;;;18222:18:::1;::::0;17715:25:1;;;18222:18:0::1;::::0;17703:2:1;17688:18;18222::0::1;17670:76:1::0;48078:162:0;48169:12;:10;:12::i;:::-;48192:40;48201:6;48209:22;48220:10;48209;:22::i;:::-;48192:8;:40::i;17532:326::-;12954:15;;-1:-1:-1;;;;;12954:15:0;12940:10;:29;;:64;;-1:-1:-1;12987:17:0;;-1:-1:-1;;;;;12987:17:0;12973:10;:31;12940:64;12918:140;;;;-1:-1:-1;;;12918:140:0;;;;;;;:::i;:::-;7615:4:::1;17676:12;:31;;17654:115;;;::::0;-1:-1:-1;;;17654:115:0;;9110:2:1;17654:115:0::1;::::0;::::1;9092:21:1::0;9149:2;9129:18;;;9122:30;9188:32;9168:18;;;9161:60;9238:18;;17654:115:0::1;9082:180:1::0;17654:115:0::1;17780:11;:26:::0;;;17822:28:::1;::::0;17715:25:1;;;17822:28:0::1;::::0;17703:2:1;17688:18;17822:28:0::1;17670:76:1::0;58781:1579:0;58871:7;58896:12;:10;:12::i;:::-;-1:-1:-1;;;;;58939:18:0;;58919:17;58939:18;;;:5;:18;;;;;58990:24;;;;58968:109;;;;-1:-1:-1;;;58968:109:0;;7695:2:1;58968:109:0;;;7677:21:1;7734:2;7714:18;;;7707:30;7773:28;7753:18;;;7746:56;7819:18;;58968:109:0;7667:176:1;58968:109:0;59137:15;59110:4;:24;;;:42;59088:124;;;;-1:-1:-1;;;59088:124:0;;13836:2:1;59088:124:0;;;13818:21:1;13875:2;13855:18;;;13848:30;13914;13894:18;;;13887:58;13962:18;;59088:124:0;13808:178:1;59088:124:0;59223:19;59245:13;:11;:13::i;:::-;59223:35;;59269:21;59293:4;:18;;;59269:42;;59322:29;59388:11;59375:10;;59354:4;:18;;;:31;;;;:::i;:::-;:45;;;;:::i;:::-;59322:77;;59607:21;59591:13;:37;59587:116;;;59670:21;59654:37;;59587:116;59713:26;59758:13;59742:4;:13;;;:29;;;;:::i;:::-;59782:13;;;:34;;;59871:18;;;;59713:58;;-1:-1:-1;59829:25:0;;59857:32;;:11;:32;:::i;:::-;59829:60;;59900:93;59936:10;59961:17;59900:21;:93::i;:::-;60018:13;60004:10;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;60065:1:0;60044:18;;;:22;;;60077:18;;;:22;;;60110:24;;;;:28;;;;60296:10;60154:167;;;18838:25:1;;;18894:2;18879:18;;18872:34;;;18922:18;;;18915:34;;;18980:2;18965:18;;18958:34;;;;-1:-1:-1;;;;;60154:167:0;;;;;18825:3:1;18810:19;60154:167:0;;;;;;;-1:-1:-1;60339:13:0;;58781:1579;-1:-1:-1;;;;;;58781:1579:0:o;41148:2153::-;41248:12;:10;:12::i;:::-;-1:-1:-1;;;;;41293:22:0;;;;;;:48;;-1:-1:-1;;;;;;41319:22:0;;41331:10;41319:22;;41293:48;41271:124;;;;-1:-1:-1;;;41271:124:0;;14552:2:1;41271:124:0;;;14534:21:1;14591:2;14571:18;;;14564:30;-1:-1:-1;;;14610:18:1;;;14603:52;14672:18;;41271:124:0;14524:172:1;41271:124:0;41683:1;41649:22;41662:8;41649:12;:22::i;:::-;-1:-1:-1;;;;;41649:36:0;;41627:118;;;;-1:-1:-1;;;41627:118:0;;12049:2:1;41627:118:0;;;12031:21:1;12088:2;12068:18;;;12061:30;12127;12107:18;;;12100:58;12175:18;;41627:118:0;12021:178:1;41627:118:0;41782:10;41756:17;41776;;;:5;:17;;;;;41929:34;;;;41981:15;;41929:49;;7185:7;;41929:49;:::i;:::-;:67;41907:152;;;;-1:-1:-1;;;41907:152:0;;16693:2:1;41907:152:0;;;16675:21:1;16732:2;16712:18;;;16705:30;16771:33;16751:18;;;16744:61;16822:18;;41907:152:0;16665:181:1;41907:152:0;42107:15;42070:34;;;:52;42135:18;42156:22;42167:10;42156;:22::i;:::-;42135:43;-1:-1:-1;42211:15:0;42189:101;;;;-1:-1:-1;;;42189:101:0;;12765:2:1;42189:101:0;;;12747:21:1;;;12784:18;;;12777:30;12843:34;12823:18;;;12816:62;12895:18;;42189:101:0;12737:182:1;42189:101:0;42303:24;42330;42343:10;42330:12;:24::i;:::-;42303:51;;42407:8;-1:-1:-1;;;;;42387:28:0;:16;-1:-1:-1;;;;;42387:28:0;;;42365:105;;;;-1:-1:-1;;;42365:105:0;;13484:2:1;42365:105:0;;;13466:21:1;13523:2;13503:18;;;13496:30;13562:25;13542:18;;;13535:53;13605:18;;42365:105:0;13456:173:1;42365:105:0;-1:-1:-1;;;;;42485:30:0;;;42481:273;;-1:-1:-1;;;;;42623:23:0;;;;;;:5;:23;;;;;42583:159;;42623:35;;42713:10;42677:33;42629:16;42677:15;:33::i;:::-;:46;;;;:::i;:::-;42583:21;:159::i;:::-;42804:25;42860:10;42832:25;42848:8;42832:15;:25::i;:::-;:38;;;;:::i;:::-;-1:-1:-1;;;;;42917:15:0;;;;;;:5;:15;;;;;42804:66;;-1:-1:-1;42881:110:0;;42917:27;;42804:66;42881:21;:110::i;:::-;43053:95;43096:4;:14;;43125:8;43053:28;:95::i;:::-;43164:129;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;-1:-1:-1;;;;;43164:129:0;;;43188:10;;43164:129;;18177:18:1;43164:129:0;;;;;;;;41148:2153;;;;;:::o;65415:725::-;65597:10;-1:-1:-1;;;;;65611:15:0;65597:29;;65575:115;;;;-1:-1:-1;;;65575:115:0;;10615:2:1;65575:115:0;;;10597:21:1;;;10634:18;;;10627:30;10693:34;10673:18;;;10666:62;10745:18;;65575:115:0;10587:182:1;65575:115:0;-1:-1:-1;;;;;65726:18:0;;65701:22;65726:18;;;:5;:18;;;;;:27;;;:36;;65756:6;;65726:36;:::i;:::-;-1:-1:-1;;;;;65773:18:0;;;;;;;:5;:18;;;;;;;:27;;:44;;;65945:53;-1:-1:-1;;;65945:53:0;;3830:15:1;;;65945:53:0;;;3812:34:1;65984:4:0;3862:18:1;;;3855:43;3914:18;;;3907:34;;;65773:44:0;;-1:-1:-1;65945:9:0;:22;;;;3747:18:1;;65945:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65938:61;;-1:-1:-1;;;65938:61:0;;;;;;;;;66015:117;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;-1:-1:-1;;;;;66015:117:0;;;;;18177:18:1;66015:117:0;;;;;;;65415:725;;;;:::o;17084:333::-;13234:15;;-1:-1:-1;;;;;13234:15:0;13220:10;:29;13198:113;;;;-1:-1:-1;;;13198:113:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;17264:34:0;::::1;;::::0;;;:19:::1;:34;::::0;;;;;:43;;-1:-1:-1;;17264:43:0::1;::::0;::::1;;::::0;;::::1;::::0;;;17323:86;;17264:43;;:34;17323:86:::1;::::0;::::1;17084:333:::0;;:::o;48911:2010::-;49077:13;49108:12;:10;:12::i;:::-;49176:1;49153:20;:24;49131:105;;;;-1:-1:-1;;;49131:105:0;;15977:2:1;49131:105:0;;;15959:21:1;16016:2;15996:18;;;15989:30;16055:29;16035:18;;;16028:57;16102:18;;49131:105:0;15949:177:1;49131:105:0;49247:20;49270:30;7185:7;49270:15;:30;:::i;:::-;-1:-1:-1;;;;;49357:36:0;;49311:43;49357:36;;;:23;:36;;;;;49483:33;;49247:53;;-1:-1:-1;49357:36:0;49483:49;;49479:242;;49558:48;;;49621:30;;;:45;;;49558:33;49681:24;;;:28;49479:242;49750:30;;;;49808:24;;;;49731:16;49871:22;:20;:22::i;:::-;49843:50;;49904:835;49923:17;49911:8;:29;49904:835;;50016:31;50027:20;50016:8;:31;:::i;:::-;49982:17;:30;;;:65;49978:416;;50081:30;;;:41;;;50141:24;;;:33;;;50198:149;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;-1:-1:-1;;;;;50198:149:0;;;;;18177:18:1;50198:149:0;;;;;;;50373:5;50366:12;;;;;;;;;49978:416;50408:27;50438:28;;;:18;:28;;;;;50485:20;;;;:25;50481:247;;50595:20;;50544:22;;50569:47;;50582:11;;50595:20;;50569:12;:47::i;:::-;50684:28;;;;50645:19;;50544:72;;-1:-1:-1;50684:28:0;50645:36;;50544:72;;-1:-1:-1;;;50645:19:0;;-1:-1:-1;;;;;50645:19:0;:36;:::i;:::-;:67;;;;:::i;:::-;50635:77;;;;:::i;:::-;;;50481:247;;-1:-1:-1;49942:10:0;;;;:::i;:::-;;;;49904:835;;;50749:30;;;:41;;;50801:24;;;:33;;;50850:41;;17715:25:1;;;-1:-1:-1;;;;;50850:41:0;;;;;17703:2:1;17688:18;50850:41:0;;;;;;;-1:-1:-1;50909:4:0;;48911:2010;-1:-1:-1;;;;;;;48911:2010:0:o;27748:239::-;-1:-1:-1;;;;;27945:18:0;;27902:7;27945:18;;;:5;:18;;;;;27934:45;;27972:6;27934:10;:45::i;19245:373::-;13234:15;;-1:-1:-1;;;;;13234:15:0;13220:10;:29;13198:113;;;;-1:-1:-1;;;13198:113:0;;;;;;;:::i;:::-;7185:7:::1;19408:18;:34;;19386:119;;;::::0;-1:-1:-1;;;19386:119:0;;17411:2:1;19386:119:0::1;::::0;::::1;17393:21:1::0;17450:2;17430:18;;;17423:30;17489:33;17469:18;;;17462:61;17540:18;;19386:119:0::1;17383:181:1::0;19386:119:0::1;19516:17;:38:::0;;;19570:40:::1;::::0;17715:25:1;;;19570:40:0::1;::::0;17703:2:1;17688:18;19570:40:0::1;17670:76:1::0;22408:370:0;7716:9;22562:12;:26;;22555:34;;-1:-1:-1;;;22555:34:0;;;;;;;;;-1:-1:-1;;;;;22607:5:0;:20;;22600:28;;-1:-1:-1;;;22600:28:0;;;;;;;;;22660:109;;;;;;;;;;22704:12;22660:109;;;;-1:-1:-1;;;;;22660:109:0;;;;;;;;;;22639:131;;;;;;;-1:-1:-1;22639:131:0;;;;;;;;;;;;-1:-1:-1;;;22639:131:0;;;;;;;;;;22408:370::o;44835:743::-;44962:16;44981:24;44994:10;44981:12;:24::i;:::-;44962:43;-1:-1:-1;;;;;;45020:22:0;;45016:70;;45068:7;44835:743;;:::o;45016:70::-;45096:26;45125:25;45141:8;45125:15;:25::i;:::-;45096:54;;45161:25;45189:5;:91;;45253:27;45274:6;45253:18;:27;:::i;:::-;45189:91;;;45210:27;45231:6;45210:18;:27;:::i;:::-;-1:-1:-1;;;;;45327:15:0;;;;;;:5;:15;;;;;45161:119;;-1:-1:-1;45291:110:0;;45327:27;;45161:119;45291:21;:110::i;:::-;45417:153;;;4644:14:1;;4637:22;4619:41;;4691:2;4676:18;;4669:34;;;4719:18;;;4712:34;;;-1:-1:-1;;;;;45417:153:0;;;45449:10;;45417:153;;4607:2:1;4592:18;45417:153:0;4574:178:1;39485:528:0;39547:28;39635:9;-1:-1:-1;;;;;39635:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7615:4;39578:10;;:41;;;;:::i;:::-;:80;;;;:::i;:::-;39547:111;;39696:11;;39673:20;:34;39669:198;;;39745:13;;39739:3;;:19;:45;;39783:1;39739:45;;;39767:13;;39761:3;;:19;;;;:::i;:::-;39733:3;:51;39669:198;;;39842:13;;39835:3;;:20;;;;;;;:::i;:::-;;;;-1:-1:-1;;39669:198:0;39887:6;;39881:3;;:12;39877:129;;;39916:6;;39910:3;:12;38069:1307;:::o;39877:129::-;39959:6;;39953:3;;:12;39949:57;;;39988:6;;39982:3;:12;39485:528;:::o;33756:1215::-;33934:18;;33905:7;;33930:50;;-1:-1:-1;33979:1:0;33972:8;;33930:50;34061:18;;34049:11;;34061:21;;34081:1;;34061:21;:::i;:::-;34049:34;;;;;;-1:-1:-1;;;34049:34:0;;;;;;;;;;;;;;;;;;:44;;;34039:54;;34035:121;;34127:18;;34115:11;;34127:22;;34148:1;;34127:22;:::i;:::-;34115:35;;;;;;-1:-1:-1;;;34115:35:0;;;;;;;;;;;;;;;;;;:41;-1:-1:-1;;;34115:41:0;;-1:-1:-1;;;;;34115:41:0;;-1:-1:-1;34108:48:0;;34035:121;34180:11;34192:1;34180:14;;;;;;-1:-1:-1;;;34180:14:0;;;;;;;;;;;;;;;;;;:24;;;34171:33;;34167:60;;;-1:-1:-1;34226:1:0;34219:8;;34167:60;34401:18;;34360:8;;34422:4;-1:-1:-1;34401:103:0;;;;-1:-1:-1;34459:18:0;;34498:6;;34447:11;;34459:25;;34480:4;;34459:25;:::i;:::-;34447:38;;;;;;-1:-1:-1;;;34447:38:0;;;;;;;;;;;;;;;;;;:48;;;:57;34401:103;34383:204;;;34550:18;;:25;;34571:4;;34550:25;:::i;:::-;34544:31;;34383:204;34662:18;;34651:8;;34662:22;;34683:1;;34662:22;:::i;:::-;34651:33;;34695:229;34708:3;34702;:9;34695:229;;;34728:8;34757:1;34740:9;34746:3;34740;:9;:::i;:::-;:13;;34752:1;34740:13;:::i;:::-;34739:19;;;;:::i;:::-;34728:30;;34807:6;34777:11;34789:3;34777:16;;;;;;-1:-1:-1;;;34777:16:0;;;;;;;;;;;;;;;;;;:26;;;:36;34773:140;;34840:3;34834:9;;34773:140;;;34890:7;34896:1;34890:3;:7;:::i;:::-;34884:13;;34773:140;34695:229;;;;34941:11;34953:3;34941:16;;;;;;-1:-1:-1;;;34941:16:0;;;;;;;;;;;;;;;;;;:22;-1:-1:-1;;;34941:22:0;;-1:-1:-1;;;;;34941:22:0;;33756:1215;-1:-1:-1;;;;;33756:1215:0:o;23100:366::-;7716:9;23278:12;:26;;23271:34;;-1:-1:-1;;;23271:34:0;;;;;;;;;23344:113;;;;;;;;;;23395:12;23344:113;;;;-1:-1:-1;;;;;23344:113:0;;;;;;;;;;23316:142;;;;;;;-1:-1:-1;23316:142:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;23316:142:0;-1:-1:-1;;;;;;23316:142:0;;;;;;;;;;;;23100:366::o;36905:381::-;36987:25;;37053:30;7185:7;37053:15;:30;:::i;:::-;37030:53;-1:-1:-1;37114:36:0;7442:2;37030:53;37114:36;:::i;:::-;:40;;37153:1;37114:40;:::i;:::-;37094:60;-1:-1:-1;37189:16:0;:12;37204:1;37189:16;:::i;:::-;37169:17;:36;37165:114;;;37251:16;:12;37266:1;37251:16;:::i;:::-;37231:36;;37165:114;36905:381;;:::o;35437:1247::-;35623:18;;35594:7;;35619:59;;-1:-1:-1;35676:1:0;35661:17;;35619:59;35759:18;;35747:11;;35759:21;;35779:1;;35759:21;:::i;:::-;35747:34;;;;;;-1:-1:-1;;;35747:34:0;;;;;;;;;;;;;;;;;;:44;;;35737:54;;35733:124;;35825:18;;35813:11;;35825:22;;35846:1;;35825:22;:::i;:::-;35813:35;;;;;;-1:-1:-1;;;35813:35:0;;;;;;;;;;;;;;;;;;:44;-1:-1:-1;;;35813:44:0;;-1:-1:-1;;;;;35813:44:0;;-1:-1:-1;35806:51:0;;35733:124;35881:11;35893:1;35881:14;;;;;;-1:-1:-1;;;35881:14:0;;;;;;;;;;;;;;;;;;:24;;;35872:33;;35868:69;;;-1:-1:-1;35935:1:0;35920:17;;35868:69;36111:18;;36070:8;;36132:4;-1:-1:-1;36111:103:0;;;;-1:-1:-1;36169:18:0;;36208:6;;36157:11;;36169:25;;36190:4;;36169:25;:::i;:::-;36157:38;;;;;;-1:-1:-1;;;36157:38:0;;;;;;;;;;;;;;;;;;:48;;;:57;36111:103;36093:204;;;36260:18;;:25;;36281:4;;36260:25;:::i;:::-;36254:31;;36093:204;36372:18;;36361:8;;36372:22;;36393:1;;36372:22;:::i;:::-;36361:33;;36405:229;36418:3;36412;:9;36405:229;;;36438:8;36467:1;36450:9;36456:3;36450;:9;:::i;:::-;:13;;36462:1;36450:13;:::i;:::-;36449:19;;;;:::i;:::-;36438:30;;36517:6;36487:11;36499:3;36487:16;;;;;;-1:-1:-1;;;36487:16:0;;;;;;;;;;;;;;;;;;:26;;;:36;36483:140;;36550:3;36544:9;;36483:140;;;36600:7;36606:1;36600:3;:7;:::i;:::-;36594:13;;36483:140;36405:229;;;;36651:11;36663:3;36651:16;;;;;;-1:-1:-1;;;36651:16:0;;;;;;;;;;;;;;;;;;:25;-1:-1:-1;;;36651:25:0;;-1:-1:-1;;;;;36651:25:0;;35437:1247;-1:-1:-1;;;;;35437:1247:0:o;52096:1048::-;52238:10;52212:17;52232;;;:5;:17;;;;;52371:12;;;;52232:17;;52212;52358:25;;:10;:25;:::i;:::-;52331:52;;52394:22;52435:21;52445:10;52435:9;:21::i;:::-;52419:4;:13;;;:37;;;;:::i;:::-;52394:62;-1:-1:-1;52507:25:0;52526:6;52507:16;:25;:::i;:::-;52489:14;:43;;52467:128;;;;-1:-1:-1;;;52467:128:0;;16333:2:1;52467:128:0;;;16315:21:1;16372:2;16352:18;;;16345:30;16411:33;16391:18;;;16384:61;16462:18;;52467:128:0;16305:181:1;52467:128:0;52645:6;52628:4;:13;;;:23;;52606:108;;;;-1:-1:-1;;;52606:108:0;;6255:2:1;52606:108:0;;;6237:21:1;6294:2;6274:18;;;6267:30;6333:33;6313:18;;;6306:61;6384:18;;52606:108:0;6227:181:1;52606:108:0;52766:22;52807:6;52791:4;:13;;;:22;;;;:::i;:::-;52824:13;;;:30;;;52982:38;;-1:-1:-1;;;52982:38:0;;53001:10;52982:38;;;4126:51:1;4193:18;;;4186:34;;;52824:30:0;;-1:-1:-1;52982:9:0;-1:-1:-1;;;;;52982:18:0;;;;4099::1;;52982:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52975:46;;-1:-1:-1;;;52975:46:0;;;;;;;;;53037:99;;;18204:25:1;;;18260:2;18245:18;;18238:34;;;53061:10:0;;53037:99;;18177:18:1;53037:99:0;;;;;;;52096:1048;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:196::-;251:6;304:2;292:9;283:7;279:23;275:32;272:2;;;325:6;317;310:22;272:2;353:29;372:9;353:29;:::i;393:419::-;479:6;487;495;503;556:3;544:9;535:7;531:23;527:33;524:2;;;578:6;570;563:22;524:2;606:29;625:9;606:29;:::i;:::-;596:39;;654:38;688:2;677:9;673:18;654:38;:::i;:::-;644:48;;711:38;745:2;734:9;730:18;711:38;:::i;:::-;701:48;;768:38;802:2;791:9;787:18;768:38;:::i;:::-;758:48;;514:298;;;;;;;:::o;817:325::-;882:6;890;943:2;931:9;922:7;918:23;914:32;911:2;;;964:6;956;949:22;911:2;992:29;1011:9;992:29;:::i;:::-;982:39;;1071:2;1060:9;1056:18;1043:32;1084:28;1106:5;1084:28;:::i;:::-;1131:5;1121:15;;;901:241;;;;;:::o;1147:264::-;1215:6;1223;1276:2;1264:9;1255:7;1251:23;1247:32;1244:2;;;1297:6;1289;1282:22;1244:2;1325:29;1344:9;1325:29;:::i;:::-;1315:39;1401:2;1386:18;;;;1373:32;;-1:-1:-1;;;1234:177:1:o;1416:338::-;1493:6;1501;1509;1562:2;1550:9;1541:7;1537:23;1533:32;1530:2;;;1583:6;1575;1568:22;1530:2;1611:29;1630:9;1611:29;:::i;:::-;1601:39;;1687:2;1676:9;1672:18;1659:32;1649:42;;1710:38;1744:2;1733:9;1729:18;1710:38;:::i;:::-;1700:48;;1520:234;;;;;:::o;1759:476::-;1854:6;1862;1870;1878;1886;1939:3;1927:9;1918:7;1914:23;1910:33;1907:2;;;1961:6;1953;1946:22;1907:2;1989:29;2008:9;1989:29;:::i;:::-;1979:39;;2065:2;2054:9;2050:18;2037:32;2027:42;;2088:38;2122:2;2111:9;2107:18;2088:38;:::i;:::-;1897:338;;;;-1:-1:-1;2078:48:1;;2173:2;2158:18;;2145:32;;-1:-1:-1;2224:3:1;2209:19;2196:33;;1897:338;-1:-1:-1;;1897:338:1:o;2240:255::-;2307:6;2360:2;2348:9;2339:7;2335:23;2331:32;2328:2;;;2381:6;2373;2366:22;2328:2;2418:9;2412:16;2437:28;2459:5;2437:28;:::i;2500:190::-;2559:6;2612:2;2600:9;2591:7;2587:23;2583:32;2580:2;;;2633:6;2625;2618:22;2580:2;-1:-1:-1;2661:23:1;;2570:120;-1:-1:-1;2570:120:1:o;2695:194::-;2765:6;2818:2;2806:9;2797:7;2793:23;2789:32;2786:2;;;2839:6;2831;2824:22;2786:2;-1:-1:-1;2867:16:1;;2776:113;-1:-1:-1;2776:113:1:o;4983:346::-;5185:2;5167:21;;;5224:2;5204:18;;;5197:30;-1:-1:-1;;;5258:2:1;5243:18;;5236:52;5320:2;5305:18;;5157:172::o;15056:354::-;15258:2;15240:21;;;15297:2;15277:18;;;15270:30;15336:32;15331:2;15316:18;;15309:60;15401:2;15386:18;;15230:180::o;21354:128::-;21394:3;21425:1;21421:6;21418:1;21415:13;21412:2;;;21431:18;;:::i;:::-;-1:-1:-1;21467:9:1;;21402:80::o;21487:217::-;21527:1;21553;21543:2;;-1:-1:-1;;;21578:31:1;;21632:4;21629:1;21622:15;21660:4;21585:1;21650:15;21543:2;-1:-1:-1;21689:9:1;;21533:171::o;21709:272::-;21749:7;-1:-1:-1;;;;;21820:10:1;;;21850;;;21883:11;;21876:19;21905:12;;;21897:21;;21872:47;21869:2;;;21922:18;;:::i;:::-;21962:13;;21761:220;-1:-1:-1;;;;21761:220:1:o;21986:168::-;22026:7;22092:1;22088;22084:6;22080:14;22077:1;22074:21;22069:1;22062:9;22055:17;22051:45;22048:2;;;22099:18;;:::i;:::-;-1:-1:-1;22139:9:1;;22038:116::o;22159:125::-;22199:4;22227:1;22224;22221:8;22218:2;;;22232:18;;:::i;:::-;-1:-1:-1;22269:9:1;;22208:76::o;22289:136::-;22328:3;22356:5;22346:2;;22365:18;;:::i;:::-;-1:-1:-1;;;22401:18:1;;22336:89::o;22430:127::-;22491:10;22486:3;22482:20;22479:1;22472:31;22522:4;22519:1;22512:15;22546:4;22543:1;22536:15;22562:118;22648:5;22641:13;22634:21;22627:5;22624:32;22614:2;;22670:1;22667;22660:12
Swarm Source
ipfs://dab22d0b89f8e4222d6d396b8e9eff20e527eeba97d049ec9d7bf982050a7ce5
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.