More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,577 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 21373579 | 35 days ago | IN | 0 ETH | 0.006244 | ||||
Unstake | 21296768 | 46 days ago | IN | 0 ETH | 0.00123053 | ||||
Claim Rewards | 21296765 | 46 days ago | IN | 0 ETH | 0.00088292 | ||||
Unstake | 21015346 | 85 days ago | IN | 0 ETH | 0.00143859 | ||||
Claim Rewards | 21015342 | 85 days ago | IN | 0 ETH | 0.00122226 | ||||
Unstake | 20686290 | 131 days ago | IN | 0 ETH | 0.00036511 | ||||
Claim Rewards | 20686289 | 131 days ago | IN | 0 ETH | 0.00027969 | ||||
Unstake | 20413381 | 169 days ago | IN | 0 ETH | 0.00066869 | ||||
Unstake | 20366116 | 175 days ago | IN | 0 ETH | 0.00039157 | ||||
Claim Rewards | 20366115 | 175 days ago | IN | 0 ETH | 0.00029134 | ||||
Unstake | 20297433 | 185 days ago | IN | 0 ETH | 0.00023902 | ||||
Unstake | 20297412 | 185 days ago | IN | 0 ETH | 0.00021411 | ||||
Claim Rewards | 20297353 | 185 days ago | IN | 0 ETH | 0.00010699 | ||||
Claim Rewards | 20297299 | 185 days ago | IN | 0 ETH | 0.00016628 | ||||
Claim Rewards | 20297292 | 185 days ago | IN | 0 ETH | 0.00015694 | ||||
Unstake | 20280176 | 187 days ago | IN | 0 ETH | 0.00039333 | ||||
Unstake | 20152186 | 205 days ago | IN | 0 ETH | 0.00025693 | ||||
Unstake | 20050162 | 220 days ago | IN | 0 ETH | 0.00063772 | ||||
Recover ERC20 | 20029184 | 223 days ago | IN | 0 ETH | 0.00111603 | ||||
Unstake | 19972123 | 230 days ago | IN | 0 ETH | 0.00094919 | ||||
Claim Rewards | 19972109 | 230 days ago | IN | 0 ETH | 0.00077819 | ||||
Unstake | 19931078 | 236 days ago | IN | 0 ETH | 0.00088244 | ||||
Claim Rewards | 19931059 | 236 days ago | IN | 0 ETH | 0.00067923 | ||||
Unstake | 19919448 | 238 days ago | IN | 0 ETH | 0.00101407 | ||||
Unstake | 19912970 | 239 days ago | IN | 0 ETH | 0.00142516 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19220662 | 336 days ago | 0.0038546 ETH |
Loading...
Loading
Contract Name:
TrestleStakingPool
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-02-10 */ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 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. */ 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]. */ 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); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // 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(errorMessage); } } } } /** * @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; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } interface IMultiplier { /** * Applies a multiplier on the _amount, based on the _pool and _beneficiary. * The multiplier is not necessarily a constant number, it can be a more complex factor. */ function applyMultiplier(uint256 _amount, uint256 _duration) external view returns (uint256); function getMultiplier(uint256 _amount, uint256 _duration) external view returns (uint256); function getDurationGroup(uint256 _duration) external view returns (uint256); function getDurationMultiplier(uint256 _duration) external view returns (uint256); } interface IPenaltyFee { /** * Calculates the penalty fee for the given _amount for a specific _beneficiary. */ function calculate( uint256 _amount, uint256 _duration, address _pool ) external view returns (uint256); } interface IStakingPool { struct StakingInfo { uint256 stakedAmount; // amount of the stake uint256 minimumStakeTimestamp; // timestamp of the minimum stake uint256 duration; // in seconds uint256 rewardPerTokenPaid; // Reward per token paid uint256 rewards; // rewards to be claimed } function rewardsMultiplier() external view returns (IMultiplier); function penaltyFeeCalculator() external view returns (IPenaltyFee); event Staked(address indexed user, uint256 stakeNumber, uint256 amount); event Unstaked(address indexed user, uint256 stakeNumber, uint256 amount); event RewardPaid(address indexed user, uint256 stakeNumber, uint256 reward); } contract TrestleStakingPool is ReentrancyGuard, IStakingPool { using SafeERC20 for IERC20; address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; IERC20 public immutable stakingToken; IERC20 public immutable rewardsToken; uint256 public immutable rewardsTokenDecimals; IMultiplier public immutable override rewardsMultiplier; IPenaltyFee public immutable override penaltyFeeCalculator; address public owner; // Duration of the rewards (in seconds) uint256 public rewardsDuration; // Timestamp of when the staking starts uint256 public startsAt; // Timestamp of when the staking ends uint256 public endsAt; // Timestamp of the reward updated uint256 public lastUpdateTime; // Reward per second (total rewards / duration) uint256 public rewardRatePerSec; // Reward per token stored uint256 public rewardPerTokenStored; bool public isPaused; // Total staked uint256 public totalRewards; // Raw amount staked by all users uint256 public totalStaked; // Total staked with each user multiplier applied uint256 public totalWeightedStake; // User address => array of the staking info mapping(address => StakingInfo[]) public userStakingInfo; // it has to be evaluated on a user basis enum StakeTimeOptions { Duration, EndTime } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event TokenRecovered(address token, uint256 amount); constructor( address _stakingToken, address _rewardToken, uint256 _rewardsTokenDecimals, address _multiplier, address _penaltyFeeCalculator ) { owner = msg.sender; stakingToken = IERC20(_stakingToken); rewardsToken = IERC20(_rewardToken); rewardsTokenDecimals = _rewardsTokenDecimals; rewardsMultiplier = IMultiplier(_multiplier); penaltyFeeCalculator = IPenaltyFee(_penaltyFeeCalculator); } /* ========== VIEWS ========== */ /** * Calculates how much rewards a user has earned up to current block, every time the user stakes/unstakes/withdraw. * We update "rewards[_user]" with how much they are entitled to, up to current block. * Next time we calculate how much they earned since last update and accumulate on rewards[_user]. */ function getUserRewards(address _user, uint256 _stakeNumber) public view returns (uint256) { uint256 weightedAmount = rewardsMultiplier.applyMultiplier( userStakingInfo[_user][_stakeNumber].stakedAmount, userStakingInfo[_user][_stakeNumber].duration ); uint256 rewardsSinceLastUpdate = ((weightedAmount * (rewardPerToken() - userStakingInfo[_user][_stakeNumber].rewardPerTokenPaid)) / (100**rewardsTokenDecimals)); return rewardsSinceLastUpdate + userStakingInfo[_user][_stakeNumber].rewards; } function lastTimeRewardApplicable() public view returns (uint256) { return block.timestamp < endsAt ? block.timestamp : endsAt; } function rewardPerToken() public view returns (uint256) { if (totalStaked == 0) { return rewardPerTokenStored; } uint256 howLongSinceLastTime = lastTimeRewardApplicable() - lastUpdateTime; return rewardPerTokenStored + ((rewardRatePerSec * howLongSinceLastTime * (100**rewardsTokenDecimals)) / totalWeightedStake); } function getUserStakes(address _user) external view returns (StakingInfo[] memory) { return userStakingInfo[_user]; } /* ========== MUTATIVE FUNCTIONS ========== */ function _updateReward(address _user, uint256 _stakeNumber) private { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (_user != address(0)) { userStakingInfo[_user][_stakeNumber].rewards = getUserRewards(_user, _stakeNumber); userStakingInfo[_user][_stakeNumber].rewardPerTokenPaid = rewardPerTokenStored; } } function stake( uint256 _amount, StakeTimeOptions _stakeTimeOption, uint256 _unstakeTime ) external nonReentrant inProgress { require(_amount > 0, "TrestleStakingPool::stake: amount = 0"); uint256 _minimumStakeTimestamp = _stakeTimeOption == StakeTimeOptions.Duration ? block.timestamp + _unstakeTime : _unstakeTime; require(_minimumStakeTimestamp > startsAt, "TrestleStakingPool::stake: _minimumStakeTimestamp <= startsAt"); require(_minimumStakeTimestamp > block.timestamp, "TrestleStakingPool::stake: _minimumStakeTimestamp <= block.timestamp"); uint256 _stakeDuration = _minimumStakeTimestamp - block.timestamp; _updateReward(address(0), 0); StakingInfo memory _stakingInfo = StakingInfo({ stakedAmount: _amount, minimumStakeTimestamp: _minimumStakeTimestamp, duration: _stakeDuration, rewardPerTokenPaid: rewardPerTokenStored, rewards: 0 }); userStakingInfo[msg.sender].push(_stakingInfo); uint256 _stakeNumber = userStakingInfo[msg.sender].length - 1; uint256 weightedStake = rewardsMultiplier.applyMultiplier(_amount, _stakeDuration); totalWeightedStake += weightedStake; totalStaked += _amount; stakingToken.safeTransferFrom(msg.sender, address(this), _amount); emit Staked(msg.sender, _stakeNumber, _amount); } function unstake(uint256 _amount, uint256 _stakeNumber) external nonReentrant { require(_amount > 0, "TrestleStakingPool::unstake: amount = 0"); require(_amount <= userStakingInfo[msg.sender][_stakeNumber].stakedAmount, "TrestleStakingPool::unstake: not enough balance"); _updateReward(msg.sender, _stakeNumber); uint256 currentWeightedStake = rewardsMultiplier.applyMultiplier( userStakingInfo[msg.sender][_stakeNumber].stakedAmount, userStakingInfo[msg.sender][_stakeNumber].duration ); totalWeightedStake -= currentWeightedStake; totalStaked -= _amount; uint256 penaltyFee = 0; if (block.timestamp < userStakingInfo[msg.sender][_stakeNumber].minimumStakeTimestamp) { penaltyFee = penaltyFeeCalculator.calculate(_amount, userStakingInfo[msg.sender][_stakeNumber].duration, address(this)); if (penaltyFee > _amount) { penaltyFee = _amount; } } userStakingInfo[msg.sender][_stakeNumber].stakedAmount -= _amount; if (userStakingInfo[msg.sender][_stakeNumber].stakedAmount == 0) { _claimRewards(msg.sender, _stakeNumber); // remove the staking info from array userStakingInfo[msg.sender][_stakeNumber] = userStakingInfo[msg.sender][userStakingInfo[msg.sender].length - 1]; userStakingInfo[msg.sender].pop(); } else { // update the weighted stake uint256 newWeightedStake = rewardsMultiplier.applyMultiplier( userStakingInfo[msg.sender][_stakeNumber].stakedAmount, userStakingInfo[msg.sender][_stakeNumber].duration ); totalWeightedStake += newWeightedStake; } if (penaltyFee > 0) { stakingToken.safeTransfer(BURN_ADDRESS, penaltyFee); _amount -= penaltyFee; } stakingToken.safeTransfer(msg.sender, _amount); emit Unstaked(msg.sender, _stakeNumber, _amount); } function _claimRewards(address _user, uint256 _stakeNumber) private { uint256 reward = userStakingInfo[_user][_stakeNumber].rewards; if (reward > 0) { userStakingInfo[_user][_stakeNumber].rewards = 0; rewardsToken.safeTransfer(_user, reward); emit RewardPaid(_user, _stakeNumber, reward); } } function claimRewards(uint256 _stakeNumber) external nonReentrant { _updateReward(msg.sender, _stakeNumber); _claimRewards(msg.sender, _stakeNumber); } /* ========== RESTRICTED FUNCTIONS ========== */ function initializeStaking( uint256 _startsAt, uint256 _rewardsDuration, uint256 _amount ) external nonReentrant onlyOwner { require(_startsAt > block.timestamp, "TrestleStakingPool::initializeStaking: _startsAt must be in the future"); require(_rewardsDuration > 0, "TrestleStakingPool::initializeStaking: _rewardsDuration = 0"); require(_amount > 0, "TrestleStakingPool::initializeStaking: _amount = 0"); require(startsAt == 0, "TrestleStakingPool::initializeStaking: staking already started"); _updateReward(address(0), 0); rewardsDuration = _rewardsDuration; startsAt = _startsAt; endsAt = _startsAt + _rewardsDuration; // add the amount to the pool uint256 initialAmount = rewardsToken.balanceOf(address(this)); rewardsToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 actualAmount = rewardsToken.balanceOf(address(this)) - initialAmount; totalRewards = actualAmount; rewardRatePerSec = actualAmount / _rewardsDuration; // set the staking to in progress isPaused = false; } function resumeStaking() external onlyOwner { require(rewardRatePerSec > 0, "TrestleStakingPool::startStaking: reward rate = 0"); require(isPaused, "TrestleStakingPool::startStaking: staking already started"); isPaused = false; } function pauseStaking() external onlyOwner { require(!isPaused, "TrestleStakingPool::pauseStaking: staking already paused"); isPaused = true; } function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token"); IERC20(tokenAddress).safeTransfer(owner, tokenAmount); emit TokenRecovered(tokenAddress, tokenAmount); } function transferOwnership(address _newOwner) external onlyOwner { address currentOwner = owner; owner = _newOwner; emit OwnershipTransferred(currentOwner, _newOwner); } /* ========== MODIFIERS ========== */ modifier inProgress() { require(!isPaused, "TrestleStakingPool::initialized: staking is paused"); require(startsAt <= block.timestamp, "TrestleStakingPool::initialized: staking has not started yet"); require(endsAt > block.timestamp, "TrestleStakingPool::notFinished: staking has finished"); _; } modifier onlyOwner() { require(msg.sender == owner, "TrestleStakingPool::onlyOwner: not authorized"); _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardsTokenDecimals","type":"uint256"},{"internalType":"address","name":"_multiplier","type":"address"},{"internalType":"address","name":"_penaltyFeeCalculator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"BURN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakeNumber","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endsAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_stakeNumber","type":"uint256"}],"name":"getUserRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserStakes","outputs":[{"components":[{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint256","name":"minimumStakeTimestamp","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"}],"internalType":"struct IStakingPool.StakingInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startsAt","type":"uint256"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"initializeStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"penaltyFeeCalculator","outputs":[{"internalType":"contract IPenaltyFee","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resumeStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRatePerSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsMultiplier","outputs":[{"internalType":"contract IMultiplier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsTokenDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"enum TrestleStakingPool.StakeTimeOptions","name":"_stakeTimeOption","type":"uint8"},{"internalType":"uint256","name":"_unstakeTime","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startsAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeightedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_stakeNumber","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userStakingInfo","outputs":[{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint256","name":"minimumStakeTimestamp","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenPaid","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101206040523480156200001257600080fd5b5060405162002aaa38038062002aaa83398101604081905262000035916200009f565b6001600081905580546001600160a01b031916331790556001600160601b0319606095861b811660805293851b841660a05260c092909252831b821660e05290911b166101005262000105565b80516001600160a01b03811681146200009a57600080fd5b919050565b600080600080600060a08688031215620000b7578081fd5b620000c28662000082565b9450620000d26020870162000082565b935060408601519250620000e96060870162000082565b9150620000f96080870162000082565b90509295509295909350565b60805160601c60a05160601c60c05160e05160601c6101005160601c6128eb620001bf60003960008181610259015261109601526000818161039a01528181610ef40152818161138501528181611c370152611d68015260008181610298015281816115a60152611eb30152600081816103db01528181610823015281816108b4015281816108fe01526121380152600081816102db01528181610c48015281816114c0015281816115030152611cf101526128eb6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639e2c8a5b11610104578063d1af0c7d116100a2578063f999c50611610071578063f999c50614610422578063f99b7d751461042a578063fccc28131461043d578063fff0c5361461044657600080fd5b8063d1af0c7d146103d6578063df136d65146103fd578063eed9da1f14610406578063f2fde38b1461040f57600080fd5b8063b6d7dc5c116100de578063b6d7dc5c14610395578063bddff592146103bc578063c8f33c91146103c5578063cd3daf9d146103ce57600080fd5b80639e2c8a5b1461035c578063af4686821461036f578063b187bd261461037857600080fd5b8063386a95251161017c578063817b1cd21161014b578063817b1cd21461030d578063842e2981146103165780638980f11f146103365780638da5cb5b1461034957600080fd5b8063386a9525146102cd57806372f702f3146102d65780637475f913146102fd57806380faa57d1461030557600080fd5b80630e15561a116101b85780630e15561a1461024b57806323a59277146102545780632792cdae1461029357806331d94f89146102ba57600080fd5b806304d978f1146101df5780630962ef791461021f5780630a09284a14610234575b600080fd5b6101f26101ed36600461255e565b610459565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61023261022d3660046125a7565b6104a7565b005b61023d60045481565b604051908152602001610216565b61023d60095481565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610216565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b6102326102c8366004612632565b610520565b61023d60025481565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6102326109ac565b61023d610b18565b61023d600a5481565b610329610324366004612544565b610b2f565b6040516102169190612679565b61023261034436600461255e565b610bd6565b60015461027b906001600160a01b031681565b61023261036a366004612611565b610d4e565b61023d60035481565b6008546103859060ff1681565b6040519015158152602001610216565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b61023d60065481565b61023d60055481565b61023d611570565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b61023d60075481565b61023d600b5481565b61023261041d366004612544565b611601565b6102326116db565b6102326104383660046125d7565b6117d3565b61027b61dead81565b61023d61045436600461255e565b611d63565b600c602052816000526040600020818154811061047557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600260005414156104ff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260005561050e3382611fad565b610518338261208a565b506001600055565b600260005414156105735760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b60026000556001546001600160a01b031633146105e85760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b4283116106835760405162461bcd60e51b815260206004820152604660248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f7374617274734174206d75737420626520696e207468652060648201527f6675747572650000000000000000000000000000000000000000000000000000608482015260a4016104f6565b600082116106f95760405162461bcd60e51b815260206004820152603b60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f726577617264734475726174696f6e203d2030000000000060648201526084016104f6565b6000811161076f5760405162461bcd60e51b815260206004820152603260248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f616d6f756e74203d2030000000000000000000000000000060648201526084016104f6565b600354156107e55760405162461bcd60e51b815260206004820152603e60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a207374616b696e6720616c72656164792073746172746564000060648201526084016104f6565b6107f0600080611fad565b60028290556003839055610804828461271a565b60049081556040516370a0823160e01b815230918101919091526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561086d57600080fd5b505afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a591906125bf565b90506108dc6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330856121a9565b6040516370a0823160e01b815230600482015260009082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b15801561094057600080fd5b505afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097891906125bf565b610982919061285c565b600981905590506109938482612732565b60065550506008805460ff191690555050600160005550565b6001546001600160a01b03163314610a1c5760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b600060065411610a945760405162461bcd60e51b815260206004820152603160248201527f54726573746c655374616b696e67506f6f6c3a3a73746172745374616b696e6760448201527f3a207265776172642072617465203d203000000000000000000000000000000060648201526084016104f6565b60085460ff16610b0c5760405162461bcd60e51b815260206004820152603960248201527f54726573746c655374616b696e67506f6f6c3a3a73746172745374616b696e6760448201527f3a207374616b696e6720616c726561647920737461727465640000000000000060648201526084016104f6565b6008805460ff19169055565b60006004544210610b2a575060045490565b504290565b6001600160a01b0381166000908152600c60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610bcb57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610b67565b505050509050919050565b6001546001600160a01b03163314610c465760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610cee5760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e0000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b600154610d08906001600160a01b03848116911683612260565b604080516001600160a01b0384168152602081018390527f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af05910160405180910390a15050565b60026000541415610da15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005581610e195760405162461bcd60e51b815260206004820152602760248201527f54726573746c655374616b696e67506f6f6c3a3a756e7374616b653a20616d6f60448201527f756e74203d20300000000000000000000000000000000000000000000000000060648201526084016104f6565b336000908152600c60205260409020805482908110610e4857634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154821115610ecf5760405162461bcd60e51b815260206004820152602f60248201527f54726573746c655374616b696e67506f6f6c3a3a756e7374616b653a206e6f7460448201527f20656e6f7567682062616c616e6365000000000000000000000000000000000060648201526084016104f6565b610ed93382611fad565b336000908152600c6020526040812080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163457b08099185908110610f3957634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c9091526040909120805486908110610f7957634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401610fb1929190918252602082015260400190565b60206040518083038186803b158015610fc957600080fd5b505afa158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100191906125bf565b905080600b6000828254611015919061285c565b9250508190555082600a600082825461102e919061285c565b9091555050336000908152600c6020526040812080548490811061106257634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016001015442101561119157336000908152600c6020526040902080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163b2c0f3cb91879190879081106110de57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600260059092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015230604482015260640160206040518083038186803b15801561114c57600080fd5b505afa158015611160573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118491906125bf565b9050838111156111915750825b336000908152600c602052604090208054859190859081106111c357634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000160008282546111e3919061285c565b9091555050336000908152600c6020526040902080548490811061121757634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600001546000141561136a5761123b338461208a565b336000908152600c6020526040902080546112589060019061285c565b8154811061127657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600c6000336001600160a01b03166001600160a01b0316815260200190815260200160002084815481106112c857634e487b7160e01b600052603260045260246000fd5b6000918252602080832084546005909302019182556001808501549083015560028085015490830155600380850154908301556004938401549390910192909255338152600c9091526040902080548061133257634e487b7160e01b600052603160045260246000fd5b6000828152602081206005600019909301928302018181556001810182905560028101829055600381018290556004015590556114ad565b336000908152600c6020526040812080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163457b080991879081106113ca57634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c909152604090912080548890811061140a57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611442929190918252602082015260400190565b60206040518083038186803b15801561145a57600080fd5b505afa15801561146e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149291906125bf565b905080600b60008282546114a6919061271a565b9091555050505b80156114f6576114e96001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661dead83612260565b6114f3818561285c565b93505b61152a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163386612260565b604080518481526020810186905233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e910160405180910390a2505060016000555050565b6000600a5460001415611584575060075490565b6000600554611591610b18565b61159b919061285c565b600b549091506115cc7f00000000000000000000000000000000000000000000000000000000000000006064612795565b826006546115da919061283d565b6115e4919061283d565b6115ee9190612732565b6007546115fb919061271a565b91505090565b6001546001600160a01b031633146116715760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001546001600160a01b0316331461174b5760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b60085460ff16156117c45760405162461bcd60e51b815260206004820152603860248201527f54726573746c655374616b696e67506f6f6c3a3a70617573655374616b696e6760448201527f3a207374616b696e6720616c726561647920706175736564000000000000000060648201526084016104f6565b6008805460ff19166001179055565b600260005414156118265760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005560085460ff16156118a45760405162461bcd60e51b815260206004820152603260248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65643a60448201527f207374616b696e6720697320706175736564000000000000000000000000000060648201526084016104f6565b42600354111561191c5760405162461bcd60e51b815260206004820152603c60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65643a60448201527f207374616b696e6720686173206e6f742073746172746564207965740000000060648201526084016104f6565b42600454116119935760405162461bcd60e51b815260206004820152603560248201527f54726573746c655374616b696e67506f6f6c3a3a6e6f7446696e69736865643a60448201527f207374616b696e67206861732066696e6973686564000000000000000000000060648201526084016104f6565b60008311611a095760405162461bcd60e51b815260206004820152602560248201527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a20616d6f756e60448201527f74203d203000000000000000000000000000000000000000000000000000000060648201526084016104f6565b600080836001811115611a2c57634e487b7160e01b600052602160045260246000fd5b14611a375781611a41565b611a41824261271a565b90506003548111611aba5760405162461bcd60e51b815260206004820152603d60248201527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a205f6d696e6960448201527f6d756d5374616b6554696d657374616d70203c3d20737461727473417400000060648201526084016104f6565b428111611b565760405162461bcd60e51b8152602060048201526044602482018190527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a205f6d696e69908201527f6d756d5374616b6554696d657374616d70203c3d20626c6f636b2e74696d657360648201527f74616d7000000000000000000000000000000000000000000000000000000000608482015260a4016104f6565b6000611b62428361285c565b9050611b6f600080611fad565b6040805160a08101825286815260208082018581528284018581526007546060850190815260006080860181815233808352600c87529782208054600181810183558285529784208951600590920201908155955186880155935160028601559151600385015590516004909301929092559381529254919291611bf3919061285c565b6040517f457b080900000000000000000000000000000000000000000000000000000000815260048101899052602481018590529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063457b08099060440160206040518083038186803b158015611c7957600080fd5b505afa158015611c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb191906125bf565b905080600b6000828254611cc5919061271a565b9250508190555087600a6000828254611cde919061271a565b90915550611d1990506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308b6121a9565b60408051838152602081018a905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a250506001600055505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663457b0809600c6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110611dd957634e487b7160e01b600052603260045260246000fd5b600091825260208083206005909202909101546001600160a01b0389168352600c9091526040909120805487908110611e2257634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611e5a929190918252602082015260400190565b60206040518083038186803b158015611e7257600080fd5b505afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa91906125bf565b90506000611ed97f00000000000000000000000000000000000000000000000000000000000000006064612795565b6001600160a01b0386166000908152600c60205260409020805486908110611f1157634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160030154611f2b611570565b611f35919061285c565b611f3f908461283d565b611f499190612732565b6001600160a01b0386166000908152600c6020526040902080549192509085908110611f8557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015481611fa2919061271a565b925050505b92915050565b611fb5611570565b600755611fc0610b18565b6005556001600160a01b0382161561208657611fdc8282611d63565b6001600160a01b0383166000908152600c6020526040902080548390811061201457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040181905550600754600c6000846001600160a01b03166001600160a01b03168152602001908152602001600020828154811061207057634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600301819055505b5050565b6001600160a01b0382166000908152600c602052604081208054839081106120c257634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040154905060008111156121a4576001600160a01b0383166000908152600c6020526040812080548490811061211757634e487b7160e01b600052603260045260246000fd5b600091825260209091206004600590920201015561215f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483612260565b60408051838152602081018390526001600160a01b038516917fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51910160405180910390a25b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261225a9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122a9565b50505050565b6040516001600160a01b0383166024820152604481018290526121a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016121f6565b60006122fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661238e9092919063ffffffff16565b8051909150156121a4578080602001905181019061231c9190612587565b6121a45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f6565b606061239d84846000856123a7565b90505b9392505050565b60608247101561241f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f6565b6001600160a01b0385163b6124765760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f6565b600080866001600160a01b03168587604051612492919061265d565b60006040518083038185875af1925050503d80600081146124cf576040519150601f19603f3d011682016040523d82523d6000602084013e6124d4565b606091505b50915091506124e48282866124ef565b979650505050505050565b606083156124fe5750816123a0565b82511561250e5782518084602001fd5b8160405162461bcd60e51b81526004016104f691906126e7565b80356001600160a01b038116811461253f57600080fd5b919050565b600060208284031215612555578081fd5b6123a082612528565b60008060408385031215612570578081fd5b61257983612528565b946020939093013593505050565b600060208284031215612598578081fd5b815180151581146123a0578182fd5b6000602082840312156125b8578081fd5b5035919050565b6000602082840312156125d0578081fd5b5051919050565b6000806000606084860312156125eb578081fd5b83359250602084013560028110612600578182fd5b929592945050506040919091013590565b60008060408385031215612623578182fd5b50508035926020909101359150565b600080600060608486031215612646578283fd5b505081359360208301359350604090920135919050565b6000825161266f818460208701612873565b9190910192915050565b602080825282518282018190526000919060409081850190868401855b828110156126da5781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101612696565b5091979650505050505050565b6020815260008251806020840152612706816040850160208701612873565b601f01601f19169190910160400192915050565b6000821982111561272d5761272d61289f565b500190565b60008261274d57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561278d5781600019048211156127735761277361289f565b8085161561278057918102915b93841c9390800290612757565b509250929050565b60006123a083836000826127ab57506001611fa7565b816127b857506000611fa7565b81600181146127ce57600281146127d8576127f4565b6001915050611fa7565b60ff8411156127e9576127e961289f565b50506001821b611fa7565b5060208310610133831016604e8410600b8410161715612817575081810a611fa7565b6128218383612752565b80600019048211156128355761283561289f565b029392505050565b60008160001904831182151516156128575761285761289f565b500290565b60008282101561286e5761286e61289f565b500390565b60005b8381101561288e578181015183820152602001612876565b8381111561225a5750506000910152565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220ae082cb65b5580073a4f9aea107bebb791e2c0f3bb69e9c875a30c7aba891be664736f6c63430008040033000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c246370000000000000000000000000000000000000000000000000000000000000009000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d0000000000000000000000006d77cffa304e1d15d9bab82372f62156739f0694
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80639e2c8a5b11610104578063d1af0c7d116100a2578063f999c50611610071578063f999c50614610422578063f99b7d751461042a578063fccc28131461043d578063fff0c5361461044657600080fd5b8063d1af0c7d146103d6578063df136d65146103fd578063eed9da1f14610406578063f2fde38b1461040f57600080fd5b8063b6d7dc5c116100de578063b6d7dc5c14610395578063bddff592146103bc578063c8f33c91146103c5578063cd3daf9d146103ce57600080fd5b80639e2c8a5b1461035c578063af4686821461036f578063b187bd261461037857600080fd5b8063386a95251161017c578063817b1cd21161014b578063817b1cd21461030d578063842e2981146103165780638980f11f146103365780638da5cb5b1461034957600080fd5b8063386a9525146102cd57806372f702f3146102d65780637475f913146102fd57806380faa57d1461030557600080fd5b80630e15561a116101b85780630e15561a1461024b57806323a59277146102545780632792cdae1461029357806331d94f89146102ba57600080fd5b806304d978f1146101df5780630962ef791461021f5780630a09284a14610234575b600080fd5b6101f26101ed36600461255e565b610459565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61023261022d3660046125a7565b6104a7565b005b61023d60045481565b604051908152602001610216565b61023d60095481565b61027b7f0000000000000000000000006d77cffa304e1d15d9bab82372f62156739f069481565b6040516001600160a01b039091168152602001610216565b61023d7f000000000000000000000000000000000000000000000000000000000000000981565b6102326102c8366004612632565b610520565b61023d60025481565b61027b7f000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad81565b6102326109ac565b61023d610b18565b61023d600a5481565b610329610324366004612544565b610b2f565b6040516102169190612679565b61023261034436600461255e565b610bd6565b60015461027b906001600160a01b031681565b61023261036a366004612611565b610d4e565b61023d60035481565b6008546103859060ff1681565b6040519015158152602001610216565b61027b7f000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d81565b61023d60065481565b61023d60055481565b61023d611570565b61027b7f000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c2463781565b61023d60075481565b61023d600b5481565b61023261041d366004612544565b611601565b6102326116db565b6102326104383660046125d7565b6117d3565b61027b61dead81565b61023d61045436600461255e565b611d63565b600c602052816000526040600020818154811061047557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600260005414156104ff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260005561050e3382611fad565b610518338261208a565b506001600055565b600260005414156105735760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b60026000556001546001600160a01b031633146105e85760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b4283116106835760405162461bcd60e51b815260206004820152604660248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f7374617274734174206d75737420626520696e207468652060648201527f6675747572650000000000000000000000000000000000000000000000000000608482015260a4016104f6565b600082116106f95760405162461bcd60e51b815260206004820152603b60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f726577617264734475726174696f6e203d2030000000000060648201526084016104f6565b6000811161076f5760405162461bcd60e51b815260206004820152603260248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a205f616d6f756e74203d2030000000000000000000000000000060648201526084016104f6565b600354156107e55760405162461bcd60e51b815260206004820152603e60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65537460448201527f616b696e673a207374616b696e6720616c72656164792073746172746564000060648201526084016104f6565b6107f0600080611fad565b60028290556003839055610804828461271a565b60049081556040516370a0823160e01b815230918101919091526000907f000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c246376001600160a01b0316906370a082319060240160206040518083038186803b15801561086d57600080fd5b505afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a591906125bf565b90506108dc6001600160a01b037f000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c24637163330856121a9565b6040516370a0823160e01b815230600482015260009082906001600160a01b037f000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c2463716906370a082319060240160206040518083038186803b15801561094057600080fd5b505afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097891906125bf565b610982919061285c565b600981905590506109938482612732565b60065550506008805460ff191690555050600160005550565b6001546001600160a01b03163314610a1c5760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b600060065411610a945760405162461bcd60e51b815260206004820152603160248201527f54726573746c655374616b696e67506f6f6c3a3a73746172745374616b696e6760448201527f3a207265776172642072617465203d203000000000000000000000000000000060648201526084016104f6565b60085460ff16610b0c5760405162461bcd60e51b815260206004820152603960248201527f54726573746c655374616b696e67506f6f6c3a3a73746172745374616b696e6760448201527f3a207374616b696e6720616c726561647920737461727465640000000000000060648201526084016104f6565b6008805460ff19169055565b60006004544210610b2a575060045490565b504290565b6001600160a01b0381166000908152600c60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610bcb57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610b67565b505050509050919050565b6001546001600160a01b03163314610c465760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b7f000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad6001600160a01b0316826001600160a01b03161415610cee5760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e0000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b600154610d08906001600160a01b03848116911683612260565b604080516001600160a01b0384168152602081018390527f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af05910160405180910390a15050565b60026000541415610da15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005581610e195760405162461bcd60e51b815260206004820152602760248201527f54726573746c655374616b696e67506f6f6c3a3a756e7374616b653a20616d6f60448201527f756e74203d20300000000000000000000000000000000000000000000000000060648201526084016104f6565b336000908152600c60205260409020805482908110610e4857634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154821115610ecf5760405162461bcd60e51b815260206004820152602f60248201527f54726573746c655374616b696e67506f6f6c3a3a756e7374616b653a206e6f7460448201527f20656e6f7567682062616c616e6365000000000000000000000000000000000060648201526084016104f6565b610ed93382611fad565b336000908152600c6020526040812080546001600160a01b037f000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d169163457b08099185908110610f3957634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c9091526040909120805486908110610f7957634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401610fb1929190918252602082015260400190565b60206040518083038186803b158015610fc957600080fd5b505afa158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100191906125bf565b905080600b6000828254611015919061285c565b9250508190555082600a600082825461102e919061285c565b9091555050336000908152600c6020526040812080548490811061106257634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016001015442101561119157336000908152600c6020526040902080546001600160a01b037f0000000000000000000000006d77cffa304e1d15d9bab82372f62156739f0694169163b2c0f3cb91879190879081106110de57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600260059092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015230604482015260640160206040518083038186803b15801561114c57600080fd5b505afa158015611160573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118491906125bf565b9050838111156111915750825b336000908152600c602052604090208054859190859081106111c357634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000160008282546111e3919061285c565b9091555050336000908152600c6020526040902080548490811061121757634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600001546000141561136a5761123b338461208a565b336000908152600c6020526040902080546112589060019061285c565b8154811061127657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600c6000336001600160a01b03166001600160a01b0316815260200190815260200160002084815481106112c857634e487b7160e01b600052603260045260246000fd5b6000918252602080832084546005909302019182556001808501549083015560028085015490830155600380850154908301556004938401549390910192909255338152600c9091526040902080548061133257634e487b7160e01b600052603160045260246000fd5b6000828152602081206005600019909301928302018181556001810182905560028101829055600381018290556004015590556114ad565b336000908152600c6020526040812080546001600160a01b037f000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d169163457b080991879081106113ca57634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c909152604090912080548890811061140a57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611442929190918252602082015260400190565b60206040518083038186803b15801561145a57600080fd5b505afa15801561146e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149291906125bf565b905080600b60008282546114a6919061271a565b9091555050505b80156114f6576114e96001600160a01b037f000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad1661dead83612260565b6114f3818561285c565b93505b61152a6001600160a01b037f000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad163386612260565b604080518481526020810186905233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e910160405180910390a2505060016000555050565b6000600a5460001415611584575060075490565b6000600554611591610b18565b61159b919061285c565b600b549091506115cc7f00000000000000000000000000000000000000000000000000000000000000096064612795565b826006546115da919061283d565b6115e4919061283d565b6115ee9190612732565b6007546115fb919061271a565b91505090565b6001546001600160a01b031633146116715760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001546001600160a01b0316331461174b5760405162461bcd60e51b815260206004820152602d60248201527f54726573746c655374616b696e67506f6f6c3a3a6f6e6c794f776e65723a206e60448201526c1bdd08185d5d1a1bdc9a5e9959609a1b60648201526084016104f6565b60085460ff16156117c45760405162461bcd60e51b815260206004820152603860248201527f54726573746c655374616b696e67506f6f6c3a3a70617573655374616b696e6760448201527f3a207374616b696e6720616c726561647920706175736564000000000000000060648201526084016104f6565b6008805460ff19166001179055565b600260005414156118265760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005560085460ff16156118a45760405162461bcd60e51b815260206004820152603260248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65643a60448201527f207374616b696e6720697320706175736564000000000000000000000000000060648201526084016104f6565b42600354111561191c5760405162461bcd60e51b815260206004820152603c60248201527f54726573746c655374616b696e67506f6f6c3a3a696e697469616c697a65643a60448201527f207374616b696e6720686173206e6f742073746172746564207965740000000060648201526084016104f6565b42600454116119935760405162461bcd60e51b815260206004820152603560248201527f54726573746c655374616b696e67506f6f6c3a3a6e6f7446696e69736865643a60448201527f207374616b696e67206861732066696e6973686564000000000000000000000060648201526084016104f6565b60008311611a095760405162461bcd60e51b815260206004820152602560248201527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a20616d6f756e60448201527f74203d203000000000000000000000000000000000000000000000000000000060648201526084016104f6565b600080836001811115611a2c57634e487b7160e01b600052602160045260246000fd5b14611a375781611a41565b611a41824261271a565b90506003548111611aba5760405162461bcd60e51b815260206004820152603d60248201527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a205f6d696e6960448201527f6d756d5374616b6554696d657374616d70203c3d20737461727473417400000060648201526084016104f6565b428111611b565760405162461bcd60e51b8152602060048201526044602482018190527f54726573746c655374616b696e67506f6f6c3a3a7374616b653a205f6d696e69908201527f6d756d5374616b6554696d657374616d70203c3d20626c6f636b2e74696d657360648201527f74616d7000000000000000000000000000000000000000000000000000000000608482015260a4016104f6565b6000611b62428361285c565b9050611b6f600080611fad565b6040805160a08101825286815260208082018581528284018581526007546060850190815260006080860181815233808352600c87529782208054600181810183558285529784208951600590920201908155955186880155935160028601559151600385015590516004909301929092559381529254919291611bf3919061285c565b6040517f457b080900000000000000000000000000000000000000000000000000000000815260048101899052602481018590529091506000906001600160a01b037f000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d169063457b08099060440160206040518083038186803b158015611c7957600080fd5b505afa158015611c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb191906125bf565b905080600b6000828254611cc5919061271a565b9250508190555087600a6000828254611cde919061271a565b90915550611d1990506001600160a01b037f000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad1633308b6121a9565b60408051838152602081018a905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a250506001600055505050505050565b6000807f000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d6001600160a01b031663457b0809600c6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110611dd957634e487b7160e01b600052603260045260246000fd5b600091825260208083206005909202909101546001600160a01b0389168352600c9091526040909120805487908110611e2257634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611e5a929190918252602082015260400190565b60206040518083038186803b158015611e7257600080fd5b505afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa91906125bf565b90506000611ed97f00000000000000000000000000000000000000000000000000000000000000096064612795565b6001600160a01b0386166000908152600c60205260409020805486908110611f1157634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160030154611f2b611570565b611f35919061285c565b611f3f908461283d565b611f499190612732565b6001600160a01b0386166000908152600c6020526040902080549192509085908110611f8557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015481611fa2919061271a565b925050505b92915050565b611fb5611570565b600755611fc0610b18565b6005556001600160a01b0382161561208657611fdc8282611d63565b6001600160a01b0383166000908152600c6020526040902080548390811061201457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040181905550600754600c6000846001600160a01b03166001600160a01b03168152602001908152602001600020828154811061207057634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600301819055505b5050565b6001600160a01b0382166000908152600c602052604081208054839081106120c257634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040154905060008111156121a4576001600160a01b0383166000908152600c6020526040812080548490811061211757634e487b7160e01b600052603260045260246000fd5b600091825260209091206004600590920201015561215f6001600160a01b037f000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c24637168483612260565b60408051838152602081018390526001600160a01b038516917fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51910160405180910390a25b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261225a9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122a9565b50505050565b6040516001600160a01b0383166024820152604481018290526121a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016121f6565b60006122fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661238e9092919063ffffffff16565b8051909150156121a4578080602001905181019061231c9190612587565b6121a45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f6565b606061239d84846000856123a7565b90505b9392505050565b60608247101561241f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f6565b6001600160a01b0385163b6124765760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f6565b600080866001600160a01b03168587604051612492919061265d565b60006040518083038185875af1925050503d80600081146124cf576040519150601f19603f3d011682016040523d82523d6000602084013e6124d4565b606091505b50915091506124e48282866124ef565b979650505050505050565b606083156124fe5750816123a0565b82511561250e5782518084602001fd5b8160405162461bcd60e51b81526004016104f691906126e7565b80356001600160a01b038116811461253f57600080fd5b919050565b600060208284031215612555578081fd5b6123a082612528565b60008060408385031215612570578081fd5b61257983612528565b946020939093013593505050565b600060208284031215612598578081fd5b815180151581146123a0578182fd5b6000602082840312156125b8578081fd5b5035919050565b6000602082840312156125d0578081fd5b5051919050565b6000806000606084860312156125eb578081fd5b83359250602084013560028110612600578182fd5b929592945050506040919091013590565b60008060408385031215612623578182fd5b50508035926020909101359150565b600080600060608486031215612646578283fd5b505081359360208301359350604090920135919050565b6000825161266f818460208701612873565b9190910192915050565b602080825282518282018190526000919060409081850190868401855b828110156126da5781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101612696565b5091979650505050505050565b6020815260008251806020840152612706816040850160208701612873565b601f01601f19169190910160400192915050565b6000821982111561272d5761272d61289f565b500190565b60008261274d57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561278d5781600019048211156127735761277361289f565b8085161561278057918102915b93841c9390800290612757565b509250929050565b60006123a083836000826127ab57506001611fa7565b816127b857506000611fa7565b81600181146127ce57600281146127d8576127f4565b6001915050611fa7565b60ff8411156127e9576127e961289f565b50506001821b611fa7565b5060208310610133831016604e8410600b8410161715612817575081810a611fa7565b6128218383612752565b80600019048211156128355761283561289f565b029392505050565b60008160001904831182151516156128575761285761289f565b500290565b60008282101561286e5761286e61289f565b500390565b60005b8381101561288e578181015183820152602001612876565b8381111561225a5750506000910152565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220ae082cb65b5580073a4f9aea107bebb791e2c0f3bb69e9c875a30c7aba891be664736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c246370000000000000000000000000000000000000000000000000000000000000009000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d0000000000000000000000006d77cffa304e1d15d9bab82372f62156739f0694
-----Decoded View---------------
Arg [0] : _stakingToken (address): 0xdE8CD13B812BcD82218754A740b27E76ec1e86aD
Arg [1] : _rewardToken (address): 0xFf9Cb08752d3A9Be72DE14CCE63f22FA19c24637
Arg [2] : _rewardsTokenDecimals (uint256): 9
Arg [3] : _multiplier (address): 0xccF3A872d6173f7480EC78c08C7703736c573f8D
Arg [4] : _penaltyFeeCalculator (address): 0x6d77cfFa304e1d15d9BAB82372f62156739F0694
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000de8cd13b812bcd82218754a740b27e76ec1e86ad
Arg [1] : 000000000000000000000000ff9cb08752d3a9be72de14cce63f22fa19c24637
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [3] : 000000000000000000000000ccf3a872d6173f7480ec78c08c7703736c573f8d
Arg [4] : 0000000000000000000000006d77cffa304e1d15d9bab82372f62156739f0694
Deployed Bytecode Sourcemap
21935:11073:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23198:56;;;;;;:::i;:::-;;:::i;:::-;;;;15821:25:1;;;15877:2;15862:18;;15855:34;;;;15905:18;;;15898:34;;;;15963:2;15948:18;;15941:34;16006:3;15991:19;;15984:35;15808:3;15793:19;23198:56:0;;;;;;;;30088:174;;;;;;:::i;:::-;;:::i;:::-;;22626:21;;;;;;;;;14900:25:1;;;14888:2;14873:18;22626:21:0;14855:76:1;22947:27:0;;;;;;22330:58;;;;;;;;-1:-1:-1;;;;;2855:55:1;;;2837:74;;2825:2;2810:18;22330:58:0;2792:125:1;22214:45:0;;;;;30326:1185;;;;;;:::i;:::-;;:::i;22471:30::-;;;;;;22128:36;;;;;31519:261;;;:::i;25004:143::-;;;:::i;23020:26::-;;;;;;25533:131;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;31962:307::-;;;;;;:::i;:::-;;:::i;22397:20::-;;;;;-1:-1:-1;;;;;22397:20:0;;;27625:2082;;;;;;:::i;:::-;;:::i;22553:23::-;;;;;;22897:20;;;;;;;;;;;;4809:14:1;;4802:22;4784:41;;4772:2;4757:18;22897:20:0;4739:92:1;22268:55:0;;;;;22783:31;;;;;;22694:29;;;;;;25155:370;;;:::i;22171:36::-;;;;;22853:35;;;;;;23108:33;;;;;;32277:201;;;;;;:::i;:::-;;:::i;31788:166::-;;;:::i;26151:1466::-;;;;;;:::i;:::-;;:::i;22038:81::-;;22077:42;22038:81;;24422:574;;;;;;:::i;:::-;;:::i;23198:56::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23198:56:0;;-1:-1:-1;23198:56:0;;;:::o;30088:174::-;1778:1;2376:7;;:19;;2368:63;;;;-1:-1:-1;;;2368:63:0;;12436:2:1;2368:63:0;;;12418:21:1;12475:2;12455:18;;;12448:30;12514:33;12494:18;;;12487:61;12565:18;;2368:63:0;;;;;;;;;1778:1;2509:7;:18;30165:39:::1;30179:10;30191:12:::0;30165:13:::1;:39::i;:::-;30215;30229:10;30241:12;30215:13;:39::i;:::-;-1:-1:-1::0;1734:1:0;2688:7;:22;30088:174::o;30326:1185::-;1778:1;2376:7;;:19;;2368:63;;;;-1:-1:-1;;;2368:63:0;;12436:2:1;2368:63:0;;;12418:21:1;12475:2;12455:18;;;12448:30;12514:33;12494:18;;;12487:61;12565:18;;2368:63:0;12408:181:1;2368:63:0;1778:1;2509:7;:18;32930:5:::1;::::0;-1:-1:-1;;;;;32930:5:0::1;32916:10;:19;32908:77;;;::::0;-1:-1:-1;;;32908:77:0;;7873:2:1;32908:77:0::1;::::0;::::1;7855:21:1::0;7912:2;7892:18;;;7885:30;7951:34;7931:18;;;7924:62;-1:-1:-1;;;8002:18:1;;;7995:43;8055:19;;32908:77:0::1;7845:235:1::0;32908:77:0::1;30512:15:::2;30500:9;:27;30492:110;;;::::0;-1:-1:-1;;;30492:110:0;;14047:2:1;30492:110:0::2;::::0;::::2;14029:21:1::0;14086:2;14066:18;;;14059:30;14125:34;14105:18;;;14098:62;14196:34;14176:18;;;14169:62;14268:8;14247:19;;;14240:37;14294:19;;30492:110:0::2;14019:300:1::0;30492:110:0::2;30640:1;30621:16;:20;30613:92;;;::::0;-1:-1:-1;;;30613:92:0;;7445:2:1;30613:92:0::2;::::0;::::2;7427:21:1::0;7484:2;7464:18;;;7457:30;7523:34;7503:18;;;7496:62;7594:29;7574:18;;;7567:57;7641:19;;30613:92:0::2;7417:249:1::0;30613:92:0::2;30734:1;30724:7;:11;30716:74;;;::::0;-1:-1:-1;;;30716:74:0;;11606:2:1;30716:74:0::2;::::0;::::2;11588:21:1::0;11645:2;11625:18;;;11618:30;11684:34;11664:18;;;11657:62;11755:20;11735:18;;;11728:48;11793:19;;30716:74:0::2;11578:240:1::0;30716:74:0::2;30809:8;::::0;:13;30801:88:::2;;;::::0;-1:-1:-1;;;30801:88:0;;13616:2:1;30801:88:0::2;::::0;::::2;13598:21:1::0;13655:2;13635:18;;;13628:30;13694:34;13674:18;;;13667:62;13765:32;13745:18;;;13738:60;13815:19;;30801:88:0::2;13588:252:1::0;30801:88:0::2;30902:28;30924:1;30928::::0;30902:13:::2;:28::i;:::-;30943:15;:34:::0;;;30988:8:::2;:20:::0;;;31028:28:::2;30961:16:::0;30999:9;31028:28:::2;:::i;:::-;31019:6;:37:::0;;;31132::::2;::::0;-1:-1:-1;;;31132:37:0;;31163:4:::2;31132:37:::0;;::::2;2837:74:1::0;;;;31108:21:0::2;::::0;31132:12:::2;-1:-1:-1::0;;;;;31132:22:0::2;::::0;::::2;::::0;2810:18:1;;31132:37:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31108:61:::0;-1:-1:-1;31180:65:0::2;-1:-1:-1::0;;;;;31180:12:0::2;:29;31210:10;31230:4;31237:7:::0;31180:29:::2;:65::i;:::-;31279:37;::::0;-1:-1:-1;;;31279:37:0;;31310:4:::2;31279:37;::::0;::::2;2837:74:1::0;31256:20:0::2;::::0;31319:13;;-1:-1:-1;;;;;31279:12:0::2;:22;::::0;::::2;::::0;2810:18:1;;31279:37:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;31343:12;:27:::0;;;31256:76;-1:-1:-1;31400:31:0::2;31415:16:::0;31256:76;31400:31:::2;:::i;:::-;31381:16;:50:::0;-1:-1:-1;;31487:8:0::2;:16:::0;;-1:-1:-1;;31487:16:0::2;::::0;;-1:-1:-1;;31487:16:0;31498:5:::2;2688:22:::0;-1:-1:-1;30326:1185:0:o;31519:261::-;32930:5;;-1:-1:-1;;;;;32930:5:0;32916:10;:19;32908:77;;;;-1:-1:-1;;;32908:77:0;;7873:2:1;32908:77:0;;;7855:21:1;7912:2;7892:18;;;7885:30;7951:34;7931:18;;;7924:62;-1:-1:-1;;;8002:18:1;;;7995:43;8055:19;;32908:77:0;7845:235:1;32908:77:0;31601:1:::1;31582:16;;:20;31574:82;;;::::0;-1:-1:-1;;;31574:82:0;;12796:2:1;31574:82:0::1;::::0;::::1;12778:21:1::0;12835:2;12815:18;;;12808:30;12874:34;12854:18;;;12847:62;12945:19;12925:18;;;12918:47;12982:19;;31574:82:0::1;12768:239:1::0;31574:82:0::1;31675:8;::::0;::::1;;31667:78;;;::::0;-1:-1:-1;;;31667:78:0;;7019:2:1;31667:78:0::1;::::0;::::1;7001:21:1::0;7058:2;7038:18;;;7031:30;7097:34;7077:18;;;7070:62;7168:27;7148:18;;;7141:55;7213:19;;31667:78:0::1;6991:247:1::0;31667:78:0::1;31756:8;:16:::0;;-1:-1:-1;;31756:16:0::1;::::0;;31519:261::o;25004:143::-;25061:7;25106:6;;25088:15;:24;:51;;-1:-1:-1;25133:6:0;;;25004:143::o;25088:51::-;-1:-1:-1;25115:15:0;;25004:143::o;25533:131::-;-1:-1:-1;;;;;25634:22:0;;;;;;:15;:22;;;;;;;;25627:29;;;;;;;;;;;;;;;;;25594:20;;25627:29;;25634:22;;25627:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25533:131;;;:::o;31962:307::-;32930:5;;-1:-1:-1;;;;;32930:5:0;32916:10;:19;32908:77;;;;-1:-1:-1;;;32908:77:0;;7873:2:1;32908:77:0;;;7855:21:1;7912:2;7892:18;;;7885:30;7951:34;7931:18;;;7924:62;-1:-1:-1;;;8002:18:1;;;7995:43;8055:19;;32908:77:0;7845:235:1;32908:77:0;32089:12:::1;-1:-1:-1::0;;;;;32065:37:0::1;:12;-1:-1:-1::0;;;;;32065:37:0::1;;;32057:83;;;::::0;-1:-1:-1;;;32057:83:0;;13214:2:1;32057:83:0::1;::::0;::::1;13196:21:1::0;13253:2;13233:18;;;13226:30;13292:34;13272:18;;;13265:62;13363:3;13343:18;;;13336:31;13384:19;;32057:83:0::1;13186:223:1::0;32057:83:0::1;32185:5;::::0;32151:53:::1;::::0;-1:-1:-1;;;;;32151:33:0;;::::1;::::0;32185:5:::1;32192:11:::0;32151:33:::1;:53::i;:::-;32220:41;::::0;;-1:-1:-1;;;;;3517:55:1;;3499:74;;3604:2;3589:18;;3582:34;;;32220:41:0::1;::::0;3472:18:1;32220:41:0::1;;;;;;;31962:307:::0;;:::o;27625:2082::-;1778:1;2376:7;;:19;;2368:63;;;;-1:-1:-1;;;2368:63:0;;12436:2:1;2368:63:0;;;12418:21:1;12475:2;12455:18;;;12448:30;12514:33;12494:18;;;12487:61;12565:18;;2368:63:0;12408:181:1;2368:63:0;1778:1;2509:7;:18;27722:11;27714:63:::1;;;::::0;-1:-1:-1;;;27714:63:0;;10434:2:1;27714:63:0::1;::::0;::::1;10416:21:1::0;10473:2;10453:18;;;10446:30;10512:34;10492:18;;;10485:62;10583:9;10563:18;;;10556:37;10610:19;;27714:63:0::1;10406:229:1::0;27714:63:0::1;27823:10;27807:27;::::0;;;:15:::1;:27;::::0;;;;:41;;27835:12;;27807:41;::::1;;;-1:-1:-1::0;;;27807:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;27796:7;:65;;27788:125;;;::::0;-1:-1:-1;;;27788:125:0;;8287:2:1;27788:125:0::1;::::0;::::1;8269:21:1::0;8326:2;8306:18;;;8299:30;8365:34;8345:18;;;8338:62;8436:17;8416:18;;;8409:45;8471:19;;27788:125:0::1;8259:237:1::0;27788:125:0::1;27926:39;27940:10;27952:12;27926:13;:39::i;:::-;28073:10;27978:28;28057:27:::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;28009:17:0::1;:33;::::0;::::1;::::0;28085:12;;28057:41;::::1;;;-1:-1:-1::0;;;28057:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:54:::0;28142:10:::1;28126:27:::0;;:15:::1;:27:::0;;;;;;;:41;;28154:12;;28126:41;::::1;;;-1:-1:-1::0;;;28126:41:0::1;;;;;;;;;;;;;;;;;;;:50;;;28009:178;;;;;;;;;;;;;;;15110:25:1::0;;;15166:2;15151:18;;15144:34;15098:2;15083:18;;15065:119;28009:178:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27978:209;;28220:20;28198:18;;:42;;;;;;;:::i;:::-;;;;;;;;28266:7;28251:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;28357:10:0::1;28286:18;28341:27:::0;;;:15:::1;:27;::::0;;;;:41;;28369:12;;28341:41;::::1;;;-1:-1:-1::0;;;28341:41:0::1;;;;;;;;;;;;;;;;;;;:63;;;28323:15;:81;28319:328;;;28490:10;28474:27;::::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;28434:20:0::1;:30;::::0;::::1;::::0;28465:7;;28474:27;28502:12;;28474:41;::::1;;;-1:-1:-1::0;;;28474:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;:50:::1;:41;::::0;;::::1;;:50;::::0;28434:106:::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;15391:25:1::0;;;;15432:18;;;15425:34;28534:4:0::1;15475:18:1::0;;;15468:83;15364:18;;28434:106:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28421:119;;28572:7;28559:10;:20;28555:81;;;-1:-1:-1::0;28613:7:0;28555:81:::1;28675:10;28659:27;::::0;;;:15:::1;:27;::::0;;;;:41;;28717:7;;28659:27;28687:12;;28659:41;::::1;;;-1:-1:-1::0;;;28659:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;:65;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;28757:10:0::1;28741:27;::::0;;;:15:::1;:27;::::0;;;;:41;;28769:12;;28741:41;::::1;;;-1:-1:-1::0;;;28741:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;28799:1;28741:59;28737:701;;;28817:39;28831:10;28843:12;28817:13;:39::i;:::-;28982:10;28966:27;::::0;;;:15:::1;:27;::::0;;;;28994:34;;:38:::1;::::0;29031:1:::1;::::0;28994:38:::1;:::i;:::-;28966:67;;;;;;-1:-1:-1::0;;;28966:67:0::1;;;;;;;;;;;;;;;;;;;28922:15;:27;28938:10;-1:-1:-1::0;;;;;28922:27:0::1;-1:-1:-1::0;;;;;28922:27:0::1;;;;;;;;;;;;28950:12;28922:41;;;;;;-1:-1:-1::0;;;28922:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;:111;;:41:::1;::::0;;::::1;;:111:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;;;29064:10:::1;29048:27:::0;;:15:::1;:27:::0;;;;;;:33;;;::::1;;-1:-1:-1::0;;;29048:33:0::1;;;;;;;;;;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;29048:33:0;;;;;::::1;;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;28737:701:::1;;;29251:10;29156:24;29235:27:::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;29183:17:0::1;:33;::::0;::::1;::::0;29263:12;;29235:41;::::1;;;-1:-1:-1::0;;;29235:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:54:::0;29324:10:::1;29308:27:::0;;:15:::1;:27:::0;;;;;;;:41;;29336:12;;29308:41;::::1;;;-1:-1:-1::0;;;29308:41:0::1;;;;;;;;;;;;;;;;;;;:50;;;29183:190;;;;;;;;;;;;;;;15110:25:1::0;;;15166:2;15151:18;;15144:34;15098:2;15083:18;;15065:119;29183:190:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29156:217;;29410:16;29388:18;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;28737:701:0::1;29454:14:::0;;29450:134:::1;;29485:51;-1:-1:-1::0;;;;;29485:12:0::1;:25;22077:42;29525:10:::0;29485:25:::1;:51::i;:::-;29551:21;29562:10:::0;29551:21;::::1;:::i;:::-;;;29450:134;29594:46;-1:-1:-1::0;;;;;29594:12:0::1;:25;29620:10;29632:7:::0;29594:25:::1;:46::i;:::-;29656:43;::::0;;15110:25:1;;;15166:2;15151:18;;15144:34;;;29665:10:0::1;::::0;29656:43:::1;::::0;15083:18:1;29656:43:0::1;;;;;;;-1:-1:-1::0;;1734:1:0;2688:7;:22;-1:-1:-1;;27625:2082:0:o;25155:370::-;25202:7;25226:11;;25241:1;25226:16;25222:76;;;-1:-1:-1;25266:20:0;;;25155:370::o;25222:76::-;25308:28;25368:14;;25339:26;:24;:26::i;:::-;:43;;;;:::i;:::-;25498:18;;25308:74;;-1:-1:-1;25468:25:0;25473:20;25468:3;:25;:::i;:::-;25444:20;25425:16;;:39;;;;:::i;:::-;:69;;;;:::i;:::-;25424:92;;;;:::i;:::-;25400:20;;:117;;;;:::i;:::-;25393:124;;;25155:370;:::o;32277:201::-;32930:5;;-1:-1:-1;;;;;32930:5:0;32916:10;:19;32908:77;;;;-1:-1:-1;;;32908:77:0;;7873:2:1;32908:77:0;;;7855:21:1;7912:2;7892:18;;;7885:30;7951:34;7931:18;;;7924:62;-1:-1:-1;;;8002:18:1;;;7995:43;8055:19;;32908:77:0;7845:235:1;32908:77:0;32376:5:::1;::::0;;-1:-1:-1;;;;;32392:17:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;32425:45:::1;::::0;32376:5;::::1;::::0;32392:17;32376:5;;32425:45:::1;::::0;32353:20:::1;::::0;32425:45:::1;32996:1;32277:201:::0;:::o;31788:166::-;32930:5;;-1:-1:-1;;;;;32930:5:0;32916:10;:19;32908:77;;;;-1:-1:-1;;;32908:77:0;;7873:2:1;32908:77:0;;;7855:21:1;7912:2;7892:18;;;7885:30;7951:34;7931:18;;;7924:62;-1:-1:-1;;;8002:18:1;;;7995:43;8055:19;;32908:77:0;7845:235:1;32908:77:0;31851:8:::1;::::0;::::1;;31850:9;31842:78;;;::::0;-1:-1:-1;;;31842:78:0;;8703:2:1;31842:78:0::1;::::0;::::1;8685:21:1::0;8742:2;8722:18;;;8715:30;8781:34;8761:18;;;8754:62;8852:26;8832:18;;;8825:54;8896:19;;31842:78:0::1;8675:246:1::0;31842:78:0::1;31931:8;:15:::0;;-1:-1:-1;;31931:15:0::1;31942:4;31931:15;::::0;;31788:166::o;26151:1466::-;1778:1;2376:7;;:19;;2368:63;;;;-1:-1:-1;;;2368:63:0;;12436:2:1;2368:63:0;;;12418:21:1;12475:2;12455:18;;;12448:30;12514:33;12494:18;;;12487:61;12565:18;;2368:63:0;12408:181:1;2368:63:0;1778:1;2509:7;:18;32573:8:::1;::::0;::::1;;32572:9;32564:72;;;::::0;-1:-1:-1;;;32564:72:0;;6600:2:1;32564:72:0::1;::::0;::::1;6582:21:1::0;6639:2;6619:18;;;6612:30;6678:34;6658:18;;;6651:62;6749:20;6729:18;;;6722:48;6787:19;;32564:72:0::1;6572:240:1::0;32564:72:0::1;32667:15;32655:8;;:27;;32647:100;;;::::0;-1:-1:-1;;;32647:100:0;;6171:2:1;32647:100:0::1;::::0;::::1;6153:21:1::0;6210:2;6190:18;;;6183:30;6249:34;6229:18;;;6222:62;6320:30;6300:18;;;6293:58;6368:19;;32647:100:0::1;6143:250:1::0;32647:100:0::1;32775:15;32766:6;;:24;32758:90;;;::::0;-1:-1:-1;;;32758:90:0;;9605:2:1;32758:90:0::1;::::0;::::1;9587:21:1::0;9644:2;9624:18;;;9617:30;9683:34;9663:18;;;9656:62;9754:23;9734:18;;;9727:51;9795:19;;32758:90:0::1;9577:243:1::0;32758:90:0::1;26336:1:::2;26326:7;:11;26318:61;;;::::0;-1:-1:-1;;;26318:61:0;;10842:2:1;26318:61:0::2;::::0;::::2;10824:21:1::0;10881:2;10861:18;;;10854:30;10920:34;10900:18;;;10893:62;10991:7;10971:18;;;10964:35;11016:19;;26318:61:0::2;10814:227:1::0;26318:61:0::2;26390:30;::::0;26423:16:::2;:45;;;;;;-1:-1:-1::0;;;26423:45:0::2;;;;;;;;;;:93;;26504:12;26423:93;;;26471:30;26489:12:::0;26471:15:::2;:30;:::i;:::-;26390:126;;26560:8;;26535:22;:33;26527:107;;;::::0;-1:-1:-1;;;26527:107:0;;14526:2:1;26527:107:0::2;::::0;::::2;14508:21:1::0;14565:2;14545:18;;;14538:30;14604:34;14584:18;;;14577:62;14675:31;14655:18;;;14648:59;14724:19;;26527:107:0::2;14498:251:1::0;26527:107:0::2;26678:15;26653:22;:40;26645:121;;;::::0;-1:-1:-1;;;26645:121:0;;9128:2:1;26645:121:0::2;::::0;::::2;9110:21:1::0;9167:2;9147:18;;;9140:30;;;9206:34;9186:18;;;9179:62;9277:34;9257:18;;;9250:62;9349:6;9328:19;;;9321:35;9373:19;;26645:121:0::2;9100:298:1::0;26645:121:0::2;26779:22;26804:40;26829:15;26804:22:::0;:40:::2;:::i;:::-;26779:65;;26857:28;26879:1;26883::::0;26857:13:::2;:28::i;:::-;26930:239;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;;;;;;;;;27112:20:::2;::::0;26930:239;;;;;;26896:31:::2;26930:239:::0;;;;;;27196:10:::2;27180:27:::0;;;:15:::2;:27:::0;;;;;:46;;::::2;::::0;;::::2;::::0;;;;;;;;;;::::2;::::0;;::::2;;::::0;;;;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;::::2;::::0;;;;27262:27;;;:34;;26930:239;;26896:31;27262:38:::2;::::0;27180:46;27262:38:::2;:::i;:::-;27337:58;::::0;;;;::::2;::::0;::::2;15110:25:1::0;;;15151:18;;;15144:34;;;27239:61:0;;-1:-1:-1;27313:21:0::2;::::0;-1:-1:-1;;;;;27337:17:0::2;:33;::::0;::::2;::::0;15083:18:1;;27337:58:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27313:82;;27428:13;27406:18;;:35;;;;;;;:::i;:::-;;;;;;;;27467:7;27452:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;27487:65:0::2;::::0;-1:-1:-1;;;;;;27487:12:0::2;:29;27517:10;27537:4;27544:7:::0;27487:29:::2;:65::i;:::-;27568:41;::::0;;15110:25:1;;;15166:2;15151:18;;15144:34;;;27575:10:0::2;::::0;27568:41:::2;::::0;15083:18:1;27568:41:0::2;;;;;;;-1:-1:-1::0;;1734:1:0;2688:7;:22;-1:-1:-1;;;;;;26151:1466:0:o;24422:574::-;24504:7;24524:22;24549:17;-1:-1:-1;;;;;24549:33:0;;24597:15;:22;24613:5;-1:-1:-1;;;;;24597:22:0;-1:-1:-1;;;;;24597:22:0;;;;;;;;;;;;24620:12;24597:36;;;;;;-1:-1:-1;;;24597:36:0;;;;;;;;;;;;;;;;;;;;;;;;:49;-1:-1:-1;;;;;24661:22:0;;;;:15;:22;;;;;;;:36;;24684:12;;24661:36;;;;-1:-1:-1;;;24661:36:0;;;;;;;;;;;;;;;;;;;:45;;;24549:168;;;;;;;;;;;;;;;15110:25:1;;;15166:2;15151:18;;15144:34;15098:2;15083:18;;15065:119;24549:168:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24524:193;-1:-1:-1;24728:30:0;24874:25;24879:20;24874:3;:25;:::i;:::-;-1:-1:-1;;;;;24800:22:0;;;;;;:15;:22;;;;;:36;;24823:12;;24800:36;;;;-1:-1:-1;;;24800:36:0;;;;;;;;;;;;;;;;;;;:55;;;24781:16;:14;:16::i;:::-;:74;;;;:::i;:::-;24763:93;;:14;:93;:::i;:::-;24762:138;;;;:::i;:::-;-1:-1:-1;;;;;24944:22:0;;;;;;:15;:22;;;;;:36;;24728:173;;-1:-1:-1;24944:22:0;24967:12;;24944:36;;;;-1:-1:-1;;;24944:36:0;;;;;;;;;;;;;;;;;;;:44;;;24919:22;:69;;;;:::i;:::-;24912:76;;;;24422:574;;;;;:::o;25726:417::-;25828:16;:14;:16::i;:::-;25805:20;:39;25872:26;:24;:26::i;:::-;25855:14;:43;-1:-1:-1;;;;;25913:19:0;;;25909:227;;25996:35;26011:5;26018:12;25996:14;:35::i;:::-;-1:-1:-1;;;;;25949:22:0;;;;;;:15;:22;;;;;:36;;25972:12;;25949:36;;;;-1:-1:-1;;;25949:36:0;;;;;;;;;;;;;;;;;;;:44;;:82;;;;26104:20;;26046:15;:22;26062:5;-1:-1:-1;;;;;26046:22:0;-1:-1:-1;;;;;26046:22:0;;;;;;;;;;;;26069:12;26046:36;;;;;;-1:-1:-1;;;26046:36:0;;;;;;;;;;;;;;;;;;;:55;;:78;;;;25909:227;25726:417;;:::o;29715:365::-;-1:-1:-1;;;;;29811:22:0;;29794:14;29811:22;;;:15;:22;;;;;:36;;29834:12;;29811:36;;;;-1:-1:-1;;;29811:36:0;;;;;;;;;;;;;;;;;;;:44;;;29794:61;;29881:1;29872:6;:10;29868:205;;;-1:-1:-1;;;;;29899:22:0;;29946:1;29899:22;;;:15;:22;;;;;:36;;29922:12;;29899:36;;;;-1:-1:-1;;;29899:36:0;;;;;;;;;;;;;;;;;:44;:36;;;;;:44;:48;29962:40;-1:-1:-1;;;;;29962:12:0;:25;29988:5;29995:6;29962:25;:40::i;:::-;30022:39;;;15110:25:1;;;15166:2;15151:18;;15144:34;;;-1:-1:-1;;;;;30022:39:0;;;;;15083:18:1;30022:39:0;;;;;;;29868:205;29715:365;;;:::o;16754:248::-;16925:68;;-1:-1:-1;;;;;3203:15:1;;;16925:68:0;;;3185:34:1;3255:15;;3235:18;;;3228:43;3287:18;;;3280:34;;;16898:96:0;;16918:5;;16948:27;;3097:18:1;;16925:68:0;;;;-1:-1:-1;;16925:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;16898:19;:96::i;:::-;16754:248;;;;:::o;16535:211::-;16679:58;;-1:-1:-1;;;;;3517:55:1;;16679:58:0;;;3499:74:1;3589:18;;;3582:34;;;16652:86:0;;16672:5;;16702:23;;3472:18:1;;16679:58:0;3454:168:1;19602:716:0;20026:23;20052:69;20080:4;20052:69;;;;;;;;;;;;;;;;;20060:5;-1:-1:-1;;;;;20052:27:0;;;:69;;;;;:::i;:::-;20136:17;;20026:95;;-1:-1:-1;20136:21:0;20132:179;;20233:10;20222:30;;;;;;;;;;;;:::i;:::-;20214:85;;;;-1:-1:-1;;;20214:85:0;;12025:2:1;20214:85:0;;;12007:21:1;12064:2;12044:18;;;12037:30;12103:34;12083:18;;;12076:62;12174:12;12154:18;;;12147:40;12204:19;;20214:85:0;11997:232:1;11434:229:0;11571:12;11603:52;11625:6;11633:4;11639:1;11642:12;11603:21;:52::i;:::-;11596:59;;11434:229;;;;;;:::o;12554:510::-;12724:12;12782:5;12757:21;:30;;12749:81;;;;-1:-1:-1;;;12749:81:0;;10027:2:1;12749:81:0;;;10009:21:1;10066:2;10046:18;;;10039:30;10105:34;10085:18;;;10078:62;10176:8;10156:18;;;10149:36;10202:19;;12749:81:0;9999:228:1;12749:81:0;-1:-1:-1;;;;;8984:19:0;;;12841:60;;;;-1:-1:-1;;;12841:60:0;;11248:2:1;12841:60:0;;;11230:21:1;11287:2;11267:18;;;11260:30;11326:31;11306:18;;;11299:59;11375:18;;12841:60:0;11220:179:1;12841:60:0;12915:12;12929:23;12956:6;-1:-1:-1;;;;;12956:11:0;12975:5;12982:4;12956:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12914:73;;;;13005:51;13022:7;13031:10;13043:12;13005:16;:51::i;:::-;12998:58;12554:510;-1:-1:-1;;;;;;;12554:510:0:o;15240:762::-;15390:12;15419:7;15415:580;;;-1:-1:-1;15450:10:0;15443:17;;15415:580;15564:17;;:21;15560:424;;15812:10;15806:17;15873:15;15860:10;15856:2;15852:19;15845:44;15760:148;15955:12;15948:20;;-1:-1:-1;;;15948:20:0;;;;;;;;:::i;14:196:1:-;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:2;;200:1;197;190:12;111:2;63:147;;;:::o;215:196::-;274:6;327:2;315:9;306:7;302:23;298:32;295:2;;;348:6;340;333:22;295:2;376:29;395:9;376:29;:::i;416:264::-;484:6;492;545:2;533:9;524:7;520:23;516:32;513:2;;;566:6;558;551:22;513:2;594:29;613:9;594:29;:::i;:::-;584:39;670:2;655:18;;;;642:32;;-1:-1:-1;;;503:177:1:o;685:297::-;752:6;805:2;793:9;784:7;780:23;776:32;773:2;;;826:6;818;811:22;773:2;863:9;857:16;916:5;909:13;902:21;895:5;892:32;882:2;;943:6;935;928:22;987:190;1046:6;1099:2;1087:9;1078:7;1074:23;1070:32;1067:2;;;1120:6;1112;1105:22;1067:2;-1:-1:-1;1148:23:1;;1057:120;-1:-1:-1;1057:120:1:o;1182:194::-;1252:6;1305:2;1293:9;1284:7;1280:23;1276:32;1273:2;;;1326:6;1318;1311:22;1273:2;-1:-1:-1;1354:16:1;;1263:113;-1:-1:-1;1263:113:1:o;1381:432::-;1478:6;1486;1494;1547:2;1535:9;1526:7;1522:23;1518:32;1515:2;;;1568:6;1560;1553:22;1515:2;1609:9;1596:23;1586:33;;1669:2;1658:9;1654:18;1641:32;1702:1;1695:5;1692:12;1682:2;;1723:6;1715;1708:22;1682:2;1505:308;;1751:5;;-1:-1:-1;;;1803:2:1;1788:18;;;;1775:32;;1505:308::o;1818:258::-;1886:6;1894;1947:2;1935:9;1926:7;1922:23;1918:32;1915:2;;;1968:6;1960;1953:22;1915:2;-1:-1:-1;;1996:23:1;;;2066:2;2051:18;;;2038:32;;-1:-1:-1;1905:171:1:o;2081:326::-;2158:6;2166;2174;2227:2;2215:9;2206:7;2202:23;2198:32;2195:2;;;2248:6;2240;2233:22;2195:2;-1:-1:-1;;2276:23:1;;;2346:2;2331:18;;2318:32;;-1:-1:-1;2397:2:1;2382:18;;;2369:32;;2185:222;-1:-1:-1;2185:222:1:o;2412:274::-;2541:3;2579:6;2573:13;2595:53;2641:6;2636:3;2629:4;2621:6;2617:17;2595:53;:::i;:::-;2664:16;;;;;2549:137;-1:-1:-1;;2549:137:1:o;3627:1012::-;3854:2;3906:21;;;3976:13;;3879:18;;;3998:22;;;3825:4;;3854:2;4039;;4057:18;;;;4098:15;;;3825:4;4144:469;4158:6;4155:1;4152:13;4144:469;;;4217:13;;4255:9;;4243:22;;4305:11;;;4299:18;4285:12;;;4278:40;4358:11;;;4352:18;4338:12;;;4331:40;4394:4;4438:11;;;4432:18;4418:12;;;4411:40;4474:4;4518:11;;;4512:18;4498:12;;;4491:40;4560:4;4551:14;;;;4588:15;;;;4180:1;4173:9;4144:469;;;-1:-1:-1;4630:3:1;;3834:805;-1:-1:-1;;;;;;;3834:805:1:o;5581:383::-;5730:2;5719:9;5712:21;5693:4;5762:6;5756:13;5805:6;5800:2;5789:9;5785:18;5778:34;5821:66;5880:6;5875:2;5864:9;5860:18;5855:2;5847:6;5843:15;5821:66;:::i;:::-;5948:2;5927:15;-1:-1:-1;;5923:29:1;5908:45;;;;5955:2;5904:54;;5702:262;-1:-1:-1;;5702:262:1:o;16030:128::-;16070:3;16101:1;16097:6;16094:1;16091:13;16088:2;;;16107:18;;:::i;:::-;-1:-1:-1;16143:9:1;;16078:80::o;16163:274::-;16203:1;16229;16219:2;;-1:-1:-1;;;16261:1:1;16254:88;16365:4;16362:1;16355:15;16393:4;16390:1;16383:15;16219:2;-1:-1:-1;16422:9:1;;16209:228::o;16442:422::-;16531:1;16574:5;16531:1;16588:270;16609:7;16599:8;16596:21;16588:270;;;16668:4;16664:1;16660:6;16656:17;16650:4;16647:27;16644:2;;;16677:18;;:::i;:::-;16727:7;16717:8;16713:22;16710:2;;;16747:16;;;;16710:2;16826:22;;;;16786:15;;;;16588:270;;;16592:3;16506:358;;;;;:::o;16869:131::-;16929:5;16958:36;16985:8;16979:4;17054:5;17084:8;17074:2;;-1:-1:-1;17125:1:1;17139:5;;17074:2;17173:4;17163:2;;-1:-1:-1;17210:1:1;17224:5;;17163:2;17255:4;17273:1;17268:59;;;;17341:1;17336:130;;;;17248:218;;17268:59;17298:1;17289:10;;17312:5;;;17336:130;17373:3;17363:8;17360:17;17357:2;;;17380:18;;:::i;:::-;-1:-1:-1;;17436:1:1;17422:16;;17451:5;;17248:218;;17550:2;17540:8;17537:16;17531:3;17525:4;17522:13;17518:36;17512:2;17502:8;17499:16;17494:2;17488:4;17485:12;17481:35;17478:77;17475:2;;;-1:-1:-1;17587:19:1;;;17619:5;;17475:2;17666:34;17691:8;17685:4;17666:34;:::i;:::-;17736:6;17732:1;17728:6;17724:19;17715:7;17712:32;17709:2;;;17747:18;;:::i;:::-;17785:20;;17064:747;-1:-1:-1;;;17064:747:1:o;17816:168::-;17856:7;17922:1;17918;17914:6;17910:14;17907:1;17904:21;17899:1;17892:9;17885:17;17881:45;17878:2;;;17929:18;;:::i;:::-;-1:-1:-1;17969:9:1;;17868:116::o;17989:125::-;18029:4;18057:1;18054;18051:8;18048:2;;;18062:18;;:::i;:::-;-1:-1:-1;18099:9:1;;18038:76::o;18119:258::-;18191:1;18201:113;18215:6;18212:1;18209:13;18201:113;;;18291:11;;;18285:18;18272:11;;;18265:39;18237:2;18230:10;18201:113;;;18332:6;18329:1;18326:13;18323:2;;;-1:-1:-1;;18367:1:1;18349:16;;18342:27;18172:205::o;18382:184::-;-1:-1:-1;;;18431:1:1;18424:88;18531:4;18528:1;18521:15;18555:4;18552:1;18545:15
Swarm Source
ipfs://ae082cb65b5580073a4f9aea107bebb791e2c0f3bb69e9c875a30c7aba891be6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.000781 | 7,093,776.7732 | $5,538.75 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.