Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x6101e060 | 19274350 | 191 days ago | IN | 0 ETH | 0.09660534 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TACoApplication
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; import "Math.sol"; import "SafeCast.sol"; import "SafeERC20.sol"; import "IERC20.sol"; import "OwnableUpgradeable.sol"; import "IApplicationWithOperator.sol"; import "IApplicationWithDecreaseDelay.sol"; import "IStaking.sol"; import "ITACoRootToChild.sol"; import "ITACoChildToRoot.sol"; /** * @title TACo Application * @notice Contract distributes rewards for participating in app and slashes for violating rules */ contract TACoApplication is IApplicationWithDecreaseDelay, IApplicationWithOperator, ITACoChildToRoot, OwnableUpgradeable { using SafeERC20 for IERC20; using SafeCast for uint256; /** * @notice Signals that distributor role was set * @param distributor Address of reward distributor */ event RewardDistributorSet(address indexed distributor); /** * @notice Signals that reward was added * @param reward Amount of reward */ event RewardAdded(uint256 reward); /** * @notice Signals that the beneficiary related to the staking provider received reward * @param stakingProvider Staking provider address * @param beneficiary Beneficiary address * @param reward Amount of reward */ event RewardPaid(address indexed stakingProvider, address indexed beneficiary, uint256 reward); /** * @notice Signals that authorization was increased for the staking provider * @param stakingProvider Staking provider address * @param fromAmount Previous amount of increased authorization * @param toAmount New amount of increased authorization */ event AuthorizationIncreased( address indexed stakingProvider, uint96 fromAmount, uint96 toAmount ); /** * @notice Signals that authorization was decreased involuntary * @param stakingProvider Staking provider address * @param fromAmount Previous amount of authorized tokens * @param toAmount Amount of authorized tokens to decrease */ event AuthorizationInvoluntaryDecreased( address indexed stakingProvider, uint96 fromAmount, uint96 toAmount ); /** * @notice Signals that authorization decrease was requested for the staking provider * @param stakingProvider Staking provider address * @param fromAmount Current amount of authorized tokens * @param toAmount Amount of authorization to decrease */ event AuthorizationDecreaseRequested( address indexed stakingProvider, uint96 fromAmount, uint96 toAmount ); /** * @notice Signals that authorization decrease was approved for the staking provider * @param stakingProvider Staking provider address * @param fromAmount Previous amount of authorized tokens * @param toAmount Decreased amount of authorized tokens */ event AuthorizationDecreaseApproved( address indexed stakingProvider, uint96 fromAmount, uint96 toAmount ); /** * @notice Signals that authorization was resynchronized with Threshold staking contract * @param stakingProvider Staking provider address * @param fromAmount Previous amount of authorized tokens * @param toAmount Resynchronized amount of authorized tokens */ event AuthorizationReSynchronized( address indexed stakingProvider, uint96 fromAmount, uint96 toAmount ); /** * @notice Signals that the staking provider was slashed * @param stakingProvider Staking provider address * @param penalty Slashing penalty * @param investigator Investigator address * @param reward Value of reward provided to investigator (in units of T) */ event Slashed( address indexed stakingProvider, uint256 penalty, address indexed investigator, uint256 reward ); /** * @notice Signals that an operator was bonded to the staking provider * @param stakingProvider Staking provider address * @param operator Operator address * @param previousOperator Previous operator address * @param startTimestamp Timestamp bonding occurred */ event OperatorBonded( address indexed stakingProvider, address indexed operator, address indexed previousOperator, uint256 startTimestamp ); /** * @notice Signals that a staking provider made a commitment * @param stakingProvider Staking provider address * @param endCommitment End of commitment */ event CommitmentMade(address indexed stakingProvider, uint256 endCommitment); /** * @notice Signals that manual child synchronization was called * @param stakingProvider Staking provider address * @param authorized Amount of authorized tokens to synchronize * @param operator Operator address to synchronize */ event ManualChildSynchronizationSent( address indexed stakingProvider, uint96 authorized, uint96 deauthorizing, uint64 endDeauthorization, address operator ); struct StakingProviderInfo { address operator; bool operatorConfirmed; uint64 operatorStartTimestamp; uint96 authorized; uint96 deauthorizing; // TODO real usage only in getActiveStakingProviders, maybe remove? uint64 endDeauthorization; uint96 tReward; uint160 rewardPerTokenPaid; uint64 endCommitment; } uint256 public constant REWARD_PER_TOKEN_MULTIPLIER = 10 ** 3; uint256 internal constant FLOATING_POINT_DIVISOR = REWARD_PER_TOKEN_MULTIPLIER * 10 ** 18; uint96 public immutable minimumAuthorization; uint256 public immutable minOperatorSeconds; uint256 public immutable rewardDuration; uint256 public immutable deauthorizationDuration; uint64 public immutable commitmentDurationOption1; uint64 public immutable commitmentDurationOption2; uint64 public immutable commitmentDurationOption3; uint64 public immutable commitmentDurationOption4; uint64 public immutable commitmentDeadline; IStaking public immutable tStaking; IERC20 public immutable token; ITACoRootToChild public childApplication; address public adjudicator; mapping(address => StakingProviderInfo) public stakingProviderInfo; address[] public stakingProviders; mapping(address => address) internal _stakingProviderFromOperator; address public rewardDistributor; uint256 public periodFinish; uint256 public rewardRateDecimals; uint256 public lastUpdateTime; uint160 public rewardPerTokenStored; uint96 public authorizedOverall; /** * @notice Constructor sets address of token contract and parameters for staking * @param _token T token contract * @param _tStaking T token staking contract * @param _minimumAuthorization Amount of minimum allowable authorization * @param _minOperatorSeconds Min amount of seconds while an operator can't be changed * @param _rewardDuration Duration of one reward cycle in seconds * @param _deauthorizationDuration Duration of decreasing authorization in seconds * @param _commitmentDurationOptions Options for commitment duration * @param _commitmentDeadline Last date to make a commitment */ constructor( IERC20 _token, IStaking _tStaking, uint96 _minimumAuthorization, uint256 _minOperatorSeconds, uint256 _rewardDuration, uint256 _deauthorizationDuration, uint64[] memory _commitmentDurationOptions, uint64 _commitmentDeadline ) { uint256 totalSupply = _token.totalSupply(); require( _rewardDuration != 0 && _tStaking.authorizedStake(address(this), address(this)) == 0 && totalSupply > 0 && _commitmentDurationOptions.length >= 1 && _commitmentDurationOptions.length <= 4, "Wrong input parameters" ); // This require is only to check potential overflow for 10% reward require( (totalSupply / 10) * FLOATING_POINT_DIVISOR <= type(uint160).max && _minimumAuthorization >= 10 ** 18 && _rewardDuration >= 1 days, "Potential overflow" ); rewardDuration = _rewardDuration; deauthorizationDuration = _deauthorizationDuration; minimumAuthorization = _minimumAuthorization; token = _token; tStaking = _tStaking; minOperatorSeconds = _minOperatorSeconds; commitmentDurationOption1 = _commitmentDurationOptions[0]; commitmentDurationOption2 = _commitmentDurationOptions.length >= 2 ? _commitmentDurationOptions[1] : 0; commitmentDurationOption3 = _commitmentDurationOptions.length >= 3 ? _commitmentDurationOptions[2] : 0; commitmentDurationOption4 = _commitmentDurationOptions.length >= 4 ? _commitmentDurationOptions[3] : 0; commitmentDeadline = _commitmentDeadline; _disableInitializers(); } /** * @dev Update reward for the specified staking provider */ modifier updateReward(address _stakingProvider) { updateRewardInternal(_stakingProvider); _; } /** * @dev Checks caller is T staking contract */ modifier onlyStakingContract() { require(msg.sender == address(tStaking), "Caller must be the T staking contract"); _; } /** * @dev Checks caller is a staking provider or stake owner */ modifier onlyOwnerOrStakingProvider(address _stakingProvider) { require(isAuthorized(_stakingProvider), "Not owner or provider"); if (_stakingProvider != msg.sender) { (address owner, , ) = tStaking.rolesOf(_stakingProvider); require(owner == msg.sender, "Not owner or provider"); } _; } /** * @notice Initialize function for using with OpenZeppelin proxy */ function initialize() external initializer { __Ownable_init(msg.sender); } /** * @notice Set contract for multi-chain interactions */ function setChildApplication(ITACoRootToChild _childApplication) external onlyOwner { require(address(_childApplication).code.length > 0, "Child app must be contract"); childApplication = _childApplication; } /** * @notice Set adjudicator contract. If zero then slashing is disabled */ function setAdjudicator(address _adjudicator) external onlyOwner { require( address(_adjudicator) != address(adjudicator), "New address must not be equal to the current one" ); adjudicator = _adjudicator; } /** * @notice Returns authorization-related parameters of the application. * @dev The minimum authorization is also returned by `minimumAuthorization()` * function, as a requirement of `IApplication` interface. * @return _minimumAuthorization The minimum authorization amount required * so that operator can participate in the application. * @return authorizationDecreaseDelay Delay in seconds that needs to pass * between the time authorization decrease is requested and the * time that request gets approved. Protects against free-riders * earning rewards and not being active in the network. * @return authorizationDecreaseChangePeriod Authorization decrease change * period in seconds. It is the time, before authorization decrease * delay end, during which the pending authorization decrease * request can be overwritten. * If set to 0, pending authorization decrease request can not be * overwritten until the entire `authorizationDecreaseDelay` ends. * If set to value equal `authorizationDecreaseDelay`, request can * always be overwritten. */ function authorizationParameters() external view override returns ( uint96 _minimumAuthorization, uint64 authorizationDecreaseDelay, uint64 authorizationDecreaseChangePeriod ) { return ( minimumAuthorization, uint64(deauthorizationDuration), uint64(deauthorizationDuration) ); } //------------------------Reward------------------------------ /** * @notice Set reward distributor address */ function setRewardDistributor(address _rewardDistributor) external onlyOwner { rewardDistributor = _rewardDistributor; emit RewardDistributorSet(_rewardDistributor); } /** * @notice Update reward for the specified staking provider * @param _stakingProvider Staking provider address */ function updateRewardInternal(address _stakingProvider) internal { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (_stakingProvider != address(0)) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; info.tReward = availableRewards(_stakingProvider); info.rewardPerTokenPaid = rewardPerTokenStored; } } /** * @notice Returns last time when reward was applicable */ function lastTimeRewardApplicable() public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } /** * @notice Returns current value of reward per token * multiplier */ function rewardPerToken() public view returns (uint160) { if (authorizedOverall == 0) { return rewardPerTokenStored; } uint256 result = rewardPerTokenStored + ((lastTimeRewardApplicable() - lastUpdateTime) * rewardRateDecimals) / authorizedOverall; return result.toUint160(); } /** * @notice Returns amount of reward in T units for the staking provider * @param _stakingProvider Staking provider address */ function availableRewards(address _stakingProvider) public view returns (uint96) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; if (!info.operatorConfirmed) { return info.tReward; } uint256 result = (uint256(info.authorized) * (rewardPerToken() - info.rewardPerTokenPaid)) / FLOATING_POINT_DIVISOR + info.tReward; return result.toUint96(); } /** * @notice Transfer reward for the next period. Can be called only by distributor * @param _reward Amount of reward */ function pushReward(uint96 _reward) external updateReward(address(0)) { require(msg.sender == rewardDistributor, "Only distributor can push rewards"); require(_reward > 0, "Reward must be specified"); require(authorizedOverall > 0, "No active staking providers"); if (block.timestamp >= periodFinish) { rewardRateDecimals = (uint256(_reward) * FLOATING_POINT_DIVISOR) / rewardDuration; } else { uint256 remaining = periodFinish - block.timestamp; uint256 leftover = remaining * rewardRateDecimals; rewardRateDecimals = (uint256(_reward) * FLOATING_POINT_DIVISOR + leftover) / rewardDuration; } lastUpdateTime = block.timestamp; periodFinish = block.timestamp + rewardDuration; emit RewardAdded(_reward); token.safeTransferFrom(msg.sender, address(this), _reward); } /** * @notice Withdraw available amount of T reward to beneficiary. Can be called only by beneficiary * @param _stakingProvider Staking provider address */ function withdrawRewards(address _stakingProvider) external updateReward(_stakingProvider) { address beneficiary = getBeneficiary(_stakingProvider); require(msg.sender == beneficiary, "Caller must be beneficiary"); StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; uint96 value = info.tReward; require(value > 0, "No reward to withdraw"); info.tReward = 0; emit RewardPaid(_stakingProvider, beneficiary, value); token.safeTransfer(beneficiary, value); } //------------------------Authorization------------------------------ /** * @notice Recalculate `authorizedOverall` if desync happened */ function resynchronizeAuthorizedOverall( StakingProviderInfo storage _info, uint96 _properAmount ) internal { if (_info.authorized != _properAmount) { authorizedOverall -= _info.authorized - _properAmount; } } /** * @notice Recalculate reward and save increased authorization. Can be called only by staking contract * @param _stakingProvider Address of staking provider * @param _fromAmount Amount of previously authorized tokens to TACo application by staking provider * @param _toAmount Amount of authorized tokens to TACo application by staking provider */ function authorizationIncreased( address _stakingProvider, uint96 _fromAmount, uint96 _toAmount ) external override onlyStakingContract updateReward(_stakingProvider) { require( _stakingProvider != address(0) && _toAmount > 0, "Input parameters must be specified" ); require(_toAmount >= minimumAuthorization, "Authorization must be greater than minimum"); StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; require( _stakingProviderFromOperator[_stakingProvider] == address(0) || _stakingProviderFromOperator[_stakingProvider] == _stakingProvider, "A provider can't be an operator for another provider" ); if (info.operatorConfirmed) { resynchronizeAuthorizedOverall(info, _fromAmount); authorizedOverall += _toAmount - _fromAmount; } info.authorized = _toAmount; emit AuthorizationIncreased(_stakingProvider, _fromAmount, _toAmount); _updateAuthorization(_stakingProvider, info); } /** * @notice Immediately decrease authorization. Can be called only by staking contract * @param _stakingProvider Address of staking provider * @param _fromAmount Previous amount of authorized tokens * @param _toAmount Amount of authorized tokens to decrease */ function involuntaryAuthorizationDecrease( address _stakingProvider, uint96 _fromAmount, uint96 _toAmount ) external override onlyStakingContract updateReward(_stakingProvider) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; if (info.operatorConfirmed) { resynchronizeAuthorizedOverall(info, _fromAmount); authorizedOverall -= _fromAmount - _toAmount; } info.authorized = _toAmount; if (info.authorized < info.deauthorizing) { info.deauthorizing = info.authorized; } emit AuthorizationInvoluntaryDecreased(_stakingProvider, _fromAmount, _toAmount); if (info.authorized == 0) { _releaseOperator(_stakingProvider); } _updateAuthorization(_stakingProvider, info); } /** * @notice Register request of decreasing authorization. Can be called only by staking contract * @param _stakingProvider Address of staking provider * @param _fromAmount Current amount of authorized tokens * @param _toAmount Amount of authorized tokens to decrease */ function authorizationDecreaseRequested( address _stakingProvider, uint96 _fromAmount, uint96 _toAmount ) external override onlyStakingContract updateReward(_stakingProvider) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; require(_toAmount <= info.authorized, "Amount to decrease greater than authorized"); require( _toAmount == 0 || _toAmount >= minimumAuthorization, "Resulting authorization will be less than minimum" ); require( info.endCommitment <= block.timestamp, "Can't request deauthorization before end of commitment" ); if (info.operatorConfirmed) { resynchronizeAuthorizedOverall(info, _fromAmount); } info.authorized = _fromAmount; info.deauthorizing = _fromAmount - _toAmount; info.endDeauthorization = uint64(block.timestamp + deauthorizationDuration); emit AuthorizationDecreaseRequested(_stakingProvider, _fromAmount, _toAmount); _updateAuthorization(_stakingProvider, info); } /** * @notice Approve request of decreasing authorization. Can be called by anyone * @param _stakingProvider Address of staking provider */ function approveAuthorizationDecrease( address _stakingProvider ) external updateReward(_stakingProvider) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; require(info.deauthorizing > 0, "There is no deauthorizing in process"); require( info.endDeauthorization <= block.timestamp, "Authorization decrease has not finished yet" ); uint96 toAmount = tStaking.approveAuthorizationDecrease(_stakingProvider); if (info.operatorConfirmed) { authorizedOverall -= info.authorized - toAmount; } emit AuthorizationDecreaseApproved(_stakingProvider, info.authorized, toAmount); info.authorized = toAmount; info.deauthorizing = 0; info.endDeauthorization = 0; if (info.authorized == 0) { _releaseOperator(_stakingProvider); } _updateAuthorization(_stakingProvider, info); } /** * @notice Read authorization from staking contract and store it. Can be called by anyone * @param _stakingProvider Address of staking provider */ function resynchronizeAuthorization( address _stakingProvider ) external updateReward(_stakingProvider) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; uint96 newAuthorized = tStaking.authorizedStake(_stakingProvider, address(this)); require(info.authorized > newAuthorized, "Nothing to synchronize"); if (info.operatorConfirmed) { authorizedOverall -= info.authorized - newAuthorized; } emit AuthorizationReSynchronized(_stakingProvider, info.authorized, newAuthorized); info.authorized = newAuthorized; if (info.authorized < info.deauthorizing) { info.deauthorizing = info.authorized; } if (info.authorized == 0) { _releaseOperator(_stakingProvider); } _updateAuthorization(_stakingProvider, info); } /** * @notice Make a commitment to not request authorization decrease for specified duration * @param _stakingProvider Staking provider address * @param _commitmentDuration Duration of commitment */ function makeCommitment( address _stakingProvider, uint64 _commitmentDuration ) external onlyOwnerOrStakingProvider(_stakingProvider) { require(block.timestamp < commitmentDeadline, "Commitment window closed"); require( _commitmentDuration > 0 && (_commitmentDuration == commitmentDurationOption1 || _commitmentDuration == commitmentDurationOption2 || _commitmentDuration == commitmentDurationOption3 || _commitmentDuration == commitmentDurationOption4), "Commitment duration must be equal to one of options" ); StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; require(info.endDeauthorization == 0, "Commitment can't be made during deauthorization"); require(info.endCommitment == 0, "Commitment already made"); info.endCommitment = uint64(block.timestamp) + _commitmentDuration; emit CommitmentMade(_stakingProvider, info.endCommitment); } //-------------------------Main------------------------- /** * @notice Returns staking provider for specified operator */ function operatorToStakingProvider(address _operator) external view returns (address) { return _stakingProviderFromOperator[_operator]; } /** * @notice Returns operator for specified staking provider */ function stakingProviderToOperator(address _stakingProvider) external view returns (address) { return stakingProviderInfo[_stakingProvider].operator; } /** * @notice Get all tokens delegated to the staking provider */ function authorizedStake(address _stakingProvider) external view returns (uint96) { return stakingProviderInfo[_stakingProvider].authorized; } /** * @notice Returns the amount of stake that are going to be effectively * staked until the specified date. I.e: in case a deauthorization * is going to be made during this period, the returned amount will * be the staked amount minus the deauthorizing amount. */ function eligibleStake( address _stakingProvider, uint256 _endDate ) public view returns (uint96) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; uint96 eligibleAmount = info.authorized; if (0 < info.endDeauthorization && info.endDeauthorization < _endDate) { eligibleAmount -= info.deauthorizing; } return eligibleAmount; } /** * @notice Returns the amount of stake that is pending authorization * decrease for the given staking provider. If no authorization * decrease has been requested, returns zero. */ function pendingAuthorizationDecrease( address _stakingProvider ) external view override returns (uint96) { return stakingProviderInfo[_stakingProvider].deauthorizing; } /** * @notice Returns the remaining time in seconds that needs to pass before * the requested authorization decrease can be approved. */ function remainingAuthorizationDecreaseDelay( address _stakingProvider ) external view override returns (uint64) { uint256 endDeauthorization = stakingProviderInfo[_stakingProvider].endDeauthorization; if (endDeauthorization <= block.timestamp) { return 0; } return uint64(endDeauthorization - block.timestamp); } /** * @notice Get the value of authorized tokens for active providers as well as providers and their authorized tokens * @param _startIndex Start index for looking in providers array * @param _maxStakingProviders Max providers for looking, if set 0 then all will be used * @param _cohortDuration Duration during which staking provider should be active. 0 means forever * @return allAuthorizedTokens Sum of authorized tokens for active providers * @return activeStakingProviders Array of providers and their authorized tokens. * Providers addresses stored together with amounts as bytes32 * @dev Note that activeStakingProviders is an array of bytes32, but you want addresses and amounts. * Careful when used directly! */ function getActiveStakingProviders( uint256 _startIndex, uint256 _maxStakingProviders, uint32 _cohortDuration ) external view returns (uint256 allAuthorizedTokens, bytes32[] memory activeStakingProviders) { uint256 endIndex = stakingProviders.length; require(_startIndex < endIndex, "Wrong start index"); if (_maxStakingProviders != 0 && _startIndex + _maxStakingProviders < endIndex) { endIndex = _startIndex + _maxStakingProviders; } activeStakingProviders = new bytes32[](endIndex - _startIndex); allAuthorizedTokens = 0; uint256 endDate = _cohortDuration == 0 ? type(uint256).max : block.timestamp + _cohortDuration; uint256 resultIndex = 0; for (uint256 i = _startIndex; i < endIndex; i++) { address stakingProvider = stakingProviders[i]; StakingProviderInfo storage info = stakingProviderInfo[stakingProvider]; uint256 eligibleAmount = eligibleStake(stakingProvider, endDate); if (eligibleAmount < minimumAuthorization || !info.operatorConfirmed) { continue; } // bytes20 -> bytes32 adds padding after address: <address><12 zeros> // uint96 -> uint256 adds padding before uint96: <20 zeros><amount> activeStakingProviders[resultIndex++] = bytes32(bytes20(stakingProvider)) | bytes32(uint256(eligibleAmount)); allAuthorizedTokens += eligibleAmount; } assembly { mstore(activeStakingProviders, resultIndex) } } /** * @notice Returns beneficiary related to the staking provider */ function getBeneficiary( address _stakingProvider ) public view returns (address payable beneficiary) { (, beneficiary, ) = tStaking.rolesOf(_stakingProvider); } /** * @notice Returns true if staking provider has authorized stake to this application */ function isAuthorized(address _stakingProvider) public view returns (bool) { return stakingProviderInfo[_stakingProvider].authorized > 0; } /** * @notice Returns true if operator has confirmed address */ // TODO maybe _stakingProvider instead of _operator as input? function isOperatorConfirmed(address _operator) public view returns (bool) { address stakingProvider = _stakingProviderFromOperator[_operator]; StakingProviderInfo storage info = stakingProviderInfo[stakingProvider]; return info.operatorConfirmed; } /** * @notice Return the length of the array of staking providers */ function getStakingProvidersLength() external view returns (uint256) { return stakingProviders.length; } /** * @notice Used by staking provider to set operator address that will * operate a node. The operator address must be unique. * Reverts if the operator is already set for the staking provider * or if the operator address is already in use. */ function registerOperator(address _operator) external override { bondOperator(msg.sender, _operator); } /** * @notice Bond operator * @param _stakingProvider Staking provider address * @param _operator Operator address. Must be an EOA, not a contract address */ function bondOperator( address _stakingProvider, address _operator ) public onlyOwnerOrStakingProvider(_stakingProvider) updateReward(_stakingProvider) { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; address previousOperator = info.operator; require( _operator != previousOperator, "Specified operator is already bonded with this provider" ); // If this staker had a operator ... if (previousOperator != address(0)) { require( !info.operatorConfirmed || block.timestamp >= uint256(info.operatorStartTimestamp) + minOperatorSeconds, "Not enough time passed to change operator" ); // Remove the old relation "operator->stakingProvider" _stakingProviderFromOperator[previousOperator] = address(0); } if (_operator != address(0)) { require( _stakingProviderFromOperator[_operator] == address(0), "Specified operator is already in use" ); require( _operator == _stakingProvider || getBeneficiary(_operator) == address(0), "Specified operator is a provider" ); // Set new operator->stakingProvider relation _stakingProviderFromOperator[_operator] = _stakingProvider; } if (info.operatorStartTimestamp == 0) { stakingProviders.push(_stakingProvider); } if (info.operatorConfirmed) { authorizedOverall -= info.authorized; } // Bond new operator (or unbond if _operator == address(0)) info.operator = _operator; info.operatorStartTimestamp = uint64(block.timestamp); emit OperatorBonded(_stakingProvider, _operator, previousOperator, block.timestamp); info.operatorConfirmed = false; childApplication.updateOperator(_stakingProvider, _operator); } /** * @notice Make a confirmation by operator */ function confirmOperatorAddress(address _operator) external override { require( msg.sender == address(childApplication), "Only child application allowed to confirm operator" ); address stakingProvider = _stakingProviderFromOperator[_operator]; // TODO only in case of desync, maybe just exit? // require(stakingProvider != address(0), "Operator has no bond with staking provider"); if (stakingProvider == address(0)) { return; } StakingProviderInfo storage info = stakingProviderInfo[stakingProvider]; if (!info.operatorConfirmed) { updateRewardInternal(stakingProvider); info.operatorConfirmed = true; authorizedOverall += info.authorized; emit OperatorConfirmed(stakingProvider, _operator); } } //-------------------------XChain------------------------- /** * @notice Resets operator confirmation */ function _releaseOperator(address _stakingProvider) internal { StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; _stakingProviderFromOperator[info.operator] = address(0); info.operator = address(0); info.operatorConfirmed = false; info.endDeauthorization = 0; info.endCommitment = 0; childApplication.updateOperator(_stakingProvider, address(0)); } /** * @notice Send updated authorized amount to xchain contract */ function _updateAuthorization( address _stakingProvider, StakingProviderInfo storage _info ) internal { childApplication.updateAuthorization( _stakingProvider, _info.authorized, _info.deauthorizing, _info.endDeauthorization ); } /** * @notice Manual signal to the bridge with the current state of the specified staking provider * @dev This method is useful only in case of issues with the bridge */ function manualChildSynchronization(address _stakingProvider) external { require(_stakingProvider != address(0), "Staking provider must be specified"); StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider]; emit ManualChildSynchronizationSent( _stakingProvider, info.authorized, info.deauthorizing, info.endDeauthorization, info.operator ); _updateAuthorization(_stakingProvider, info); childApplication.updateOperator(_stakingProvider, info.operator); } //-------------------------Slashing------------------------- /** * @notice Slash the provider's stake and reward the investigator * @param _stakingProvider Staking provider address * @param _penalty Penalty * @param _investigator Investigator */ function slash(address _stakingProvider, uint96 _penalty, address _investigator) external { require(msg.sender == adjudicator, "Only adjudicator allowed to slash"); address[] memory stakingProviderWrapper = new address[](1); stakingProviderWrapper[0] = _stakingProvider; tStaking.seize(_penalty, 100, _investigator, stakingProviderWrapper); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; import {Initializable} from "Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-3.0-or-later // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ pragma solidity ^0.8.9; /// @title Application interface for Threshold Network applications /// @notice Generic interface for an application. Application is an external /// smart contract or a set of smart contracts utilizing functionalities /// offered by Threshold Network. Applications authorized for the given /// staking provider are eligible to slash the stake delegated to that /// staking provider. interface IApplication { /// @dev Event emitted by `withdrawRewards` function. event RewardsWithdrawn(address indexed stakingProvider, uint96 amount); /// @notice Withdraws application rewards for the given staking provider. /// Rewards are withdrawn to the staking provider's beneficiary /// address set in the staking contract. /// @dev Emits `RewardsWithdrawn` event. function withdrawRewards(address stakingProvider) external; /// @notice Used by T staking contract to inform the application that the /// authorized amount for the given staking provider increased. /// The application may do any necessary housekeeping. The /// application must revert the transaction in case the /// authorization is below the minimum required. function authorizationIncreased( address stakingProvider, uint96 fromAmount, uint96 toAmount ) external; /// @notice Used by T staking contract to inform the application that the /// authorization decrease for the given staking provider has been /// requested. The application should mark the authorization as /// pending decrease and respond to the staking contract with /// `approveAuthorizationDecrease` at its discretion. It may /// happen right away but it also may happen several months later. /// If there is already a pending authorization decrease request /// for the application, and the application does not agree for /// overwriting it, the function should revert. function authorizationDecreaseRequested( address stakingProvider, uint96 fromAmount, uint96 toAmount ) external; /// @notice Used by T staking contract to inform the application the /// authorization has been decreased for the given staking provider /// involuntarily, as a result of slashing. Lets the application to /// do any housekeeping neccessary. Called with 250k gas limit and /// does not revert the transaction if /// `involuntaryAuthorizationDecrease` call failed. function involuntaryAuthorizationDecrease( address stakingProvider, uint96 fromAmount, uint96 toAmount ) external; /// @notice Returns the amount of application rewards available for /// withdrawal for the given staking provider. function availableRewards(address stakingProvider) external view returns (uint96); /// @notice The minimum authorization amount required for the staking /// provider so that they can participate in the application. function minimumAuthorization() external view returns (uint96); }
// SPDX-License-Identifier: GPL-3.0-or-later // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ pragma solidity ^0.8.9; import "IApplication.sol"; /// @title Interface for Threshold Network applications with delay after decrease request interface IApplicationWithDecreaseDelay is IApplication { /// @notice Returns authorization-related parameters of the application. /// @dev The minimum authorization is also returned by `minimumAuthorization()` /// function, as a requirement of `IApplication` interface. /// @return _minimumAuthorization The minimum authorization amount required /// so that operator can participate in the application. /// @return authorizationDecreaseDelay Delay in seconds that needs to pass /// between the time authorization decrease is requested and the /// time that request gets approved. Protects against free-riders /// earning rewards and not being active in the network. /// @return authorizationDecreaseChangePeriod Authorization decrease change /// period in seconds. It is the time, before authorization decrease /// delay end, during which the pending authorization decrease /// request can be overwritten. /// If set to 0, pending authorization decrease request can not be /// overwritten until the entire `authorizationDecreaseDelay` ends. /// If set to value equal `authorizationDecreaseDelay`, request can /// always be overwritten. function authorizationParameters() external view returns ( uint96 _minimumAuthorization, uint64 authorizationDecreaseDelay, uint64 authorizationDecreaseChangePeriod ); /// @notice Returns the amount of stake that is pending authorization /// decrease for the given staking provider. If no authorization /// decrease has been requested, returns zero. function pendingAuthorizationDecrease(address _stakingProvider) external view returns (uint96); /// @notice Returns the remaining time in seconds that needs to pass before /// the requested authorization decrease can be approved. function remainingAuthorizationDecreaseDelay( address stakingProvider ) external view returns (uint64); /// @notice Approves the previously registered authorization decrease /// request. Reverts if authorization decrease delay has not passed /// yet or if the authorization decrease was not requested for the /// given staking provider. function approveAuthorizationDecrease(address stakingProvider) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ pragma solidity ^0.8.9; import "IApplication.sol"; /// @title Interface for Threshold Network applications with operator role interface IApplicationWithOperator is IApplication { /// @notice Returns operator registered for the given staking provider. function stakingProviderToOperator(address stakingProvider) external view returns (address); /// @notice Returns staking provider of the given operator. function operatorToStakingProvider(address operator) external view returns (address); /// @notice Used by staking provider to set operator address that will /// operate a node. The operator addressmust be unique. /// Reverts if the operator is already set for the staking provider /// or if the operator address is already in use. /// @dev Depending on application the given staking provider can set operator /// address only one or multiple times. Besides that application can decide /// if function reverts if there is a pending authorization decrease for /// the staking provider. function registerOperator(address operator) external; // TODO consider that? // /// @notice Used by additional role (owner for example) to set operator address that will // /// operate a node for the specified staking provider. // function registerOperator(address stakingProvider, address operator) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: GPL-3.0-or-later // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ██████████████ ▐████▌ ██████████████ // ██████████████ ▐████▌ ██████████████ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ // ▐████▌ ▐████▌ pragma solidity ^0.8.9; /// @title Interface of Threshold Network staking contract /// @notice The staking contract enables T owners to have their wallets offline /// and their stake managed by staking providers on their behalf. /// The staking contract does not define operator role. The operator /// responsible for running off-chain client software is appointed by /// the staking provider in the particular application utilizing the /// staking contract. All off-chain client software should be able /// to run without exposing operator's or staking provider’s private /// key and should not require any owner’s keys at all. The stake /// delegation optimizes the network throughput without compromising the /// security of the owners’ stake. interface IStaking { enum StakeType { NU, KEEP, T } // // // Delegating a stake // // /// @notice Creates a delegation with `msg.sender` owner with the given /// staking provider, beneficiary, and authorizer. Transfers the /// given amount of T to the staking contract. /// @dev The owner of the delegation needs to have the amount approved to /// transfer to the staking contract. function stake( address stakingProvider, address payable beneficiary, address authorizer, uint96 amount ) external; /// @notice Allows the Governance to set the minimum required stake amount. /// This amount is required to protect against griefing the staking /// contract and individual applications are allowed to require /// higher minimum stakes if necessary. function setMinimumStakeAmount(uint96 amount) external; // // // Authorizing an application // // /// @notice Allows the Governance to approve the particular application /// before individual stake authorizers are able to authorize it. function approveApplication(address application) external; /// @notice Increases the authorization of the given staking provider for /// the given application by the given amount. Can only be called by /// the authorizer for that staking provider. /// @dev Calls `authorizationIncreased(address stakingProvider, uint256 amount)` /// on the given application to notify the application about /// authorization change. See `IApplication`. function increaseAuthorization( address stakingProvider, address application, uint96 amount ) external; /// @notice Requests decrease of the authorization for the given staking /// provider on the given application by the provided amount. /// It may not change the authorized amount immediatelly. When /// it happens depends on the application. Can only be called by the /// given staking provider’s authorizer. Overwrites pending /// authorization decrease for the given staking provider and /// application if the application agrees for that. If the /// application does not agree for overwriting, the function /// reverts. /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)` /// on the given application. See `IApplication`. function requestAuthorizationDecrease( address stakingProvider, address application, uint96 amount ) external; /// @notice Requests decrease of all authorizations for the given staking /// provider on all applications by all authorized amount. /// It may not change the authorized amount immediatelly. When /// it happens depends on the application. Can only be called by the /// given staking provider’s authorizer. Overwrites pending /// authorization decrease for the given staking provider and /// application. /// @dev Calls `authorizationDecreaseRequested(address stakingProvider, uint256 amount)` /// for each authorized application. See `IApplication`. function requestAuthorizationDecrease(address stakingProvider) external; /// @notice Called by the application at its discretion to approve the /// previously requested authorization decrease request. Can only be /// called by the application that was previously requested to /// decrease the authorization for that staking provider. /// Returns resulting authorized amount for the application. function approveAuthorizationDecrease(address stakingProvider) external returns (uint96); /// @notice Decreases the authorization for the given `stakingProvider` on /// the given disabled `application`, for all authorized amount. /// Can be called by anyone. function forceDecreaseAuthorization( address stakingProvider, address application ) external; /// @notice Pauses the given application’s eligibility to slash stakes. /// Besides that stakers can't change authorization to the application. /// Can be called only by the Panic Button of the particular /// application. The paused application can not slash stakes until /// it is approved again by the Governance using `approveApplication` /// function. Should be used only in case of an emergency. function pauseApplication(address application) external; /// @notice Disables the given application. The disabled application can't /// slash stakers. Also stakers can't increase authorization to that /// application but can decrease without waiting by calling /// `requestAuthorizationDecrease` at any moment. Can be called only /// by the governance. The disabled application can't be approved /// again. Should be used only in case of an emergency. function disableApplication(address application) external; /// @notice Sets the Panic Button role for the given application to the /// provided address. Can only be called by the Governance. If the /// Panic Button for the given application should be disabled, the /// role address should be set to 0x0 address. function setPanicButton(address application, address panicButton) external; /// @notice Sets the maximum number of applications one staking provider can /// have authorized. Used to protect against DoSing slashing queue. /// Can only be called by the Governance. function setAuthorizationCeiling(uint256 ceiling) external; // // // Stake top-up // // /// @notice Increases the amount of the stake for the given staking provider. /// If `autoIncrease` flag is true then the amount will be added for /// all authorized applications. /// @dev The sender of this transaction needs to have the amount approved to /// transfer to the staking contract. function topUp(address stakingProvider, uint96 amount) external; /// @notice Toggle `autoIncrease` flag. If true then the complete amount /// in top-up will be added to already authorized applications. function toggleAutoAuthorizationIncrease(address stakingProvider) external; // // // Undelegating a stake (unstaking) // // /// @notice Reduces the liquid T stake amount by the provided amount and /// withdraws T to the owner. Reverts if there is at least one /// authorization higher than the sum of the legacy stake and /// remaining liquid T stake or if the unstake amount is higher than /// the liquid T stake amount. Can be called only by the delegation /// owner or the staking provider. function unstakeT(address stakingProvider, uint96 amount) external; /// @notice Sets the legacy KEEP staking contract active stake amount cached /// in T staking contract to 0. Reverts if the amount of liquid T /// staked in T staking contract is lower than the highest /// application authorization. This function allows to unstake from /// KEEP staking contract and still being able to operate in T /// network and earning rewards based on the liquid T staked. Can be /// called only by the delegation owner or the staking provider. function unstakeKeep(address stakingProvider) external; /// @notice Sets to 0 the amount of T that is cached from the legacy /// NU staking contract. Reverts if there is at least one /// authorization higher than the sum of remaining legacy NU stake /// and native T stake for that staking provider or if the unstaked /// amount is higher than the cached legacy stake amount. If succeeded, /// the legacy NU stake can be partially or fully undelegated on /// the legacy NU staking contract. This function allows to unstake /// from NU staking contract while still being able to operate in /// T network and earning rewards based on the native T staked. /// Can be called only by the stake owner or the staking provider. function unstakeNu(address stakingProvider) external; /// @notice Sets cached legacy stake amount to 0, sets the liquid T stake /// amount to 0 and withdraws all liquid T from the stake to the /// owner. Reverts if there is at least one non-zero authorization. /// Can be called only by the delegation owner or the staking /// provider. function unstakeAll(address stakingProvider) external; // // // Keeping information in sync // // /// @notice Sets reward in T tokens for notification of misbehaviour /// of one staking provider. Can only be called by the governance. function setNotificationReward(uint96 reward) external; /// @notice Transfer some amount of T tokens as reward for notifications /// of misbehaviour function pushNotificationReward(uint96 reward) external; /// @notice Withdraw some amount of T tokens from notifiers treasury. /// Can only be called by the governance. function withdrawNotificationReward(address recipient, uint96 amount) external; /// @notice Adds staking providers to the slashing queue along with the /// amount that should be slashed from each one of them. Can only be /// called by application authorized for all staking providers in /// the array. function slash(uint96 amount, address[] memory stakingProviders) external; /// @notice Adds staking providers to the slashing queue along with the /// amount. The notifier will receive reward per each staking /// provider from notifiers treasury. Can only be called by /// application authorized for all staking providers in the array. function seize( uint96 amount, uint256 rewardMultipier, address notifier, address[] memory stakingProviders ) external; /// @notice Takes the given number of queued slashing operations and /// processes them. Receives 5% of the slashed amount. /// Executes `involuntaryAllocationDecrease` function on each /// affected application. function processSlashing(uint256 count) external; // // // Auxiliary functions // // /// @notice Returns the authorized stake amount of the staking provider for /// the application. function authorizedStake(address stakingProvider, address application) external view returns (uint96); /// @notice Returns staked amount of T, Keep and Nu for the specified /// staking provider. /// @dev All values are in T denomination function stakes(address stakingProvider) external view returns ( uint96 tStake, uint96 keepInTStake, uint96 nuInTStake ); /// @notice Returns start staking timestamp. /// @dev This value is set at most once. function getStartStakingTimestamp(address stakingProvider) external view returns (uint256); /// @notice Returns auto-increase flag. function getAutoIncreaseFlag(address stakingProvider) external view returns (bool); /// @notice Returns staked amount of NU for the specified staking provider. function stakedNu(address stakingProvider) external view returns (uint256); /// @notice Gets the stake owner, the beneficiary and the authorizer /// for the specified staking provider address. /// @return owner Stake owner address. /// @return beneficiary Beneficiary address. /// @return authorizer Authorizer address. function rolesOf(address stakingProvider) external view returns ( address owner, address payable beneficiary, address authorizer ); /// @notice Returns length of application array function getApplicationsLength() external view returns (uint256); /// @notice Returns length of slashing queue function getSlashingQueueLength() external view returns (uint256); /// @notice Returns minimum possible stake for T, KEEP or NU in T /// denomination. /// @dev For example, suppose the given staking provider has 10 T, 20 T worth /// of KEEP, and 30 T worth of NU all staked, and the maximum /// application authorization is 40 T, then `getMinStaked` for /// that staking provider returns: /// * 0 T if KEEP stake type specified i.e. /// min = 40 T max - (10 T) = 30 T /// * 10 T if NU stake type specified i.e. /// min = 40 T max - (10 T) = 30 T /// * 0 T if T stake type specified i.e. /// min = 40 T max = 40 T /// In other words, the minimum stake amount for the specified /// stake type is the minimum amount of stake of the given type /// needed to satisfy the maximum application authorization given /// the staked amounts of the T stake types for that staking provider. function getMinStaked(address stakingProvider, StakeType stakeTypes) external view returns (uint96); /// @notice Returns available amount to authorize for the specified application function getAvailableToAuthorize( address stakingProvider, address application ) external view returns (uint96); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; /** * @title ITACoChildToRoot * @notice Interface for x-chain interactions from coordinator to application */ interface ITACoChildToRoot { /** * @notice Signals that an operator address is confirmed * @param stakingProvider Staking provider address * @param operator Operator address */ event OperatorConfirmed(address indexed stakingProvider, address indexed operator); function confirmOperatorAddress(address operator) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; /** * @title ITACoRootToChild * @notice Interface for x-chain interactions from application to coordinator */ interface ITACoRootToChild { event OperatorUpdated(address indexed stakingProvider, address indexed operator); event AuthorizationUpdated( address indexed stakingProvider, uint96 authorized, uint96 deauthorizing, uint64 endDeauthorization ); function updateOperator(address stakingProvider, address operator) external; function updateAuthorization(address stakingProvider, uint96 authorized) external; function updateAuthorization( address stakingProvider, uint96 authorized, uint96 deauthorizing, uint64 endDeauthorization ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {ContextUpgradeable} from "ContextUpgradeable.sol"; import {Initializable} from "Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Ownable struct OwnableStorage { address _owner; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300; function _getOwnableStorage() private pure returns (OwnableStorage storage $) { assembly { $.slot := OwnableStorageLocation } } /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { OwnableStorage storage $ = _getOwnableStorage(); return $._owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { OwnableStorage storage $ = _getOwnableStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "IERC20.sol"; import {IERC20Permit} from "IERC20Permit.sol"; import {Address} from "Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"contract IStaking","name":"_tStaking","type":"address"},{"internalType":"uint96","name":"_minimumAuthorization","type":"uint96"},{"internalType":"uint256","name":"_minOperatorSeconds","type":"uint256"},{"internalType":"uint256","name":"_rewardDuration","type":"uint256"},{"internalType":"uint256","name":"_deauthorizationDuration","type":"uint256"},{"internalType":"uint64[]","name":"_commitmentDurationOptions","type":"uint64[]"},{"internalType":"uint64","name":"_commitmentDeadline","type":"uint64"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"fromAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"toAmount","type":"uint96"}],"name":"AuthorizationDecreaseApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"fromAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"toAmount","type":"uint96"}],"name":"AuthorizationDecreaseRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"fromAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"toAmount","type":"uint96"}],"name":"AuthorizationIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"fromAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"toAmount","type":"uint96"}],"name":"AuthorizationInvoluntaryDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"fromAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"toAmount","type":"uint96"}],"name":"AuthorizationReSynchronized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint256","name":"endCommitment","type":"uint256"}],"name":"CommitmentMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"authorized","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"deauthorizing","type":"uint96"},{"indexed":false,"internalType":"uint64","name":"endDeauthorization","type":"uint64"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"ManualChildSynchronizationSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"previousOperator","type":"address"},{"indexed":false,"internalType":"uint256","name":"startTimestamp","type":"uint256"}],"name":"OperatorBonded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"OperatorConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"distributor","type":"address"}],"name":"RewardDistributorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"RewardsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProvider","type":"address"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"},{"indexed":true,"internalType":"address","name":"investigator","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Slashed","type":"event"},{"inputs":[],"name":"REWARD_PER_TOKEN_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adjudicator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"approveAuthorizationDecrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint96","name":"_fromAmount","type":"uint96"},{"internalType":"uint96","name":"_toAmount","type":"uint96"}],"name":"authorizationDecreaseRequested","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint96","name":"_fromAmount","type":"uint96"},{"internalType":"uint96","name":"_toAmount","type":"uint96"}],"name":"authorizationIncreased","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authorizationParameters","outputs":[{"internalType":"uint96","name":"_minimumAuthorization","type":"uint96"},{"internalType":"uint64","name":"authorizationDecreaseDelay","type":"uint64"},{"internalType":"uint64","name":"authorizationDecreaseChangePeriod","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorizedOverall","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"authorizedStake","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"availableRewards","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"bondOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"childApplication","outputs":[{"internalType":"contract ITACoRootToChild","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitmentDeadline","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitmentDurationOption1","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitmentDurationOption2","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitmentDurationOption3","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitmentDurationOption4","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"confirmOperatorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deauthorizationDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint256","name":"_endDate","type":"uint256"}],"name":"eligibleStake","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_maxStakingProviders","type":"uint256"},{"internalType":"uint32","name":"_cohortDuration","type":"uint32"}],"name":"getActiveStakingProviders","outputs":[{"internalType":"uint256","name":"allAuthorizedTokens","type":"uint256"},{"internalType":"bytes32[]","name":"activeStakingProviders","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"getBeneficiary","outputs":[{"internalType":"address payable","name":"beneficiary","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingProvidersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint96","name":"_fromAmount","type":"uint96"},{"internalType":"uint96","name":"_toAmount","type":"uint96"}],"name":"involuntaryAuthorizationDecrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"isOperatorConfirmed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint64","name":"_commitmentDuration","type":"uint64"}],"name":"makeCommitment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"manualChildSynchronization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minOperatorSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumAuthorization","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"operatorToStakingProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"pendingAuthorizationDecrease","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"_reward","type":"uint96"}],"name":"pushReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"registerOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"remainingAuthorizationDecreaseDelay","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"resynchronizeAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint160","name":"","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint160","name":"","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRateDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adjudicator","type":"address"}],"name":"setAdjudicator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITACoRootToChild","name":"_childApplication","type":"address"}],"name":"setChildApplication","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardDistributor","type":"address"}],"name":"setRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"},{"internalType":"uint96","name":"_penalty","type":"uint96"},{"internalType":"address","name":"_investigator","type":"address"}],"name":"slash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingProviderInfo","outputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"operatorConfirmed","type":"bool"},{"internalType":"uint64","name":"operatorStartTimestamp","type":"uint64"},{"internalType":"uint96","name":"authorized","type":"uint96"},{"internalType":"uint96","name":"deauthorizing","type":"uint96"},{"internalType":"uint64","name":"endDeauthorization","type":"uint64"},{"internalType":"uint96","name":"tReward","type":"uint96"},{"internalType":"uint160","name":"rewardPerTokenPaid","type":"uint160"},{"internalType":"uint64","name":"endCommitment","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"stakingProviderToOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingProviders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tStaking","outputs":[{"internalType":"contract IStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingProvider","type":"address"}],"name":"withdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101e06040523480156200001257600080fd5b506040516200441e3803806200441e83398101604081905262000035916200049f565b6000886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000076573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009c9190620005e3565b90508415801590620001265750604051637004922d60e11b8152306004820181905260248201526001600160a01b0389169063e009245a90604401602060405180830381865afa158015620000f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200011b9190620005fd565b6001600160601b0316155b8015620001335750600081115b80156200014257506001835110155b80156200015157506004835111155b620001a35760405162461bcd60e51b815260206004820152601660248201527f57726f6e6720696e70757420706172616d65746572730000000000000000000060448201526064015b60405180910390fd5b6001600160a01b03620001c16103e8670de0b6b3a764000062000622565b620001ce600a846200064e565b620001da919062000622565b11158015620001fa5750670de0b6b3a7640000876001600160601b031610155b80156200020a5750620151808510155b6200024d5760405162461bcd60e51b8152602060048201526012602482015271506f74656e7469616c206f766572666c6f7760701b60448201526064016200019a565b60c085905260e08490526001600160601b0387166080526001600160a01b03808a166101c05288166101a05260a08690528251839060009062000294576200029462000671565b60209081029190910101516001600160401b031661010052825160021115620002bf576000620002de565b82600181518110620002d557620002d562000671565b60200260200101515b6001600160401b031661012052825160031115620002fe5760006200031d565b8260028151811062000314576200031462000671565b60200260200101515b6001600160401b0316610140528251600411156200033d5760006200035c565b8260038151811062000353576200035362000671565b60200260200101515b6001600160401b03908116610160528216610180526200037b6200038a565b50505050505050505062000687565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620003db5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146200043b5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6001600160a01b03811681146200043b57600080fd5b80516001600160601b03811681146200046c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516001600160401b03811681146200046c57600080fd5b600080600080600080600080610100898b031215620004bd57600080fd5b8851620004ca816200043e565b809850506020808a0151620004df816200043e565b9750620004ef60408b0162000454565b60608b015160808c015160a08d015160c08e0151939a50919850965094506001600160401b03808211156200052357600080fd5b818c0191508c601f8301126200053857600080fd5b8151818111156200054d576200054d62000471565b8060051b604051601f19603f8301168101818110858211171562000575576200057562000471565b60405291825284820192508381018501918f8311156200059457600080fd5b938501935b82851015620005bd57620005ad8562000487565b8452938501939285019262000599565b809750505050505050620005d460e08a0162000487565b90509295985092959890939650565b600060208284031215620005f657600080fd5b5051919050565b6000602082840312156200061057600080fd5b6200061b8262000454565b9392505050565b80820281158282048414176200064857634e487b7160e01b600052601160045260246000fd5b92915050565b6000826200066c57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c051613c5a620007c460003960008181610a58015281816116e10152611edf01526000818161096201528181610b2a015281816110c6015281816118a3015281816119230152818161203e015281816123d10152818161263001528181612b750152612fa70152600081816107b601526126ce015260008181610863015261280d0152600081816107f001526127d10152600081816105ae015261279501526000818161055c015261275a0152600081816106b90152818161075f0152611b96015260008181610a1e01528181611d8301528181611e010152611e6e0152600081816106130152610c9201526000818161068d015281816109e4015281816114ef01528181611a090152612c360152613c5a6000f3fe608060405234801561001057600080fd5b50600436106103835760003560e01c80638fa990e3116101de578063c9bacaad1161010f578063ebe2b12b116100ad578063f854a27f1161007c578063f854a27f14610a40578063fc0c546a14610a53578063fd2a478814610a7a578063fe9fbb8014610ab657600080fd5b8063ebe2b12b146109d6578063f0820c92146109df578063f2fde38b14610a06578063f520e7e514610a1957600080fd5b8063dbaa0fc6116100e9578063dbaa0fc61461095d578063ded56d4514610984578063df136d65146109b0578063ea0ffa4d146109c357600080fd5b8063c9bacaad14610928578063cd3daf9d1461093b578063d8dfde561461094357600080fd5b8063ab6ba2d01161017c578063bb42895111610156578063bb428951146108ab578063c4903d5b146108be578063c7c49c98146108f3578063c8f33c911461091f57600080fd5b8063ab6ba2d01461085e578063acc2166a14610885578063ba7e5b2b1461089857600080fd5b80639c9de028116101b85780639c9de028146108125780639cafa10314610825578063a1809b9514610838578063a48d2d411461084b57600080fd5b80638fa990e3146107b1578063967c4199146107d857806397b486e9146107eb57600080fd5b806353c2ed8e116102b85780637b14729e116102565780638129fc1c116102305780638129fc1c1461074a57806386f69014146107525780638d0853c11461075a5780638da5cb5b1461078157600080fd5b80637b14729e1461067f5780637dbee7a3146106ef57806380faa57d1461074257600080fd5b8063715018a611610292578063715018a614610648578063737616051461065057806375e0ae5a14610663578063796bb62b1461067657600080fd5b806353c2ed8e146105fb57806369bdf9e41461060e5780636a7f7a901461063557600080fd5b80633682a45011610325578063495a507a116102ff578063495a507a146105575780634bae3b32146105965780634cc20b11146105a9578063505a1b31146105d057600080fd5b80633682a450146105105780633875d1131461052357806342d866931461054457600080fd5b806314a854741161036157806314a85474146104a85780633032398f146104bb57806330fb5005146104d2578063334987ab146104fd57600080fd5b806302132c01146103885780630ceff8c81461039d578063104953bf14610495575b600080fd5b61039b610396366004613733565b610ac9565b005b6104266103ab36600461376c565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b038083169460ff600160a01b850416946001600160401b03600160a81b9095048516946001600160601b0380841695600160601b808604831696600160c01b9096048416959285169404909116911689565b604080516001600160a01b039a8b16815298151560208a01526001600160401b03978816908901526001600160601b039586166060890152938516608088015291851660a08701529290921660c0850152931660e0830152909116610100820152610120015b60405180910390f35b61039b6104a336600461376c565b611037565b61039b6104b636600461379e565b6110bb565b6104c46103e881565b60405190815260200161048c565b6104e56104e03660046137e9565b61126a565b6040516001600160601b03909116815260200161048c565b61039b61050b36600461376c565b6112f4565b61039b61051e36600461376c565b611395565b610536610531366004613815565b6113a2565b60405161048c92919061384c565b61039b61055236600461376c565b61159a565b61057e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b03909116815260200161048c565b61039b6105a436600461376c565b611711565b61057e7f000000000000000000000000000000000000000000000000000000000000000081565b6105e36105de36600461376c565b611881565b6040516001600160a01b03909116815260200161048c565b6001546105e3906001600160a01b031681565b6104c47f000000000000000000000000000000000000000000000000000000000000000081565b61039b61064336600461379e565b611918565b61039b611c3d565b61039b61065e36600461389c565b611c51565b61039b61067136600461376c565b611f14565b6104c460075481565b604080516001600160601b037f00000000000000000000000000000000000000000000000000000000000000001681526001600160401b037f000000000000000000000000000000000000000000000000000000000000000016602082018190529181019190915260600161048c565b6107326106fd36600461376c565b6001600160a01b039081166000908152600460209081526040808320549093168252600290522054600160a01b900460ff1690565b604051901515815260200161048c565b6104c46121a6565b61039b6121b9565b6003546104c4565b6104c47f000000000000000000000000000000000000000000000000000000000000000081565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03166105e3565b61057e7f000000000000000000000000000000000000000000000000000000000000000081565b6000546105e3906001600160a01b031681565b61057e7f000000000000000000000000000000000000000000000000000000000000000081565b61057e61082036600461376c565b6122c5565b6105e36108333660046138b9565b612312565b61039b61084636600461376c565b61233c565b61039b61085936600461376c565b61238e565b61057e7f000000000000000000000000000000000000000000000000000000000000000081565b6005546105e3906001600160a01b031681565b61039b6108a63660046138d2565b6125d8565b61039b6108b936600461376c565b612a06565b6104e56108cc36600461376c565b6001600160a01b03166000908152600260205260409020600101546001600160601b031690565b6105e361090136600461376c565b6001600160a01b039081166000908152600260205260409020541690565b6104c460085481565b61039b61093636600461379e565b612b6a565b6105e3612e51565b6009546104e590600160a01b90046001600160601b031681565b6105e37f000000000000000000000000000000000000000000000000000000000000000081565b6105e361099236600461376c565b6001600160a01b039081166000908152600460205260409020541690565b6009546105e3906001600160a01b031681565b61039b6109d136600461390c565b612ee8565b6104c460065481565b6104e57f000000000000000000000000000000000000000000000000000000000000000081565b61039b610a1436600461376c565b61301d565b6104c47f000000000000000000000000000000000000000000000000000000000000000081565b6104e5610a4e36600461376c565b613058565b6105e37f000000000000000000000000000000000000000000000000000000000000000081565b6104e5610a8836600461376c565b6001600160a01b0316600090815260026020526040902060010154600160601b90046001600160601b031690565b610732610ac436600461376c565b613127565b81610ad381613127565b610af85760405162461bcd60e51b8152600401610aef9061394c565b60405180910390fd5b6001600160a01b0381163314610bc657604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa158015610b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b97919061397b565b50909150506001600160a01b0381163314610bc45760405162461bcd60e51b8152600401610aef9061394c565b505b82610bd081613150565b6001600160a01b03808516600090815260026020526040902080549091908116908516819003610c685760405162461bcd60e51b815260206004820152603760248201527f537065636966696564206f70657261746f7220697320616c726561647920626f60448201527f6e646564207769746820746869732070726f76696465720000000000000000006064820152608401610aef565b6001600160a01b03811615610d50578154600160a01b900460ff161580610ccb57508154610cc7907f000000000000000000000000000000000000000000000000000000000000000090600160a81b90046001600160401b03166139d3565b4210155b610d295760405162461bcd60e51b815260206004820152602960248201527f4e6f7420656e6f7567682074696d652070617373656420746f206368616e67656044820152681037b832b930ba37b960b91b6064820152608401610aef565b6001600160a01b038116600090815260046020526040902080546001600160a01b03191690555b6001600160a01b03851615610e7f576001600160a01b038581166000908152600460205260409020541615610dd35760405162461bcd60e51b8152602060048201526024808201527f537065636966696564206f70657261746f7220697320616c726561647920696e6044820152632075736560e01b6064820152608401610aef565b856001600160a01b0316856001600160a01b03161480610e0457506000610df986611881565b6001600160a01b0316145b610e505760405162461bcd60e51b815260206004820181905260248201527f537065636966696564206f70657261746f7220697320612070726f76696465726044820152606401610aef565b6001600160a01b03858116600090815260046020526040902080546001600160a01b0319169188169190911790555b8154600160a81b90046001600160401b0316600003610ee457600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0388161790555b8154600160a01b900460ff1615610f45576001820154600980546001600160601b0392831692601491610f20918591600160a01b9004166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b81546001600160a01b03868116600168ffffffffffffffff0160a01b03199092168217600160a81b426001600160401b0381169190910291909117855560405190815283821692918916907fa38fda88cb3c476adfa74c64be4d74c915b19a3e587e77b887ca804fb9c82c7c9060200160405180910390a4815460ff60a01b191682556000546040516346696b9f60e11b81526001600160a01b038881166004830152878116602483015290911690638cd2d73e90604401600060405180830381600087803b15801561101757600080fd5b505af115801561102b573d6000803e3d6000fd5b50505050505050505050565b61103f6131ef565b6000816001600160a01b03163b116110995760405162461bcd60e51b815260206004820152601a60248201527f4368696c6420617070206d75737420626520636f6e74726163740000000000006044820152606401610aef565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111035760405162461bcd60e51b8152600401610aef90613a0d565b8261110d81613150565b6001600160a01b03841660009081526002602052604090208054600160a01b900460ff161561119157611140818561324a565b61114a83856139e6565b6009805460149061116c908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821792839055600160601b90920490911611156111ed57600181018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b604080516001600160601b038087168252851660208201526001600160a01b038716917f72cc05b0073888d0e26528638b21fdaa2d4af96a641469fe63a87de3c4a84d79910160405180910390a260018101546001600160601b031660000361125957611259856132c4565b611263858261335e565b5050505050565b6001600160a01b038216600090815260026020526040812060018101546001600160601b03811690600160c01b90046001600160401b0316158015906112c357506001820154600160c01b90046001600160401b031684115b156112ea5760018201546112e790600160601b90046001600160601b0316826139e6565b90505b9150505b92915050565b6112fc6131ef565b6001546001600160a01b03908116908216036113735760405162461bcd60e51b815260206004820152603060248201527f4e65772061646472657373206d757374206e6f7420626520657175616c20746f60448201526f207468652063757272656e74206f6e6560801b6064820152608401610aef565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61139f3382610ac9565b50565b6003546000906060908086106113ee5760405162461bcd60e51b81526020600482015260116024820152700aee4dedcce40e6e8c2e4e840d2dcc8caf607b1b6044820152606401610aef565b841580159061140557508061140386886139d3565b105b156114175761141485876139d3565b90505b6114218682613a52565b6001600160401b0381111561143857611438613a65565b604051908082528060200260200182016040528015611461578160200160208202803683370190505b506000935091508263ffffffff85161561148a5761148563ffffffff8616426139d3565b61148e565b6000195b90506000875b8381101561158b576000600382815481106114b1576114b1613a7b565b60009182526020808320909101546001600160a01b0316808352600290915260408220909250906114e2838761126a565b6001600160601b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160601b031681108061152d57508154600160a01b900460ff16155b1561153a57505050611583565b6001600160601b0319606084901b168117888661155681613a91565b97508151811061156857611568613a7b565b602090810291909101015261157d818a6139d3565b98505050505b600101611494565b50808452505050935093915050565b806115a481613150565b60006115af83611881565b9050336001600160a01b038216146116095760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206d7573742062652062656e65666963696172790000000000006044820152606401610aef565b6001600160a01b0383166000908152600260208190526040909120908101546001600160601b0316806116765760405162461bcd60e51b81526020600482015260156024820152744e6f2072657761726420746f20776974686472617760581b6044820152606401610aef565b6002820180546001600160601b03191690556040516001600160601b03821681526001600160a01b0384811691908716907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a36112636001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846001600160601b0384166133c7565b6000546001600160a01b031633146117865760405162461bcd60e51b815260206004820152603260248201527f4f6e6c79206368696c64206170706c69636174696f6e20616c6c6f7765642074604482015271379031b7b73334b9369037b832b930ba37b960711b6064820152608401610aef565b6001600160a01b0380821660009081526004602052604090205416806117aa575050565b6001600160a01b03811660009081526002602052604090208054600160a01b900460ff1661187c576117db82613150565b805460ff60a01b1916600160a01b90811782556001820154600980546001600160601b0392831693919260149261181792869291900416613aaa565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550826001600160a01b0316826001600160a01b03167fdbc602361eaa7fb503df3c16078c71b39d28412df5e9980bec6f489f78bb175c60405160405180910390a35b505050565b604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa1580156118ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611910919061397b565b509392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146119605760405162461bcd60e51b8152600401610aef90613a0d565b8261196a81613150565b6001600160a01b038416600090815260026020526040902060018101546001600160601b0390811690841611156119f65760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e7420746f2064656372656173652067726561746572207468616e20604482015269185d5d1a1bdc9a5e995960b21b6064820152608401610aef565b6001600160601b0383161580611a3e57507f00000000000000000000000000000000000000000000000000000000000000006001600160601b0316836001600160601b031610155b611aa45760405162461bcd60e51b815260206004820152603160248201527f526573756c74696e6720617574686f72697a6174696f6e2077696c6c206265206044820152706c657373207468616e206d696e696d756d60781b6064820152608401610aef565b6003810154426001600160401b039091161115611b225760405162461bcd60e51b815260206004820152603660248201527f43616e27742072657175657374206465617574686f72697a6174696f6e206265604482015275199bdc9948195b99081bd98818dbdb5b5a5d1b595b9d60521b6064820152608401610aef565b8054600160a01b900460ff1615611b3d57611b3d818561324a565b6001810180546001600160601b0319166001600160601b038616179055611b6483856139e6565b6001820180546001600160601b0392909216600160601b02600160601b600160c01b0319909216919091179055611bbb7f0000000000000000000000000000000000000000000000000000000000000000426139d3565b6001820180546001600160401b0392909216600160c01b026001600160c01b03909216919091179055604080516001600160601b038087168252851660208201526001600160a01b038716917f38b892bbec4f2d2e5372217fea7a4784417ae853489cd584b204f534b5c08f9591015b60405180910390a2611263858261335e565b611c456131ef565b611c4f6000613426565b565b6000611c5c81613150565b6005546001600160a01b03163314611cc05760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79206469737472696275746f722063616e2070757368207265776172646044820152607360f81b6064820152608401610aef565b6000826001600160601b031611611d195760405162461bcd60e51b815260206004820152601860248201527f526577617264206d7573742062652073706563696669656400000000000000006044820152606401610aef565b600954600160a01b90046001600160601b0316611d785760405162461bcd60e51b815260206004820152601b60248201527f4e6f20616374697665207374616b696e672070726f76696465727300000000006044820152606401610aef565b6006544210611ddb577f0000000000000000000000000000000000000000000000000000000000000000611db66103e8670de0b6b3a7640000613aca565b611dc9906001600160601b038516613aca565b611dd39190613ae1565b600755611e62565b600042600654611deb9190613a52565b9050600060075482611dfd9190613aca565b90507f000000000000000000000000000000000000000000000000000000000000000081611e356103e8670de0b6b3a7640000613aca565b611e48906001600160601b038816613aca565b611e5291906139d3565b611e5c9190613ae1565b60075550505b426008819055611e93907f0000000000000000000000000000000000000000000000000000000000000000906139d3565b6006556040516001600160601b03831681527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1611f106001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633306001600160601b038616613497565b5050565b80611f1e81613150565b6001600160a01b03821660009081526002602052604090206001810154600160601b90046001600160601b0316611fa35760405162461bcd60e51b8152602060048201526024808201527f5468657265206973206e6f206465617574686f72697a696e6720696e2070726f6044820152636365737360e01b6064820152608401610aef565b600181015442600160c01b9091046001600160401b0316111561201c5760405162461bcd60e51b815260206004820152602b60248201527f417574686f72697a6174696f6e20646563726561736520686173206e6f74206660448201526a1a5b9a5cda1959081e595d60aa1b6064820152608401610aef565b604051633af0572d60e11b81526001600160a01b0384811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906375e0ae5a906024016020604051808303816000875af1158015612089573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ad9190613b03565b8254909150600160a01b900460ff16156121215760018201546120da9082906001600160601b03166139e6565b600980546014906120fc908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5879576c6c99ad6d1778483480ffa393a0f7b8ac18d53402720d8dd8e4617f7d910160405180910390a26001600160601b0381166001830181905560000361219657612196846132c4565b6121a0848361335e565b50505050565b60006121b4426006546134d0565b905090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156121fe5750825b90506000826001600160401b0316600114801561221a5750303b155b905081158015612228575080155b156122465760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561227057845460ff60401b1916600160401b1785555b612279336134e6565b831561126357845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038116600090815260026020526040812060010154600160c01b90046001600160401b03164281116123015750600092915050565b61230b4282613a52565b9392505050565b6003818154811061232257600080fd5b6000918252602090912001546001600160a01b0316905081565b6123446131ef565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f075c02c513a415bd4ff5976f8aa6fc5767d2183daca9ec00ab71ce78e8bf815890600090a250565b8061239881613150565b6001600160a01b038281166000818152600260205260408082209051637004922d60e11b815260048101939093523060248401529290917f00000000000000000000000000000000000000000000000000000000000000009091169063e009245a90604401602060405180830381865afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e9190613b03565b60018301549091506001600160601b038083169116116124995760405162461bcd60e51b81526020600482015260166024820152754e6f7468696e6720746f2073796e6368726f6e697a6560501b6044820152606401610aef565b8154600160a01b900460ff161561250a5760018201546124c39082906001600160601b03166139e6565b600980546014906124e5908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5e26a115e9efdff9c71141dec1f9cc5dd2ec5e717da782cef55a475506e56788910160405180910390a26001820180546001600160601b0319166001600160601b0383811691821792839055600160601b90920490911611156125ba57600182018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b60018201546001600160601b031660000361219657612196846132c4565b816125e281613127565b6125fe5760405162461bcd60e51b8152600401610aef9061394c565b6001600160a01b03811633146126cc57604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa158015612679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269d919061397b565b50909150506001600160a01b03811633146126ca5760405162461bcd60e51b8152600401610aef9061394c565b505b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b031642106127445760405162461bcd60e51b815260206004820152601860248201527f436f6d6d69746d656e742077696e646f7720636c6f73656400000000000000006044820152606401610aef565b6000826001600160401b031611801561284157507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b031614806127c957507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b8061280557507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b8061284157507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b6128a95760405162461bcd60e51b815260206004820152603360248201527f436f6d6d69746d656e74206475726174696f6e206d75737420626520657175616044820152726c20746f206f6e65206f66206f7074696f6e7360681b6064820152608401610aef565b6001600160a01b03831660009081526002602052604090206001810154600160c01b90046001600160401b03161561293b5760405162461bcd60e51b815260206004820152602f60248201527f436f6d6d69746d656e742063616e2774206265206d61646520647572696e672060448201526e3232b0baba3437b934bd30ba34b7b760891b6064820152608401610aef565b60038101546001600160401b0316156129965760405162461bcd60e51b815260206004820152601760248201527f436f6d6d69746d656e7420616c7265616479206d6164650000000000000000006044820152606401610aef565b6129a08342613b20565b60038201805467ffffffffffffffff19166001600160401b039290921691821790556040519081526001600160a01b038516907f293c61c79ecf0bcac67f97a5925ba2e75c025c6231a4ab629862b570730a264b9060200160405180910390a250505050565b6001600160a01b038116612a675760405162461bcd60e51b815260206004820152602260248201527f5374616b696e672070726f7669646572206d7573742062652073706563696669604482015261195960f21b6064820152608401610aef565b6001600160a01b038181166000818152600260209081526040918290206001810154815484516001600160601b038084168252600160601b84041694810194909452600160c01b9091046001600160401b031683850152909416606082015290517fcdc04e3c6e3b10c218c3f6c8b4471a698e140d3a7544169e2162ff71488b4031916080908290030190a2612afd828261335e565b60005481546040516346696b9f60e11b81526001600160a01b0385811660048301529182166024820152911690638cd2d73e906044015b600060405180830381600087803b158015612b4e57600080fd5b505af1158015612b62573d6000803e3d6000fd5b505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612bb25760405162461bcd60e51b8152600401610aef90613a0d565b82612bbc81613150565b6001600160a01b03841615801590612bdd57506000826001600160601b0316115b612c345760405162461bcd60e51b815260206004820152602260248201527f496e70757420706172616d6574657273206d7573742062652073706563696669604482015261195960f21b6064820152608401610aef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160601b0316826001600160601b03161015612cc95760405162461bcd60e51b815260206004820152602a60248201527f417574686f72697a6174696f6e206d7573742062652067726561746572207468604482015269616e206d696e696d756d60b01b6064820152608401610aef565b6001600160a01b0380851660009081526002602090815260408083206004909252909120549091161580612d1757506001600160a01b03808616600081815260046020526040902054909116145b612d805760405162461bcd60e51b815260206004820152603460248201527f412070726f76696465722063616e277420626520616e206f70657261746f72206044820152733337b91030b737ba3432b910383937bb34b232b960611b6064820152608401610aef565b8054600160a01b900460ff1615612dec57612d9b818561324a565b612da584846139e6565b60098054601490612dc7908490600160a01b90046001600160601b0316613aaa565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821790925560408051928716835260208301919091526001600160a01b038716917f9e46043a7120cf056d21eda9b6d78ffd99571a62fb6ff91a471a73e4b8484e1c9101611c2b565b600954600090600160a01b90046001600160601b03168103612e7d57506009546001600160a01b031690565b600954600754600854600092600160a01b90046001600160601b03169190612ea36121a6565b612ead9190613a52565b612eb79190613aca565b612ec19190613ae1565b600954612ed791906001600160a01b03166139d3565b9050612ee2816134f7565b91505090565b6001546001600160a01b03163314612f4c5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646a7564696361746f7220616c6c6f77656420746f20736c61736044820152600d60fb1b6064820152608401610aef565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110612f8257612f82613a7b565b6001600160a01b0392831660209182029290920101526040516383ddba8f60e01b81527f0000000000000000000000000000000000000000000000000000000000000000909116906383ddba8f90612fe590869060649087908790600401613b40565b600060405180830381600087803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b5050505050505050565b6130256131ef565b6001600160a01b03811661304f57604051631e4fbdf760e01b815260006004820152602401610aef565b61139f81613426565b6001600160a01b03811660009081526002602052604081208054600160a01b900460ff1661309357600201546001600160601b031692915050565b60028101546000906001600160601b03166130b86103e8670de0b6b3a7640000613aca565b6002840154600160601b90046001600160a01b03166130d5612e51565b6130df9190613bb3565b6001850154613100916001600160a01b0316906001600160601b0316613aca565b61310a9190613ae1565b61311491906139d3565b905061311f8161352f565b949350505050565b6001600160a01b03166000908152600260205260409020600101546001600160601b0316151590565b613158612e51565b600980546001600160a01b0319166001600160a01b03929092169190911790556131806121a6565b6008556001600160a01b0381161561139f576001600160a01b03811660009081526002602052604090206131b382613058565b60029190910180546001600160601b0319166001600160601b0390921691821781556009546001600160a01b0316600160601b02909117905550565b336132217f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614611c4f5760405163118cdaa760e01b8152336004820152602401610aef565b60018201546001600160601b03828116911614611f1057600182015461327a9082906001600160601b03166139e6565b6009805460149061329c908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6001600160a01b03818116600081815260026020908152604080832080548616845260049283905281842080546001600160a01b031916905580546001600160a81b03191681556001810180546001600160c01b0316905560038101805467ffffffffffffffff19169055835491516346696b9f60e11b815292830194909452602482019290925291921690638cd2d73e90604401612b34565b600054600182015460405163248b36bf60e21b81526001600160a01b0385811660048301526001600160601b038084166024840152600160601b8404166044830152600160c01b9092046001600160401b0316606482015291169063922cdafc90608401612b34565b6040516001600160a01b0383811660248301526044820183905261187c91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613563565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526121a09186918216906323b872dd906084016133f4565b60008183106134df578161230b565b5090919050565b6134ee6135c6565b61139f8161360f565b60006001600160a01b0382111561352b576040516306dfcc6560e41b815260a0600482015260248101839052604401610aef565b5090565b60006001600160601b0382111561352b576040516306dfcc6560e41b81526060600482015260248101839052604401610aef565b60006135786001600160a01b03841683613617565b9050805160001415801561359d57508080602001905181019061359b9190613bd3565b155b1561187c57604051635274afe760e01b81526001600160a01b0384166004820152602401610aef565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611c4f57604051631afcd79f60e31b815260040160405180910390fd5b6130256135c6565b606061230b8383600084600080856001600160a01b0316848660405161363d9190613bf5565b60006040518083038185875af1925050503d806000811461367a576040519150601f19603f3d011682016040523d82523d6000602084013e61367f565b606091505b509150915061368f868383613699565b9695505050505050565b6060826136ae576136a9826136f5565b61230b565b81511580156136c557506001600160a01b0384163b155b156136ee57604051639996b31560e01b81526001600160a01b0385166004820152602401610aef565b508061230b565b8051156137055780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b038116811461139f57600080fd5b6000806040838503121561374657600080fd5b82356137518161371e565b915060208301356137618161371e565b809150509250929050565b60006020828403121561377e57600080fd5b813561230b8161371e565b6001600160601b038116811461139f57600080fd5b6000806000606084860312156137b357600080fd5b83356137be8161371e565b925060208401356137ce81613789565b915060408401356137de81613789565b809150509250925092565b600080604083850312156137fc57600080fd5b82356138078161371e565b946020939093013593505050565b60008060006060848603121561382a57600080fd5b8335925060208401359150604084013563ffffffff811681146137de57600080fd5b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561388f57845183529383019391830191600101613873565b5090979650505050505050565b6000602082840312156138ae57600080fd5b813561230b81613789565b6000602082840312156138cb57600080fd5b5035919050565b600080604083850312156138e557600080fd5b82356138f08161371e565b915060208301356001600160401b038116811461376157600080fd5b60008060006060848603121561392157600080fd5b833561392c8161371e565b9250602084013561393c81613789565b915060408401356137de8161371e565b6020808252601590820152742737ba1037bbb732b91037b910383937bb34b232b960591b604082015260600190565b60008060006060848603121561399057600080fd5b835161399b8161371e565b60208501519093506139ac8161371e565b60408501519092506137de8161371e565b634e487b7160e01b600052601160045260246000fd5b808201808211156112ee576112ee6139bd565b6001600160601b03828116828216039080821115613a0657613a066139bd565b5092915050565b60208082526025908201527f43616c6c6572206d757374206265207468652054207374616b696e6720636f6e6040820152641d1c9858dd60da1b606082015260800190565b818103818111156112ee576112ee6139bd565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201613aa357613aa36139bd565b5060010190565b6001600160601b03818116838216019080821115613a0657613a066139bd565b80820281158282048414176112ee576112ee6139bd565b600082613afe57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613b1557600080fd5b815161230b81613789565b6001600160401b03818116838216019080821115613a0657613a066139bd565b6001600160601b038516815260208082018590526001600160a01b038481166040840152608060608401819052845190840181905260009285810192909160a0860190855b81811015613ba3578551841683529484019491840191600101613b85565b50909a9950505050505050505050565b6001600160a01b03828116828216039080821115613a0657613a066139bd565b600060208284031215613be557600080fd5b8151801515811461230b57600080fd5b6000825160005b81811015613c165760208186018101518583015201613bfc565b50600092019182525091905056fea264697066735822122054c1baa24cdc63ac1ba9c8a897ef2e9c3550525c49b7bced055e14c270551b8264736f6c63430008170033000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee500000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7000000000000000000000000000000000000000000000878678326eac9000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000002819a00000000000000000000000000000000000000000000000000000000000eff10000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000065a5c6ff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000077f8800000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000001dfe2000000000000000000000000000000000000000000000000000000000002cfd300
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103835760003560e01c80638fa990e3116101de578063c9bacaad1161010f578063ebe2b12b116100ad578063f854a27f1161007c578063f854a27f14610a40578063fc0c546a14610a53578063fd2a478814610a7a578063fe9fbb8014610ab657600080fd5b8063ebe2b12b146109d6578063f0820c92146109df578063f2fde38b14610a06578063f520e7e514610a1957600080fd5b8063dbaa0fc6116100e9578063dbaa0fc61461095d578063ded56d4514610984578063df136d65146109b0578063ea0ffa4d146109c357600080fd5b8063c9bacaad14610928578063cd3daf9d1461093b578063d8dfde561461094357600080fd5b8063ab6ba2d01161017c578063bb42895111610156578063bb428951146108ab578063c4903d5b146108be578063c7c49c98146108f3578063c8f33c911461091f57600080fd5b8063ab6ba2d01461085e578063acc2166a14610885578063ba7e5b2b1461089857600080fd5b80639c9de028116101b85780639c9de028146108125780639cafa10314610825578063a1809b9514610838578063a48d2d411461084b57600080fd5b80638fa990e3146107b1578063967c4199146107d857806397b486e9146107eb57600080fd5b806353c2ed8e116102b85780637b14729e116102565780638129fc1c116102305780638129fc1c1461074a57806386f69014146107525780638d0853c11461075a5780638da5cb5b1461078157600080fd5b80637b14729e1461067f5780637dbee7a3146106ef57806380faa57d1461074257600080fd5b8063715018a611610292578063715018a614610648578063737616051461065057806375e0ae5a14610663578063796bb62b1461067657600080fd5b806353c2ed8e146105fb57806369bdf9e41461060e5780636a7f7a901461063557600080fd5b80633682a45011610325578063495a507a116102ff578063495a507a146105575780634bae3b32146105965780634cc20b11146105a9578063505a1b31146105d057600080fd5b80633682a450146105105780633875d1131461052357806342d866931461054457600080fd5b806314a854741161036157806314a85474146104a85780633032398f146104bb57806330fb5005146104d2578063334987ab146104fd57600080fd5b806302132c01146103885780630ceff8c81461039d578063104953bf14610495575b600080fd5b61039b610396366004613733565b610ac9565b005b6104266103ab36600461376c565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b038083169460ff600160a01b850416946001600160401b03600160a81b9095048516946001600160601b0380841695600160601b808604831696600160c01b9096048416959285169404909116911689565b604080516001600160a01b039a8b16815298151560208a01526001600160401b03978816908901526001600160601b039586166060890152938516608088015291851660a08701529290921660c0850152931660e0830152909116610100820152610120015b60405180910390f35b61039b6104a336600461376c565b611037565b61039b6104b636600461379e565b6110bb565b6104c46103e881565b60405190815260200161048c565b6104e56104e03660046137e9565b61126a565b6040516001600160601b03909116815260200161048c565b61039b61050b36600461376c565b6112f4565b61039b61051e36600461376c565b611395565b610536610531366004613815565b6113a2565b60405161048c92919061384c565b61039b61055236600461376c565b61159a565b61057e7f000000000000000000000000000000000000000000000000000000000077f88081565b6040516001600160401b03909116815260200161048c565b61039b6105a436600461376c565b611711565b61057e7f0000000000000000000000000000000000000000000000000000000000eff10081565b6105e36105de36600461376c565b611881565b6040516001600160a01b03909116815260200161048c565b6001546105e3906001600160a01b031681565b6104c47f000000000000000000000000000000000000000000000000000000000001518081565b61039b61064336600461379e565b611918565b61039b611c3d565b61039b61065e36600461389c565b611c51565b61039b61067136600461376c565b611f14565b6104c460075481565b604080516001600160601b037f000000000000000000000000000000000000000000000878678326eac90000001681526001600160401b037f0000000000000000000000000000000000000000000000000000000000eff10016602082018190529181019190915260600161048c565b6107326106fd36600461376c565b6001600160a01b039081166000908152600460209081526040808320549093168252600290522054600160a01b900460ff1690565b604051901515815260200161048c565b6104c46121a6565b61039b6121b9565b6003546104c4565b6104c47f0000000000000000000000000000000000000000000000000000000000eff10081565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03166105e3565b61057e7f0000000000000000000000000000000000000000000000000000000065a5c6ff81565b6000546105e3906001600160a01b031681565b61057e7f0000000000000000000000000000000000000000000000000000000001dfe20081565b61057e61082036600461376c565b6122c5565b6105e36108333660046138b9565b612312565b61039b61084636600461376c565b61233c565b61039b61085936600461376c565b61238e565b61057e7f0000000000000000000000000000000000000000000000000000000002cfd30081565b6005546105e3906001600160a01b031681565b61039b6108a63660046138d2565b6125d8565b61039b6108b936600461376c565b612a06565b6104e56108cc36600461376c565b6001600160a01b03166000908152600260205260409020600101546001600160601b031690565b6105e361090136600461376c565b6001600160a01b039081166000908152600260205260409020541690565b6104c460085481565b61039b61093636600461379e565b612b6a565b6105e3612e51565b6009546104e590600160a01b90046001600160601b031681565b6105e37f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd781565b6105e361099236600461376c565b6001600160a01b039081166000908152600460205260409020541690565b6009546105e3906001600160a01b031681565b61039b6109d136600461390c565b612ee8565b6104c460065481565b6104e57f000000000000000000000000000000000000000000000878678326eac900000081565b61039b610a1436600461376c565b61301d565b6104c47f00000000000000000000000000000000000000000000000000000000002819a081565b6104e5610a4e36600461376c565b613058565b6105e37f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee581565b6104e5610a8836600461376c565b6001600160a01b0316600090815260026020526040902060010154600160601b90046001600160601b031690565b610732610ac436600461376c565b613127565b81610ad381613127565b610af85760405162461bcd60e51b8152600401610aef9061394c565b60405180910390fd5b6001600160a01b0381163314610bc657604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa158015610b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b97919061397b565b50909150506001600160a01b0381163314610bc45760405162461bcd60e51b8152600401610aef9061394c565b505b82610bd081613150565b6001600160a01b03808516600090815260026020526040902080549091908116908516819003610c685760405162461bcd60e51b815260206004820152603760248201527f537065636966696564206f70657261746f7220697320616c726561647920626f60448201527f6e646564207769746820746869732070726f76696465720000000000000000006064820152608401610aef565b6001600160a01b03811615610d50578154600160a01b900460ff161580610ccb57508154610cc7907f000000000000000000000000000000000000000000000000000000000001518090600160a81b90046001600160401b03166139d3565b4210155b610d295760405162461bcd60e51b815260206004820152602960248201527f4e6f7420656e6f7567682074696d652070617373656420746f206368616e67656044820152681037b832b930ba37b960b91b6064820152608401610aef565b6001600160a01b038116600090815260046020526040902080546001600160a01b03191690555b6001600160a01b03851615610e7f576001600160a01b038581166000908152600460205260409020541615610dd35760405162461bcd60e51b8152602060048201526024808201527f537065636966696564206f70657261746f7220697320616c726561647920696e6044820152632075736560e01b6064820152608401610aef565b856001600160a01b0316856001600160a01b03161480610e0457506000610df986611881565b6001600160a01b0316145b610e505760405162461bcd60e51b815260206004820181905260248201527f537065636966696564206f70657261746f7220697320612070726f76696465726044820152606401610aef565b6001600160a01b03858116600090815260046020526040902080546001600160a01b0319169188169190911790555b8154600160a81b90046001600160401b0316600003610ee457600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0388161790555b8154600160a01b900460ff1615610f45576001820154600980546001600160601b0392831692601491610f20918591600160a01b9004166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b81546001600160a01b03868116600168ffffffffffffffff0160a01b03199092168217600160a81b426001600160401b0381169190910291909117855560405190815283821692918916907fa38fda88cb3c476adfa74c64be4d74c915b19a3e587e77b887ca804fb9c82c7c9060200160405180910390a4815460ff60a01b191682556000546040516346696b9f60e11b81526001600160a01b038881166004830152878116602483015290911690638cd2d73e90604401600060405180830381600087803b15801561101757600080fd5b505af115801561102b573d6000803e3d6000fd5b50505050505050505050565b61103f6131ef565b6000816001600160a01b03163b116110995760405162461bcd60e51b815260206004820152601a60248201527f4368696c6420617070206d75737420626520636f6e74726163740000000000006044820152606401610aef565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd716146111035760405162461bcd60e51b8152600401610aef90613a0d565b8261110d81613150565b6001600160a01b03841660009081526002602052604090208054600160a01b900460ff161561119157611140818561324a565b61114a83856139e6565b6009805460149061116c908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821792839055600160601b90920490911611156111ed57600181018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b604080516001600160601b038087168252851660208201526001600160a01b038716917f72cc05b0073888d0e26528638b21fdaa2d4af96a641469fe63a87de3c4a84d79910160405180910390a260018101546001600160601b031660000361125957611259856132c4565b611263858261335e565b5050505050565b6001600160a01b038216600090815260026020526040812060018101546001600160601b03811690600160c01b90046001600160401b0316158015906112c357506001820154600160c01b90046001600160401b031684115b156112ea5760018201546112e790600160601b90046001600160601b0316826139e6565b90505b9150505b92915050565b6112fc6131ef565b6001546001600160a01b03908116908216036113735760405162461bcd60e51b815260206004820152603060248201527f4e65772061646472657373206d757374206e6f7420626520657175616c20746f60448201526f207468652063757272656e74206f6e6560801b6064820152608401610aef565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61139f3382610ac9565b50565b6003546000906060908086106113ee5760405162461bcd60e51b81526020600482015260116024820152700aee4dedcce40e6e8c2e4e840d2dcc8caf607b1b6044820152606401610aef565b841580159061140557508061140386886139d3565b105b156114175761141485876139d3565b90505b6114218682613a52565b6001600160401b0381111561143857611438613a65565b604051908082528060200260200182016040528015611461578160200160208202803683370190505b506000935091508263ffffffff85161561148a5761148563ffffffff8616426139d3565b61148e565b6000195b90506000875b8381101561158b576000600382815481106114b1576114b1613a7b565b60009182526020808320909101546001600160a01b0316808352600290915260408220909250906114e2838761126a565b6001600160601b031690507f000000000000000000000000000000000000000000000878678326eac90000006001600160601b031681108061152d57508154600160a01b900460ff16155b1561153a57505050611583565b6001600160601b0319606084901b168117888661155681613a91565b97508151811061156857611568613a7b565b602090810291909101015261157d818a6139d3565b98505050505b600101611494565b50808452505050935093915050565b806115a481613150565b60006115af83611881565b9050336001600160a01b038216146116095760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206d7573742062652062656e65666963696172790000000000006044820152606401610aef565b6001600160a01b0383166000908152600260208190526040909120908101546001600160601b0316806116765760405162461bcd60e51b81526020600482015260156024820152744e6f2072657761726420746f20776974686472617760581b6044820152606401610aef565b6002820180546001600160601b03191690556040516001600160601b03821681526001600160a01b0384811691908716907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a36112636001600160a01b037f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee516846001600160601b0384166133c7565b6000546001600160a01b031633146117865760405162461bcd60e51b815260206004820152603260248201527f4f6e6c79206368696c64206170706c69636174696f6e20616c6c6f7765642074604482015271379031b7b73334b9369037b832b930ba37b960711b6064820152608401610aef565b6001600160a01b0380821660009081526004602052604090205416806117aa575050565b6001600160a01b03811660009081526002602052604090208054600160a01b900460ff1661187c576117db82613150565b805460ff60a01b1916600160a01b90811782556001820154600980546001600160601b0392831693919260149261181792869291900416613aaa565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550826001600160a01b0316826001600160a01b03167fdbc602361eaa7fb503df3c16078c71b39d28412df5e9980bec6f489f78bb175c60405160405180910390a35b505050565b604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa1580156118ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611910919061397b565b509392505050565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd716146119605760405162461bcd60e51b8152600401610aef90613a0d565b8261196a81613150565b6001600160a01b038416600090815260026020526040902060018101546001600160601b0390811690841611156119f65760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e7420746f2064656372656173652067726561746572207468616e20604482015269185d5d1a1bdc9a5e995960b21b6064820152608401610aef565b6001600160601b0383161580611a3e57507f000000000000000000000000000000000000000000000878678326eac90000006001600160601b0316836001600160601b031610155b611aa45760405162461bcd60e51b815260206004820152603160248201527f526573756c74696e6720617574686f72697a6174696f6e2077696c6c206265206044820152706c657373207468616e206d696e696d756d60781b6064820152608401610aef565b6003810154426001600160401b039091161115611b225760405162461bcd60e51b815260206004820152603660248201527f43616e27742072657175657374206465617574686f72697a6174696f6e206265604482015275199bdc9948195b99081bd98818dbdb5b5a5d1b595b9d60521b6064820152608401610aef565b8054600160a01b900460ff1615611b3d57611b3d818561324a565b6001810180546001600160601b0319166001600160601b038616179055611b6483856139e6565b6001820180546001600160601b0392909216600160601b02600160601b600160c01b0319909216919091179055611bbb7f0000000000000000000000000000000000000000000000000000000000eff100426139d3565b6001820180546001600160401b0392909216600160c01b026001600160c01b03909216919091179055604080516001600160601b038087168252851660208201526001600160a01b038716917f38b892bbec4f2d2e5372217fea7a4784417ae853489cd584b204f534b5c08f9591015b60405180910390a2611263858261335e565b611c456131ef565b611c4f6000613426565b565b6000611c5c81613150565b6005546001600160a01b03163314611cc05760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79206469737472696275746f722063616e2070757368207265776172646044820152607360f81b6064820152608401610aef565b6000826001600160601b031611611d195760405162461bcd60e51b815260206004820152601860248201527f526577617264206d7573742062652073706563696669656400000000000000006044820152606401610aef565b600954600160a01b90046001600160601b0316611d785760405162461bcd60e51b815260206004820152601b60248201527f4e6f20616374697665207374616b696e672070726f76696465727300000000006044820152606401610aef565b6006544210611ddb577f00000000000000000000000000000000000000000000000000000000002819a0611db66103e8670de0b6b3a7640000613aca565b611dc9906001600160601b038516613aca565b611dd39190613ae1565b600755611e62565b600042600654611deb9190613a52565b9050600060075482611dfd9190613aca565b90507f00000000000000000000000000000000000000000000000000000000002819a081611e356103e8670de0b6b3a7640000613aca565b611e48906001600160601b038816613aca565b611e5291906139d3565b611e5c9190613ae1565b60075550505b426008819055611e93907f00000000000000000000000000000000000000000000000000000000002819a0906139d3565b6006556040516001600160601b03831681527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1611f106001600160a01b037f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee51633306001600160601b038616613497565b5050565b80611f1e81613150565b6001600160a01b03821660009081526002602052604090206001810154600160601b90046001600160601b0316611fa35760405162461bcd60e51b8152602060048201526024808201527f5468657265206973206e6f206465617574686f72697a696e6720696e2070726f6044820152636365737360e01b6064820152608401610aef565b600181015442600160c01b9091046001600160401b0316111561201c5760405162461bcd60e51b815260206004820152602b60248201527f417574686f72697a6174696f6e20646563726561736520686173206e6f74206660448201526a1a5b9a5cda1959081e595d60aa1b6064820152608401610aef565b604051633af0572d60e11b81526001600160a01b0384811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7909116906375e0ae5a906024016020604051808303816000875af1158015612089573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ad9190613b03565b8254909150600160a01b900460ff16156121215760018201546120da9082906001600160601b03166139e6565b600980546014906120fc908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5879576c6c99ad6d1778483480ffa393a0f7b8ac18d53402720d8dd8e4617f7d910160405180910390a26001600160601b0381166001830181905560000361219657612196846132c4565b6121a0848361335e565b50505050565b60006121b4426006546134d0565b905090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156121fe5750825b90506000826001600160401b0316600114801561221a5750303b155b905081158015612228575080155b156122465760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561227057845460ff60401b1916600160401b1785555b612279336134e6565b831561126357845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038116600090815260026020526040812060010154600160c01b90046001600160401b03164281116123015750600092915050565b61230b4282613a52565b9392505050565b6003818154811061232257600080fd5b6000918252602090912001546001600160a01b0316905081565b6123446131ef565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f075c02c513a415bd4ff5976f8aa6fc5767d2183daca9ec00ab71ce78e8bf815890600090a250565b8061239881613150565b6001600160a01b038281166000818152600260205260408082209051637004922d60e11b815260048101939093523060248401529290917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd79091169063e009245a90604401602060405180830381865afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e9190613b03565b60018301549091506001600160601b038083169116116124995760405162461bcd60e51b81526020600482015260166024820152754e6f7468696e6720746f2073796e6368726f6e697a6560501b6044820152606401610aef565b8154600160a01b900460ff161561250a5760018201546124c39082906001600160601b03166139e6565b600980546014906124e5908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5e26a115e9efdff9c71141dec1f9cc5dd2ec5e717da782cef55a475506e56788910160405180910390a26001820180546001600160601b0319166001600160601b0383811691821792839055600160601b90920490911611156125ba57600182018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b60018201546001600160601b031660000361219657612196846132c4565b816125e281613127565b6125fe5760405162461bcd60e51b8152600401610aef9061394c565b6001600160a01b03811633146126cc57604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa158015612679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269d919061397b565b50909150506001600160a01b03811633146126ca5760405162461bcd60e51b8152600401610aef9061394c565b505b7f0000000000000000000000000000000000000000000000000000000065a5c6ff6001600160401b031642106127445760405162461bcd60e51b815260206004820152601860248201527f436f6d6d69746d656e742077696e646f7720636c6f73656400000000000000006044820152606401610aef565b6000826001600160401b031611801561284157507f000000000000000000000000000000000000000000000000000000000077f8806001600160401b0316826001600160401b031614806127c957507f0000000000000000000000000000000000000000000000000000000000eff1006001600160401b0316826001600160401b0316145b8061280557507f0000000000000000000000000000000000000000000000000000000001dfe2006001600160401b0316826001600160401b0316145b8061284157507f0000000000000000000000000000000000000000000000000000000002cfd3006001600160401b0316826001600160401b0316145b6128a95760405162461bcd60e51b815260206004820152603360248201527f436f6d6d69746d656e74206475726174696f6e206d75737420626520657175616044820152726c20746f206f6e65206f66206f7074696f6e7360681b6064820152608401610aef565b6001600160a01b03831660009081526002602052604090206001810154600160c01b90046001600160401b03161561293b5760405162461bcd60e51b815260206004820152602f60248201527f436f6d6d69746d656e742063616e2774206265206d61646520647572696e672060448201526e3232b0baba3437b934bd30ba34b7b760891b6064820152608401610aef565b60038101546001600160401b0316156129965760405162461bcd60e51b815260206004820152601760248201527f436f6d6d69746d656e7420616c7265616479206d6164650000000000000000006044820152606401610aef565b6129a08342613b20565b60038201805467ffffffffffffffff19166001600160401b039290921691821790556040519081526001600160a01b038516907f293c61c79ecf0bcac67f97a5925ba2e75c025c6231a4ab629862b570730a264b9060200160405180910390a250505050565b6001600160a01b038116612a675760405162461bcd60e51b815260206004820152602260248201527f5374616b696e672070726f7669646572206d7573742062652073706563696669604482015261195960f21b6064820152608401610aef565b6001600160a01b038181166000818152600260209081526040918290206001810154815484516001600160601b038084168252600160601b84041694810194909452600160c01b9091046001600160401b031683850152909416606082015290517fcdc04e3c6e3b10c218c3f6c8b4471a698e140d3a7544169e2162ff71488b4031916080908290030190a2612afd828261335e565b60005481546040516346696b9f60e11b81526001600160a01b0385811660048301529182166024820152911690638cd2d73e906044015b600060405180830381600087803b158015612b4e57600080fd5b505af1158015612b62573d6000803e3d6000fd5b505050505050565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd71614612bb25760405162461bcd60e51b8152600401610aef90613a0d565b82612bbc81613150565b6001600160a01b03841615801590612bdd57506000826001600160601b0316115b612c345760405162461bcd60e51b815260206004820152602260248201527f496e70757420706172616d6574657273206d7573742062652073706563696669604482015261195960f21b6064820152608401610aef565b7f000000000000000000000000000000000000000000000878678326eac90000006001600160601b0316826001600160601b03161015612cc95760405162461bcd60e51b815260206004820152602a60248201527f417574686f72697a6174696f6e206d7573742062652067726561746572207468604482015269616e206d696e696d756d60b01b6064820152608401610aef565b6001600160a01b0380851660009081526002602090815260408083206004909252909120549091161580612d1757506001600160a01b03808616600081815260046020526040902054909116145b612d805760405162461bcd60e51b815260206004820152603460248201527f412070726f76696465722063616e277420626520616e206f70657261746f72206044820152733337b91030b737ba3432b910383937bb34b232b960611b6064820152608401610aef565b8054600160a01b900460ff1615612dec57612d9b818561324a565b612da584846139e6565b60098054601490612dc7908490600160a01b90046001600160601b0316613aaa565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821790925560408051928716835260208301919091526001600160a01b038716917f9e46043a7120cf056d21eda9b6d78ffd99571a62fb6ff91a471a73e4b8484e1c9101611c2b565b600954600090600160a01b90046001600160601b03168103612e7d57506009546001600160a01b031690565b600954600754600854600092600160a01b90046001600160601b03169190612ea36121a6565b612ead9190613a52565b612eb79190613aca565b612ec19190613ae1565b600954612ed791906001600160a01b03166139d3565b9050612ee2816134f7565b91505090565b6001546001600160a01b03163314612f4c5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646a7564696361746f7220616c6c6f77656420746f20736c61736044820152600d60fb1b6064820152608401610aef565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110612f8257612f82613a7b565b6001600160a01b0392831660209182029290920101526040516383ddba8f60e01b81527f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7909116906383ddba8f90612fe590869060649087908790600401613b40565b600060405180830381600087803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b5050505050505050565b6130256131ef565b6001600160a01b03811661304f57604051631e4fbdf760e01b815260006004820152602401610aef565b61139f81613426565b6001600160a01b03811660009081526002602052604081208054600160a01b900460ff1661309357600201546001600160601b031692915050565b60028101546000906001600160601b03166130b86103e8670de0b6b3a7640000613aca565b6002840154600160601b90046001600160a01b03166130d5612e51565b6130df9190613bb3565b6001850154613100916001600160a01b0316906001600160601b0316613aca565b61310a9190613ae1565b61311491906139d3565b905061311f8161352f565b949350505050565b6001600160a01b03166000908152600260205260409020600101546001600160601b0316151590565b613158612e51565b600980546001600160a01b0319166001600160a01b03929092169190911790556131806121a6565b6008556001600160a01b0381161561139f576001600160a01b03811660009081526002602052604090206131b382613058565b60029190910180546001600160601b0319166001600160601b0390921691821781556009546001600160a01b0316600160601b02909117905550565b336132217f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614611c4f5760405163118cdaa760e01b8152336004820152602401610aef565b60018201546001600160601b03828116911614611f1057600182015461327a9082906001600160601b03166139e6565b6009805460149061329c908490600160a01b90046001600160601b03166139e6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6001600160a01b03818116600081815260026020908152604080832080548616845260049283905281842080546001600160a01b031916905580546001600160a81b03191681556001810180546001600160c01b0316905560038101805467ffffffffffffffff19169055835491516346696b9f60e11b815292830194909452602482019290925291921690638cd2d73e90604401612b34565b600054600182015460405163248b36bf60e21b81526001600160a01b0385811660048301526001600160601b038084166024840152600160601b8404166044830152600160c01b9092046001600160401b0316606482015291169063922cdafc90608401612b34565b6040516001600160a01b0383811660248301526044820183905261187c91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613563565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526121a09186918216906323b872dd906084016133f4565b60008183106134df578161230b565b5090919050565b6134ee6135c6565b61139f8161360f565b60006001600160a01b0382111561352b576040516306dfcc6560e41b815260a0600482015260248101839052604401610aef565b5090565b60006001600160601b0382111561352b576040516306dfcc6560e41b81526060600482015260248101839052604401610aef565b60006135786001600160a01b03841683613617565b9050805160001415801561359d57508080602001905181019061359b9190613bd3565b155b1561187c57604051635274afe760e01b81526001600160a01b0384166004820152602401610aef565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611c4f57604051631afcd79f60e31b815260040160405180910390fd5b6130256135c6565b606061230b8383600084600080856001600160a01b0316848660405161363d9190613bf5565b60006040518083038185875af1925050503d806000811461367a576040519150601f19603f3d011682016040523d82523d6000602084013e61367f565b606091505b509150915061368f868383613699565b9695505050505050565b6060826136ae576136a9826136f5565b61230b565b81511580156136c557506001600160a01b0384163b155b156136ee57604051639996b31560e01b81526001600160a01b0385166004820152602401610aef565b508061230b565b8051156137055780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b038116811461139f57600080fd5b6000806040838503121561374657600080fd5b82356137518161371e565b915060208301356137618161371e565b809150509250929050565b60006020828403121561377e57600080fd5b813561230b8161371e565b6001600160601b038116811461139f57600080fd5b6000806000606084860312156137b357600080fd5b83356137be8161371e565b925060208401356137ce81613789565b915060408401356137de81613789565b809150509250925092565b600080604083850312156137fc57600080fd5b82356138078161371e565b946020939093013593505050565b60008060006060848603121561382a57600080fd5b8335925060208401359150604084013563ffffffff811681146137de57600080fd5b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561388f57845183529383019391830191600101613873565b5090979650505050505050565b6000602082840312156138ae57600080fd5b813561230b81613789565b6000602082840312156138cb57600080fd5b5035919050565b600080604083850312156138e557600080fd5b82356138f08161371e565b915060208301356001600160401b038116811461376157600080fd5b60008060006060848603121561392157600080fd5b833561392c8161371e565b9250602084013561393c81613789565b915060408401356137de8161371e565b6020808252601590820152742737ba1037bbb732b91037b910383937bb34b232b960591b604082015260600190565b60008060006060848603121561399057600080fd5b835161399b8161371e565b60208501519093506139ac8161371e565b60408501519092506137de8161371e565b634e487b7160e01b600052601160045260246000fd5b808201808211156112ee576112ee6139bd565b6001600160601b03828116828216039080821115613a0657613a066139bd565b5092915050565b60208082526025908201527f43616c6c6572206d757374206265207468652054207374616b696e6720636f6e6040820152641d1c9858dd60da1b606082015260800190565b818103818111156112ee576112ee6139bd565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201613aa357613aa36139bd565b5060010190565b6001600160601b03818116838216019080821115613a0657613a066139bd565b80820281158282048414176112ee576112ee6139bd565b600082613afe57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613b1557600080fd5b815161230b81613789565b6001600160401b03818116838216019080821115613a0657613a066139bd565b6001600160601b038516815260208082018590526001600160a01b038481166040840152608060608401819052845190840181905260009285810192909160a0860190855b81811015613ba3578551841683529484019491840191600101613b85565b50909a9950505050505050505050565b6001600160a01b03828116828216039080821115613a0657613a066139bd565b600060208284031215613be557600080fd5b8151801515811461230b57600080fd5b6000825160005b81811015613c165760208186018101518583015201613bfc565b50600092019182525091905056fea264697066735822122054c1baa24cdc63ac1ba9c8a897ef2e9c3550525c49b7bced055e14c270551b8264736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee500000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7000000000000000000000000000000000000000000000878678326eac9000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000002819a00000000000000000000000000000000000000000000000000000000000eff10000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000065a5c6ff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000077f8800000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000001dfe2000000000000000000000000000000000000000000000000000000000002cfd300
-----Decoded View---------------
Arg [0] : _token (address): 0xCdF7028ceAB81fA0C6971208e83fa7872994beE5
Arg [1] : _tStaking (address): 0x01B67b1194C75264d06F808A921228a95C765dd7
Arg [2] : _minimumAuthorization (uint96): 40000000000000000000000
Arg [3] : _minOperatorSeconds (uint256): 86400
Arg [4] : _rewardDuration (uint256): 2628000
Arg [5] : _deauthorizationDuration (uint256): 15724800
Arg [6] : _commitmentDurationOptions (uint64[]): 7862400,15724800,31449600,47174400
Arg [7] : _commitmentDeadline (uint64): 1705363199
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee5
Arg [1] : 00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7
Arg [2] : 000000000000000000000000000000000000000000000878678326eac9000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [4] : 00000000000000000000000000000000000000000000000000000000002819a0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000eff100
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [7] : 0000000000000000000000000000000000000000000000000000000065a5c6ff
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [9] : 000000000000000000000000000000000000000000000000000000000077f880
Arg [10] : 0000000000000000000000000000000000000000000000000000000000eff100
Arg [11] : 0000000000000000000000000000000000000000000000000000000001dfe200
Arg [12] : 0000000000000000000000000000000000000000000000000000000002cfd300
Deployed Bytecode Sourcemap
493:36078:15:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31196:2031;;;;;;:::i;:::-;;:::i;:::-;;6318:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6318:66:15;;;;;-1:-1:-1;;;6318:66:15;;;;-1:-1:-1;;;;;;;;6318:66:15;;;;;;-1:-1:-1;;;;;6318:66:15;;;;-1:-1:-1;;;6318:66:15;;;;;;-1:-1:-1;;;6318:66:15;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1204:15:16;;;1186:34;;1263:14;;1256:22;1251:2;1236:18;;1229:50;-1:-1:-1;;;;;1352:15:16;;;1332:18;;;1325:43;-1:-1:-1;;;;;1449:15:16;;;1444:2;1429:18;;1422:43;1502:15;;;1496:3;1481:19;;1474:44;1555:15;;;1166:3;1534:19;;1527:44;1608:15;;;;1602:3;1587:19;;1580:44;1661:15;;1655:3;1640:19;;1633:44;1714:15;;;1708:3;1693:19;;1686:44;1135:3;1120:19;6318:66:15;;;;;;;;10297:228;;;;;;:::i;:::-;;:::i;18735:852::-;;;;;;:::i;:::-;;:::i;5532:61::-;;5586:7;5532:61;;;;;2835:25:16;;;2823:2;2808:18;5532:61:15;2689:177:16;25594:430:15;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3353:39:16;;;3335:58;;3323:2;3308:18;25594:430:15;3191:208:16;10622:258:15;;;;;;:::i;:::-;;:::i;30893:115::-;;;;;;:::i;:::-;;:::i;27770:1647::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;15966:546::-;;;;;;:::i;:::-;;:::i;5894:49::-;;;;;;;;-1:-1:-1;;;;;4691:31:16;;;4673:50;;4661:2;4646:18;5894:49:15;4529:200:16;33296:865:15;;;;;;:::i;:::-;;:::i;5949:49::-;;;;;29506:185;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;4914:32:16;;;4896:51;;4884:2;4869:18;29506:185:15;4734:219:16;6285:26:15;;;;;-1:-1:-1;;;;;6285:26:15;;;5745:43;;;;;19894:1121;;;;;;:::i;:::-;;:::i;3131:101:12:-;;;:::i;14856:929:15:-;;;;;;:::i;:::-;;:::i;21180:968::-;;;;;;:::i;:::-;;:::i;6572:33::-;;;;;;12135:414;;;;-1:-1:-1;;;;;12422:20:15;5630:39:16;5612:58;;-1:-1:-1;;;;;12463:23:15;5743:15:16;5738:2;5723:18;;5716:43;;;5775:18;;;5768:43;;;;5600:2;5585:18;12135:414:15;5416:401:16;30103:277:15;;;;;;:::i;:::-;-1:-1:-1;;;;;30214:39:15;;;30172:4;30214:39;;;:28;:39;;;;;;;;;;;;30298:36;;:19;:36;;;30351:22;-1:-1:-1;;;30351:22:15;;;;;30103:277;;;;5987:14:16;;5980:22;5962:41;;5950:2;5935:18;30103:277:15;5822:187:16;13535:129:15;;;:::i;10132:86::-;;;:::i;30469:116::-;30555:16;:23;30469:116;;5839:48;;;;;2417:144:12;1289:22;2546:8;-1:-1:-1;;;;;2546:8:12;2417:144;;6114:42:15;;;;;6239:40;;;;;-1:-1:-1;;;;;6239:40:15;;;6004:49;;;;;26616:373;;;;;;:::i;:::-;;:::i;6390:33::-;;;;;;:::i;:::-;;:::i;12685:187::-;;;;;;:::i;:::-;;:::i;22323:881::-;;;;;;:::i;:::-;;:::i;6059:49::-;;;;;6501:32;;;;;-1:-1:-1;;;;;6501:32:15;;;23433:1053;;;;;;:::i;:::-;;:::i;35321:585::-;;;;;;:::i;:::-;;:::i;25115:154::-;;;;;;:::i;:::-;-1:-1:-1;;;;;25214:37:15;25189:6;25214:37;;;:19;:37;;;;;:48;;;-1:-1:-1;;;;;25214:48:15;;25115:154;24866:163;;;;;;:::i;:::-;-1:-1:-1;;;;;24976:37:15;;;24950:7;24976:37;;;:19;:37;;;;;:46;;;24866:163;6611:29;;;;;;17320:1117;;;;;;:::i;:::-;;:::i;13756:349::-;;;:::i;6687:31::-;;;;;-1:-1:-1;;;6687:31:15;;-1:-1:-1;;;;;6687:31:15;;;6163:34;;;;;24632:149;;;;;;:::i;:::-;-1:-1:-1;;;;;24735:39:15;;;24709:7;24735:39;;;:28;:39;;;;;;;;24632:149;6646:35;;;;;-1:-1:-1;;;;;6646:35:15;;;36191:378;;;;;;:::i;:::-;;:::i;6539:27::-;;;;;;5695:44;;;;;3381:215:12;;;;;;:::i;:::-;;:::i;5794:39:15:-;;;;;14259:450;;;;;;:::i;:::-;;:::i;6203:29::-;;;;;26253:193;;;;;;:::i;:::-;-1:-1:-1;;;;;26388:37:15;26363:6;26388:37;;;:19;:37;;;;;:51;;;-1:-1:-1;;;26388:51:15;;-1:-1:-1;;;;;26388:51:15;;26253:193;29802:151;;;;;;:::i;:::-;;:::i;31196:2031::-;31319:16;9774:30;9787:16;9774:12;:30::i;:::-;9766:64;;;;-1:-1:-1;;;9766:64:15;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;9844:30:15;;9864:10;9844:30;9840:184;;9912:34;;-1:-1:-1;;;9912:34:15;;-1:-1:-1;;;;;4914:32:16;;;9912:34:15;;;4896:51:16;9891:13:15;;9912:8;:16;;;;;;4869:18:16;;9912:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;9890:56:15;;-1:-1:-1;;;;;;;9968:19:15;;9977:10;9968:19;9960:53;;;;-1:-1:-1;;;9960:53:15;;;;;;;:::i;:::-;9876:148;9840:184;31350:16:::1;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1::0;;;;;31413:37:15;;::::2;31378:32;31413:37:::0;;;:19:::2;:37;::::0;;;;31487:13;;31413:37;;31487:13;;::::2;::::0;31531:29;::::2;::::0;;;31510:131:::2;;;::::0;-1:-1:-1;;;31510:131:15;;9133:2:16;31510:131:15::2;::::0;::::2;9115:21:16::0;9172:2;9152:18;;;9145:30;9211:34;9191:18;;;9184:62;9282:25;9262:18;;;9255:53;9325:19;;31510:131:15::2;8931:419:16::0;31510:131:15::2;-1:-1:-1::0;;;;;31700:30:15;::::2;::::0;31696:424:::2;;31772:22:::0;;-1:-1:-1;;;31772:22:15;::::2;;;31771:23;::::0;:123:::2;;-1:-1:-1::0;31845:27:15;;31837:57:::2;::::0;31876:18:::2;::::0;-1:-1:-1;;;31845:27:15;::::2;-1:-1:-1::0;;;;;31845:27:15::2;31837:57;:::i;:::-;31818:15;:76;;31771:123;31746:223;;;::::0;-1:-1:-1;;;31746:223:15;;9819:2:16;31746:223:15::2;::::0;::::2;9801:21:16::0;9858:2;9838:18;;;9831:30;9897:34;9877:18;;;9870:62;-1:-1:-1;;;9948:18:16;;;9941:39;9997:19;;31746:223:15::2;9617:405:16::0;31746:223:15::2;-1:-1:-1::0;;;;;32050:46:15;::::2;32107:1;32050:46:::0;;;:28:::2;:46;::::0;;;;:59;;-1:-1:-1;;;;;;32050:59:15::2;::::0;;31696:424:::2;-1:-1:-1::0;;;;;32134:23:15;::::2;::::0;32130:509:::2;;-1:-1:-1::0;;;;;32198:39:15;;::::2;32249:1;32198:39:::0;;;:28:::2;:39;::::0;;;;;::::2;:53:::0;32173:148:::2;;;::::0;-1:-1:-1;;;32173:148:15;;10229:2:16;32173:148:15::2;::::0;::::2;10211:21:16::0;10268:2;10248:18;;;10241:30;10307:34;10287:18;;;10280:62;-1:-1:-1;;;10358:18:16;;;10351:34;10402:19;;32173:148:15::2;10027:400:16::0;32173:148:15::2;32373:16;-1:-1:-1::0;;;;;32360:29:15::2;:9;-1:-1:-1::0;;;;;32360:29:15::2;;:72;;;-1:-1:-1::0;32430:1:15::2;32393:25;32408:9:::0;32393:14:::2;:25::i;:::-;-1:-1:-1::0;;;;;32393:39:15::2;;32360:72;32335:163;;;::::0;-1:-1:-1;;;32335:163:15;;10634:2:16;32335:163:15::2;::::0;::::2;10616:21:16::0;;;10653:18;;;10646:30;10712:34;10692:18;;;10685:62;10764:18;;32335:163:15::2;10432:356:16::0;32335:163:15::2;-1:-1:-1::0;;;;;32570:39:15;;::::2;;::::0;;;:28:::2;:39;::::0;;;;:58;;-1:-1:-1;;;;;;32570:58:15::2;::::0;;::::2;::::0;;;::::2;::::0;;32130:509:::2;32653:27:::0;;-1:-1:-1;;;32653:27:15;::::2;-1:-1:-1::0;;;;;32653:27:15::2;;:32:::0;32649:102:::2;;32701:16;:39:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;32701:39:15;;;;;::::2;::::0;;-1:-1:-1;;;;;;32701:39:15::2;-1:-1:-1::0;;;;;32701:39:15;::::2;;::::0;;32649:102:::2;32765:22:::0;;-1:-1:-1;;;32765:22:15;::::2;;;32761:89;;;32824:15;::::0;::::2;::::0;32803:17:::2;:36:::0;;-1:-1:-1;;;;;32824:15:15;;::::2;::::0;32803:17:::2;::::0;:36:::2;::::0;32824:15;;-1:-1:-1;;;32803:36:15;::::2;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;32803:36:15::2;;;;;-1:-1:-1::0;;;;;32803:36:15::2;;;;;;32761:89;32928:25:::0;;-1:-1:-1;;;;;32928:25:15;;::::2;-1:-1:-1::0;;;;;;32963:53:15;;;;;-1:-1:-1;;;33000:15:15::2;-1:-1:-1::0;;;;;32963:53:15;::::2;::::0;;;::::2;::::0;;;::::2;::::0;;33031:78:::2;::::0;2835:25:16;;;33031:78:15;;::::2;::::0;32928:25;33031:78;::::2;::::0;::::2;::::0;2823:2:16;2808:18;33031:78:15::2;;;;;;;33120:30:::0;;-1:-1:-1;;;;33120:30:15::2;::::0;;-1:-1:-1;33160:16:15;:60:::2;::::0;-1:-1:-1;;;33160:60:15;;-1:-1:-1;;;;;11219:15:16;;;33160:60:15::2;::::0;::::2;11201:34:16::0;11271:15;;;11251:18;;;11244:43;33160:16:15;;::::2;::::0;:31:::2;::::0;11136:18:16;;33160:60:15::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;31368:1859;;10033:1:::1;31196:2031:::0;;;:::o;10297:228::-;2310:13:12;:11;:13::i;:::-;10440:1:15::1;10407:17;-1:-1:-1::0;;;;;10399:38:15::1;;:42;10391:81;;;::::0;-1:-1:-1;;;10391:81:15;;11500:2:16;10391:81:15::1;::::0;::::1;11482:21:16::0;11539:2;11519:18;;;11512:30;11578:28;11558:18;;;11551:56;11624:18;;10391:81:15::1;11298:350:16::0;10391:81:15::1;10482:16;:36:::0;;-1:-1:-1;;;;;;10482:36:15::1;-1:-1:-1::0;;;;;10482:36:15;;;::::1;::::0;;;::::1;::::0;;10297:228::o;18735:852::-;9518:10;-1:-1:-1;;;;;9540:8:15;9518:31;;9510:81;;;;-1:-1:-1;;;9510:81:15;;;;;;;:::i;:::-;18922:16:::1;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1::0;;;;;18985:37:15;::::2;18950:32;18985:37:::0;;;:19:::2;:37;::::0;;;;19036:22;;-1:-1:-1;;;19036:22:15;::::2;;;19032:160;;;19074:49;19105:4;19111:11;19074:30;:49::i;:::-;19158:23;19172:9:::0;19158:11;:23:::2;:::i;:::-;19137:17;:44:::0;;:17:::2;::::0;:44:::2;::::0;;;-1:-1:-1;;;19137:44:15;::::2;-1:-1:-1::0;;;;;19137:44:15::2;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;19137:44:15::2;;;;;-1:-1:-1::0;;;;;19137:44:15::2;;;;;;19032:160;19202:15;::::0;::::2;:27:::0;;-1:-1:-1;;;;;;19202:27:15::2;-1:-1:-1::0;;;;;19202:27:15;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;19261:18:15;;::::2;::::0;;::::2;-1:-1:-1::0;19239:103:15::2;;;19316:15;::::0;::::2;::::0;;-1:-1:-1;;;;;;;;19316:15:15;::::2;19295:36;-1:-1:-1::0;;;;;;;;19295:36:15;;::::2;;::::0;;19239:103:::2;19356:75;::::0;;-1:-1:-1;;;;;12292:15:16;;;12274:34;;12344:15;;12339:2;12324:18;;12317:43;-1:-1:-1;;;;;19356:75:15;::::2;::::0;::::2;::::0;12202:18:16;19356:75:15::2;;;;;;;19446:15;::::0;::::2;::::0;-1:-1:-1;;;;;19446:15:15::2;;:20:::0;19442:85:::2;;19482:34;19499:16;19482;:34::i;:::-;19536:44;19557:16;19575:4;19536:20;:44::i;:::-;18940:647;9601:1:::1;18735:852:::0;;;:::o;25594:430::-;-1:-1:-1;;;;;25757:37:15;;25704:6;25757:37;;;:19;:37;;;;;25829:15;;;;-1:-1:-1;;;;;25829:15:15;;;-1:-1:-1;;;25862:23:15;;-1:-1:-1;;;;;25862:23:15;25858:27;;;;:65;;-1:-1:-1;25889:23:15;;;;-1:-1:-1;;;25889:23:15;;-1:-1:-1;;;;;25889:23:15;-1:-1:-1;;25858:65:15;25854:132;;;25957:18;;;;25939:36;;-1:-1:-1;;;25957:18:15;;-1:-1:-1;;;;;25957:18:15;25939:36;;:::i;:::-;;;25854:132;26003:14;-1:-1:-1;;25594:430:15;;;;;:::o;10622:258::-;2310:13:12;:11;:13::i;:::-;10751:11:15::1;::::0;-1:-1:-1;;;;;10751:11:15;;::::1;10718:45:::0;;::::1;::::0;10697:140:::1;;;::::0;-1:-1:-1;;;10697:140:15;;12573:2:16;10697:140:15::1;::::0;::::1;12555:21:16::0;12612:2;12592:18;;;12585:30;12651:34;12631:18;;;12624:62;-1:-1:-1;;;12702:18:16;;;12695:46;12758:19;;10697:140:15::1;12371:412:16::0;10697:140:15::1;10847:11;:26:::0;;-1:-1:-1;;;;;;10847:26:15::1;-1:-1:-1::0;;;;;10847:26:15;;;::::1;::::0;;;::::1;::::0;;10622:258::o;30893:115::-;30966:35;30979:10;30991:9;30966:12;:35::i;:::-;30893:115;:::o;27770:1647::-;28032:16;:23;27933:27;;27962:39;;28073:22;;;28065:52;;;;-1:-1:-1;;;28065:52:15;;12990:2:16;28065:52:15;;;12972:21:16;13029:2;13009:18;;;13002:30;-1:-1:-1;;;13048:18:16;;;13041:47;13105:18;;28065:52:15;12788:341:16;28065:52:15;28131:25;;;;;:74;;-1:-1:-1;28197:8:15;28160:34;28174:20;28160:11;:34;:::i;:::-;:45;28131:74;28127:150;;;28232:34;28246:20;28232:11;:34;:::i;:::-;28221:45;;28127:150;28325:22;28336:11;28325:8;:22;:::i;:::-;-1:-1:-1;;;;;28311:37:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28311:37:15;-1:-1:-1;28380:1:15;;-1:-1:-1;28286:62:15;-1:-1:-1;28380:1:15;28409:20;;;;:100;;28476:33;;;;:15;:33;:::i;:::-;28409:100;;;-1:-1:-1;;28409:100:15;28391:118;-1:-1:-1;28520:19:15;28570:11;28553:773;28587:8;28583:1;:12;28553:773;;;28616:23;28642:16;28659:1;28642:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;28642:19:15;28710:36;;;:19;:36;;;;;;28642:19;;-1:-1:-1;28710:36:15;28785:39;28642:19;28816:7;28785:13;:39::i;:::-;-1:-1:-1;;;;;28760:64:15;;;28859:20;-1:-1:-1;;;;;28842:37:15;:14;:37;:64;;;-1:-1:-1;28884:22:15;;-1:-1:-1;;;28884:22:15;;;;28883:23;28842:64;28838:111;;;28926:8;;;;;28838:111;-1:-1:-1;;;;;;29188:24:15;;;;29180:33;:84;;29124:22;29147:13;;;;:::i;:::-;;;29124:37;;;;;;;;:::i;:::-;;;;;;;;;;:140;29278:37;29301:14;29278:37;;:::i;:::-;;;28602:724;;;28553:773;28597:3;;28553:773;;;;29389:11;29365:22;29358:43;29344:67;;;27770:1647;;;;;;:::o;15966:546::-;16039:16;9343:38;9364:16;9343:20;:38::i;:::-;16067:19:::1;16089:32;16104:16;16089:14;:32::i;:::-;16067:54:::0;-1:-1:-1;16139:10:15::1;-1:-1:-1::0;;;;;16139:25:15;::::1;;16131:64;;;::::0;-1:-1:-1;;;16131:64:15;;13873:2:16;16131:64:15::1;::::0;::::1;13855:21:16::0;13912:2;13892:18;;;13885:30;13951:28;13931:18;;;13924:56;13997:18;;16131:64:15::1;13671:350:16::0;16131:64:15::1;-1:-1:-1::0;;;;;16241:37:15;::::1;16206:32;16241:37:::0;;;:19:::1;:37;::::0;;;;;;;16303:12;;::::1;::::0;-1:-1:-1;;;;;16303:12:15::1;16333:9:::0;16325:43:::1;;;::::0;-1:-1:-1;;;16325:43:15;;14228:2:16;16325:43:15::1;::::0;::::1;14210:21:16::0;14267:2;14247:18;;;14240:30;-1:-1:-1;;;14286:18:16;;;14279:51;14347:18;;16325:43:15::1;14026:345:16::0;16325:43:15::1;16378:12;::::0;::::1;:16:::0;;-1:-1:-1;;;;;;16378:16:15::1;::::0;;16409:48:::1;::::0;-1:-1:-1;;;;;3353:39:16;;3335:58;;-1:-1:-1;;;;;16409:48:15;;::::1;::::0;;;::::1;::::0;::::1;::::0;3323:2:16;3308:18;16409:48:15::1;;;;;;;16467:38;-1:-1:-1::0;;;;;16467:5:15::1;:18;16486:11:::0;-1:-1:-1;;;;;16467:38:15;::::1;:18;:38::i;33296:865::-:0;33418:16;;-1:-1:-1;;;;;33418:16:15;33396:10;:39;33375:136;;;;-1:-1:-1;;;33375:136:15;;14792:2:16;33375:136:15;;;14774:21:16;14831:2;14811:18;;;14804:30;14870:34;14850:18;;;14843:62;-1:-1:-1;;;14921:18:16;;;14914:48;14979:19;;33375:136:15;14590:414:16;33375:136:15;-1:-1:-1;;;;;33547:39:15;;;33521:23;33547:39;;;:28;:39;;;;;;;;33750:66;;33799:7;33296:865;:::o;33750:66::-;-1:-1:-1;;;;;33861:36:15;;33826:32;33861:36;;;:19;:36;;;;;33912:22;;-1:-1:-1;;;33912:22:15;;;;33907:248;;33950:37;33971:15;33950:20;:37::i;:::-;34001:29;;-1:-1:-1;;;;34001:29:15;-1:-1:-1;;;34001:29:15;;;;;34026:4;34065:15;;;34044:17;:36;;-1:-1:-1;;;;;34065:15:15;;;;34044:17;;34001:22;;34044:36;;34065:15;;34044:36;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;34044:36:15;;;;;-1:-1:-1;;;;;34044:36:15;;;;;;34134:9;-1:-1:-1;;;;;34099:45:15;34117:15;-1:-1:-1;;;;;34099:45:15;;;;;;;;;;;33907:248;33365:796;;33296:865;:::o;29506:185::-;29650:34;;-1:-1:-1;;;29650:34:15;;-1:-1:-1;;;;;4914:32:16;;;29650:34:15;;;4896:51:16;29591:27:15;;29650:8;:16;;;;;;4869:18:16;;29650:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;29630:54:15;29506:185;-1:-1:-1;;;29506:185:15:o;19894:1121::-;9518:10;-1:-1:-1;;;;;9540:8:15;9518:31;;9510:81;;;;-1:-1:-1;;;9510:81:15;;;;;;;:::i;:::-;20079:16:::1;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1::0;;;;;20142:37:15;::::2;20107:32;20142:37:::0;;;:19:::2;:37;::::0;;;;20210:15:::2;::::0;::::2;::::0;-1:-1:-1;;;;;20210:15:15;;::::2;20197:28:::0;;::::2;;;20189:83;;;::::0;-1:-1:-1;;;20189:83:15;;15404:2:16;20189:83:15::2;::::0;::::2;15386:21:16::0;15443:2;15423:18;;;15416:30;15482:34;15462:18;;;15455:62;-1:-1:-1;;;15533:18:16;;;15526:40;15583:19;;20189:83:15::2;15202:406:16::0;20189:83:15::2;-1:-1:-1::0;;;;;20303:14:15;::::2;::::0;;:51:::2;;;20334:20;-1:-1:-1::0;;;;;20321:33:15::2;:9;-1:-1:-1::0;;;;;20321:33:15::2;;;20303:51;20282:147;;;::::0;-1:-1:-1;;;20282:147:15;;15815:2:16;20282:147:15::2;::::0;::::2;15797:21:16::0;15854:2;15834:18;;;15827:30;15893:34;15873:18;;;15866:62;-1:-1:-1;;;15944:18:16;;;15937:47;16001:19;;20282:147:15::2;15613:413:16::0;20282:147:15::2;20460:18;::::0;::::2;::::0;20482:15:::2;-1:-1:-1::0;;;;;20460:18:15;;::::2;:37;;20439:138;;;::::0;-1:-1:-1;;;20439:138:15;;16233:2:16;20439:138:15::2;::::0;::::2;16215:21:16::0;16272:2;16252:18;;;16245:30;16311:34;16291:18;;;16284:62;-1:-1:-1;;;16362:18:16;;;16355:52;16424:19;;20439:138:15::2;16031:418:16::0;20439:138:15::2;20591:22:::0;;-1:-1:-1;;;20591:22:15;::::2;;;20587:102;;;20629:49;20660:4;20666:11;20629:30;:49::i;:::-;20699:15;::::0;::::2;:29:::0;;-1:-1:-1;;;;;;20699:29:15::2;-1:-1:-1::0;;;;;20699:29:15;::::2;;::::0;;20759:23:::2;20773:9:::0;20699:29;20759:23:::2;:::i;:::-;20738:18;::::0;::::2;:44:::0;;-1:-1:-1;;;;;20738:44:15;;;::::2;-1:-1:-1::0;;;20738:44:15::2;-1:-1:-1::0;;;;;;;;20738:44:15;;::::2;::::0;;;::::2;::::0;;20825:41:::2;20843:23;20825:15;:41;:::i;:::-;20792:23;::::0;::::2;:75:::0;;-1:-1:-1;;;;;20792:75:15;;;::::2;-1:-1:-1::0;;;20792:75:15::2;-1:-1:-1::0;;;;;20792:75:15;;::::2;::::0;;;::::2;::::0;;20882:72:::2;::::0;;-1:-1:-1;;;;;12292:15:16;;;12274:34;;12344:15;;12339:2;12324:18;;12317:43;-1:-1:-1;;;;;20882:72:15;::::2;::::0;::::2;::::0;12202:18:16;20882:72:15::2;;;;;;;;20964:44;20985:16;21003:4;20964:20;:44::i;3131:101:12:-:0;2310:13;:11;:13::i;:::-;3195:30:::1;3222:1;3195:18;:30::i;:::-;3131:101::o:0;14856:929:15:-;14922:1;9343:38;9364:16;9343:20;:38::i;:::-;14958:17:::1;::::0;-1:-1:-1;;;;;14958:17:15::1;14944:10;:31;14936:77;;;::::0;-1:-1:-1;;;14936:77:15;;16656:2:16;14936:77:15::1;::::0;::::1;16638:21:16::0;16695:2;16675:18;;;16668:30;16734:34;16714:18;;;16707:62;-1:-1:-1;;;16785:18:16;;;16778:31;16826:19;;14936:77:15::1;16454:397:16::0;14936:77:15::1;15041:1;15031:7;-1:-1:-1::0;;;;;15031:11:15::1;;15023:48;;;::::0;-1:-1:-1;;;15023:48:15;;17058:2:16;15023:48:15::1;::::0;::::1;17040:21:16::0;17097:2;17077:18;;;17070:30;17136:26;17116:18;;;17109:54;17180:18;;15023:48:15::1;16856:348:16::0;15023:48:15::1;15089:17;::::0;-1:-1:-1;;;15089:17:15;::::1;-1:-1:-1::0;;;;;15089:17:15::1;15081:61;;;::::0;-1:-1:-1;;;15081:61:15;;17411:2:16;15081:61:15::1;::::0;::::1;17393:21:16::0;17450:2;17430:18;;;17423:30;17489:29;17469:18;;;17462:57;17536:18;;15081:61:15::1;17209:351:16::0;15081:61:15::1;15175:12;;15156:15;:31;15152:425;;15270:14;5650:38;5586:7;5680:8;5650:38;:::i;:::-;15225:41;::::0;-1:-1:-1;;;;;15225:16:15;::::1;:41;:::i;:::-;15224:60;;;;:::i;:::-;15203:18;:81:::0;15152:425:::1;;;15315:17;15350:15;15335:12;;:30;;;;:::i;:::-;15315:50;;15379:16;15410:18;;15398:9;:30;;;;:::i;:::-;15379:49:::0;-1:-1:-1;15552:14:15::1;15379:49:::0;5650:38:::1;5586:7;5680:8;5650:38;:::i;:::-;15480:41;::::0;-1:-1:-1;;;;;15480:16:15;::::1;:41;:::i;:::-;:52;;;;:::i;:::-;15479:87;;;;:::i;:::-;15442:18;:124:::0;-1:-1:-1;;15152:425:15::1;15603:15;15586:14;:32:::0;;;15643::::1;::::0;15661:14:::1;::::0;15643:32:::1;:::i;:::-;15628:12;:47:::0;15690:20:::1;::::0;-1:-1:-1;;;;;3353:39:16;;3335:58;;15690:20:15::1;::::0;3323:2:16;3308:18;15690:20:15::1;;;;;;;15720:58;-1:-1:-1::0;;;;;15720:5:15::1;:22;15743:10;15763:4;-1:-1:-1::0;;;;;15720:58:15;::::1;:22;:58::i;:::-;14856:929:::0;;:::o;21180:968::-;21280:16;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1;;;;;21343:37:15;::::1;21308:32;21343:37:::0;;;:19:::1;:37;::::0;;;;21398:18:::1;::::0;::::1;::::0;-1:-1:-1;;;21398:18:15;::::1;-1:-1:-1::0;;;;;21398:18:15::1;21390:71;;;::::0;-1:-1:-1;;;21390:71:15;;18162:2:16;21390:71:15::1;::::0;::::1;18144:21:16::0;18201:2;18181:18;;;18174:30;18240:34;18220:18;;;18213:62;-1:-1:-1;;;18291:18:16;;;18284:34;18335:19;;21390:71:15::1;17960:400:16::0;21390:71:15::1;21492:23;::::0;::::1;::::0;21519:15:::1;-1:-1:-1::0;;;21492:23:15;;::::1;-1:-1:-1::0;;;;;21492:23:15::1;:42;;21471:132;;;::::0;-1:-1:-1;;;21471:132:15;;18567:2:16;21471:132:15::1;::::0;::::1;18549:21:16::0;18606:2;18586:18;;;18579:30;18645:34;18625:18;;;18618:62;-1:-1:-1;;;18696:18:16;;;18689:41;18747:19;;21471:132:15::1;18365:407:16::0;21471:132:15::1;21632:55;::::0;-1:-1:-1;;;21632:55:15;;-1:-1:-1;;;;;4914:32:16;;;21632:55:15::1;::::0;::::1;4896:51:16::0;21614:15:15::1;::::0;21632:8:::1;:37:::0;;::::1;::::0;::::1;::::0;4869:18:16;;21632:55:15::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21702:22:::0;;21614:73;;-1:-1:-1;;;;21702:22:15;::::1;;;21698:100;;;21761:15;::::0;::::1;::::0;:26:::1;::::0;21779:8;;-1:-1:-1;;;;;21761:15:15::1;:26;:::i;:::-;21740:17;:47:::0;;:17:::1;::::0;:47:::1;::::0;;;-1:-1:-1;;;21740:47:15;::::1;-1:-1:-1::0;;;;;21740:47:15::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;21740:47:15::1;;;;;-1:-1:-1::0;;;;;21740:47:15::1;;;;;;21698:100;21861:15;::::0;::::1;::::0;21813:74:::1;::::0;;-1:-1:-1;;;;;21861:15:15;;::::1;12274:34:16::0;;12344:15;;;12339:2;12324:18;;12317:43;-1:-1:-1;;;;;21813:74:15;::::1;::::0;::::1;::::0;12202:18:16;21813:74:15::1;;;;;;;-1:-1:-1::0;;;;;21897:26:15;::::1;:15;::::0;::::1;21965:27:::0;;;21897:15:::1;22007:20:::0;22003:85:::1;;22043:34;22060:16;22043;:34::i;:::-;22097:44;22118:16;22136:4;22097:20;:44::i;:::-;21298:850;;21180:968:::0;;:::o;13535:129::-;13592:7;13618:39;13627:15;13644:12;;13618:8;:39::i;:::-;13611:46;;13535:129;:::o;10132:86::-;8870:21:10;4302:15;;-1:-1:-1;;;4302:15:10;;;;4301:16;;-1:-1:-1;;;;;4348:14:10;4158:30;4726:16;;:34;;;;;4746:14;4726:34;4706:54;;4770:17;4790:11;-1:-1:-1;;;;;4790:16:10;4805:1;4790:16;:50;;;;-1:-1:-1;4818:4:10;4810:25;:30;4790:50;4770:70;;4856:12;4855:13;:30;;;;;4873:12;4872:13;4855:30;4851:91;;;4908:23;;-1:-1:-1;;;4908:23:10;;;;;;;;;;;4851:91;4951:18;;-1:-1:-1;;4951:18:10;4968:1;4951:18;;;4979:67;;;;5013:22;;-1:-1:-1;;;;5013:22:10;-1:-1:-1;;;5013:22:10;;;4979:67;10185:26:15::1;10200:10;10185:14;:26::i;:::-;5070:14:10::0;5066:101;;;5100:23;;-1:-1:-1;;;;5100:23:10;;;5142:14;;-1:-1:-1;4673:50:16;;5142:14:10;;4661:2:16;4646:18;5142:14:10;;;;;;;4092:1081;;;;;10132:86:15:o;26616:373::-;-1:-1:-1;;;;;26780:37:15;;26733:6;26780:37;;;:19;:37;;;;;:56;;;-1:-1:-1;;;26780:56:15;;-1:-1:-1;;;;;26780:56:15;26872:15;26850:37;;26846:76;;-1:-1:-1;26910:1:15;;26616:373;-1:-1:-1;;26616:373:15:o;26846:76::-;26945:36;26966:15;26945:18;:36;:::i;:::-;26931:51;26616:373;-1:-1:-1;;;26616:373:15:o;6390:33::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6390:33:15;;-1:-1:-1;6390:33:15;:::o;12685:187::-;2310:13:12;:11;:13::i;:::-;12772:17:15::1;:38:::0;;-1:-1:-1;;;;;;12772:38:15::1;-1:-1:-1::0;;;;;12772:38:15;::::1;::::0;;::::1;::::0;;;12825:40:::1;::::0;::::1;::::0;-1:-1:-1;;12825:40:15::1;12685:187:::0;:::o;22323:881::-;22421:16;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1;;;;;22484:37:15;;::::1;22449:32;22484:37:::0;;;:19:::1;:37;::::0;;;;;22554:57;;-1:-1:-1;;;22554:57:15;;::::1;::::0;::::1;11201:34:16::0;;;;22605:4:15::1;11251:18:16::0;;;11244:43;22484:37:15;22449:32;;22554:8:::1;:24:::0;;::::1;::::0;::::1;::::0;11136:18:16;;22554:57:15::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22629:15;::::0;::::1;::::0;22531:80;;-1:-1:-1;;;;;;22629:31:15;;::::1;:15:::0;::::1;:31;22621:66;;;::::0;-1:-1:-1;;;22621:66:15;;19447:2:16;22621:66:15::1;::::0;::::1;19429:21:16::0;19486:2;19466:18;;;19459:30;-1:-1:-1;;;19505:18:16;;;19498:52;19567:18;;22621:66:15::1;19245:346:16::0;22621:66:15::1;22702:22:::0;;-1:-1:-1;;;22702:22:15;::::1;;;22698:105;;;22761:15;::::0;::::1;::::0;:31:::1;::::0;22779:13;;-1:-1:-1;;;;;22761:15:15::1;:31;:::i;:::-;22740:17;:52:::0;;:17:::1;::::0;:52:::1;::::0;;;-1:-1:-1;;;22740:52:15;::::1;-1:-1:-1::0;;;;;22740:52:15::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;22740:52:15::1;;;;;-1:-1:-1::0;;;;;22740:52:15::1;;;;;;22698:105;22863:15;::::0;::::1;::::0;22817:77:::1;::::0;;-1:-1:-1;;;;;22863:15:15;;::::1;12274:34:16::0;;12344:15;;;12339:2;12324:18;;12317:43;-1:-1:-1;;;;;22817:77:15;::::1;::::0;::::1;::::0;12202:18:16;22817:77:15::1;;;;;;;22905:15;::::0;::::1;:31:::0;;-1:-1:-1;;;;;;22905:31:15::1;-1:-1:-1::0;;;;;22905:31:15;;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;22968:18:15;;::::1;::::0;;::::1;-1:-1:-1::0;22946:103:15::1;;;23023:15;::::0;::::1;::::0;;-1:-1:-1;;;;;;;;23023:15:15;::::1;23002:36;-1:-1:-1::0;;;;;;;;23002:36:15;;::::1;;::::0;;22946:103:::1;23063:15;::::0;::::1;::::0;-1:-1:-1;;;;;23063:15:15::1;;:20:::0;23059:85:::1;;23099:34;23116:16;23099;:34::i;23433:1053::-:0;23569:16;9774:30;9787:16;9774:12;:30::i;:::-;9766:64;;;;-1:-1:-1;;;9766:64:15;;;;;;;:::i;:::-;-1:-1:-1;;;;;9844:30:15;;9864:10;9844:30;9840:184;;9912:34;;-1:-1:-1;;;9912:34:15;;-1:-1:-1;;;;;4914:32:16;;;9912:34:15;;;4896:51:16;9891:13:15;;9912:8;:16;;;;;;4869:18:16;;9912:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;9890:56:15;;-1:-1:-1;;;;;;;9968:19:15;;9977:10;9968:19;9960:53;;;;-1:-1:-1;;;9960:53:15;;;;;;;:::i;:::-;9876:148;9840:184;23623:18:::1;-1:-1:-1::0;;;;;23605:36:15::1;:15;:36;23597:73;;;::::0;-1:-1:-1;;;23597:73:15;;19798:2:16;23597:73:15::1;::::0;::::1;19780:21:16::0;19837:2;19817:18;;;19810:30;19876:26;19856:18;;;19849:54;19920:18;;23597:73:15::1;19596:348:16::0;23597:73:15::1;23723:1;23701:19;-1:-1:-1::0;;;;;23701:23:15::1;;:309;;;;;23768:25;-1:-1:-1::0;;;;;23745:48:15::1;:19;-1:-1:-1::0;;;;;23745:48:15::1;;:120;;;;23840:25;-1:-1:-1::0;;;;;23817:48:15::1;:19;-1:-1:-1::0;;;;;23817:48:15::1;;23745:120;:192;;;;23912:25;-1:-1:-1::0;;;;;23889:48:15::1;:19;-1:-1:-1::0;;;;;23889:48:15::1;;23745:192;:264;;;;23984:25;-1:-1:-1::0;;;;;23961:48:15::1;:19;-1:-1:-1::0;;;;;23961:48:15::1;;23745:264;23680:407;;;::::0;-1:-1:-1;;;23680:407:15;;20151:2:16;23680:407:15::1;::::0;::::1;20133:21:16::0;20190:2;20170:18;;;20163:30;20229:34;20209:18;;;20202:62;-1:-1:-1;;;20280:18:16;;;20273:49;20339:19;;23680:407:15::1;19949:415:16::0;23680:407:15::1;-1:-1:-1::0;;;;;24132:37:15;::::1;24097:32;24132:37:::0;;;:19:::1;:37;::::0;;;;24187:23:::1;::::0;::::1;::::0;-1:-1:-1;;;24187:23:15;::::1;-1:-1:-1::0;;;;;24187:23:15::1;:28:::0;24179:88:::1;;;::::0;-1:-1:-1;;;24179:88:15;;20571:2:16;24179:88:15::1;::::0;::::1;20553:21:16::0;20610:2;20590:18;;;20583:30;20649:34;20629:18;;;20622:62;-1:-1:-1;;;20700:18:16;;;20693:45;20755:19;;24179:88:15::1;20369:411:16::0;24179:88:15::1;24285:18;::::0;::::1;::::0;-1:-1:-1;;;;;24285:18:15::1;:23:::0;24277:59:::1;;;::::0;-1:-1:-1;;;24277:59:15;;20987:2:16;24277:59:15::1;::::0;::::1;20969:21:16::0;21026:2;21006:18;;;20999:30;21065:25;21045:18;;;21038:53;21108:18;;24277:59:15::1;20785:347:16::0;24277:59:15::1;24367:45;24393:19:::0;24374:15:::1;24367:45;:::i;:::-;24346:18;::::0;::::1;:66:::0;;-1:-1:-1;;24346:66:15::1;-1:-1:-1::0;;;;;24346:66:15;;;::::1;::::0;;::::1;::::0;;24427:52:::1;::::0;4673:50:16;;;-1:-1:-1;;;;;24427:52:15;::::1;::::0;::::1;::::0;4661:2:16;4646:18;24427:52:15::1;;;;;;;23587:899;23433:1053:::0;;;:::o;35321:585::-;-1:-1:-1;;;;;35410:30:15;;35402:77;;;;-1:-1:-1;;;35402:77:15;;21730:2:16;35402:77:15;;;21712:21:16;21769:2;21749:18;;;21742:30;21808:34;21788:18;;;21781:62;-1:-1:-1;;;21859:18:16;;;21852:32;21901:19;;35402:77:15;21528:398:16;35402:77:15;-1:-1:-1;;;;;35524:37:15;;;35489:32;35524:37;;;:19;:37;;;;;;;;;35650:15;;;;35748:13;;35576:195;;-1:-1:-1;;;;;35650:15:15;;;22201:34:16;;-1:-1:-1;;;35679:18:15;;;22251::16;;;22244:43;;;;-1:-1:-1;;;35711:23:15;;;-1:-1:-1;;;;;35711:23:15;22303:18:16;;;22296:59;35748:13:15;;;22386:2:16;22371:18;;22364:60;35576:195:15;;;;22143:3:16;35576:195:15;;;;;;;35781:44;35802:16;35820:4;35781:20;:44::i;:::-;35835:16;;35885:13;;35835:64;;-1:-1:-1;;;35835:64:15;;-1:-1:-1;;;;;11219:15:16;;;35835:64:15;;;11201:34:16;35885:13:15;;;11251:18:16;;;11244:43;35835:16:15;;;:31;;11136:18:16;;35835:64:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35392:514;35321:585;:::o;17320:1117::-;9518:10;-1:-1:-1;;;;;9540:8:15;9518:31;;9510:81;;;;-1:-1:-1;;;9510:81:15;;;;;;;:::i;:::-;17497:16:::1;9343:38;9364:16;9343:20;:38::i;:::-;-1:-1:-1::0;;;;;17546:30:15;::::2;::::0;;::::2;::::0;:47:::2;;;17592:1;17580:9;-1:-1:-1::0;;;;;17580:13:15::2;;17546:47;17525:128;;;::::0;-1:-1:-1;;;17525:128:15;;22637:2:16;17525:128:15::2;::::0;::::2;22619:21:16::0;22676:2;22656:18;;;22649:30;22715:34;22695:18;;;22688:62;-1:-1:-1;;;22766:18:16;;;22759:32;22808:19;;17525:128:15::2;22435:398:16::0;17525:128:15::2;17684:20;-1:-1:-1::0;;;;;17671:33:15::2;:9;-1:-1:-1::0;;;;;17671:33:15::2;;;17663:88;;;::::0;-1:-1:-1;;;17663:88:15;;23040:2:16;17663:88:15::2;::::0;::::2;23022:21:16::0;23079:2;23059:18;;;23052:30;23118:34;23098:18;;;23091:62;-1:-1:-1;;;23169:18:16;;;23162:40;23219:19;;17663:88:15::2;22838:406:16::0;17663:88:15::2;-1:-1:-1::0;;;;;17797:37:15;;::::2;17762:32;17797:37:::0;;;:19:::2;:37;::::0;;;;;;;17865:28:::2;:46:::0;;;;;;;17797:37;;17865:46:::2;:60:::0;;:146:::2;;-1:-1:-1::0;;;;;;17945:66:15;;::::2;:46;::::0;;;:28:::2;:46;::::0;;;;;;;::::2;:66;17865:146;17844:245;;;::::0;-1:-1:-1;;;17844:245:15;;23451:2:16;17844:245:15::2;::::0;::::2;23433:21:16::0;23490:2;23470:18;;;23463:30;23529:34;23509:18;;;23502:62;-1:-1:-1;;;23580:18:16;;;23573:50;23640:19;;17844:245:15::2;23249:416:16::0;17844:245:15::2;18104:22:::0;;-1:-1:-1;;;18104:22:15;::::2;;;18100:160;;;18142:49;18173:4;18179:11;18142:30;:49::i;:::-;18226:23;18238:11:::0;18226:9;:23:::2;:::i;:::-;18205:17;:44:::0;;:17:::2;::::0;:44:::2;::::0;;;-1:-1:-1;;;18205:44:15;::::2;-1:-1:-1::0;;;;;18205:44:15::2;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;18205:44:15::2;;;;;-1:-1:-1::0;;;;;18205:44:15::2;;;;;;18100:160;18270:15;::::0;::::2;:27:::0;;-1:-1:-1;;;;;;18270:27:15::2;-1:-1:-1::0;;;;;18270:27:15;;::::2;::::0;;::::2;::::0;;;18312:64:::2;::::0;;12292:15:16;;;12274:34;;12339:2;12324:18;;12317:43;;;;-1:-1:-1;;;;;18312:64:15;::::2;::::0;::::2;::::0;12202:18:16;18312:64:15::2;12059:307:16::0;13756:349:15;13826:17;;13803:7;;-1:-1:-1;;;13826:17:15;;-1:-1:-1;;;;;13826:17:15;:22;;13822:80;;-1:-1:-1;13871:20:15;;-1:-1:-1;;;;;13871:20:15;;13756:349::o;13822:80::-;14046:17;;14012:18;;13994:14;;13911;;-1:-1:-1;;;14046:17:15;;-1:-1:-1;;;;;14046:17:15;;14012:18;13965:26;:24;:26::i;:::-;:43;;;;:::i;:::-;13964:66;;;;:::i;:::-;13963:100;;;;:::i;:::-;13928:20;;:135;;;-1:-1:-1;;;;;13928:20:15;:135;:::i;:::-;13911:152;;14080:18;:6;:16;:18::i;:::-;14073:25;;;13756:349;:::o;36191:378::-;36313:11;;-1:-1:-1;;;;;36313:11:15;36299:10;:25;36291:71;;;;-1:-1:-1;;;36291:71:15;;23872:2:16;36291:71:15;;;23854:21:16;23911:2;23891:18;;;23884:30;23950:34;23930:18;;;23923:62;-1:-1:-1;;;24001:18:16;;;23994:31;24042:19;;36291:71:15;23670:397:16;36291:71:15;36414:16;;;36428:1;36414:16;;;;;;;;;36372:39;;36414:16;;;;;;;;;;;-1:-1:-1;36414:16:15;36372:58;;36468:16;36440:22;36463:1;36440:25;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36440:44:15;;;:25;;;;;;;;;:44;36494:68;;-1:-1:-1;;;36494:68:15;;:8;:14;;;;;;:68;;36509:8;;36519:3;;36524:13;;36539:22;;36494:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36281:288;36191:378;;;:::o;3381:215:12:-;2310:13;:11;:13::i;:::-;-1:-1:-1;;;;;3465:22:12;::::1;3461:91;;3510:31;::::0;-1:-1:-1;;;3510:31:12;;3538:1:::1;3510:31;::::0;::::1;4896:51:16::0;4869:18;;3510:31:12::1;4734:219:16::0;3461:91:12::1;3561:28;3580:8;3561:18;:28::i;14259:450:15:-:0;-1:-1:-1;;;;;14385:37:15;;14332:6;14385:37;;;:19;:37;;;;;14437:22;;-1:-1:-1;;;14437:22:15;;;;14432:73;;14482:12;;;-1:-1:-1;;;;;14482:12:15;;14259:450;-1:-1:-1;;14259:450:15:o;14432:73::-;14656:12;;;;14514:14;;-1:-1:-1;;;;;14656:12:15;5650:38;5586:7;5680:8;5650:38;:::i;:::-;14579:23;;;;-1:-1:-1;;;14579:23:15;;-1:-1:-1;;;;;14579:23:15;14560:16;:14;:16::i;:::-;:42;;;;:::i;:::-;14540:15;;;;14532:71;;-1:-1:-1;;;;;14532:71:15;;-1:-1:-1;;;;;14540:15:15;14532:71;:::i;:::-;14531:110;;;;:::i;:::-;:137;;;;:::i;:::-;14514:154;;14685:17;:6;:15;:17::i;:::-;14678:24;14259:450;-1:-1:-1;;;;14259:450:15:o;29802:151::-;-1:-1:-1;;;;;29894:37:15;29871:4;29894:37;;;:19;:37;;;;;:48;;;-1:-1:-1;;;;;29894:48:15;:52;;;29802:151::o;13014:439::-;13112:16;:14;:16::i;:::-;13089:20;:39;;-1:-1:-1;;;;;;13089:39:15;-1:-1:-1;;;;;13089:39:15;;;;;;;;;;13155:26;:24;:26::i;:::-;13138:14;:43;-1:-1:-1;;;;;13195:30:15;;;13191:256;;-1:-1:-1;;;;;13276:37:15;;13241:32;13276:37;;;:19;:37;;;;;13342:34;13296:16;13342;:34::i;:::-;13327:12;;;;;:49;;-1:-1:-1;;;;;;13327:49:15;-1:-1:-1;;;;;13327:49:15;;;;;;;;13416:20;;-1:-1:-1;;;;;13416:20:15;-1:-1:-1;;;13390:46:15;;;;;;-1:-1:-1;13014:439:15:o;2634:162:12:-;951:10:1;2693:7:12;1289:22;2546:8;-1:-1:-1;;;;;2546:8:12;;2417:144;2693:7;-1:-1:-1;;;;;2693:23:12;;2689:101;;2739:40;;-1:-1:-1;;;2739:40:12;;951:10:1;2739:40:12;;;4896:51:16;4869:18;;2739:40:12;4734:219:16;16674:261:15;16816:16;;;;-1:-1:-1;;;;;16816:33:15;;;:16;;:33;16812:117;;16886:16;;;;:32;;16905:13;;-1:-1:-1;;;;;16886:16:15;:32;:::i;:::-;16865:17;:53;;:17;;:53;;;;-1:-1:-1;;;16865:53:15;;-1:-1:-1;;;;;16865:53:15;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;16865:53:15;;;;;-1:-1:-1;;;;;16865:53:15;;;;;;16674:261;;:::o;34291:432::-;-1:-1:-1;;;;;34397:37:15;;;34362:32;34397:37;;;:19;:37;;;;;;;;34473:13;;;;34444:43;;:28;:43;;;;;;;:56;;-1:-1:-1;;;;;;34444:56:15;;;34510:26;;-1:-1:-1;;;;;;34546:30:15;;;-1:-1:-1;34586:23:15;;:27;;-1:-1:-1;;;;;34586:27:15;;;34623:18;;;:22;;-1:-1:-1;;34623:22:15;;;34655:16;;:61;;-1:-1:-1;;;34655:61:15;;;;;11201:34:16;;;;11251:18;;;11244:43;;;;34397:37:15;;34655:16;;:31;;11136:18:16;;34655:61:15;10989:304:16;34810:316:15;34942:16;;;35022;;;34942:177;;-1:-1:-1;;;34942:177:15;;-1:-1:-1;;;;;25455:32:16;;;34942:177:15;;;25437:51:16;-1:-1:-1;;;;;35022:16:15;;;25549:18:16;;;25542:43;-1:-1:-1;;;35052:19:15;;;25601:18:16;;;25594:43;-1:-1:-1;;;35085:24:15;;;-1:-1:-1;;;;;35085:24:15;25653:18:16;;;25646:59;34942:16:15;;;:36;;25409:19:16;;34942:177:15;25212:499:16;1271:160:14;1380:43;;-1:-1:-1;;;;;25908:32:16;;;1380:43:14;;;25890:51:16;25957:18;;;25950:34;;;1353:71:14;;1373:5;;1395:14;;;;;25863:18:16;;1380:43:14;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1380:43:14;;;;;;;;;;;1353:19;:71::i;3750:248:12:-;1289:22;3899:8;;-1:-1:-1;;;;;;3917:19:12;;-1:-1:-1;;;;;3917:19:12;;;;;;;;3951:40;;3899:8;;;;;3951:40;;3823:24;;3951:40;3813:185;;3750:248;:::o;1670:188:14:-;1797:53;;-1:-1:-1;;;;;26253:15:16;;;1797:53:14;;;26235:34:16;26305:15;;;26285:18;;;26278:43;26337:18;;;26330:34;;;1770:81:14;;1790:5;;1812:18;;;;;26170::16;;1797:53:14;25995:375:16;2557:104:11;2615:7;2645:1;2641;:5;:13;;2653:1;2641:13;;;-1:-1:-1;2649:1:11;;2634:20;-1:-1:-1;2557:104:11:o;1823:127:12:-;6931:20:10;:18;:20::i;:::-;1905:38:12::1;1930:12;1905:24;:38::i;7223:218:13:-:0;7280:7;-1:-1:-1;;;;;7303:25:13;;7299:105;;;7351:42;;-1:-1:-1;;;7351:42:13;;7382:3;7351:42;;;26557:36:16;26609:18;;;26602:34;;;26530:18;;7351:42:13;26375:267:16;7299:105:13;-1:-1:-1;7428:5:13;7223:218::o;11291:213::-;11347:6;-1:-1:-1;;;;;11369:24:13;;11365:103;;;11416:41;;-1:-1:-1;;;11416:41:13;;11447:2;11416:41;;;26557:36:16;26609:18;;;26602:34;;;26530:18;;11416:41:13;26375:267:16;4027:629:14;4446:23;4472:33;-1:-1:-1;;;;;4472:27:14;;4500:4;4472:27;:33::i;:::-;4446:59;;4519:10;:17;4540:1;4519:22;;:57;;;;;4557:10;4546:30;;;;;;;;;;;;:::i;:::-;4545:31;4519:57;4515:135;;;4599:40;;-1:-1:-1;;;4599:40:14;;-1:-1:-1;;;;;4914:32:16;;4599:40:14;;;4896:51:16;4869:18;;4599:40:14;4734:219:16;7084:141:10;8870:21;8560:40;-1:-1:-1;;;8560:40:10;;;;7146:73;;7191:17;;-1:-1:-1;;;7191:17:10;;;;;;;;;;;1956:235:12;6931:20:10;:18;:20::i;2705:151:0:-;2780:12;2811:38;2833:6;2841:4;2847:1;2780:12;3421;3435:23;3462:6;-1:-1:-1;;;;;3462:11:0;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;:::-;3503:62;3180:392;-1:-1:-1;;;;;;3180:392:0:o;4625:582::-;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;;;;;;5071:18:0;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:0;;-1:-1:-1;;;;;4914:32:16;;5121:24:0;;;4896:51:16;4869:18;;5121:24:0;4734:219:16;5041:119:0;-1:-1:-1;5180:10:0;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:0;;;;;;;;;;;14:131:16;-1:-1:-1;;;;;89:31:16;;79:42;;69:70;;135:1;132;125:12;150:388;218:6;226;279:2;267:9;258:7;254:23;250:32;247:52;;;295:1;292;285:12;247:52;334:9;321:23;353:31;378:5;353:31;:::i;:::-;403:5;-1:-1:-1;460:2:16;445:18;;432:32;473:33;432:32;473:33;:::i;:::-;525:7;515:17;;;150:388;;;;;:::o;543:247::-;602:6;655:2;643:9;634:7;630:23;626:32;623:52;;;671:1;668;661:12;623:52;710:9;697:23;729:31;754:5;729:31;:::i;2017:137::-;-1:-1:-1;;;;;2095:5:16;2091:38;2084:5;2081:49;2071:77;;2144:1;2141;2134:12;2159:525;2234:6;2242;2250;2303:2;2291:9;2282:7;2278:23;2274:32;2271:52;;;2319:1;2316;2309:12;2271:52;2358:9;2345:23;2377:31;2402:5;2377:31;:::i;:::-;2427:5;-1:-1:-1;2484:2:16;2469:18;;2456:32;2497;2456;2497;:::i;:::-;2548:7;-1:-1:-1;2607:2:16;2592:18;;2579:32;2620;2579;2620;:::i;:::-;2671:7;2661:17;;;2159:525;;;;;:::o;2871:315::-;2939:6;2947;3000:2;2988:9;2979:7;2975:23;2971:32;2968:52;;;3016:1;3013;3006:12;2968:52;3055:9;3042:23;3074:31;3099:5;3074:31;:::i;:::-;3124:5;3176:2;3161:18;;;;3148:32;;-1:-1:-1;;;2871:315:16:o;3404:412::-;3480:6;3488;3496;3549:2;3537:9;3528:7;3524:23;3520:32;3517:52;;;3565:1;3562;3555:12;3517:52;3601:9;3588:23;3578:33;;3658:2;3647:9;3643:18;3630:32;3620:42;;3712:2;3701:9;3697:18;3684:32;3756:10;3749:5;3745:22;3738:5;3735:33;3725:61;;3782:1;3779;3772:12;3821:703;3991:4;4039:2;4028:9;4024:18;4069:6;4058:9;4051:25;4095:2;4133;4128;4117:9;4113:18;4106:30;4156:6;4191;4185:13;4222:6;4214;4207:22;4260:2;4249:9;4245:18;4238:25;;4298:2;4290:6;4286:15;4272:29;;4319:1;4329:169;4343:6;4340:1;4337:13;4329:169;;;4404:13;;4392:26;;4473:15;;;;4438:12;;;;4365:1;4358:9;4329:169;;;-1:-1:-1;4515:3:16;;3821:703;-1:-1:-1;;;;;;;3821:703:16:o;5166:245::-;5224:6;5277:2;5265:9;5256:7;5252:23;5248:32;5245:52;;;5293:1;5290;5283:12;5245:52;5332:9;5319:23;5351:30;5375:5;5351:30;:::i;6246:180::-;6305:6;6358:2;6346:9;6337:7;6333:23;6329:32;6326:52;;;6374:1;6371;6364:12;6326:52;-1:-1:-1;6397:23:16;;6246:180;-1:-1:-1;6246:180:16:o;6431:427::-;6498:6;6506;6559:2;6547:9;6538:7;6534:23;6530:32;6527:52;;;6575:1;6572;6565:12;6527:52;6614:9;6601:23;6633:31;6658:5;6633:31;:::i;:::-;6683:5;-1:-1:-1;6740:2:16;6725:18;;6712:32;-1:-1:-1;;;;;6775:32:16;;6763:45;;6753:73;;6822:1;6819;6812:12;7295:527;7371:6;7379;7387;7440:2;7428:9;7419:7;7415:23;7411:32;7408:52;;;7456:1;7453;7446:12;7408:52;7495:9;7482:23;7514:31;7539:5;7514:31;:::i;:::-;7564:5;-1:-1:-1;7621:2:16;7606:18;;7593:32;7634;7593;7634;:::i;:::-;7685:7;-1:-1:-1;7744:2:16;7729:18;;7716:32;7757:33;7716:32;7757:33;:::i;8049:345::-;8251:2;8233:21;;;8290:2;8270:18;;;8263:30;-1:-1:-1;;;8324:2:16;8309:18;;8302:51;8385:2;8370:18;;8049:345::o;8399:527::-;8495:6;8503;8511;8564:2;8552:9;8543:7;8539:23;8535:32;8532:52;;;8580:1;8577;8570:12;8532:52;8612:9;8606:16;8631:31;8656:5;8631:31;:::i;:::-;8731:2;8716:18;;8710:25;8681:5;;-1:-1:-1;8744:33:16;8710:25;8744:33;:::i;:::-;8848:2;8833:18;;8827:25;8796:7;;-1:-1:-1;8861:33:16;8827:25;8861:33;:::i;9355:127::-;9416:10;9411:3;9407:20;9404:1;9397:31;9447:4;9444:1;9437:15;9471:4;9468:1;9461:15;9487:125;9552:9;;;9573:10;;;9570:36;;;9586:18;;:::i;10793:191::-;-1:-1:-1;;;;;10920:10:16;;;10908;;;10904:27;;10943:12;;;10940:38;;;10958:18;;:::i;:::-;10940:38;10793:191;;;;:::o;11653:401::-;11855:2;11837:21;;;11894:2;11874:18;;;11867:30;11933:34;11928:2;11913:18;;11906:62;-1:-1:-1;;;11999:2:16;11984:18;;11977:35;12044:3;12029:19;;11653:401::o;13134:128::-;13201:9;;;13222:11;;;13219:37;;;13236:18;;:::i;13267:127::-;13328:10;13323:3;13319:20;13316:1;13309:31;13359:4;13356:1;13349:15;13383:4;13380:1;13373:15;13399:127;13460:10;13455:3;13451:20;13448:1;13441:31;13491:4;13488:1;13481:15;13515:4;13512:1;13505:15;13531:135;13570:3;13591:17;;;13588:43;;13611:18;;:::i;:::-;-1:-1:-1;13658:1:16;13647:13;;13531:135::o;15009:188::-;-1:-1:-1;;;;;15122:10:16;;;15134;;;15118:27;;15157:11;;;15154:37;;;15171:18;;:::i;17565:168::-;17638:9;;;17669;;17686:15;;;17680:22;;17666:37;17656:71;;17707:18;;:::i;17738:217::-;17778:1;17804;17794:132;;17848:10;17843:3;17839:20;17836:1;17829:31;17883:4;17880:1;17873:15;17911:4;17908:1;17901:15;17794:132;-1:-1:-1;17940:9:16;;17738:217::o;18777:249::-;18846:6;18899:2;18887:9;18878:7;18874:23;18870:32;18867:52;;;18915:1;18912;18905:12;18867:52;18947:9;18941:16;18966:30;18990:5;18966:30;:::i;21137:180::-;-1:-1:-1;;;;;21242:10:16;;;21254;;;21238:27;;21277:11;;;21274:37;;;21291:18;;:::i;24072:945::-;-1:-1:-1;;;;;24385:39:16;;24367:58;;24444:2;24462:18;;;24455:34;;;-1:-1:-1;;;;;24563:15:16;;;24558:2;24543:18;;24536:43;24354:3;24610:2;24595:18;;24588:31;;;24668:13;;24339:19;;;24690:22;;;24306:4;;24770:15;;;;24444:2;;24516:3;24728:19;;;24306:4;24813:178;24827:6;24824:1;24821:13;24813:178;;;24892:13;;24888:22;;24876:35;;24966:15;;;;24931:12;;;;24849:1;24842:9;24813:178;;;-1:-1:-1;25008:3:16;;24072:945;-1:-1:-1;;;;;;;;;;24072:945:16:o;25022:185::-;-1:-1:-1;;;;;25143:10:16;;;25131;;;25127:27;;25166:12;;;25163:38;;;25181:18;;:::i;26918:277::-;26985:6;27038:2;27026:9;27017:7;27013:23;27009:32;27006:52;;;27054:1;27051;27044:12;27006:52;27086:9;27080:16;27139:5;27132:13;27125:21;27118:5;27115:32;27105:60;;27161:1;27158;27151:12;27200:412;27329:3;27367:6;27361:13;27392:1;27402:129;27416:6;27413:1;27410:13;27402:129;;;27514:4;27498:14;;;27494:25;;27488:32;27475:11;;;27468:53;27431:12;27402:129;;;-1:-1:-1;27586:1:16;27550:16;;27575:13;;;-1:-1:-1;27550:16:16;27200:412;-1:-1:-1;27200:412:16:o
Swarm Source
ipfs://54c1baa24cdc63ac1ba9c8a897ef2e9c3550525c49b7bced055e14c270551b82
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.