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 | 18728528 | 268 days ago | IN | 0 ETH | 0.22205932 |
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, 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) == address(0), "Child application is already set"); 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 Get all tokens delegated to the staking provider */ function getEligibleAmount(StakingProviderInfo storage _info) internal view returns (uint96) { return _info.authorized - _info.deauthorizing; } /** * @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 * @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 ) 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 resultIndex = 0; for (uint256 i = _startIndex; i < endIndex; i++) { address stakingProvider = stakingProviders[i]; StakingProviderInfo storage info = stakingProviderInfo[stakingProvider]; uint256 eligibleAmount = getEligibleAmount(info); 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 { // TODO send both authorized and eligible amounts in case of slashing from child app uint96 eligibleAmount = getEligibleAmount(_info); childApplication.updateAuthorization(_stakingProvider, eligibleAmount); } /** * @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.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 amount); function updateOperator(address stakingProvider, address operator) external; function updateAuthorization(address stakingProvider, uint96 amount) 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":"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":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_maxStakingProviders","type":"uint256"}],"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
6101e06040523480156200001257600080fd5b506040516200437e3803806200437e83398101604081905262000035916200049f565b6000886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000076573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009c9190620005e3565b90508415801590620001265750604051637004922d60e11b8152306004820181905260248201526001600160a01b0389169063e009245a90604401602060405180830381865afa158015620000f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200011b9190620005fd565b6001600160601b0316155b8015620001335750600081115b80156200014257506001835110155b80156200015157506004835111155b620001a35760405162461bcd60e51b815260206004820152601660248201527f57726f6e6720696e70757420706172616d65746572730000000000000000000060448201526064015b60405180910390fd5b6001600160a01b03620001c16103e8670de0b6b3a764000062000622565b620001ce600a846200064e565b620001da919062000622565b11158015620001fa5750670de0b6b3a7640000876001600160601b031610155b80156200020a5750620151808510155b6200024d5760405162461bcd60e51b8152602060048201526012602482015271506f74656e7469616c206f766572666c6f7760701b60448201526064016200019a565b60c085905260e08490526001600160601b0387166080526001600160a01b03808a166101c05288166101a05260a08690528251839060009062000294576200029462000671565b60209081029190910101516001600160401b031661010052825160021115620002bf576000620002de565b82600181518110620002d557620002d562000671565b60200260200101515b6001600160401b031661012052825160031115620002fe5760006200031d565b8260028151811062000314576200031462000671565b60200260200101515b6001600160401b0316610140528251600411156200033d5760006200035c565b8260038151811062000353576200035362000671565b60200260200101515b6001600160401b03908116610160528216610180526200037b6200038a565b50505050505050505062000687565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620003db5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146200043b5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6001600160a01b03811681146200043b57600080fd5b80516001600160601b03811681146200046c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516001600160401b03811681146200046c57600080fd5b600080600080600080600080610100898b031215620004bd57600080fd5b8851620004ca816200043e565b809850506020808a0151620004df816200043e565b9750620004ef60408b0162000454565b60608b015160808c015160a08d015160c08e0151939a50919850965094506001600160401b03808211156200052357600080fd5b818c0191508c601f8301126200053857600080fd5b8151818111156200054d576200054d62000471565b8060051b604051601f19603f8301168101818110858211171562000575576200057562000471565b60405291825284820192508381018501918f8311156200059457600080fd5b938501935b82851015620005bd57620005ad8562000487565b8452938501939285019262000599565b809750505050505050620005d460e08a0162000487565b90509295985092959890939650565b600060208284031215620005f657600080fd5b5051919050565b6000602082840312156200061057600080fd5b6200061b8262000454565b9392505050565b80820281158282048414176200064857634e487b7160e01b600052601160045260246000fd5b92915050565b6000826200066c57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c051613bba620007c460003960008181610a3a0152818161149a0152611c9801526000818161092301528181610b0c015281816111010152818161165c015281816116dc01528181611df70152818161218a015281816123e90152818161290b0152612f0901526000818161075f015261248701526000818161080c01526125c6015260008181610799015261258a015260008181610557015261254e015260008181610505015261251301526000818161066201528181610708015261194f015260008181610a0001528181611b3c01528181611bba0152611c270152600081816105bc0152610c74015260008181610636015281816109c6015281816117c2015281816129cc0152612da10152613bba6000f3fe608060405234801561001057600080fd5b50600436106103785760003560e01c806397b486e9116101d3578063d8dfde5611610104578063f0820c92116100a2578063f854a27f1161007c578063f854a27f14610a22578063fc0c546a14610a35578063fd2a478814610a5c578063fe9fbb8014610a9857600080fd5b8063f0820c92146109c1578063f2fde38b146109e8578063f520e7e5146109fb57600080fd5b8063df136d65116100de578063df136d6514610971578063e58e018e14610984578063ea0ffa4d146109a5578063ebe2b12b146109b857600080fd5b8063d8dfde5614610904578063dbaa0fc61461091e578063ded56d451461094557600080fd5b8063ba7e5b2b11610171578063c7c49c981161014b578063c7c49c98146108b4578063c8f33c91146108e0578063c9bacaad146108e9578063cd3daf9d146108fc57600080fd5b8063ba7e5b2b14610841578063bb42895114610854578063c4903d5b1461086757600080fd5b8063a1809b95116101ad578063a1809b95146107e1578063a48d2d41146107f4578063ab6ba2d014610807578063acc2166a1461082e57600080fd5b806397b486e9146107945780639c9de028146107bb5780639cafa103146107ce57600080fd5b80636a7f7a90116102ad57806380faa57d1161024b5780638d0853c1116102255780638d0853c1146107035780638da5cb5b1461072a5780638fa990e31461075a578063967c41991461078157600080fd5b806380faa57d146106eb5780638129fc1c146106f357806386f69014146106fb57600080fd5b806375e0ae5a1161028757806375e0ae5a1461060c578063796bb62b1461061f5780637b14729e146106285780637dbee7a31461069857600080fd5b80636a7f7a90146105de578063715018a6146105f157806373761605146105f957600080fd5b806342d866931161031a5780634cc20b11116102f45780634cc20b1114610552578063505a1b311461057957806353c2ed8e146105a457806369bdf9e4146105b757600080fd5b806342d86693146104ed578063495a507a146105005780634bae3b321461053f57600080fd5b806314a854741161035657806314a854741461049d5780633032398f146104b0578063334987ab146104c75780633682a450146104da57600080fd5b806302132c011461037d5780630ceff8c814610392578063104953bf1461048a575b600080fd5b61039061038b3660046136d4565b610aab565b005b61041b6103a036600461370d565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b038083169460ff600160a01b850416946001600160401b03600160a81b9095048516946001600160601b0380841695600160601b808604831696600160c01b9096048416959285169404909116911689565b604080516001600160a01b039a8b16815298151560208a01526001600160401b03978816908901526001600160601b039586166060890152938516608088015291851660a08701529290921660c0850152931660e0830152909116610100820152610120015b60405180910390f35b61039061049836600461370d565b611019565b6103906104ab36600461373f565b6110f6565b6104b96103e881565b604051908152602001610481565b6103906104d536600461370d565b6112a5565b6103906104e836600461370d565b611346565b6103906104fb36600461370d565b611353565b6105277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b039091168152602001610481565b61039061054d36600461370d565b6114ca565b6105277f000000000000000000000000000000000000000000000000000000000000000081565b61058c61058736600461370d565b61163a565b6040516001600160a01b039091168152602001610481565b60015461058c906001600160a01b031681565b6104b97f000000000000000000000000000000000000000000000000000000000000000081565b6103906105ec36600461373f565b6116d1565b6103906119f6565b61039061060736600461378a565b611a0a565b61039061061a36600461370d565b611ccd565b6104b960075481565b604080516001600160601b037f00000000000000000000000000000000000000000000000000000000000000001681526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000166020820181905291810191909152606001610481565b6106db6106a636600461370d565b6001600160a01b039081166000908152600460209081526040808320549093168252600290522054600160a01b900460ff1690565b6040519015158152602001610481565b6104b9611f5f565b610390611f72565b6003546104b9565b6104b97f000000000000000000000000000000000000000000000000000000000000000081565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661058c565b6105277f000000000000000000000000000000000000000000000000000000000000000081565b60005461058c906001600160a01b031681565b6105277f000000000000000000000000000000000000000000000000000000000000000081565b6105276107c936600461370d565b61207e565b61058c6107dc3660046137a7565b6120cb565b6103906107ef36600461370d565b6120f5565b61039061080236600461370d565b612147565b6105277f000000000000000000000000000000000000000000000000000000000000000081565b60055461058c906001600160a01b031681565b61039061084f3660046137c0565b612391565b61039061086236600461370d565b6127bf565b61089c61087536600461370d565b6001600160a01b03166000908152600260205260409020600101546001600160601b031690565b6040516001600160601b039091168152602001610481565b61058c6108c236600461370d565b6001600160a01b039081166000908152600260205260409020541690565b6104b960085481565b6103906108f736600461373f565b612900565b61058c612be7565b60095461089c90600160a01b90046001600160601b031681565b61058c7f000000000000000000000000000000000000000000000000000000000000000081565b61058c61095336600461370d565b6001600160a01b039081166000908152600460205260409020541690565b60095461058c906001600160a01b031681565b6109976109923660046137fa565b612c7e565b60405161048192919061381c565b6103906109b336600461386c565b612e4a565b6104b960065481565b61089c7f000000000000000000000000000000000000000000000000000000000000000081565b6103906109f636600461370d565b612f7f565b6104b97f000000000000000000000000000000000000000000000000000000000000000081565b61089c610a3036600461370d565b612fba565b61058c7f000000000000000000000000000000000000000000000000000000000000000081565b61089c610a6a36600461370d565b6001600160a01b0316600090815260026020526040902060010154600160601b90046001600160601b031690565b6106db610aa636600461370d565b613089565b81610ab581613089565b610ada5760405162461bcd60e51b8152600401610ad1906138ac565b60405180910390fd5b6001600160a01b0381163314610ba857604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa158015610b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7991906138db565b50909150506001600160a01b0381163314610ba65760405162461bcd60e51b8152600401610ad1906138ac565b505b82610bb2816130b2565b6001600160a01b03808516600090815260026020526040902080549091908116908516819003610c4a5760405162461bcd60e51b815260206004820152603760248201527f537065636966696564206f70657261746f7220697320616c726561647920626f60448201527f6e646564207769746820746869732070726f76696465720000000000000000006064820152608401610ad1565b6001600160a01b03811615610d32578154600160a01b900460ff161580610cad57508154610ca9907f000000000000000000000000000000000000000000000000000000000000000090600160a81b90046001600160401b0316613933565b4210155b610d0b5760405162461bcd60e51b815260206004820152602960248201527f4e6f7420656e6f7567682074696d652070617373656420746f206368616e67656044820152681037b832b930ba37b960b91b6064820152608401610ad1565b6001600160a01b038116600090815260046020526040902080546001600160a01b03191690555b6001600160a01b03851615610e61576001600160a01b038581166000908152600460205260409020541615610db55760405162461bcd60e51b8152602060048201526024808201527f537065636966696564206f70657261746f7220697320616c726561647920696e6044820152632075736560e01b6064820152608401610ad1565b856001600160a01b0316856001600160a01b03161480610de657506000610ddb8661163a565b6001600160a01b0316145b610e325760405162461bcd60e51b815260206004820181905260248201527f537065636966696564206f70657261746f7220697320612070726f76696465726044820152606401610ad1565b6001600160a01b03858116600090815260046020526040902080546001600160a01b0319169188169190911790555b8154600160a81b90046001600160401b0316600003610ec657600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0388161790555b8154600160a01b900460ff1615610f27576001820154600980546001600160601b0392831692601491610f02918591600160a01b900416613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b81546001600160a01b03868116600168ffffffffffffffff0160a01b03199092168217600160a81b426001600160401b0381169190910291909117855560405190815283821692918916907fa38fda88cb3c476adfa74c64be4d74c915b19a3e587e77b887ca804fb9c82c7c9060200160405180910390a4815460ff60a01b191682556000546040516346696b9f60e11b81526001600160a01b038881166004830152878116602483015290911690638cd2d73e90604401600060405180830381600087803b158015610ff957600080fd5b505af115801561100d573d6000803e3d6000fd5b50505050505050505050565b611021613151565b6000546001600160a01b03161561107a5760405162461bcd60e51b815260206004820181905260248201527f4368696c64206170706c69636174696f6e20697320616c7265616479207365746044820152606401610ad1565b6000816001600160a01b03163b116110d45760405162461bcd60e51b815260206004820152601a60248201527f4368696c6420617070206d75737420626520636f6e74726163740000000000006044820152606401610ad1565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461113e5760405162461bcd60e51b8152600401610ad19061396d565b82611148816130b2565b6001600160a01b03841660009081526002602052604090208054600160a01b900460ff16156111cc5761117b81856131ac565b6111858385613946565b600980546014906111a7908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821792839055600160601b909204909116111561122857600181018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b604080516001600160601b038087168252851660208201526001600160a01b038716917f72cc05b0073888d0e26528638b21fdaa2d4af96a641469fe63a87de3c4a84d79910160405180910390a260018101546001600160601b03166000036112945761129485613226565b61129e85826132c0565b5050505050565b6112ad613151565b6001546001600160a01b03908116908216036113245760405162461bcd60e51b815260206004820152603060248201527f4e65772061646472657373206d757374206e6f7420626520657175616c20746f60448201526f207468652063757272656e74206f6e6560801b6064820152608401610ad1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6113503382610aab565b50565b8061135d816130b2565b60006113688361163a565b9050336001600160a01b038216146113c25760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206d7573742062652062656e65666963696172790000000000006044820152606401610ad1565b6001600160a01b0383166000908152600260208190526040909120908101546001600160601b03168061142f5760405162461bcd60e51b81526020600482015260156024820152744e6f2072657761726420746f20776974686472617760581b6044820152606401610ad1565b6002820180546001600160601b03191690556040516001600160601b03821681526001600160a01b0384811691908716907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a361129e6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846001600160601b038416613340565b6000546001600160a01b0316331461153f5760405162461bcd60e51b815260206004820152603260248201527f4f6e6c79206368696c64206170706c69636174696f6e20616c6c6f7765642074604482015271379031b7b73334b9369037b832b930ba37b960711b6064820152608401610ad1565b6001600160a01b038082166000908152600460205260409020541680611563575050565b6001600160a01b03811660009081526002602052604090208054600160a01b900460ff1661163557611594826130b2565b805460ff60a01b1916600160a01b90811782556001820154600980546001600160601b039283169391926014926115d0928692919004166139b2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550826001600160a01b0316826001600160a01b03167fdbc602361eaa7fb503df3c16078c71b39d28412df5e9980bec6f489f78bb175c60405160405180910390a35b505050565b604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa1580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c991906138db565b509392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146117195760405162461bcd60e51b8152600401610ad19061396d565b82611723816130b2565b6001600160a01b038416600090815260026020526040902060018101546001600160601b0390811690841611156117af5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e7420746f2064656372656173652067726561746572207468616e20604482015269185d5d1a1bdc9a5e995960b21b6064820152608401610ad1565b6001600160601b03831615806117f757507f00000000000000000000000000000000000000000000000000000000000000006001600160601b0316836001600160601b031610155b61185d5760405162461bcd60e51b815260206004820152603160248201527f526573756c74696e6720617574686f72697a6174696f6e2077696c6c206265206044820152706c657373207468616e206d696e696d756d60781b6064820152608401610ad1565b6003810154426001600160401b0390911611156118db5760405162461bcd60e51b815260206004820152603660248201527f43616e27742072657175657374206465617574686f72697a6174696f6e206265604482015275199bdc9948195b99081bd98818dbdb5b5a5d1b595b9d60521b6064820152608401610ad1565b8054600160a01b900460ff16156118f6576118f681856131ac565b6001810180546001600160601b0319166001600160601b03861617905561191d8385613946565b6001820180546001600160601b0392909216600160601b02600160601b600160c01b03199092169190911790556119747f000000000000000000000000000000000000000000000000000000000000000042613933565b6001820180546001600160401b0392909216600160c01b026001600160c01b03909216919091179055604080516001600160601b038087168252851660208201526001600160a01b038716917f38b892bbec4f2d2e5372217fea7a4784417ae853489cd584b204f534b5c08f9591015b60405180910390a261129e85826132c0565b6119fe613151565b611a08600061339f565b565b6000611a15816130b2565b6005546001600160a01b03163314611a795760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79206469737472696275746f722063616e2070757368207265776172646044820152607360f81b6064820152608401610ad1565b6000826001600160601b031611611ad25760405162461bcd60e51b815260206004820152601860248201527f526577617264206d7573742062652073706563696669656400000000000000006044820152606401610ad1565b600954600160a01b90046001600160601b0316611b315760405162461bcd60e51b815260206004820152601b60248201527f4e6f20616374697665207374616b696e672070726f76696465727300000000006044820152606401610ad1565b6006544210611b94577f0000000000000000000000000000000000000000000000000000000000000000611b6f6103e8670de0b6b3a76400006139d2565b611b82906001600160601b0385166139d2565b611b8c91906139e9565b600755611c1b565b600042600654611ba49190613a0b565b9050600060075482611bb691906139d2565b90507f000000000000000000000000000000000000000000000000000000000000000081611bee6103e8670de0b6b3a76400006139d2565b611c01906001600160601b0388166139d2565b611c0b9190613933565b611c1591906139e9565b60075550505b426008819055611c4c907f000000000000000000000000000000000000000000000000000000000000000090613933565b6006556040516001600160601b03831681527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1611cc96001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633306001600160601b038616613410565b5050565b80611cd7816130b2565b6001600160a01b03821660009081526002602052604090206001810154600160601b90046001600160601b0316611d5c5760405162461bcd60e51b8152602060048201526024808201527f5468657265206973206e6f206465617574686f72697a696e6720696e2070726f6044820152636365737360e01b6064820152608401610ad1565b600181015442600160c01b9091046001600160401b03161115611dd55760405162461bcd60e51b815260206004820152602b60248201527f417574686f72697a6174696f6e20646563726561736520686173206e6f74206660448201526a1a5b9a5cda1959081e595d60aa1b6064820152608401610ad1565b604051633af0572d60e11b81526001600160a01b0384811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906375e0ae5a906024016020604051808303816000875af1158015611e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e669190613a1e565b8254909150600160a01b900460ff1615611eda576001820154611e939082906001600160601b0316613946565b60098054601490611eb5908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5879576c6c99ad6d1778483480ffa393a0f7b8ac18d53402720d8dd8e4617f7d910160405180910390a26001600160601b03811660018301819055600003611f4f57611f4f84613226565b611f5984836132c0565b50505050565b6000611f6d42600654613449565b905090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015611fb75750825b90506000826001600160401b03166001148015611fd35750303b155b905081158015611fe1575080155b15611fff5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561202957845460ff60401b1916600160401b1785555b61203233613463565b831561129e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038116600090815260026020526040812060010154600160c01b90046001600160401b03164281116120ba5750600092915050565b6120c44282613a0b565b9392505050565b600381815481106120db57600080fd5b6000918252602090912001546001600160a01b0316905081565b6120fd613151565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f075c02c513a415bd4ff5976f8aa6fc5767d2183daca9ec00ab71ce78e8bf815890600090a250565b80612151816130b2565b6001600160a01b038281166000818152600260205260408082209051637004922d60e11b815260048101939093523060248401529290917f00000000000000000000000000000000000000000000000000000000000000009091169063e009245a90604401602060405180830381865afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f79190613a1e565b60018301549091506001600160601b038083169116116122525760405162461bcd60e51b81526020600482015260166024820152754e6f7468696e6720746f2073796e6368726f6e697a6560501b6044820152606401610ad1565b8154600160a01b900460ff16156122c357600182015461227c9082906001600160601b0316613946565b6009805460149061229e908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5e26a115e9efdff9c71141dec1f9cc5dd2ec5e717da782cef55a475506e56788910160405180910390a26001820180546001600160601b0319166001600160601b0383811691821792839055600160601b909204909116111561237357600182018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b60018201546001600160601b0316600003611f4f57611f4f84613226565b8161239b81613089565b6123b75760405162461bcd60e51b8152600401610ad1906138ac565b6001600160a01b038116331461248557604051632de9480760e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632de9480790602401606060405180830381865afa158015612432573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245691906138db565b50909150506001600160a01b03811633146124835760405162461bcd60e51b8152600401610ad1906138ac565b505b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b031642106124fd5760405162461bcd60e51b815260206004820152601860248201527f436f6d6d69746d656e742077696e646f7720636c6f73656400000000000000006044820152606401610ad1565b6000826001600160401b03161180156125fa57507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316148061258257507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b806125be57507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b806125fa57507f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b0316145b6126625760405162461bcd60e51b815260206004820152603360248201527f436f6d6d69746d656e74206475726174696f6e206d75737420626520657175616044820152726c20746f206f6e65206f66206f7074696f6e7360681b6064820152608401610ad1565b6001600160a01b03831660009081526002602052604090206001810154600160c01b90046001600160401b0316156126f45760405162461bcd60e51b815260206004820152602f60248201527f436f6d6d69746d656e742063616e2774206265206d61646520647572696e672060448201526e3232b0baba3437b934bd30ba34b7b760891b6064820152608401610ad1565b60038101546001600160401b03161561274f5760405162461bcd60e51b815260206004820152601760248201527f436f6d6d69746d656e7420616c7265616479206d6164650000000000000000006044820152606401610ad1565b6127598342613a3b565b60038201805467ffffffffffffffff19166001600160401b039290921691821790556040519081526001600160a01b038516907f293c61c79ecf0bcac67f97a5925ba2e75c025c6231a4ab629862b570730a264b9060200160405180910390a250505050565b6001600160a01b0381166128205760405162461bcd60e51b815260206004820152602260248201527f5374616b696e672070726f7669646572206d7573742062652073706563696669604482015261195960f21b6064820152608401610ad1565b6001600160a01b038181166000818152600260209081526040918290206001810154815484516001600160601b03909216825290951691850191909152927f8dd220764537278d5094ef78e8e7584b819d083dd7905d32d09a928ec26466f2910160405180910390a261289382826132c0565b60005481546040516346696b9f60e11b81526001600160a01b0385811660048301529182166024820152911690638cd2d73e906044015b600060405180830381600087803b1580156128e457600080fd5b505af11580156128f8573d6000803e3d6000fd5b505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146129485760405162461bcd60e51b8152600401610ad19061396d565b82612952816130b2565b6001600160a01b0384161580159061297357506000826001600160601b0316115b6129ca5760405162461bcd60e51b815260206004820152602260248201527f496e70757420706172616d6574657273206d7573742062652073706563696669604482015261195960f21b6064820152608401610ad1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160601b0316826001600160601b03161015612a5f5760405162461bcd60e51b815260206004820152602a60248201527f417574686f72697a6174696f6e206d7573742062652067726561746572207468604482015269616e206d696e696d756d60b01b6064820152608401610ad1565b6001600160a01b0380851660009081526002602090815260408083206004909252909120549091161580612aad57506001600160a01b03808616600081815260046020526040902054909116145b612b165760405162461bcd60e51b815260206004820152603460248201527f412070726f76696465722063616e277420626520616e206f70657261746f72206044820152733337b91030b737ba3432b910383937bb34b232b960611b6064820152608401610ad1565b8054600160a01b900460ff1615612b8257612b3181856131ac565b612b3b8484613946565b60098054601490612b5d908490600160a01b90046001600160601b03166139b2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821790925560408051928716835260208301919091526001600160a01b038716917f9e46043a7120cf056d21eda9b6d78ffd99571a62fb6ff91a471a73e4b8484e1c91016119e4565b600954600090600160a01b90046001600160601b03168103612c1357506009546001600160a01b031690565b600954600754600854600092600160a01b90046001600160601b03169190612c39611f5f565b612c439190613a0b565b612c4d91906139d2565b612c5791906139e9565b600954612c6d91906001600160a01b0316613933565b9050612c7881613474565b91505090565b600354600090606090808510612cca5760405162461bcd60e51b81526020600482015260116024820152700aee4dedcce40e6e8c2e4e840d2dcc8caf607b1b6044820152606401610ad1565b8315801590612ce1575080612cdf8587613933565b105b15612cf357612cf08486613933565b90505b612cfd8582613a0b565b6001600160401b03811115612d1457612d14613a5b565b604051908082528060200260200182016040528015612d3d578160200160208202803683370190505b5060009350915082855b82811015612e3d57600060038281548110612d6457612d64613a71565b60009182526020808320909101546001600160a01b031680835260029091526040822090925090612d94826134ac565b6001600160601b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160601b0316811080612ddf57508154600160a01b900460ff16155b15612dec57505050612e35565b6001600160601b0319606084901b1681178786612e0881613a87565b975081518110612e1a57612e1a613a71565b6020908102919091010152612e2f8189613933565b97505050505b600101612d47565b5080835250509250929050565b6001546001600160a01b03163314612eae5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646a7564696361746f7220616c6c6f77656420746f20736c61736044820152600d60fb1b6064820152608401610ad1565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110612ee457612ee4613a71565b6001600160a01b0392831660209182029290920101526040516383ddba8f60e01b81527f0000000000000000000000000000000000000000000000000000000000000000909116906383ddba8f90612f4790869060649087908790600401613aa0565b600060405180830381600087803b158015612f6157600080fd5b505af1158015612f75573d6000803e3d6000fd5b5050505050505050565b612f87613151565b6001600160a01b038116612fb157604051631e4fbdf760e01b815260006004820152602401610ad1565b6113508161339f565b6001600160a01b03811660009081526002602052604081208054600160a01b900460ff16612ff557600201546001600160601b031692915050565b60028101546000906001600160601b031661301a6103e8670de0b6b3a76400006139d2565b6002840154600160601b90046001600160a01b0316613037612be7565b6130419190613b13565b6001850154613062916001600160a01b0316906001600160601b03166139d2565b61306c91906139e9565b6130769190613933565b9050613081816134d0565b949350505050565b6001600160a01b03166000908152600260205260409020600101546001600160601b0316151590565b6130ba612be7565b600980546001600160a01b0319166001600160a01b03929092169190911790556130e2611f5f565b6008556001600160a01b03811615611350576001600160a01b038116600090815260026020526040902061311582612fba565b60029190910180546001600160601b0319166001600160601b0390921691821781556009546001600160a01b0316600160601b02909117905550565b336131837f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614611a085760405163118cdaa760e01b8152336004820152602401610ad1565b60018201546001600160601b03828116911614611cc95760018201546131dc9082906001600160601b0316613946565b600980546014906131fe908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6001600160a01b03818116600081815260026020908152604080832080548616845260049283905281842080546001600160a01b031916905580546001600160a81b03191681556001810180546001600160c01b0316905560038101805467ffffffffffffffff19169055835491516346696b9f60e11b815292830194909452602482019290925291921690638cd2d73e906044016128ca565b60006132cb826134ac565b6000546040516334cdb41f60e11b81526001600160a01b0386811660048301526001600160601b038416602483015292935091169063699b683e90604401600060405180830381600087803b15801561332357600080fd5b505af1158015613337573d6000803e3d6000fd5b50505050505050565b6040516001600160a01b0383811660248301526044820183905261163591859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613504565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040516001600160a01b038481166024830152838116604483015260648201839052611f599186918216906323b872dd9060840161336d565b6000818310613458578161345a565b825b90505b92915050565b61346b613567565b611350816135b0565b60006001600160a01b038211156134a8576040516306dfcc6560e41b815260a0600482015260248101839052604401610ad1565b5090565b600181015460009061345d906001600160601b03600160601b820481169116613946565b60006001600160601b038211156134a8576040516306dfcc6560e41b81526060600482015260248101839052604401610ad1565b60006135196001600160a01b038416836135b8565b9050805160001415801561353e57508080602001905181019061353c9190613b33565b155b1561163557604051635274afe760e01b81526001600160a01b0384166004820152602401610ad1565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611a0857604051631afcd79f60e31b815260040160405180910390fd5b612f87613567565b606061345a8383600084600080856001600160a01b031684866040516135de9190613b55565b60006040518083038185875af1925050503d806000811461361b576040519150601f19603f3d011682016040523d82523d6000602084013e613620565b606091505b509150915061363086838361363a565b9695505050505050565b60608261364f5761364a82613696565b6120c4565b815115801561366657506001600160a01b0384163b155b1561368f57604051639996b31560e01b81526001600160a01b0385166004820152602401610ad1565b50806120c4565b8051156136a65780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b038116811461135057600080fd5b600080604083850312156136e757600080fd5b82356136f2816136bf565b91506020830135613702816136bf565b809150509250929050565b60006020828403121561371f57600080fd5b81356120c4816136bf565b6001600160601b038116811461135057600080fd5b60008060006060848603121561375457600080fd5b833561375f816136bf565b9250602084013561376f8161372a565b9150604084013561377f8161372a565b809150509250925092565b60006020828403121561379c57600080fd5b81356120c48161372a565b6000602082840312156137b957600080fd5b5035919050565b600080604083850312156137d357600080fd5b82356137de816136bf565b915060208301356001600160401b038116811461370257600080fd5b6000806040838503121561380d57600080fd5b50508035926020909101359150565b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561385f57845183529383019391830191600101613843565b5090979650505050505050565b60008060006060848603121561388157600080fd5b833561388c816136bf565b9250602084013561389c8161372a565b9150604084013561377f816136bf565b6020808252601590820152742737ba1037bbb732b91037b910383937bb34b232b960591b604082015260600190565b6000806000606084860312156138f057600080fd5b83516138fb816136bf565b602085015190935061390c816136bf565b604085015190925061377f816136bf565b634e487b7160e01b600052601160045260246000fd5b8082018082111561345d5761345d61391d565b6001600160601b038281168282160390808211156139665761396661391d565b5092915050565b60208082526025908201527f43616c6c6572206d757374206265207468652054207374616b696e6720636f6e6040820152641d1c9858dd60da1b606082015260800190565b6001600160601b038181168382160190808211156139665761396661391d565b808202811582820484141761345d5761345d61391d565b600082613a0657634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561345d5761345d61391d565b600060208284031215613a3057600080fd5b81516120c48161372a565b6001600160401b038181168382160190808211156139665761396661391d565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201613a9957613a9961391d565b5060010190565b6001600160601b038516815260208082018590526001600160a01b038481166040840152608060608401819052845190840181905260009285810192909160a0860190855b81811015613b03578551841683529484019491840191600101613ae5565b50909a9950505050505050505050565b6001600160a01b038281168282160390808211156139665761396661391d565b600060208284031215613b4557600080fd5b815180151581146120c457600080fd5b6000825160005b81811015613b765760208186018101518583015201613b5c565b50600092019182525091905056fea2646970667358221220ba8c34bd6934abc38ea2173b1d189a6c68f5640b54b5cd8be301c549ad4ff43564736f6c63430008170033000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee500000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7000000000000000000000000000000000000000000000878678326eac9000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000002819a00000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000006590aeff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000077f8800000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000001dfe2000000000000000000000000000000000000000000000000000000000002cfd300
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103785760003560e01c806397b486e9116101d3578063d8dfde5611610104578063f0820c92116100a2578063f854a27f1161007c578063f854a27f14610a22578063fc0c546a14610a35578063fd2a478814610a5c578063fe9fbb8014610a9857600080fd5b8063f0820c92146109c1578063f2fde38b146109e8578063f520e7e5146109fb57600080fd5b8063df136d65116100de578063df136d6514610971578063e58e018e14610984578063ea0ffa4d146109a5578063ebe2b12b146109b857600080fd5b8063d8dfde5614610904578063dbaa0fc61461091e578063ded56d451461094557600080fd5b8063ba7e5b2b11610171578063c7c49c981161014b578063c7c49c98146108b4578063c8f33c91146108e0578063c9bacaad146108e9578063cd3daf9d146108fc57600080fd5b8063ba7e5b2b14610841578063bb42895114610854578063c4903d5b1461086757600080fd5b8063a1809b95116101ad578063a1809b95146107e1578063a48d2d41146107f4578063ab6ba2d014610807578063acc2166a1461082e57600080fd5b806397b486e9146107945780639c9de028146107bb5780639cafa103146107ce57600080fd5b80636a7f7a90116102ad57806380faa57d1161024b5780638d0853c1116102255780638d0853c1146107035780638da5cb5b1461072a5780638fa990e31461075a578063967c41991461078157600080fd5b806380faa57d146106eb5780638129fc1c146106f357806386f69014146106fb57600080fd5b806375e0ae5a1161028757806375e0ae5a1461060c578063796bb62b1461061f5780637b14729e146106285780637dbee7a31461069857600080fd5b80636a7f7a90146105de578063715018a6146105f157806373761605146105f957600080fd5b806342d866931161031a5780634cc20b11116102f45780634cc20b1114610552578063505a1b311461057957806353c2ed8e146105a457806369bdf9e4146105b757600080fd5b806342d86693146104ed578063495a507a146105005780634bae3b321461053f57600080fd5b806314a854741161035657806314a854741461049d5780633032398f146104b0578063334987ab146104c75780633682a450146104da57600080fd5b806302132c011461037d5780630ceff8c814610392578063104953bf1461048a575b600080fd5b61039061038b3660046136d4565b610aab565b005b61041b6103a036600461370d565b600260208190526000918252604090912080546001820154928201546003909201546001600160a01b038083169460ff600160a01b850416946001600160401b03600160a81b9095048516946001600160601b0380841695600160601b808604831696600160c01b9096048416959285169404909116911689565b604080516001600160a01b039a8b16815298151560208a01526001600160401b03978816908901526001600160601b039586166060890152938516608088015291851660a08701529290921660c0850152931660e0830152909116610100820152610120015b60405180910390f35b61039061049836600461370d565b611019565b6103906104ab36600461373f565b6110f6565b6104b96103e881565b604051908152602001610481565b6103906104d536600461370d565b6112a5565b6103906104e836600461370d565b611346565b6103906104fb36600461370d565b611353565b6105277f000000000000000000000000000000000000000000000000000000000077f88081565b6040516001600160401b039091168152602001610481565b61039061054d36600461370d565b6114ca565b6105277f0000000000000000000000000000000000000000000000000000000000eff10081565b61058c61058736600461370d565b61163a565b6040516001600160a01b039091168152602001610481565b60015461058c906001600160a01b031681565b6104b97f000000000000000000000000000000000000000000000000000000000001518081565b6103906105ec36600461373f565b6116d1565b6103906119f6565b61039061060736600461378a565b611a0a565b61039061061a36600461370d565b611ccd565b6104b960075481565b604080516001600160601b037f000000000000000000000000000000000000000000000878678326eac90000001681526001600160401b037f0000000000000000000000000000000000000000000000000000000000eff100166020820181905291810191909152606001610481565b6106db6106a636600461370d565b6001600160a01b039081166000908152600460209081526040808320549093168252600290522054600160a01b900460ff1690565b6040519015158152602001610481565b6104b9611f5f565b610390611f72565b6003546104b9565b6104b97f0000000000000000000000000000000000000000000000000000000000eff10081565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661058c565b6105277f000000000000000000000000000000000000000000000000000000006590aeff81565b60005461058c906001600160a01b031681565b6105277f0000000000000000000000000000000000000000000000000000000001dfe20081565b6105276107c936600461370d565b61207e565b61058c6107dc3660046137a7565b6120cb565b6103906107ef36600461370d565b6120f5565b61039061080236600461370d565b612147565b6105277f0000000000000000000000000000000000000000000000000000000002cfd30081565b60055461058c906001600160a01b031681565b61039061084f3660046137c0565b612391565b61039061086236600461370d565b6127bf565b61089c61087536600461370d565b6001600160a01b03166000908152600260205260409020600101546001600160601b031690565b6040516001600160601b039091168152602001610481565b61058c6108c236600461370d565b6001600160a01b039081166000908152600260205260409020541690565b6104b960085481565b6103906108f736600461373f565b612900565b61058c612be7565b60095461089c90600160a01b90046001600160601b031681565b61058c7f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd781565b61058c61095336600461370d565b6001600160a01b039081166000908152600460205260409020541690565b60095461058c906001600160a01b031681565b6109976109923660046137fa565b612c7e565b60405161048192919061381c565b6103906109b336600461386c565b612e4a565b6104b960065481565b61089c7f000000000000000000000000000000000000000000000878678326eac900000081565b6103906109f636600461370d565b612f7f565b6104b97f00000000000000000000000000000000000000000000000000000000002819a081565b61089c610a3036600461370d565b612fba565b61058c7f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee581565b61089c610a6a36600461370d565b6001600160a01b0316600090815260026020526040902060010154600160601b90046001600160601b031690565b6106db610aa636600461370d565b613089565b81610ab581613089565b610ada5760405162461bcd60e51b8152600401610ad1906138ac565b60405180910390fd5b6001600160a01b0381163314610ba857604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa158015610b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7991906138db565b50909150506001600160a01b0381163314610ba65760405162461bcd60e51b8152600401610ad1906138ac565b505b82610bb2816130b2565b6001600160a01b03808516600090815260026020526040902080549091908116908516819003610c4a5760405162461bcd60e51b815260206004820152603760248201527f537065636966696564206f70657261746f7220697320616c726561647920626f60448201527f6e646564207769746820746869732070726f76696465720000000000000000006064820152608401610ad1565b6001600160a01b03811615610d32578154600160a01b900460ff161580610cad57508154610ca9907f000000000000000000000000000000000000000000000000000000000001518090600160a81b90046001600160401b0316613933565b4210155b610d0b5760405162461bcd60e51b815260206004820152602960248201527f4e6f7420656e6f7567682074696d652070617373656420746f206368616e67656044820152681037b832b930ba37b960b91b6064820152608401610ad1565b6001600160a01b038116600090815260046020526040902080546001600160a01b03191690555b6001600160a01b03851615610e61576001600160a01b038581166000908152600460205260409020541615610db55760405162461bcd60e51b8152602060048201526024808201527f537065636966696564206f70657261746f7220697320616c726561647920696e6044820152632075736560e01b6064820152608401610ad1565b856001600160a01b0316856001600160a01b03161480610de657506000610ddb8661163a565b6001600160a01b0316145b610e325760405162461bcd60e51b815260206004820181905260248201527f537065636966696564206f70657261746f7220697320612070726f76696465726044820152606401610ad1565b6001600160a01b03858116600090815260046020526040902080546001600160a01b0319169188169190911790555b8154600160a81b90046001600160401b0316600003610ec657600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0388161790555b8154600160a01b900460ff1615610f27576001820154600980546001600160601b0392831692601491610f02918591600160a01b900416613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b81546001600160a01b03868116600168ffffffffffffffff0160a01b03199092168217600160a81b426001600160401b0381169190910291909117855560405190815283821692918916907fa38fda88cb3c476adfa74c64be4d74c915b19a3e587e77b887ca804fb9c82c7c9060200160405180910390a4815460ff60a01b191682556000546040516346696b9f60e11b81526001600160a01b038881166004830152878116602483015290911690638cd2d73e90604401600060405180830381600087803b158015610ff957600080fd5b505af115801561100d573d6000803e3d6000fd5b50505050505050505050565b611021613151565b6000546001600160a01b03161561107a5760405162461bcd60e51b815260206004820181905260248201527f4368696c64206170706c69636174696f6e20697320616c7265616479207365746044820152606401610ad1565b6000816001600160a01b03163b116110d45760405162461bcd60e51b815260206004820152601a60248201527f4368696c6420617070206d75737420626520636f6e74726163740000000000006044820152606401610ad1565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7161461113e5760405162461bcd60e51b8152600401610ad19061396d565b82611148816130b2565b6001600160a01b03841660009081526002602052604090208054600160a01b900460ff16156111cc5761117b81856131ac565b6111858385613946565b600980546014906111a7908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821792839055600160601b909204909116111561122857600181018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b604080516001600160601b038087168252851660208201526001600160a01b038716917f72cc05b0073888d0e26528638b21fdaa2d4af96a641469fe63a87de3c4a84d79910160405180910390a260018101546001600160601b03166000036112945761129485613226565b61129e85826132c0565b5050505050565b6112ad613151565b6001546001600160a01b03908116908216036113245760405162461bcd60e51b815260206004820152603060248201527f4e65772061646472657373206d757374206e6f7420626520657175616c20746f60448201526f207468652063757272656e74206f6e6560801b6064820152608401610ad1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6113503382610aab565b50565b8061135d816130b2565b60006113688361163a565b9050336001600160a01b038216146113c25760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206d7573742062652062656e65666963696172790000000000006044820152606401610ad1565b6001600160a01b0383166000908152600260208190526040909120908101546001600160601b03168061142f5760405162461bcd60e51b81526020600482015260156024820152744e6f2072657761726420746f20776974686472617760581b6044820152606401610ad1565b6002820180546001600160601b03191690556040516001600160601b03821681526001600160a01b0384811691908716907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a361129e6001600160a01b037f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee516846001600160601b038416613340565b6000546001600160a01b0316331461153f5760405162461bcd60e51b815260206004820152603260248201527f4f6e6c79206368696c64206170706c69636174696f6e20616c6c6f7765642074604482015271379031b7b73334b9369037b832b930ba37b960711b6064820152608401610ad1565b6001600160a01b038082166000908152600460205260409020541680611563575050565b6001600160a01b03811660009081526002602052604090208054600160a01b900460ff1661163557611594826130b2565b805460ff60a01b1916600160a01b90811782556001820154600980546001600160601b039283169391926014926115d0928692919004166139b2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550826001600160a01b0316826001600160a01b03167fdbc602361eaa7fb503df3c16078c71b39d28412df5e9980bec6f489f78bb175c60405160405180910390a35b505050565b604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa1580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c991906138db565b509392505050565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd716146117195760405162461bcd60e51b8152600401610ad19061396d565b82611723816130b2565b6001600160a01b038416600090815260026020526040902060018101546001600160601b0390811690841611156117af5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e7420746f2064656372656173652067726561746572207468616e20604482015269185d5d1a1bdc9a5e995960b21b6064820152608401610ad1565b6001600160601b03831615806117f757507f000000000000000000000000000000000000000000000878678326eac90000006001600160601b0316836001600160601b031610155b61185d5760405162461bcd60e51b815260206004820152603160248201527f526573756c74696e6720617574686f72697a6174696f6e2077696c6c206265206044820152706c657373207468616e206d696e696d756d60781b6064820152608401610ad1565b6003810154426001600160401b0390911611156118db5760405162461bcd60e51b815260206004820152603660248201527f43616e27742072657175657374206465617574686f72697a6174696f6e206265604482015275199bdc9948195b99081bd98818dbdb5b5a5d1b595b9d60521b6064820152608401610ad1565b8054600160a01b900460ff16156118f6576118f681856131ac565b6001810180546001600160601b0319166001600160601b03861617905561191d8385613946565b6001820180546001600160601b0392909216600160601b02600160601b600160c01b03199092169190911790556119747f0000000000000000000000000000000000000000000000000000000000eff10042613933565b6001820180546001600160401b0392909216600160c01b026001600160c01b03909216919091179055604080516001600160601b038087168252851660208201526001600160a01b038716917f38b892bbec4f2d2e5372217fea7a4784417ae853489cd584b204f534b5c08f9591015b60405180910390a261129e85826132c0565b6119fe613151565b611a08600061339f565b565b6000611a15816130b2565b6005546001600160a01b03163314611a795760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79206469737472696275746f722063616e2070757368207265776172646044820152607360f81b6064820152608401610ad1565b6000826001600160601b031611611ad25760405162461bcd60e51b815260206004820152601860248201527f526577617264206d7573742062652073706563696669656400000000000000006044820152606401610ad1565b600954600160a01b90046001600160601b0316611b315760405162461bcd60e51b815260206004820152601b60248201527f4e6f20616374697665207374616b696e672070726f76696465727300000000006044820152606401610ad1565b6006544210611b94577f00000000000000000000000000000000000000000000000000000000002819a0611b6f6103e8670de0b6b3a76400006139d2565b611b82906001600160601b0385166139d2565b611b8c91906139e9565b600755611c1b565b600042600654611ba49190613a0b565b9050600060075482611bb691906139d2565b90507f00000000000000000000000000000000000000000000000000000000002819a081611bee6103e8670de0b6b3a76400006139d2565b611c01906001600160601b0388166139d2565b611c0b9190613933565b611c1591906139e9565b60075550505b426008819055611c4c907f00000000000000000000000000000000000000000000000000000000002819a090613933565b6006556040516001600160601b03831681527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1611cc96001600160a01b037f000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee51633306001600160601b038616613410565b5050565b80611cd7816130b2565b6001600160a01b03821660009081526002602052604090206001810154600160601b90046001600160601b0316611d5c5760405162461bcd60e51b8152602060048201526024808201527f5468657265206973206e6f206465617574686f72697a696e6720696e2070726f6044820152636365737360e01b6064820152608401610ad1565b600181015442600160c01b9091046001600160401b03161115611dd55760405162461bcd60e51b815260206004820152602b60248201527f417574686f72697a6174696f6e20646563726561736520686173206e6f74206660448201526a1a5b9a5cda1959081e595d60aa1b6064820152608401610ad1565b604051633af0572d60e11b81526001600160a01b0384811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7909116906375e0ae5a906024016020604051808303816000875af1158015611e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e669190613a1e565b8254909150600160a01b900460ff1615611eda576001820154611e939082906001600160601b0316613946565b60098054601490611eb5908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5879576c6c99ad6d1778483480ffa393a0f7b8ac18d53402720d8dd8e4617f7d910160405180910390a26001600160601b03811660018301819055600003611f4f57611f4f84613226565b611f5984836132c0565b50505050565b6000611f6d42600654613449565b905090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015611fb75750825b90506000826001600160401b03166001148015611fd35750303b155b905081158015611fe1575080155b15611fff5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561202957845460ff60401b1916600160401b1785555b61203233613463565b831561129e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038116600090815260026020526040812060010154600160c01b90046001600160401b03164281116120ba5750600092915050565b6120c44282613a0b565b9392505050565b600381815481106120db57600080fd5b6000918252602090912001546001600160a01b0316905081565b6120fd613151565b600580546001600160a01b0319166001600160a01b0383169081179091556040517f075c02c513a415bd4ff5976f8aa6fc5767d2183daca9ec00ab71ce78e8bf815890600090a250565b80612151816130b2565b6001600160a01b038281166000818152600260205260408082209051637004922d60e11b815260048101939093523060248401529290917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd79091169063e009245a90604401602060405180830381865afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f79190613a1e565b60018301549091506001600160601b038083169116116122525760405162461bcd60e51b81526020600482015260166024820152754e6f7468696e6720746f2073796e6368726f6e697a6560501b6044820152606401610ad1565b8154600160a01b900460ff16156122c357600182015461227c9082906001600160601b0316613946565b6009805460149061229e908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001820154604080516001600160601b03928316815291831660208301526001600160a01b038616917f5e26a115e9efdff9c71141dec1f9cc5dd2ec5e717da782cef55a475506e56788910160405180910390a26001820180546001600160601b0319166001600160601b0383811691821792839055600160601b909204909116111561237357600182018054600160601b6001600160601b03821602600160601b600160c01b03199091161790555b60018201546001600160601b0316600003611f4f57611f4f84613226565b8161239b81613089565b6123b75760405162461bcd60e51b8152600401610ad1906138ac565b6001600160a01b038116331461248557604051632de9480760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd790911690632de9480790602401606060405180830381865afa158015612432573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245691906138db565b50909150506001600160a01b03811633146124835760405162461bcd60e51b8152600401610ad1906138ac565b505b7f000000000000000000000000000000000000000000000000000000006590aeff6001600160401b031642106124fd5760405162461bcd60e51b815260206004820152601860248201527f436f6d6d69746d656e742077696e646f7720636c6f73656400000000000000006044820152606401610ad1565b6000826001600160401b03161180156125fa57507f000000000000000000000000000000000000000000000000000000000077f8806001600160401b0316826001600160401b0316148061258257507f0000000000000000000000000000000000000000000000000000000000eff1006001600160401b0316826001600160401b0316145b806125be57507f0000000000000000000000000000000000000000000000000000000001dfe2006001600160401b0316826001600160401b0316145b806125fa57507f0000000000000000000000000000000000000000000000000000000002cfd3006001600160401b0316826001600160401b0316145b6126625760405162461bcd60e51b815260206004820152603360248201527f436f6d6d69746d656e74206475726174696f6e206d75737420626520657175616044820152726c20746f206f6e65206f66206f7074696f6e7360681b6064820152608401610ad1565b6001600160a01b03831660009081526002602052604090206001810154600160c01b90046001600160401b0316156126f45760405162461bcd60e51b815260206004820152602f60248201527f436f6d6d69746d656e742063616e2774206265206d61646520647572696e672060448201526e3232b0baba3437b934bd30ba34b7b760891b6064820152608401610ad1565b60038101546001600160401b03161561274f5760405162461bcd60e51b815260206004820152601760248201527f436f6d6d69746d656e7420616c7265616479206d6164650000000000000000006044820152606401610ad1565b6127598342613a3b565b60038201805467ffffffffffffffff19166001600160401b039290921691821790556040519081526001600160a01b038516907f293c61c79ecf0bcac67f97a5925ba2e75c025c6231a4ab629862b570730a264b9060200160405180910390a250505050565b6001600160a01b0381166128205760405162461bcd60e51b815260206004820152602260248201527f5374616b696e672070726f7669646572206d7573742062652073706563696669604482015261195960f21b6064820152608401610ad1565b6001600160a01b038181166000818152600260209081526040918290206001810154815484516001600160601b03909216825290951691850191909152927f8dd220764537278d5094ef78e8e7584b819d083dd7905d32d09a928ec26466f2910160405180910390a261289382826132c0565b60005481546040516346696b9f60e11b81526001600160a01b0385811660048301529182166024820152911690638cd2d73e906044015b600060405180830381600087803b1580156128e457600080fd5b505af11580156128f8573d6000803e3d6000fd5b505050505050565b336001600160a01b037f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd716146129485760405162461bcd60e51b8152600401610ad19061396d565b82612952816130b2565b6001600160a01b0384161580159061297357506000826001600160601b0316115b6129ca5760405162461bcd60e51b815260206004820152602260248201527f496e70757420706172616d6574657273206d7573742062652073706563696669604482015261195960f21b6064820152608401610ad1565b7f000000000000000000000000000000000000000000000878678326eac90000006001600160601b0316826001600160601b03161015612a5f5760405162461bcd60e51b815260206004820152602a60248201527f417574686f72697a6174696f6e206d7573742062652067726561746572207468604482015269616e206d696e696d756d60b01b6064820152608401610ad1565b6001600160a01b0380851660009081526002602090815260408083206004909252909120549091161580612aad57506001600160a01b03808616600081815260046020526040902054909116145b612b165760405162461bcd60e51b815260206004820152603460248201527f412070726f76696465722063616e277420626520616e206f70657261746f72206044820152733337b91030b737ba3432b910383937bb34b232b960611b6064820152608401610ad1565b8054600160a01b900460ff1615612b8257612b3181856131ac565b612b3b8484613946565b60098054601490612b5d908490600160a01b90046001600160601b03166139b2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001810180546001600160601b0319166001600160601b0385811691821790925560408051928716835260208301919091526001600160a01b038716917f9e46043a7120cf056d21eda9b6d78ffd99571a62fb6ff91a471a73e4b8484e1c91016119e4565b600954600090600160a01b90046001600160601b03168103612c1357506009546001600160a01b031690565b600954600754600854600092600160a01b90046001600160601b03169190612c39611f5f565b612c439190613a0b565b612c4d91906139d2565b612c5791906139e9565b600954612c6d91906001600160a01b0316613933565b9050612c7881613474565b91505090565b600354600090606090808510612cca5760405162461bcd60e51b81526020600482015260116024820152700aee4dedcce40e6e8c2e4e840d2dcc8caf607b1b6044820152606401610ad1565b8315801590612ce1575080612cdf8587613933565b105b15612cf357612cf08486613933565b90505b612cfd8582613a0b565b6001600160401b03811115612d1457612d14613a5b565b604051908082528060200260200182016040528015612d3d578160200160208202803683370190505b5060009350915082855b82811015612e3d57600060038281548110612d6457612d64613a71565b60009182526020808320909101546001600160a01b031680835260029091526040822090925090612d94826134ac565b6001600160601b031690507f000000000000000000000000000000000000000000000878678326eac90000006001600160601b0316811080612ddf57508154600160a01b900460ff16155b15612dec57505050612e35565b6001600160601b0319606084901b1681178786612e0881613a87565b975081518110612e1a57612e1a613a71565b6020908102919091010152612e2f8189613933565b97505050505b600101612d47565b5080835250509250929050565b6001546001600160a01b03163314612eae5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646a7564696361746f7220616c6c6f77656420746f20736c61736044820152600d60fb1b6064820152608401610ad1565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110612ee457612ee4613a71565b6001600160a01b0392831660209182029290920101526040516383ddba8f60e01b81527f00000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7909116906383ddba8f90612f4790869060649087908790600401613aa0565b600060405180830381600087803b158015612f6157600080fd5b505af1158015612f75573d6000803e3d6000fd5b5050505050505050565b612f87613151565b6001600160a01b038116612fb157604051631e4fbdf760e01b815260006004820152602401610ad1565b6113508161339f565b6001600160a01b03811660009081526002602052604081208054600160a01b900460ff16612ff557600201546001600160601b031692915050565b60028101546000906001600160601b031661301a6103e8670de0b6b3a76400006139d2565b6002840154600160601b90046001600160a01b0316613037612be7565b6130419190613b13565b6001850154613062916001600160a01b0316906001600160601b03166139d2565b61306c91906139e9565b6130769190613933565b9050613081816134d0565b949350505050565b6001600160a01b03166000908152600260205260409020600101546001600160601b0316151590565b6130ba612be7565b600980546001600160a01b0319166001600160a01b03929092169190911790556130e2611f5f565b6008556001600160a01b03811615611350576001600160a01b038116600090815260026020526040902061311582612fba565b60029190910180546001600160601b0319166001600160601b0390921691821781556009546001600160a01b0316600160601b02909117905550565b336131837f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614611a085760405163118cdaa760e01b8152336004820152602401610ad1565b60018201546001600160601b03828116911614611cc95760018201546131dc9082906001600160601b0316613946565b600980546014906131fe908490600160a01b90046001600160601b0316613946565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6001600160a01b03818116600081815260026020908152604080832080548616845260049283905281842080546001600160a01b031916905580546001600160a81b03191681556001810180546001600160c01b0316905560038101805467ffffffffffffffff19169055835491516346696b9f60e11b815292830194909452602482019290925291921690638cd2d73e906044016128ca565b60006132cb826134ac565b6000546040516334cdb41f60e11b81526001600160a01b0386811660048301526001600160601b038416602483015292935091169063699b683e90604401600060405180830381600087803b15801561332357600080fd5b505af1158015613337573d6000803e3d6000fd5b50505050505050565b6040516001600160a01b0383811660248301526044820183905261163591859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613504565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040516001600160a01b038481166024830152838116604483015260648201839052611f599186918216906323b872dd9060840161336d565b6000818310613458578161345a565b825b90505b92915050565b61346b613567565b611350816135b0565b60006001600160a01b038211156134a8576040516306dfcc6560e41b815260a0600482015260248101839052604401610ad1565b5090565b600181015460009061345d906001600160601b03600160601b820481169116613946565b60006001600160601b038211156134a8576040516306dfcc6560e41b81526060600482015260248101839052604401610ad1565b60006135196001600160a01b038416836135b8565b9050805160001415801561353e57508080602001905181019061353c9190613b33565b155b1561163557604051635274afe760e01b81526001600160a01b0384166004820152602401610ad1565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611a0857604051631afcd79f60e31b815260040160405180910390fd5b612f87613567565b606061345a8383600084600080856001600160a01b031684866040516135de9190613b55565b60006040518083038185875af1925050503d806000811461361b576040519150601f19603f3d011682016040523d82523d6000602084013e613620565b606091505b509150915061363086838361363a565b9695505050505050565b60608261364f5761364a82613696565b6120c4565b815115801561366657506001600160a01b0384163b155b1561368f57604051639996b31560e01b81526001600160a01b0385166004820152602401610ad1565b50806120c4565b8051156136a65780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b038116811461135057600080fd5b600080604083850312156136e757600080fd5b82356136f2816136bf565b91506020830135613702816136bf565b809150509250929050565b60006020828403121561371f57600080fd5b81356120c4816136bf565b6001600160601b038116811461135057600080fd5b60008060006060848603121561375457600080fd5b833561375f816136bf565b9250602084013561376f8161372a565b9150604084013561377f8161372a565b809150509250925092565b60006020828403121561379c57600080fd5b81356120c48161372a565b6000602082840312156137b957600080fd5b5035919050565b600080604083850312156137d357600080fd5b82356137de816136bf565b915060208301356001600160401b038116811461370257600080fd5b6000806040838503121561380d57600080fd5b50508035926020909101359150565b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561385f57845183529383019391830191600101613843565b5090979650505050505050565b60008060006060848603121561388157600080fd5b833561388c816136bf565b9250602084013561389c8161372a565b9150604084013561377f816136bf565b6020808252601590820152742737ba1037bbb732b91037b910383937bb34b232b960591b604082015260600190565b6000806000606084860312156138f057600080fd5b83516138fb816136bf565b602085015190935061390c816136bf565b604085015190925061377f816136bf565b634e487b7160e01b600052601160045260246000fd5b8082018082111561345d5761345d61391d565b6001600160601b038281168282160390808211156139665761396661391d565b5092915050565b60208082526025908201527f43616c6c6572206d757374206265207468652054207374616b696e6720636f6e6040820152641d1c9858dd60da1b606082015260800190565b6001600160601b038181168382160190808211156139665761396661391d565b808202811582820484141761345d5761345d61391d565b600082613a0657634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561345d5761345d61391d565b600060208284031215613a3057600080fd5b81516120c48161372a565b6001600160401b038181168382160190808211156139665761396661391d565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201613a9957613a9961391d565b5060010190565b6001600160601b038516815260208082018590526001600160a01b038481166040840152608060608401819052845190840181905260009285810192909160a0860190855b81811015613b03578551841683529484019491840191600101613ae5565b50909a9950505050505050505050565b6001600160a01b038281168282160390808211156139665761396661391d565b600060208284031215613b4557600080fd5b815180151581146120c457600080fd5b6000825160005b81811015613b765760208186018101518583015201613b5c565b50600092019182525091905056fea2646970667358221220ba8c34bd6934abc38ea2173b1d189a6c68f5640b54b5cd8be301c549ad4ff43564736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee500000000000000000000000001b67b1194c75264d06f808a921228a95c765dd7000000000000000000000000000000000000000000000878678326eac9000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000002819a00000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000006590aeff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000077f8800000000000000000000000000000000000000000000000000000000000eff1000000000000000000000000000000000000000000000000000000000001dfe2000000000000000000000000000000000000000000000000000000000002cfd300
-----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): 1703980799
-----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] : 000000000000000000000000000000000000000000000000000000006590aeff
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [9] : 000000000000000000000000000000000000000000000000000000000077f880
Arg [10] : 0000000000000000000000000000000000000000000000000000000000eff100
Arg [11] : 0000000000000000000000000000000000000000000000000000000001dfe200
Arg [12] : 0000000000000000000000000000000000000000000000000000000002cfd300
Deployed Bytecode Sourcemap
493:35243:15:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30432:2031;;;;;;:::i;:::-;;:::i;:::-;;6253:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6253:66:15;;;;;-1:-1:-1;;;6253:66:15;;;;-1:-1:-1;;;;;;;;6253:66:15;;;;;;-1:-1:-1;;;;;6253:66:15;;;;-1:-1:-1;;;6253:66:15;;;;;;-1:-1:-1;;;6253: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;6253:66:15;;;;;;;;10232:322;;;;;;:::i;:::-;;:::i;18764:852::-;;;;;;:::i;:::-;;:::i;5467:61::-;;5521:7;5467:61;;;;;2835:25:16;;;2823:2;2808:18;5467:61:15;2689:177:16;10651:258:15;;;;;;:::i;:::-;;:::i;30129:115::-;;;;;;:::i;:::-;;:::i;15995:546::-;;;;;;:::i;:::-;;:::i;5829:49::-;;;;;;;;-1:-1:-1;;;;;3033:31:16;;;3015:50;;3003:2;2988:18;5829:49:15;2871:200:16;32532:865:15;;;;;;:::i;:::-;;:::i;5884:49::-;;;;;28742:185;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3256:32:16;;;3238:51;;3226:2;3211:18;28742:185:15;3076:219:16;6220:26:15;;;;;-1:-1:-1;;;;;6220:26:15;;;5680:43;;;;;19923:1121;;;;;;:::i;:::-;;:::i;3131:101:12:-;;;:::i;14885:929:15:-;;;;;;:::i;:::-;;:::i;21209:968::-;;;;;;:::i;:::-;;:::i;6507:33::-;;;;;;12164:414;;;;-1:-1:-1;;;;;12451:20:15;3972:39:16;3954:58;;-1:-1:-1;;;;;12492:23:15;4085:15:16;4080:2;4065:18;;4058:43;;;4117:18;;;4110:43;;;;3942:2;3927:18;12164:414:15;3758:401:16;29339:277:15;;;;;;:::i;:::-;-1:-1:-1;;;;;29450:39:15;;;29408:4;29450:39;;;:28;:39;;;;;;;;;;;;29534:36;;:19;:36;;;29587:22;-1:-1:-1;;;29587:22:15;;;;;29339:277;;;;4329:14:16;;4322:22;4304:41;;4292:2;4277:18;29339:277:15;4164:187:16;13564:129:15;;;:::i;10067:86::-;;;:::i;29705:116::-;29791:16;:23;29705:116;;5774:48;;;;;2417:144:12;1289:22;2546:8;-1:-1:-1;;;;;2546:8:12;2417:144;;6049:42:15;;;;;6174:40;;;;;-1:-1:-1;;;;;6174:40:15;;;5939:49;;;;;26131:373;;;;;;:::i;:::-;;:::i;6325:33::-;;;;;;:::i;:::-;;:::i;12714:187::-;;;;;;:::i;:::-;;:::i;22352:881::-;;;;;;:::i;:::-;;:::i;5994:49::-;;;;;6436:32;;;;;-1:-1:-1;;;;;6436:32:15;;;23462:1053;;;;;;:::i;:::-;;:::i;34601:470::-;;;;;;:::i;:::-;;:::i;25144:154::-;;;;;;:::i;:::-;-1:-1:-1;;;;;25243:37:15;25218:6;25243:37;;;:19;:37;;;;;:48;;;-1:-1:-1;;;;;25243:48:15;;25144:154;;;;-1:-1:-1;;;;;5367:39:16;;;5349:58;;5337:2;5322:18;25144:154:15;5205:208:16;24895:163:15;;;;;;:::i;:::-;-1:-1:-1;;;;;25005:37:15;;;24979:7;25005:37;;;:19;:37;;;;;:46;;;24895:163;6546:29;;;;;;17349:1117;;;;;;:::i;:::-;;:::i;13785:349::-;;;:::i;6622:31::-;;;;;-1:-1:-1;;;6622:31:15;;-1:-1:-1;;;;;6622:31:15;;;6098:34;;;;;24661:149;;;;;;:::i;:::-;-1:-1:-1;;;;;24764:39:15;;;24738:7;24764:39;;;:28;:39;;;;;;;;24661:149;6581:35;;;;;-1:-1:-1;;;;;6581:35:15;;;27182:1471;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;35356:378::-;;;;;;:::i;:::-;;:::i;6474:27::-;;;;;;5630:44;;;;;3381:215:12;;;;;;:::i;:::-;;:::i;5729:39:15:-;;;;;14288:450;;;;;;:::i;:::-;;:::i;6138:29::-;;;;;25768:193;;;;;;:::i;:::-;-1:-1:-1;;;;;25903:37:15;25878:6;25903:37;;;:19;:37;;;;;:51;;;-1:-1:-1;;;25903:51:15;;-1:-1:-1;;;;;25903:51:15;;25768:193;29038:151;;;;;;:::i;:::-;;:::i;30432:2031::-;30555:16;9709:30;9722:16;9709:12;:30::i;:::-;9701:64;;;;-1:-1:-1;;;9701:64:15;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;9779:30:15;;9799:10;9779:30;9775:184;;9847:34;;-1:-1:-1;;;9847:34:15;;-1:-1:-1;;;;;3256:32:16;;;9847:34:15;;;3238:51:16;9826:13:15;;9847:8;:16;;;;;;3211:18:16;;9847:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;9825:56:15;;-1:-1:-1;;;;;;;9903:19:15;;9912:10;9903:19;9895:53;;;;-1:-1:-1;;;9895:53:15;;;;;;;:::i;:::-;9811:148;9775:184;30586:16:::1;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1::0;;;;;30649:37:15;;::::2;30614:32;30649:37:::0;;;:19:::2;:37;::::0;;;;30723:13;;30649:37;;30723:13;;::::2;::::0;30767:29;::::2;::::0;;;30746:131:::2;;;::::0;-1:-1:-1;;;30746:131:15;;8649:2:16;30746:131:15::2;::::0;::::2;8631:21:16::0;8688:2;8668:18;;;8661:30;8727:34;8707:18;;;8700:62;8798:25;8778:18;;;8771:53;8841:19;;30746:131:15::2;8447:419:16::0;30746:131:15::2;-1:-1:-1::0;;;;;30936:30:15;::::2;::::0;30932:424:::2;;31008:22:::0;;-1:-1:-1;;;31008:22:15;::::2;;;31007:23;::::0;:123:::2;;-1:-1:-1::0;31081:27:15;;31073:57:::2;::::0;31112:18:::2;::::0;-1:-1:-1;;;31081:27:15;::::2;-1:-1:-1::0;;;;;31081:27:15::2;31073:57;:::i;:::-;31054:15;:76;;31007:123;30982:223;;;::::0;-1:-1:-1;;;30982:223:15;;9335:2:16;30982:223:15::2;::::0;::::2;9317:21:16::0;9374:2;9354:18;;;9347:30;9413:34;9393:18;;;9386:62;-1:-1:-1;;;9464:18:16;;;9457:39;9513:19;;30982:223:15::2;9133:405:16::0;30982:223:15::2;-1:-1:-1::0;;;;;31286:46:15;::::2;31343:1;31286:46:::0;;;:28:::2;:46;::::0;;;;:59;;-1:-1:-1;;;;;;31286:59:15::2;::::0;;30932:424:::2;-1:-1:-1::0;;;;;31370:23:15;::::2;::::0;31366:509:::2;;-1:-1:-1::0;;;;;31434:39:15;;::::2;31485:1;31434:39:::0;;;:28:::2;:39;::::0;;;;;::::2;:53:::0;31409:148:::2;;;::::0;-1:-1:-1;;;31409:148:15;;9745:2:16;31409:148:15::2;::::0;::::2;9727:21:16::0;9784:2;9764:18;;;9757:30;9823:34;9803:18;;;9796:62;-1:-1:-1;;;9874:18:16;;;9867:34;9918:19;;31409:148:15::2;9543:400:16::0;31409:148:15::2;31609:16;-1:-1:-1::0;;;;;31596:29:15::2;:9;-1:-1:-1::0;;;;;31596:29:15::2;;:72;;;-1:-1:-1::0;31666:1:15::2;31629:25;31644:9:::0;31629:14:::2;:25::i;:::-;-1:-1:-1::0;;;;;31629:39:15::2;;31596:72;31571:163;;;::::0;-1:-1:-1;;;31571:163:15;;10150:2:16;31571:163:15::2;::::0;::::2;10132:21:16::0;;;10169:18;;;10162:30;10228:34;10208:18;;;10201:62;10280:18;;31571:163:15::2;9948:356:16::0;31571:163:15::2;-1:-1:-1::0;;;;;31806:39:15;;::::2;;::::0;;;:28:::2;:39;::::0;;;;:58;;-1:-1:-1;;;;;;31806:58:15::2;::::0;;::::2;::::0;;;::::2;::::0;;31366:509:::2;31889:27:::0;;-1:-1:-1;;;31889:27:15;::::2;-1:-1:-1::0;;;;;31889:27:15::2;;:32:::0;31885:102:::2;;31937:16;:39:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;31937:39:15;;;;;::::2;::::0;;-1:-1:-1;;;;;;31937:39:15::2;-1:-1:-1::0;;;;;31937:39:15;::::2;;::::0;;31885:102:::2;32001:22:::0;;-1:-1:-1;;;32001:22:15;::::2;;;31997:89;;;32060:15;::::0;::::2;::::0;32039:17:::2;:36:::0;;-1:-1:-1;;;;;32060:15:15;;::::2;::::0;32039:17:::2;::::0;:36:::2;::::0;32060:15;;-1:-1:-1;;;32039:36:15;::::2;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;32039:36:15::2;;;;;-1:-1:-1::0;;;;;32039:36:15::2;;;;;;31997:89;32164:25:::0;;-1:-1:-1;;;;;32164:25:15;;::::2;-1:-1:-1::0;;;;;;32199:53:15;;;;;-1:-1:-1;;;32236:15:15::2;-1:-1:-1::0;;;;;32199:53:15;::::2;::::0;;;::::2;::::0;;;::::2;::::0;;32267:78:::2;::::0;2835:25:16;;;32267:78:15;;::::2;::::0;32164:25;32267:78;::::2;::::0;::::2;::::0;2823:2:16;2808:18;32267:78:15::2;;;;;;;32356:30:::0;;-1:-1:-1;;;;32356:30:15::2;::::0;;-1:-1:-1;32396:16:15;:60:::2;::::0;-1:-1:-1;;;32396:60:15;;-1:-1:-1;;;;;10735:15:16;;;32396:60:15::2;::::0;::::2;10717:34:16::0;10787:15;;;10767:18;;;10760:43;32396:16:15;;::::2;::::0;:31:::2;::::0;10652:18:16;;32396:60:15::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;30604:1859;;9968:1:::1;30432:2031:::0;;;:::o;10232:322::-;2310:13:12;:11;:13::i;:::-;10371:1:15::1;10342:16:::0;-1:-1:-1;;;;;10342:16:15::1;10334:39:::0;10326:84:::1;;;::::0;-1:-1:-1;;;10326:84:15;;11016:2:16;10326:84:15::1;::::0;::::1;10998:21:16::0;;;11035:18;;;11028:30;11094:34;11074:18;;;11067:62;11146:18;;10326:84:15::1;10814:356:16::0;10326:84:15::1;10469:1;10436:17;-1:-1:-1::0;;;;;10428:38:15::1;;:42;10420:81;;;::::0;-1:-1:-1;;;10420:81:15;;11377:2:16;10420:81:15::1;::::0;::::1;11359:21:16::0;11416:2;11396:18;;;11389:30;11455:28;11435:18;;;11428:56;11501:18;;10420:81:15::1;11175:350:16::0;10420:81:15::1;10511:16;:36:::0;;-1:-1:-1;;;;;;10511:36:15::1;-1:-1:-1::0;;;;;10511:36:15;;;::::1;::::0;;;::::1;::::0;;10232:322::o;18764:852::-;9453:10;-1:-1:-1;;;;;9475:8:15;9453:31;;9445:81;;;;-1:-1:-1;;;9445:81:15;;;;;;;:::i;:::-;18951:16:::1;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1::0;;;;;19014:37:15;::::2;18979:32;19014:37:::0;;;:19:::2;:37;::::0;;;;19065:22;;-1:-1:-1;;;19065:22:15;::::2;;;19061:160;;;19103:49;19134:4;19140:11;19103:30;:49::i;:::-;19187:23;19201:9:::0;19187:11;:23:::2;:::i;:::-;19166:17;:44:::0;;:17:::2;::::0;:44:::2;::::0;;;-1:-1:-1;;;19166:44:15;::::2;-1:-1:-1::0;;;;;19166:44:15::2;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;19166:44:15::2;;;;;-1:-1:-1::0;;;;;19166:44:15::2;;;;;;19061:160;19231:15;::::0;::::2;:27:::0;;-1:-1:-1;;;;;;19231:27:15::2;-1:-1:-1::0;;;;;19231:27:15;;::::2;::::0;;::::2;::::0;;;;-1:-1:-1;;;19290:18:15;;::::2;::::0;;::::2;-1:-1:-1::0;19268:103:15::2;;;19345:15;::::0;::::2;::::0;;-1:-1:-1;;;;;;;;19345:15:15;::::2;19324:36;-1:-1:-1::0;;;;;;;;19324:36:15;;::::2;;::::0;;19268:103:::2;19385:75;::::0;;-1:-1:-1;;;;;12169:15:16;;;12151:34;;12221:15;;12216:2;12201:18;;12194:43;-1:-1:-1;;;;;19385:75:15;::::2;::::0;::::2;::::0;12079:18:16;19385:75:15::2;;;;;;;19475:15;::::0;::::2;::::0;-1:-1:-1;;;;;19475:15:15::2;;:20:::0;19471:85:::2;;19511:34;19528:16;19511;:34::i;:::-;19565:44;19586:16;19604:4;19565:20;:44::i;:::-;18969:647;9536:1:::1;18764:852:::0;;;:::o;10651:258::-;2310:13:12;:11;:13::i;:::-;10780:11:15::1;::::0;-1:-1:-1;;;;;10780:11:15;;::::1;10747:45:::0;;::::1;::::0;10726:140:::1;;;::::0;-1:-1:-1;;;10726:140:15;;12450:2:16;10726:140:15::1;::::0;::::1;12432:21:16::0;12489:2;12469:18;;;12462:30;12528:34;12508:18;;;12501:62;-1:-1:-1;;;12579:18:16;;;12572:46;12635:19;;10726:140:15::1;12248:412:16::0;10726:140:15::1;10876:11;:26:::0;;-1:-1:-1;;;;;;10876:26:15::1;-1:-1:-1::0;;;;;10876:26:15;;;::::1;::::0;;;::::1;::::0;;10651:258::o;30129:115::-;30202:35;30215:10;30227:9;30202:12;:35::i;:::-;30129:115;:::o;15995:546::-;16068:16;9278:38;9299:16;9278:20;:38::i;:::-;16096:19:::1;16118:32;16133:16;16118:14;:32::i;:::-;16096:54:::0;-1:-1:-1;16168:10:15::1;-1:-1:-1::0;;;;;16168:25:15;::::1;;16160:64;;;::::0;-1:-1:-1;;;16160:64:15;;12867:2:16;16160:64:15::1;::::0;::::1;12849:21:16::0;12906:2;12886:18;;;12879:30;12945:28;12925:18;;;12918:56;12991:18;;16160:64:15::1;12665:350:16::0;16160:64:15::1;-1:-1:-1::0;;;;;16270:37:15;::::1;16235:32;16270:37:::0;;;:19:::1;:37;::::0;;;;;;;16332:12;;::::1;::::0;-1:-1:-1;;;;;16332:12:15::1;16362:9:::0;16354:43:::1;;;::::0;-1:-1:-1;;;16354:43:15;;13222:2:16;16354:43:15::1;::::0;::::1;13204:21:16::0;13261:2;13241:18;;;13234:30;-1:-1:-1;;;13280:18:16;;;13273:51;13341:18;;16354:43:15::1;13020:345:16::0;16354:43:15::1;16407:12;::::0;::::1;:16:::0;;-1:-1:-1;;;;;;16407:16:15::1;::::0;;16438:48:::1;::::0;-1:-1:-1;;;;;5367:39:16;;5349:58;;-1:-1:-1;;;;;16438:48:15;;::::1;::::0;;;::::1;::::0;::::1;::::0;5337:2:16;5322:18;16438:48:15::1;;;;;;;16496:38;-1:-1:-1::0;;;;;16496:5:15::1;:18;16515:11:::0;-1:-1:-1;;;;;16496:38:15;::::1;:18;:38::i;32532:865::-:0;32654:16;;-1:-1:-1;;;;;32654:16:15;32632:10;:39;32611:136;;;;-1:-1:-1;;;32611:136:15;;13786:2:16;32611:136:15;;;13768:21:16;13825:2;13805:18;;;13798:30;13864:34;13844:18;;;13837:62;-1:-1:-1;;;13915:18:16;;;13908:48;13973:19;;32611:136:15;13584:414:16;32611:136:15;-1:-1:-1;;;;;32783:39:15;;;32757:23;32783:39;;;:28;:39;;;;;;;;32986:66;;33035:7;32532:865;:::o;32986:66::-;-1:-1:-1;;;;;33097:36:15;;33062:32;33097:36;;;:19;:36;;;;;33148:22;;-1:-1:-1;;;33148:22:15;;;;33143:248;;33186:37;33207:15;33186:20;:37::i;:::-;33237:29;;-1:-1:-1;;;;33237:29:15;-1:-1:-1;;;33237:29:15;;;;;33262:4;33301:15;;;33280:17;:36;;-1:-1:-1;;;;;33301:15:15;;;;33280:17;;33237:22;;33280:36;;33301:15;;33280:36;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;33280:36:15;;;;;-1:-1:-1;;;;;33280:36:15;;;;;;33370:9;-1:-1:-1;;;;;33335:45:15;33353:15;-1:-1:-1;;;;;33335:45:15;;;;;;;;;;;33143:248;32601:796;;32532:865;:::o;28742:185::-;28886:34;;-1:-1:-1;;;28886:34:15;;-1:-1:-1;;;;;3256:32:16;;;28886:34:15;;;3238:51:16;28827:27:15;;28886:8;:16;;;;;;3211:18:16;;28886:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;28866:54:15;28742:185;-1:-1:-1;;;28742:185:15:o;19923:1121::-;9453:10;-1:-1:-1;;;;;9475:8:15;9453:31;;9445:81;;;;-1:-1:-1;;;9445:81:15;;;;;;;:::i;:::-;20108:16:::1;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1::0;;;;;20171:37:15;::::2;20136:32;20171:37:::0;;;:19:::2;:37;::::0;;;;20239:15:::2;::::0;::::2;::::0;-1:-1:-1;;;;;20239:15:15;;::::2;20226:28:::0;;::::2;;;20218:83;;;::::0;-1:-1:-1;;;20218:83:15;;14398:2:16;20218:83:15::2;::::0;::::2;14380:21:16::0;14437:2;14417:18;;;14410:30;14476:34;14456:18;;;14449:62;-1:-1:-1;;;14527:18:16;;;14520:40;14577:19;;20218:83:15::2;14196:406:16::0;20218:83:15::2;-1:-1:-1::0;;;;;20332:14:15;::::2;::::0;;:51:::2;;;20363:20;-1:-1:-1::0;;;;;20350:33:15::2;:9;-1:-1:-1::0;;;;;20350:33:15::2;;;20332:51;20311:147;;;::::0;-1:-1:-1;;;20311:147:15;;14809:2:16;20311:147:15::2;::::0;::::2;14791:21:16::0;14848:2;14828:18;;;14821:30;14887:34;14867:18;;;14860:62;-1:-1:-1;;;14938:18:16;;;14931:47;14995:19;;20311:147:15::2;14607:413:16::0;20311:147:15::2;20489:18;::::0;::::2;::::0;20511:15:::2;-1:-1:-1::0;;;;;20489:18:15;;::::2;:37;;20468:138;;;::::0;-1:-1:-1;;;20468:138:15;;15227:2:16;20468:138:15::2;::::0;::::2;15209:21:16::0;15266:2;15246:18;;;15239:30;15305:34;15285:18;;;15278:62;-1:-1:-1;;;15356:18:16;;;15349:52;15418:19;;20468:138:15::2;15025:418:16::0;20468:138:15::2;20620:22:::0;;-1:-1:-1;;;20620:22:15;::::2;;;20616:102;;;20658:49;20689:4;20695:11;20658:30;:49::i;:::-;20728:15;::::0;::::2;:29:::0;;-1:-1:-1;;;;;;20728:29:15::2;-1:-1:-1::0;;;;;20728:29:15;::::2;;::::0;;20788:23:::2;20802:9:::0;20728:29;20788:23:::2;:::i;:::-;20767:18;::::0;::::2;:44:::0;;-1:-1:-1;;;;;20767:44:15;;;::::2;-1:-1:-1::0;;;20767:44:15::2;-1:-1:-1::0;;;;;;;;20767:44:15;;::::2;::::0;;;::::2;::::0;;20854:41:::2;20872:23;20854:15;:41;:::i;:::-;20821:23;::::0;::::2;:75:::0;;-1:-1:-1;;;;;20821:75:15;;;::::2;-1:-1:-1::0;;;20821:75:15::2;-1:-1:-1::0;;;;;20821:75:15;;::::2;::::0;;;::::2;::::0;;20911:72:::2;::::0;;-1:-1:-1;;;;;12169:15:16;;;12151:34;;12221:15;;12216:2;12201:18;;12194:43;-1:-1:-1;;;;;20911:72:15;::::2;::::0;::::2;::::0;12079:18:16;20911:72:15::2;;;;;;;;20993:44;21014:16;21032:4;20993: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;14885:929:15:-;14951:1;9278:38;9299:16;9278:20;:38::i;:::-;14987:17:::1;::::0;-1:-1:-1;;;;;14987:17:15::1;14973:10;:31;14965:77;;;::::0;-1:-1:-1;;;14965:77:15;;15650:2:16;14965:77:15::1;::::0;::::1;15632:21:16::0;15689:2;15669:18;;;15662:30;15728:34;15708:18;;;15701:62;-1:-1:-1;;;15779:18:16;;;15772:31;15820:19;;14965:77:15::1;15448:397:16::0;14965:77:15::1;15070:1;15060:7;-1:-1:-1::0;;;;;15060:11:15::1;;15052:48;;;::::0;-1:-1:-1;;;15052:48:15;;16052:2:16;15052:48:15::1;::::0;::::1;16034:21:16::0;16091:2;16071:18;;;16064:30;16130:26;16110:18;;;16103:54;16174:18;;15052:48:15::1;15850:348:16::0;15052:48:15::1;15118:17;::::0;-1:-1:-1;;;15118:17:15;::::1;-1:-1:-1::0;;;;;15118:17:15::1;15110:61;;;::::0;-1:-1:-1;;;15110:61:15;;16405:2:16;15110:61:15::1;::::0;::::1;16387:21:16::0;16444:2;16424:18;;;16417:30;16483:29;16463:18;;;16456:57;16530:18;;15110:61:15::1;16203:351:16::0;15110:61:15::1;15204:12;;15185:15;:31;15181:425;;15299:14;5585:38;5521:7;5615:8;5585:38;:::i;:::-;15254:41;::::0;-1:-1:-1;;;;;15254:16:15;::::1;:41;:::i;:::-;15253:60;;;;:::i;:::-;15232:18;:81:::0;15181:425:::1;;;15344:17;15379:15;15364:12;;:30;;;;:::i;:::-;15344:50;;15408:16;15439:18;;15427:9;:30;;;;:::i;:::-;15408:49:::0;-1:-1:-1;15581:14:15::1;15408:49:::0;5585:38:::1;5521:7;5615:8;5585:38;:::i;:::-;15509:41;::::0;-1:-1:-1;;;;;15509:16:15;::::1;:41;:::i;:::-;:52;;;;:::i;:::-;15508:87;;;;:::i;:::-;15471:18;:124:::0;-1:-1:-1;;15181:425:15::1;15632:15;15615:14;:32:::0;;;15672::::1;::::0;15690:14:::1;::::0;15672:32:::1;:::i;:::-;15657:12;:47:::0;15719:20:::1;::::0;-1:-1:-1;;;;;5367:39:16;;5349:58;;15719:20:15::1;::::0;5337:2:16;5322:18;15719:20:15::1;;;;;;;15749:58;-1:-1:-1::0;;;;;15749:5:15::1;:22;15772:10;15792:4;-1:-1:-1::0;;;;;15749:58:15;::::1;:22;:58::i;:::-;14885:929:::0;;:::o;21209:968::-;21309:16;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1;;;;;21372:37:15;::::1;21337:32;21372:37:::0;;;:19:::1;:37;::::0;;;;21427:18:::1;::::0;::::1;::::0;-1:-1:-1;;;21427:18:15;::::1;-1:-1:-1::0;;;;;21427:18:15::1;21419:71;;;::::0;-1:-1:-1;;;21419:71:15;;17289:2:16;21419:71:15::1;::::0;::::1;17271:21:16::0;17328:2;17308:18;;;17301:30;17367:34;17347:18;;;17340:62;-1:-1:-1;;;17418:18:16;;;17411:34;17462:19;;21419:71:15::1;17087:400:16::0;21419:71:15::1;21521:23;::::0;::::1;::::0;21548:15:::1;-1:-1:-1::0;;;21521:23:15;;::::1;-1:-1:-1::0;;;;;21521:23:15::1;:42;;21500:132;;;::::0;-1:-1:-1;;;21500:132:15;;17694:2:16;21500:132:15::1;::::0;::::1;17676:21:16::0;17733:2;17713:18;;;17706:30;17772:34;17752:18;;;17745:62;-1:-1:-1;;;17823:18:16;;;17816:41;17874:19;;21500:132:15::1;17492:407:16::0;21500:132:15::1;21661:55;::::0;-1:-1:-1;;;21661:55:15;;-1:-1:-1;;;;;3256:32:16;;;21661:55:15::1;::::0;::::1;3238:51:16::0;21643:15:15::1;::::0;21661:8:::1;:37:::0;;::::1;::::0;::::1;::::0;3211:18:16;;21661:55:15::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21731:22:::0;;21643:73;;-1:-1:-1;;;;21731:22:15;::::1;;;21727:100;;;21790:15;::::0;::::1;::::0;:26:::1;::::0;21808:8;;-1:-1:-1;;;;;21790:15:15::1;:26;:::i;:::-;21769:17;:47:::0;;:17:::1;::::0;:47:::1;::::0;;;-1:-1:-1;;;21769:47:15;::::1;-1:-1:-1::0;;;;;21769:47:15::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;21769:47:15::1;;;;;-1:-1:-1::0;;;;;21769:47:15::1;;;;;;21727:100;21890:15;::::0;::::1;::::0;21842:74:::1;::::0;;-1:-1:-1;;;;;21890:15:15;;::::1;12151:34:16::0;;12221:15;;;12216:2;12201:18;;12194:43;-1:-1:-1;;;;;21842:74:15;::::1;::::0;::::1;::::0;12079:18:16;21842:74:15::1;;;;;;;-1:-1:-1::0;;;;;21926:26:15;::::1;:15;::::0;::::1;21994:27:::0;;;21926:15:::1;22036:20:::0;22032:85:::1;;22072:34;22089:16;22072;:34::i;:::-;22126:44;22147:16;22165:4;22126:20;:44::i;:::-;21327:850;;21209:968:::0;;:::o;13564:129::-;13621:7;13647:39;13656:15;13673:12;;13647:8;:39::i;:::-;13640:46;;13564:129;:::o;10067: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;10120:26:15::1;10135:10;10120:14;:26::i;:::-;5070:14:10::0;5066:101;;;5100:23;;-1:-1:-1;;;;5100:23:10;;;5142:14;;-1:-1:-1;3015:50:16;;5142:14:10;;3003:2:16;2988:18;5142:14:10;;;;;;;4092:1081;;;;;10067:86:15:o;26131:373::-;-1:-1:-1;;;;;26295:37:15;;26248:6;26295:37;;;:19;:37;;;;;:56;;;-1:-1:-1;;;26295:56:15;;-1:-1:-1;;;;;26295:56:15;26387:15;26365:37;;26361:76;;-1:-1:-1;26425:1:15;;26131:373;-1:-1:-1;;26131:373:15:o;26361:76::-;26460:36;26481:15;26460:18;:36;:::i;:::-;26446:51;26131:373;-1:-1:-1;;;26131:373:15:o;6325:33::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6325:33:15;;-1:-1:-1;6325:33:15;:::o;12714:187::-;2310:13:12;:11;:13::i;:::-;12801:17:15::1;:38:::0;;-1:-1:-1;;;;;;12801:38:15::1;-1:-1:-1::0;;;;;12801:38:15;::::1;::::0;;::::1;::::0;;;12854:40:::1;::::0;::::1;::::0;-1:-1:-1;;12854:40:15::1;12714:187:::0;:::o;22352:881::-;22450:16;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1;;;;;22513:37:15;;::::1;22478:32;22513:37:::0;;;:19:::1;:37;::::0;;;;;22583:57;;-1:-1:-1;;;22583:57:15;;::::1;::::0;::::1;10717:34:16::0;;;;22634:4:15::1;10767:18:16::0;;;10760:43;22513:37:15;22478:32;;22583:8:::1;:24:::0;;::::1;::::0;::::1;::::0;10652:18:16;;22583:57:15::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22658:15;::::0;::::1;::::0;22560:80;;-1:-1:-1;;;;;;22658:31:15;;::::1;:15:::0;::::1;:31;22650:66;;;::::0;-1:-1:-1;;;22650:66:15;;18574:2:16;22650:66:15::1;::::0;::::1;18556:21:16::0;18613:2;18593:18;;;18586:30;-1:-1:-1;;;18632:18:16;;;18625:52;18694:18;;22650:66:15::1;18372:346:16::0;22650:66:15::1;22731:22:::0;;-1:-1:-1;;;22731:22:15;::::1;;;22727:105;;;22790:15;::::0;::::1;::::0;:31:::1;::::0;22808:13;;-1:-1:-1;;;;;22790:15:15::1;:31;:::i;:::-;22769:17;:52:::0;;:17:::1;::::0;:52:::1;::::0;;;-1:-1:-1;;;22769:52:15;::::1;-1:-1:-1::0;;;;;22769:52:15::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;22769:52:15::1;;;;;-1:-1:-1::0;;;;;22769:52:15::1;;;;;;22727:105;22892:15;::::0;::::1;::::0;22846:77:::1;::::0;;-1:-1:-1;;;;;22892:15:15;;::::1;12151:34:16::0;;12221:15;;;12216:2;12201:18;;12194:43;-1:-1:-1;;;;;22846:77:15;::::1;::::0;::::1;::::0;12079:18:16;22846:77:15::1;;;;;;;22934:15;::::0;::::1;:31:::0;;-1:-1:-1;;;;;;22934:31:15::1;-1:-1:-1::0;;;;;22934:31:15;;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;22997:18:15;;::::1;::::0;;::::1;-1:-1:-1::0;22975:103:15::1;;;23052:15;::::0;::::1;::::0;;-1:-1:-1;;;;;;;;23052:15:15;::::1;23031:36;-1:-1:-1::0;;;;;;;;23031:36:15;;::::1;;::::0;;22975:103:::1;23092:15;::::0;::::1;::::0;-1:-1:-1;;;;;23092:15:15::1;;:20:::0;23088:85:::1;;23128:34;23145:16;23128;:34::i;23462:1053::-:0;23598:16;9709:30;9722:16;9709:12;:30::i;:::-;9701:64;;;;-1:-1:-1;;;9701:64:15;;;;;;;:::i;:::-;-1:-1:-1;;;;;9779:30:15;;9799:10;9779:30;9775:184;;9847:34;;-1:-1:-1;;;9847:34:15;;-1:-1:-1;;;;;3256:32:16;;;9847:34:15;;;3238:51:16;9826:13:15;;9847:8;:16;;;;;;3211:18:16;;9847:34:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;9825:56:15;;-1:-1:-1;;;;;;;9903:19:15;;9912:10;9903:19;9895:53;;;;-1:-1:-1;;;9895:53:15;;;;;;;:::i;:::-;9811:148;9775:184;23652:18:::1;-1:-1:-1::0;;;;;23634:36:15::1;:15;:36;23626:73;;;::::0;-1:-1:-1;;;23626:73:15;;18925:2:16;23626:73:15::1;::::0;::::1;18907:21:16::0;18964:2;18944:18;;;18937:30;19003:26;18983:18;;;18976:54;19047:18;;23626:73:15::1;18723:348:16::0;23626:73:15::1;23752:1;23730:19;-1:-1:-1::0;;;;;23730:23:15::1;;:309;;;;;23797:25;-1:-1:-1::0;;;;;23774:48:15::1;:19;-1:-1:-1::0;;;;;23774:48:15::1;;:120;;;;23869:25;-1:-1:-1::0;;;;;23846:48:15::1;:19;-1:-1:-1::0;;;;;23846:48:15::1;;23774:120;:192;;;;23941:25;-1:-1:-1::0;;;;;23918:48:15::1;:19;-1:-1:-1::0;;;;;23918:48:15::1;;23774:192;:264;;;;24013:25;-1:-1:-1::0;;;;;23990:48:15::1;:19;-1:-1:-1::0;;;;;23990:48:15::1;;23774:264;23709:407;;;::::0;-1:-1:-1;;;23709:407:15;;19278:2:16;23709:407:15::1;::::0;::::1;19260:21:16::0;19317:2;19297:18;;;19290:30;19356:34;19336:18;;;19329:62;-1:-1:-1;;;19407:18:16;;;19400:49;19466:19;;23709:407:15::1;19076:415:16::0;23709:407:15::1;-1:-1:-1::0;;;;;24161:37:15;::::1;24126:32;24161:37:::0;;;:19:::1;:37;::::0;;;;24216:23:::1;::::0;::::1;::::0;-1:-1:-1;;;24216:23:15;::::1;-1:-1:-1::0;;;;;24216:23:15::1;:28:::0;24208:88:::1;;;::::0;-1:-1:-1;;;24208:88:15;;19698:2:16;24208:88:15::1;::::0;::::1;19680:21:16::0;19737:2;19717:18;;;19710:30;19776:34;19756:18;;;19749:62;-1:-1:-1;;;19827:18:16;;;19820:45;19882:19;;24208:88:15::1;19496:411:16::0;24208:88:15::1;24314:18;::::0;::::1;::::0;-1:-1:-1;;;;;24314:18:15::1;:23:::0;24306:59:::1;;;::::0;-1:-1:-1;;;24306:59:15;;20114:2:16;24306:59:15::1;::::0;::::1;20096:21:16::0;20153:2;20133:18;;;20126:30;20192:25;20172:18;;;20165:53;20235:18;;24306:59:15::1;19912:347:16::0;24306:59:15::1;24396:45;24422:19:::0;24403:15:::1;24396:45;:::i;:::-;24375:18;::::0;::::1;:66:::0;;-1:-1:-1;;24375:66:15::1;-1:-1:-1::0;;;;;24375:66:15;;;::::1;::::0;;::::1;::::0;;24456:52:::1;::::0;3015:50:16;;;-1:-1:-1;;;;;24456:52:15;::::1;::::0;::::1;::::0;3003:2:16;2988:18;24456:52:15::1;;;;;;;23616:899;23462:1053:::0;;;:::o;34601:470::-;-1:-1:-1;;;;;34690:30:15;;34682:77;;;;-1:-1:-1;;;34682:77:15;;20857:2:16;34682:77:15;;;20839:21:16;20896:2;20876:18;;;20869:30;20935:34;20915:18;;;20908:62;-1:-1:-1;;;20986:18:16;;;20979:32;21028:19;;34682:77:15;20655:398:16;34682:77:15;-1:-1:-1;;;;;34804:37:15;;;34769:32;34804:37;;;:19;:37;;;;;;;;;34905:15;;;;34922:13;;34856:80;;-1:-1:-1;;;;;34905:15:15;;;21230:58:16;;34922:13:15;;;21304:18:16;;;21297:60;;;;34804:37:15;34856:80;;21203:18:16;34856:80:15;;;;;;;34946:44;34967:16;34985:4;34946:20;:44::i;:::-;35000:16;;35050:13;;35000:64;;-1:-1:-1;;;35000:64:15;;-1:-1:-1;;;;;10735:15:16;;;35000:64:15;;;10717:34:16;35050:13:15;;;10767:18:16;;;10760:43;35000:16:15;;;:31;;10652:18:16;;35000:64:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34672:399;34601:470;:::o;17349:1117::-;9453:10;-1:-1:-1;;;;;9475:8:15;9453:31;;9445:81;;;;-1:-1:-1;;;9445:81:15;;;;;;;:::i;:::-;17526:16:::1;9278:38;9299:16;9278:20;:38::i;:::-;-1:-1:-1::0;;;;;17575:30:15;::::2;::::0;;::::2;::::0;:47:::2;;;17621:1;17609:9;-1:-1:-1::0;;;;;17609:13:15::2;;17575:47;17554:128;;;::::0;-1:-1:-1;;;17554:128:15;;21570:2:16;17554:128:15::2;::::0;::::2;21552:21:16::0;21609:2;21589:18;;;21582:30;21648:34;21628:18;;;21621:62;-1:-1:-1;;;21699:18:16;;;21692:32;21741:19;;17554:128:15::2;21368:398:16::0;17554:128:15::2;17713:20;-1:-1:-1::0;;;;;17700:33:15::2;:9;-1:-1:-1::0;;;;;17700:33:15::2;;;17692:88;;;::::0;-1:-1:-1;;;17692:88:15;;21973:2:16;17692:88:15::2;::::0;::::2;21955:21:16::0;22012:2;21992:18;;;21985:30;22051:34;22031:18;;;22024:62;-1:-1:-1;;;22102:18:16;;;22095:40;22152:19;;17692:88:15::2;21771:406:16::0;17692:88:15::2;-1:-1:-1::0;;;;;17826:37:15;;::::2;17791:32;17826:37:::0;;;:19:::2;:37;::::0;;;;;;;17894:28:::2;:46:::0;;;;;;;17826:37;;17894:46:::2;:60:::0;;:146:::2;;-1:-1:-1::0;;;;;;17974:66:15;;::::2;:46;::::0;;;:28:::2;:46;::::0;;;;;;;::::2;:66;17894:146;17873:245;;;::::0;-1:-1:-1;;;17873:245:15;;22384:2:16;17873:245:15::2;::::0;::::2;22366:21:16::0;22423:2;22403:18;;;22396:30;22462:34;22442:18;;;22435:62;-1:-1:-1;;;22513:18:16;;;22506:50;22573:19;;17873:245:15::2;22182:416:16::0;17873:245:15::2;18133:22:::0;;-1:-1:-1;;;18133:22:15;::::2;;;18129:160;;;18171:49;18202:4;18208:11;18171:30;:49::i;:::-;18255:23;18267:11:::0;18255:9;:23:::2;:::i;:::-;18234:17;:44:::0;;:17:::2;::::0;:44:::2;::::0;;;-1:-1:-1;;;18234:44:15;::::2;-1:-1:-1::0;;;;;18234:44:15::2;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;18234:44:15::2;;;;;-1:-1:-1::0;;;;;18234:44:15::2;;;;;;18129:160;18299:15;::::0;::::2;:27:::0;;-1:-1:-1;;;;;;18299:27:15::2;-1:-1:-1::0;;;;;18299:27:15;;::::2;::::0;;::::2;::::0;;;18341:64:::2;::::0;;12169:15:16;;;12151:34;;12216:2;12201:18;;12194:43;;;;-1:-1:-1;;;;;18341:64:15;::::2;::::0;::::2;::::0;12079:18:16;18341:64:15::2;11936:307:16::0;13785:349:15;13855:17;;13832:7;;-1:-1:-1;;;13855:17:15;;-1:-1:-1;;;;;13855:17:15;:22;;13851:80;;-1:-1:-1;13900:20:15;;-1:-1:-1;;;;;13900:20:15;;13785:349::o;13851:80::-;14075:17;;14041:18;;14023:14;;13940;;-1:-1:-1;;;14075:17:15;;-1:-1:-1;;;;;14075:17:15;;14041:18;13994:26;:24;:26::i;:::-;:43;;;;:::i;:::-;13993:66;;;;:::i;:::-;13992:100;;;;:::i;:::-;13957:20;;:135;;;-1:-1:-1;;;;;13957:20:15;:135;:::i;:::-;13940:152;;14109:18;:6;:16;:18::i;:::-;14102:25;;;13785:349;:::o;27182:1471::-;27412:16;:23;27313:27;;27342:39;;27453:22;;;27445:52;;;;-1:-1:-1;;;27445:52:15;;22805:2:16;27445:52:15;;;22787:21:16;22844:2;22824:18;;;22817:30;-1:-1:-1;;;22863:18:16;;;22856:47;22920:18;;27445:52:15;22603:341:16;27445:52:15;27511:25;;;;;:74;;-1:-1:-1;27577:8:15;27540:34;27554:20;27540:11;:34;:::i;:::-;:45;27511:74;27507:150;;;27612:34;27626:20;27612:11;:34;:::i;:::-;27601:45;;27507:150;27705:22;27716:11;27705:8;:22;:::i;:::-;-1:-1:-1;;;;;27691:37:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27691:37:15;-1:-1:-1;27760:1:15;;-1:-1:-1;27666:62:15;-1:-1:-1;27760:1:15;27822:11;27805:757;27839:8;27835:1;:12;27805:757;;;27868:23;27894:16;27911:1;27894:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;27894:19:15;27962:36;;;:19;:36;;;;;;27894:19;;-1:-1:-1;27962:36:15;28037:23;27962:36;28037:17;:23::i;:::-;-1:-1:-1;;;;;28012:48:15;;;28095:20;-1:-1:-1;;;;;28078:37:15;:14;:37;:64;;;-1:-1:-1;28120:22:15;;-1:-1:-1;;;28120:22:15;;;;28119:23;28078:64;28074:111;;;28162:8;;;;;28074:111;-1:-1:-1;;;;;;28424:24:15;;;;28416:33;:84;;28360:22;28383:13;;;;:::i;:::-;;;28360:37;;;;;;;;:::i;:::-;;;;;;;;;;:140;28514:37;28537:14;28514:37;;:::i;:::-;;;27854:708;;;27805:757;27849:3;;27805:757;;;;28625:11;28601:22;28594:43;28580:67;;27182:1471;;;;;:::o;35356:378::-;35478:11;;-1:-1:-1;;;;;35478:11:15;35464:10;:25;35456:71;;;;-1:-1:-1;;;35456:71:15;;23555:2:16;35456:71:15;;;23537:21:16;23594:2;23574:18;;;23567:30;23633:34;23613:18;;;23606:62;-1:-1:-1;;;23684:18:16;;;23677:31;23725:19;;35456:71:15;23353:397:16;35456:71:15;35579:16;;;35593:1;35579:16;;;;;;;;;35537:39;;35579:16;;;;;;;;;;;-1:-1:-1;35579:16:15;35537:58;;35633:16;35605:22;35628:1;35605:25;;;;;;;;:::i;:::-;-1:-1:-1;;;;;35605:44:15;;;:25;;;;;;;;;:44;35659:68;;-1:-1:-1;;;35659:68:15;;:8;:14;;;;;;:68;;35674:8;;35684:3;;35689:13;;35704:22;;35659:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35446:288;35356: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;3238:51:16::0;3211:18;;3510:31:12::1;3076:219:16::0;3461:91:12::1;3561:28;3580:8;3561:18;:28::i;14288:450:15:-:0;-1:-1:-1;;;;;14414:37:15;;14361:6;14414:37;;;:19;:37;;;;;14466:22;;-1:-1:-1;;;14466:22:15;;;;14461:73;;14511:12;;;-1:-1:-1;;;;;14511:12:15;;14288:450;-1:-1:-1;;14288:450:15:o;14461:73::-;14685:12;;;;14543:14;;-1:-1:-1;;;;;14685:12:15;5585:38;5521:7;5615:8;5585:38;:::i;:::-;14608:23;;;;-1:-1:-1;;;14608:23:15;;-1:-1:-1;;;;;14608:23:15;14589:16;:14;:16::i;:::-;:42;;;;:::i;:::-;14569:15;;;;14561:71;;-1:-1:-1;;;;;14561:71:15;;-1:-1:-1;;;;;14569:15:15;14561:71;:::i;:::-;14560:110;;;;:::i;:::-;:137;;;;:::i;:::-;14543:154;;14714:17;:6;:15;:17::i;:::-;14707:24;14288:450;-1:-1:-1;;;;14288:450:15:o;29038:151::-;-1:-1:-1;;;;;29130:37:15;29107:4;29130:37;;;:19;:37;;;;;:48;;;-1:-1:-1;;;;;29130:48:15;:52;;;29038:151::o;13043:439::-;13141:16;:14;:16::i;:::-;13118:20;:39;;-1:-1:-1;;;;;;13118:39:15;-1:-1:-1;;;;;13118:39:15;;;;;;;;;;13184:26;:24;:26::i;:::-;13167:14;:43;-1:-1:-1;;;;;13224:30:15;;;13220:256;;-1:-1:-1;;;;;13305:37:15;;13270:32;13305:37;;;:19;:37;;;;;13371:34;13325:16;13371;:34::i;:::-;13356:12;;;;;:49;;-1:-1:-1;;;;;;13356:49:15;-1:-1:-1;;;;;13356:49:15;;;;;;;;13445:20;;-1:-1:-1;;;;;13445:20:15;-1:-1:-1;;;13419:46:15;;;;;;-1:-1:-1;13043: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;;;3238:51:16;3211:18;;2739:40:12;3076:219:16;16703:261:15;16845:16;;;;-1:-1:-1;;;;;16845:33:15;;;:16;;:33;16841:117;;16915:16;;;;:32;;16934:13;;-1:-1:-1;;;;;16915:16:15;:32;:::i;:::-;16894:17;:53;;:17;;:53;;;;-1:-1:-1;;;16894:53:15;;-1:-1:-1;;;;;16894:53:15;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;16894:53:15;;;;;-1:-1:-1;;;;;16894:53:15;;;;;;16703:261;;:::o;33527:432::-;-1:-1:-1;;;;;33633:37:15;;;33598:32;33633:37;;;:19;:37;;;;;;;;33709:13;;;;33680:43;;:28;:43;;;;;;;:56;;-1:-1:-1;;;;;;33680:56:15;;;33746:26;;-1:-1:-1;;;;;;33782:30:15;;;-1:-1:-1;33822:23:15;;:27;;-1:-1:-1;;;;;33822:27:15;;;33859:18;;;:22;;-1:-1:-1;;33859:22:15;;;33891:16;;:61;;-1:-1:-1;;;33891:61:15;;;;;10717:34:16;;;;10767:18;;;10760:43;;;;33633:37:15;;33891:16;;:31;;10652:18:16;;33891:61:15;10505:304:16;34046:360:15;34271:21;34295:24;34313:5;34295:17;:24::i;:::-;34329:16;;:70;;-1:-1:-1;;;34329:70:15;;-1:-1:-1;;;;;25085:32:16;;;34329:70:15;;;25067:51:16;-1:-1:-1;;;;;25154:39:16;;25134:18;;;25127:67;34271:48:15;;-1:-1:-1;34329:16:15;;;:36;;25040:18:16;;34329:70:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34168:238;34046:360;;:::o;1271:160:14:-;1380:43;;-1:-1:-1;;;;;25397:32:16;;;1380:43:14;;;25379:51:16;25446:18;;;25439:34;;;1353:71:14;;1373:5;;1395:14;;;;;25352: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;;;;;25742:15:16;;;1797:53:14;;;25724:34:16;25794:15;;;25774:18;;;25767:43;25826:18;;;25819:34;;;1770:81:14;;1790:5;;1812:18;;;;;25659::16;;1797:53:14;25484:375:16;2557:104:11;2615:7;2645:1;2641;:5;:13;;2653:1;2641:13;;;2649:1;2641:13;2634:20;;2557:104;;;;;:::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;;;26046:36:16;26098:18;;;26091:34;;;26019:18;;7351:42:13;25864:267:16;7299:105:13;-1:-1:-1;7428:5:13;7223:218::o;25384:155:15:-;25513:19;;;;25469:6;;25494:38;;-1:-1:-1;;;;;;;;25513:19:15;;;;;25494:16;:38;:::i;11291:213:13:-;11347:6;-1:-1:-1;;;;;11369:24:13;;11365:103;;;11416:41;;-1:-1:-1;;;11416:41:13;;11447:2;11416:41;;;26046:36:16;26098:18;;;26091:34;;;26019:18;;11416:41:13;25864: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;;;;;3256:32:16;;4599:40:14;;;3238:51:16;3211:18;;4599:40:14;3076: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;;;;;3256:32:16;;5121:24:0;;;3238:51:16;3211:18;;5121:24:0;3076: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;3508:245::-;3566:6;3619:2;3607:9;3598:7;3594:23;3590:32;3587:52;;;3635:1;3632;3625:12;3587:52;3674:9;3661:23;3693:30;3717:5;3693:30;:::i;4588:180::-;4647:6;4700:2;4688:9;4679:7;4675:23;4671:32;4668:52;;;4716:1;4713;4706:12;4668:52;-1:-1:-1;4739:23:16;;4588:180;-1:-1:-1;4588:180:16:o;4773:427::-;4840:6;4848;4901:2;4889:9;4880:7;4876:23;4872:32;4869:52;;;4917:1;4914;4907:12;4869:52;4956:9;4943:23;4975:31;5000:5;4975:31;:::i;:::-;5025:5;-1:-1:-1;5082:2:16;5067:18;;5054:32;-1:-1:-1;;;;;5117:32:16;;5105:45;;5095:73;;5164:1;5161;5154:12;5850:248;5918:6;5926;5979:2;5967:9;5958:7;5954:23;5950:32;5947:52;;;5995:1;5992;5985:12;5947:52;-1:-1:-1;;6018:23:16;;;6088:2;6073:18;;;6060:32;;-1:-1:-1;5850:248:16:o;6103:703::-;6273:4;6321:2;6310:9;6306:18;6351:6;6340:9;6333:25;6377:2;6415;6410;6399:9;6395:18;6388:30;6438:6;6473;6467:13;6504:6;6496;6489:22;6542:2;6531:9;6527:18;6520:25;;6580:2;6572:6;6568:15;6554:29;;6601:1;6611:169;6625:6;6622:1;6619:13;6611:169;;;6686:13;;6674:26;;6755:15;;;;6720:12;;;;6647:1;6640:9;6611:169;;;-1:-1:-1;6797:3:16;;6103:703;-1:-1:-1;;;;;;;6103:703:16:o;6811:527::-;6887:6;6895;6903;6956:2;6944:9;6935:7;6931:23;6927:32;6924:52;;;6972:1;6969;6962:12;6924:52;7011:9;6998:23;7030:31;7055:5;7030:31;:::i;:::-;7080:5;-1:-1:-1;7137:2:16;7122:18;;7109:32;7150;7109;7150;:::i;:::-;7201:7;-1:-1:-1;7260:2:16;7245:18;;7232:32;7273:33;7232:32;7273:33;:::i;7565:345::-;7767:2;7749:21;;;7806:2;7786:18;;;7779:30;-1:-1:-1;;;7840:2:16;7825:18;;7818:51;7901:2;7886:18;;7565:345::o;7915:527::-;8011:6;8019;8027;8080:2;8068:9;8059:7;8055:23;8051:32;8048:52;;;8096:1;8093;8086:12;8048:52;8128:9;8122:16;8147:31;8172:5;8147:31;:::i;:::-;8247:2;8232:18;;8226:25;8197:5;;-1:-1:-1;8260:33:16;8226:25;8260:33;:::i;:::-;8364:2;8349:18;;8343:25;8312:7;;-1:-1:-1;8377:33:16;8343:25;8377:33;:::i;8871:127::-;8932:10;8927:3;8923:20;8920:1;8913:31;8963:4;8960:1;8953:15;8987:4;8984:1;8977:15;9003:125;9068:9;;;9089:10;;;9086:36;;;9102:18;;:::i;10309:191::-;-1:-1:-1;;;;;10436:10:16;;;10424;;;10420:27;;10459:12;;;10456:38;;;10474:18;;:::i;:::-;10456:38;10309:191;;;;:::o;11530:401::-;11732:2;11714:21;;;11771:2;11751:18;;;11744:30;11810:34;11805:2;11790:18;;11783:62;-1:-1:-1;;;11876:2:16;11861:18;;11854:35;11921:3;11906:19;;11530:401::o;14003:188::-;-1:-1:-1;;;;;14116:10:16;;;14128;;;14112:27;;14151:11;;;14148:37;;;14165:18;;:::i;16559:168::-;16632:9;;;16663;;16680:15;;;16674:22;;16660:37;16650:71;;16701:18;;:::i;16732:217::-;16772:1;16798;16788:132;;16842:10;16837:3;16833:20;16830:1;16823:31;16877:4;16874:1;16867:15;16905:4;16902:1;16895:15;16788:132;-1:-1:-1;16934:9:16;;16732:217::o;16954:128::-;17021:9;;;17042:11;;;17039:37;;;17056:18;;:::i;17904:249::-;17973:6;18026:2;18014:9;18005:7;18001:23;17997:32;17994:52;;;18042:1;18039;18032:12;17994:52;18074:9;18068:16;18093:30;18117:5;18093:30;:::i;20264:180::-;-1:-1:-1;;;;;20369:10:16;;;20381;;;20365:27;;20404:11;;;20401:37;;;20418:18;;:::i;22949:127::-;23010:10;23005:3;23001:20;22998:1;22991:31;23041:4;23038:1;23031:15;23065:4;23062:1;23055:15;23081:127;23142:10;23137:3;23133:20;23130:1;23123:31;23173:4;23170:1;23163:15;23197:4;23194:1;23187:15;23213:135;23252:3;23273:17;;;23270:43;;23293:18;;:::i;:::-;-1:-1:-1;23340:1:16;23329:13;;23213:135::o;23755:945::-;-1:-1:-1;;;;;24068:39:16;;24050:58;;24127:2;24145:18;;;24138:34;;;-1:-1:-1;;;;;24246:15:16;;;24241:2;24226:18;;24219:43;24037:3;24293:2;24278:18;;24271:31;;;24351:13;;24022:19;;;24373:22;;;23989:4;;24453:15;;;;24127:2;;24199:3;24411:19;;;23989:4;24496:178;24510:6;24507:1;24504:13;24496:178;;;24575:13;;24571:22;;24559:35;;24649:15;;;;24614:12;;;;24532:1;24525:9;24496:178;;;-1:-1:-1;24691:3:16;;23755:945;-1:-1:-1;;;;;;;;;;23755:945:16:o;24705:185::-;-1:-1:-1;;;;;24826:10:16;;;24814;;;24810:27;;24849:12;;;24846:38;;;24864:18;;:::i;26407:277::-;26474:6;26527:2;26515:9;26506:7;26502:23;26498:32;26495:52;;;26543:1;26540;26533:12;26495:52;26575:9;26569:16;26628:5;26621:13;26614:21;26607:5;26604:32;26594:60;;26650:1;26647;26640:12;26689:412;26818:3;26856:6;26850:13;26881:1;26891:129;26905:6;26902:1;26899:13;26891:129;;;27003:4;26987:14;;;26983:25;;26977:32;26964:11;;;26957:53;26920:12;26891:129;;;-1:-1:-1;27075:1:16;27039:16;;27064:13;;;-1:-1:-1;27039:16:16;26689:412;-1:-1:-1;26689:412:16:o
Swarm Source
ipfs://ba8c34bd6934abc38ea2173b1d189a6c68f5640b54b5cd8be301c549ad4ff435
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.