Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 33 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 66588509 | 62 days ago | IN | 0 POL | 0.00418931 | ||||
Unstake | 66153224 | 73 days ago | IN | 0 POL | 0.00768678 | ||||
Unstake | 65925989 | 79 days ago | IN | 0 POL | 0.00453241 | ||||
Claim Rewards | 65925983 | 79 days ago | IN | 0 POL | 0.00385792 | ||||
Claim Rewards | 65896233 | 80 days ago | IN | 0 POL | 0.00701526 | ||||
Claim Rewards | 63667683 | 136 days ago | IN | 0 POL | 0.05392853 | ||||
Stake | 62973905 | 153 days ago | IN | 0 POL | 0.00792164 | ||||
Claim Rewards | 62595571 | 162 days ago | IN | 0 POL | 0.00351348 | ||||
Stake | 62145151 | 173 days ago | IN | 0 POL | 0.00746302 | ||||
Unstake | 60871632 | 205 days ago | IN | 0 POL | 0.00449549 | ||||
Unstake | 60871625 | 205 days ago | IN | 0 POL | 0.0046656 | ||||
Stake | 60714871 | 209 days ago | IN | 0 POL | 0.00607307 | ||||
Stake | 59616871 | 237 days ago | IN | 0 POL | 0.00728768 | ||||
Stake | 59398510 | 242 days ago | IN | 0 POL | 0.00662612 | ||||
Stake | 59359881 | 243 days ago | IN | 0 POL | 0.00721729 | ||||
Stake | 59354056 | 243 days ago | IN | 0 POL | 0.00691336 | ||||
Stake | 59352912 | 243 days ago | IN | 0 POL | 0.00688551 | ||||
Claim Rewards | 59352893 | 243 days ago | IN | 0 POL | 0.00347084 | ||||
Stake | 59278845 | 245 days ago | IN | 0 POL | 0.00722977 | ||||
Stake | 59278675 | 245 days ago | IN | 0 POL | 0.0080056 | ||||
Unstake | 59278629 | 245 days ago | IN | 0 POL | 0.00502514 | ||||
Stake | 59278618 | 245 days ago | IN | 0 POL | 0.00800561 | ||||
Unstake | 59278581 | 245 days ago | IN | 0 POL | 0.00539458 | ||||
Stake | 59278570 | 245 days ago | IN | 0 POL | 0.00837953 | ||||
Unstake | 59278260 | 245 days ago | IN | 0 POL | 0.00539528 |
Loading...
Loading
Contract Name:
CUBE_Staking
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2024-08-05 */ // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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); } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @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); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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); } } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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"); } } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // 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; } } // File: interfaces/IMultiplier.sol pragma solidity 0.8.4; 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); } // File: interfaces/IPenaltyFee.sol pragma solidity 0.8.4; 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); } // File: interfaces/IStakingPool.sol pragma solidity 0.8.4; 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); } // File: StakingPool.sol pragma solidity 0.8.4; contract CUBE_Staking 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)) / (10**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 * (10**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, "CUBE_Staking::stake: amount = 0"); uint256 _minimumStakeTimestamp = _stakeTimeOption == StakeTimeOptions.Duration ? block.timestamp + _unstakeTime : _unstakeTime; require(_minimumStakeTimestamp > startsAt, "CUBE_Staking::stake: _minimumStakeTimestamp <= startsAt"); require(_minimumStakeTimestamp > block.timestamp, "CUBE_Staking::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, "CUBE_Staking::unstake: amount = 0"); require(_amount <= userStakingInfo[msg.sender][_stakeNumber].stakedAmount, "CUBE_Staking::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, "CUBE_Staking::initializeStaking: _startsAt must be in the future"); require(_rewardsDuration > 0, "CUBE_Staking::initializeStaking: _rewardsDuration = 0"); require(_amount > 0, "CUBE_Staking::initializeStaking: _amount = 0"); require(startsAt == 0, "CUBE_Staking::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, "CUBE_Staking::startStaking: reward rate = 0"); require(isPaused, "CUBE_Staking::startStaking: staking already started"); isPaused = false; } function pauseStaking() external onlyOwner { require(!isPaused, "CUBE_Staking::pauseStaking: staking already paused"); isPaused = true; } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token"); require(tokenAddress != address(rewardsToken), "Cannot withdraw the reward 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, "CUBE_Staking::initialized: staking is paused"); require(startsAt <= block.timestamp, "CUBE_Staking::initialized: staking has not started yet"); require(endsAt > block.timestamp, "CUBE_Staking::notFinished: staking has finished"); _; } modifier onlyOwner() { require(msg.sender == owner, "CUBE_Staking::onlyOwner: not authorized"); _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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 CUBE_Staking.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
6101206040523480156200001257600080fd5b5060405162002aa438038062002aa483398101604081905262000035916200009f565b6001600081905580546001600160a01b031916331790556001600160601b0319606095861b811660805293851b841660a05260c092909252831b821660e05290911b166101005262000105565b80516001600160a01b03811681146200009a57600080fd5b919050565b600080600080600060a08688031215620000b7578081fd5b620000c28662000082565b9450620000d26020870162000082565b935060408601519250620000e96060870162000082565b9150620000f96080870162000082565b90509295509295909350565b60805160601c60a05160601c60c05160e05160601c6101005160601c6128de620001c66000396000818161025901526110e201526000818161039a01528181610f40015281816113d101528181611c2a0152611d5b015260008181610298015281816115f20152611ea60152600081816103db015281816107f90152818161088a015281816108d401528181610cba015261212b0152600081816102db01528181610c120152818161150c0152818161154f0152611ce401526128de6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639e2c8a5b11610104578063d1af0c7d116100a2578063f999c50611610071578063f999c50614610422578063f99b7d751461042a578063fccc28131461043d578063fff0c5361461044657600080fd5b8063d1af0c7d146103d6578063df136d65146103fd578063eed9da1f14610406578063f2fde38b1461040f57600080fd5b8063b6d7dc5c116100de578063b6d7dc5c14610395578063bddff592146103bc578063c8f33c91146103c5578063cd3daf9d146103ce57600080fd5b80639e2c8a5b1461035c578063af4686821461036f578063b187bd261461037857600080fd5b8063386a95251161017c578063817b1cd21161014b578063817b1cd21461030d578063842e2981146103165780638980f11f146103365780638da5cb5b1461034957600080fd5b8063386a9525146102cd57806372f702f3146102d65780637475f913146102fd57806380faa57d1461030557600080fd5b80630e15561a116101b85780630e15561a1461024b57806323a59277146102545780632792cdae1461029357806331d94f89146102ba57600080fd5b806304d978f1146101df5780630962ef791461021f5780630a09284a14610234575b600080fd5b6101f26101ed366004612551565b610459565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61023261022d36600461259a565b6104a7565b005b61023d60045481565b604051908152602001610216565b61023d60095481565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610216565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b6102326102c8366004612625565b610520565b61023d60025481565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b610232610982565b61023d610ae8565b61023d600a5481565b610329610324366004612537565b610aff565b604051610216919061266c565b610232610344366004612551565b610ba6565b60015461027b906001600160a01b031681565b61023261036a366004612604565b610d9a565b61023d60035481565b6008546103859060ff1681565b6040519015158152602001610216565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b61023d60065481565b61023d60055481565b61023d6115bc565b61027b7f000000000000000000000000000000000000000000000000000000000000000081565b61023d60075481565b61023d600b5481565b61023261041d366004612537565b61164d565b610232611721565b6102326104383660046125ca565b611813565b61027b61dead81565b61023d610454366004612551565b611d56565b600c602052816000526040600020818154811061047557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600260005414156104ff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260005561050e3382611fa0565b610518338261207d565b506001600055565b600260005414156105735760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b60026000556001546001600160a01b031633146105e25760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b428311610659576040805162461bcd60e51b81526020600482015260248101919091527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f7374617274734174206d75737420626520696e207468652066757475726560648201526084016104f6565b600082116106cf5760405162461bcd60e51b815260206004820152603560248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f726577617264734475726174696f6e203d2030000000000000000000000060648201526084016104f6565b600081116107455760405162461bcd60e51b815260206004820152602c60248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f616d6f756e74203d2030000000000000000000000000000000000000000060648201526084016104f6565b600354156107bb5760405162461bcd60e51b815260206004820152603860248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f207374616b696e6720616c72656164792073746172746564000000000000000060648201526084016104f6565b6107c6600080611fa0565b600282905560038390556107da828461270d565b60049081556040516370a0823160e01b815230918101919091526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561084357600080fd5b505afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b91906125b2565b90506108b26001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308561219c565b6040516370a0823160e01b815230600482015260009082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b15801561091657600080fd5b505afa15801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e91906125b2565b610958919061284f565b600981905590506109698482612725565b60065550506008805460ff191690555050600160005550565b6001546001600160a01b031633146109ec5760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b600060065411610a645760405162461bcd60e51b815260206004820152602b60248201527f435542455f5374616b696e673a3a73746172745374616b696e673a207265776160448201527f72642072617465203d203000000000000000000000000000000000000000000060648201526084016104f6565b60085460ff16610adc5760405162461bcd60e51b815260206004820152603360248201527f435542455f5374616b696e673a3a73746172745374616b696e673a207374616b60448201527f696e6720616c726561647920737461727465640000000000000000000000000060648201526084016104f6565b6008805460ff19169055565b60006004544210610afa575060045490565b504290565b6001600160a01b0381166000908152600c60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610b9b57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610b37565b505050509050919050565b6001546001600160a01b03163314610c105760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610cb85760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e0000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610d3a5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207769746864726177207468652072657761726420746f6b656e60448201526064016104f6565b600154610d54906001600160a01b03848116911683612253565b604080516001600160a01b0384168152602081018390527f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af05910160405180910390a15050565b60026000541415610ded5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005581610e655760405162461bcd60e51b815260206004820152602160248201527f435542455f5374616b696e673a3a756e7374616b653a20616d6f756e74203d2060448201527f300000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b336000908152600c60205260409020805482908110610e9457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154821115610f1b5760405162461bcd60e51b815260206004820152602960248201527f435542455f5374616b696e673a3a756e7374616b653a206e6f7420656e6f756760448201527f682062616c616e6365000000000000000000000000000000000000000000000060648201526084016104f6565b610f253382611fa0565b336000908152600c6020526040812080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163457b08099185908110610f8557634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c9091526040909120805486908110610fc557634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401610ffd929190918252602082015260400190565b60206040518083038186803b15801561101557600080fd5b505afa158015611029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104d91906125b2565b905080600b6000828254611061919061284f565b9250508190555082600a600082825461107a919061284f565b9091555050336000908152600c602052604081208054849081106110ae57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600101544210156111dd57336000908152600c6020526040902080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163b2c0f3cb918791908790811061112a57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600260059092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015230604482015260640160206040518083038186803b15801561119857600080fd5b505afa1580156111ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d091906125b2565b9050838111156111dd5750825b336000908152600c6020526040902080548591908590811061120f57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600001600082825461122f919061284f565b9091555050336000908152600c6020526040902080548490811061126357634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154600014156113b657611287338461207d565b336000908152600c6020526040902080546112a49060019061284f565b815481106112c257634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600c6000336001600160a01b03166001600160a01b03168152602001908152602001600020848154811061131457634e487b7160e01b600052603260045260246000fd5b6000918252602080832084546005909302019182556001808501549083015560028085015490830155600380850154908301556004938401549390910192909255338152600c9091526040902080548061137e57634e487b7160e01b600052603160045260246000fd5b6000828152602081206005600019909301928302018181556001810182905560028101829055600381018290556004015590556114f9565b336000908152600c6020526040812080546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163457b0809918790811061141657634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c909152604090912080548890811061145657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b815260040161148e929190918252602082015260400190565b60206040518083038186803b1580156114a657600080fd5b505afa1580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de91906125b2565b905080600b60008282546114f2919061270d565b9091555050505b8015611542576115356001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661dead83612253565b61153f818561284f565b93505b6115766001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163386612253565b604080518481526020810186905233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e910160405180910390a2505060016000555050565b6000600a54600014156115d0575060075490565b60006005546115dd610ae8565b6115e7919061284f565b600b549091506116187f0000000000000000000000000000000000000000000000000000000000000000600a612788565b826006546116269190612830565b6116309190612830565b61163a9190612725565b600754611647919061270d565b91505090565b6001546001600160a01b031633146116b75760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001546001600160a01b0316331461178b5760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b60085460ff16156118045760405162461bcd60e51b815260206004820152603260248201527f435542455f5374616b696e673a3a70617573655374616b696e673a207374616b60448201527f696e6720616c726561647920706175736564000000000000000000000000000060648201526084016104f6565b6008805460ff19166001179055565b600260005414156118665760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005560085460ff16156118e45760405162461bcd60e51b815260206004820152602c60248201527f435542455f5374616b696e673a3a696e697469616c697a65643a207374616b6960448201527f6e6720697320706175736564000000000000000000000000000000000000000060648201526084016104f6565b42600354111561195c5760405162461bcd60e51b815260206004820152603660248201527f435542455f5374616b696e673a3a696e697469616c697a65643a207374616b6960448201527f6e6720686173206e6f742073746172746564207965740000000000000000000060648201526084016104f6565b42600454116119d35760405162461bcd60e51b815260206004820152602f60248201527f435542455f5374616b696e673a3a6e6f7446696e69736865643a207374616b6960448201527f6e67206861732066696e6973686564000000000000000000000000000000000060648201526084016104f6565b60008311611a235760405162461bcd60e51b815260206004820152601f60248201527f435542455f5374616b696e673a3a7374616b653a20616d6f756e74203d20300060448201526064016104f6565b600080836001811115611a4657634e487b7160e01b600052602160045260246000fd5b14611a515781611a5b565b611a5b824261270d565b90506003548111611ad45760405162461bcd60e51b815260206004820152603760248201527f435542455f5374616b696e673a3a7374616b653a205f6d696e696d756d53746160448201527f6b6554696d657374616d70203c3d20737461727473417400000000000000000060648201526084016104f6565b428111611b495760405162461bcd60e51b815260206004820152603e60248201527f435542455f5374616b696e673a3a7374616b653a205f6d696e696d756d53746160448201527f6b6554696d657374616d70203c3d20626c6f636b2e74696d657374616d70000060648201526084016104f6565b6000611b55428361284f565b9050611b62600080611fa0565b6040805160a08101825286815260208082018581528284018581526007546060850190815260006080860181815233808352600c87529782208054600181810183558285529784208951600590920201908155955186880155935160028601559151600385015590516004909301929092559381529254919291611be6919061284f565b6040517f457b080900000000000000000000000000000000000000000000000000000000815260048101899052602481018590529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063457b08099060440160206040518083038186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca491906125b2565b905080600b6000828254611cb8919061270d565b9250508190555087600a6000828254611cd1919061270d565b90915550611d0c90506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308b61219c565b60408051838152602081018a905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a250506001600055505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663457b0809600c6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110611dcc57634e487b7160e01b600052603260045260246000fd5b600091825260208083206005909202909101546001600160a01b0389168352600c9091526040909120805487908110611e1557634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611e4d929190918252602082015260400190565b60206040518083038186803b158015611e6557600080fd5b505afa158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d91906125b2565b90506000611ecc7f0000000000000000000000000000000000000000000000000000000000000000600a612788565b6001600160a01b0386166000908152600c60205260409020805486908110611f0457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160030154611f1e6115bc565b611f28919061284f565b611f329084612830565b611f3c9190612725565b6001600160a01b0386166000908152600c6020526040902080549192509085908110611f7857634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015481611f95919061270d565b925050505b92915050565b611fa86115bc565b600755611fb3610ae8565b6005556001600160a01b0382161561207957611fcf8282611d56565b6001600160a01b0383166000908152600c6020526040902080548390811061200757634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040181905550600754600c6000846001600160a01b03166001600160a01b03168152602001908152602001600020828154811061206357634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600301819055505b5050565b6001600160a01b0382166000908152600c602052604081208054839081106120b557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015490506000811115612197576001600160a01b0383166000908152600c6020526040812080548490811061210a57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600460059092020101556121526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483612253565b60408051838152602081018390526001600160a01b038516917fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51910160405180910390a25b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261224d9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261229c565b50505050565b6040516001600160a01b0383166024820152604481018290526121979084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016121e9565b60006122f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166123819092919063ffffffff16565b805190915015612197578080602001905181019061230f919061257a565b6121975760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f6565b6060612390848460008561239a565b90505b9392505050565b6060824710156124125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f6565b6001600160a01b0385163b6124695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f6565b600080866001600160a01b031685876040516124859190612650565b60006040518083038185875af1925050503d80600081146124c2576040519150601f19603f3d011682016040523d82523d6000602084013e6124c7565b606091505b50915091506124d78282866124e2565b979650505050505050565b606083156124f1575081612393565b8251156125015782518084602001fd5b8160405162461bcd60e51b81526004016104f691906126da565b80356001600160a01b038116811461253257600080fd5b919050565b600060208284031215612548578081fd5b6123938261251b565b60008060408385031215612563578081fd5b61256c8361251b565b946020939093013593505050565b60006020828403121561258b578081fd5b81518015158114612393578182fd5b6000602082840312156125ab578081fd5b5035919050565b6000602082840312156125c3578081fd5b5051919050565b6000806000606084860312156125de578081fd5b833592506020840135600281106125f3578182fd5b929592945050506040919091013590565b60008060408385031215612616578182fd5b50508035926020909101359150565b600080600060608486031215612639578283fd5b505081359360208301359350604090920135919050565b60008251612662818460208701612866565b9190910192915050565b602080825282518282018190526000919060409081850190868401855b828110156126cd5781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101612689565b5091979650505050505050565b60208152600082518060208401526126f9816040850160208701612866565b601f01601f19169190910160400192915050565b6000821982111561272057612720612892565b500190565b60008261274057634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561278057816000190482111561276657612766612892565b8085161561277357918102915b93841c939080029061274a565b509250929050565b6000612393838360008261279e57506001611f9a565b816127ab57506000611f9a565b81600181146127c157600281146127cb576127e7565b6001915050611f9a565b60ff8411156127dc576127dc612892565b50506001821b611f9a565b5060208310610133831016604e8410600b841016171561280a575081810a611f9a565b6128148383612745565b806000190482111561282857612828612892565b029392505050565b600081600019048311821515161561284a5761284a612892565b500290565b60008282101561286157612861612892565b500390565b60005b83811015612881578181015183820152602001612869565b8381111561224d5750506000910152565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202523186e9426f7b35f8497e626dc7031e7803b50a048d519e8f8390d34120b7b64736f6c634300080400330000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a20000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a20000000000000000000000000000000000000000000000000000000000000012000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4000000000000000000000000d4c9052f3292cb674c7f353944629c2828d3b4a8
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80639e2c8a5b11610104578063d1af0c7d116100a2578063f999c50611610071578063f999c50614610422578063f99b7d751461042a578063fccc28131461043d578063fff0c5361461044657600080fd5b8063d1af0c7d146103d6578063df136d65146103fd578063eed9da1f14610406578063f2fde38b1461040f57600080fd5b8063b6d7dc5c116100de578063b6d7dc5c14610395578063bddff592146103bc578063c8f33c91146103c5578063cd3daf9d146103ce57600080fd5b80639e2c8a5b1461035c578063af4686821461036f578063b187bd261461037857600080fd5b8063386a95251161017c578063817b1cd21161014b578063817b1cd21461030d578063842e2981146103165780638980f11f146103365780638da5cb5b1461034957600080fd5b8063386a9525146102cd57806372f702f3146102d65780637475f913146102fd57806380faa57d1461030557600080fd5b80630e15561a116101b85780630e15561a1461024b57806323a59277146102545780632792cdae1461029357806331d94f89146102ba57600080fd5b806304d978f1146101df5780630962ef791461021f5780630a09284a14610234575b600080fd5b6101f26101ed366004612551565b610459565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61023261022d36600461259a565b6104a7565b005b61023d60045481565b604051908152602001610216565b61023d60095481565b61027b7f000000000000000000000000d4c9052f3292cb674c7f353944629c2828d3b4a881565b6040516001600160a01b039091168152602001610216565b61023d7f000000000000000000000000000000000000000000000000000000000000001281565b6102326102c8366004612625565b610520565b61023d60025481565b61027b7f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a281565b610232610982565b61023d610ae8565b61023d600a5481565b610329610324366004612537565b610aff565b604051610216919061266c565b610232610344366004612551565b610ba6565b60015461027b906001600160a01b031681565b61023261036a366004612604565b610d9a565b61023d60035481565b6008546103859060ff1681565b6040519015158152602001610216565b61027b7f000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc481565b61023d60065481565b61023d60055481565b61023d6115bc565b61027b7f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a281565b61023d60075481565b61023d600b5481565b61023261041d366004612537565b61164d565b610232611721565b6102326104383660046125ca565b611813565b61027b61dead81565b61023d610454366004612551565b611d56565b600c602052816000526040600020818154811061047557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600260005414156104ff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260005561050e3382611fa0565b610518338261207d565b506001600055565b600260005414156105735760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b60026000556001546001600160a01b031633146105e25760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b428311610659576040805162461bcd60e51b81526020600482015260248101919091527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f7374617274734174206d75737420626520696e207468652066757475726560648201526084016104f6565b600082116106cf5760405162461bcd60e51b815260206004820152603560248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f726577617264734475726174696f6e203d2030000000000000000000000060648201526084016104f6565b600081116107455760405162461bcd60e51b815260206004820152602c60248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f205f616d6f756e74203d2030000000000000000000000000000000000000000060648201526084016104f6565b600354156107bb5760405162461bcd60e51b815260206004820152603860248201527f435542455f5374616b696e673a3a696e697469616c697a655374616b696e673a60448201527f207374616b696e6720616c72656164792073746172746564000000000000000060648201526084016104f6565b6107c6600080611fa0565b600282905560038390556107da828461270d565b60049081556040516370a0823160e01b815230918101919091526000907f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a26001600160a01b0316906370a082319060240160206040518083038186803b15801561084357600080fd5b505afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b91906125b2565b90506108b26001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a21633308561219c565b6040516370a0823160e01b815230600482015260009082906001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a216906370a082319060240160206040518083038186803b15801561091657600080fd5b505afa15801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e91906125b2565b610958919061284f565b600981905590506109698482612725565b60065550506008805460ff191690555050600160005550565b6001546001600160a01b031633146109ec5760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b600060065411610a645760405162461bcd60e51b815260206004820152602b60248201527f435542455f5374616b696e673a3a73746172745374616b696e673a207265776160448201527f72642072617465203d203000000000000000000000000000000000000000000060648201526084016104f6565b60085460ff16610adc5760405162461bcd60e51b815260206004820152603360248201527f435542455f5374616b696e673a3a73746172745374616b696e673a207374616b60448201527f696e6720616c726561647920737461727465640000000000000000000000000060648201526084016104f6565b6008805460ff19169055565b60006004544210610afa575060045490565b504290565b6001600160a01b0381166000908152600c60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610b9b57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610b37565b505050509050919050565b6001546001600160a01b03163314610c105760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b7f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a26001600160a01b0316826001600160a01b03161415610cb85760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e0000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b7f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a26001600160a01b0316826001600160a01b03161415610d3a5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74207769746864726177207468652072657761726420746f6b656e60448201526064016104f6565b600154610d54906001600160a01b03848116911683612253565b604080516001600160a01b0384168152602081018390527f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af05910160405180910390a15050565b60026000541415610ded5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005581610e655760405162461bcd60e51b815260206004820152602160248201527f435542455f5374616b696e673a3a756e7374616b653a20616d6f756e74203d2060448201527f300000000000000000000000000000000000000000000000000000000000000060648201526084016104f6565b336000908152600c60205260409020805482908110610e9457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154821115610f1b5760405162461bcd60e51b815260206004820152602960248201527f435542455f5374616b696e673a3a756e7374616b653a206e6f7420656e6f756760448201527f682062616c616e6365000000000000000000000000000000000000000000000060648201526084016104f6565b610f253382611fa0565b336000908152600c6020526040812080546001600160a01b037f000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4169163457b08099185908110610f8557634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c9091526040909120805486908110610fc557634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401610ffd929190918252602082015260400190565b60206040518083038186803b15801561101557600080fd5b505afa158015611029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104d91906125b2565b905080600b6000828254611061919061284f565b9250508190555082600a600082825461107a919061284f565b9091555050336000908152600c602052604081208054849081106110ae57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600101544210156111dd57336000908152600c6020526040902080546001600160a01b037f000000000000000000000000d4c9052f3292cb674c7f353944629c2828d3b4a8169163b2c0f3cb918791908790811061112a57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600260059092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015230604482015260640160206040518083038186803b15801561119857600080fd5b505afa1580156111ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d091906125b2565b9050838111156111dd5750825b336000908152600c6020526040902080548591908590811061120f57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600001600082825461122f919061284f565b9091555050336000908152600c6020526040902080548490811061126357634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160000154600014156113b657611287338461207d565b336000908152600c6020526040902080546112a49060019061284f565b815481106112c257634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600c6000336001600160a01b03166001600160a01b03168152602001908152602001600020848154811061131457634e487b7160e01b600052603260045260246000fd5b6000918252602080832084546005909302019182556001808501549083015560028085015490830155600380850154908301556004938401549390910192909255338152600c9091526040902080548061137e57634e487b7160e01b600052603160045260246000fd5b6000828152602081206005600019909301928302018181556001810182905560028101829055600381018290556004015590556114f9565b336000908152600c6020526040812080546001600160a01b037f000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4169163457b0809918790811061141657634e487b7160e01b600052603260045260246000fd5b60009182526020808320600590920290910154338352600c909152604090912080548890811061145657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b815260040161148e929190918252602082015260400190565b60206040518083038186803b1580156114a657600080fd5b505afa1580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de91906125b2565b905080600b60008282546114f2919061270d565b9091555050505b8015611542576115356001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a21661dead83612253565b61153f818561284f565b93505b6115766001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a2163386612253565b604080518481526020810186905233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e910160405180910390a2505060016000555050565b6000600a54600014156115d0575060075490565b60006005546115dd610ae8565b6115e7919061284f565b600b549091506116187f0000000000000000000000000000000000000000000000000000000000000012600a612788565b826006546116269190612830565b6116309190612830565b61163a9190612725565b600754611647919061270d565b91505090565b6001546001600160a01b031633146116b75760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001546001600160a01b0316331461178b5760405162461bcd60e51b815260206004820152602760248201527f435542455f5374616b696e673a3a6f6e6c794f776e65723a206e6f74206175746044820152661a1bdc9a5e995960ca1b60648201526084016104f6565b60085460ff16156118045760405162461bcd60e51b815260206004820152603260248201527f435542455f5374616b696e673a3a70617573655374616b696e673a207374616b60448201527f696e6720616c726561647920706175736564000000000000000000000000000060648201526084016104f6565b6008805460ff19166001179055565b600260005414156118665760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f6565b600260005560085460ff16156118e45760405162461bcd60e51b815260206004820152602c60248201527f435542455f5374616b696e673a3a696e697469616c697a65643a207374616b6960448201527f6e6720697320706175736564000000000000000000000000000000000000000060648201526084016104f6565b42600354111561195c5760405162461bcd60e51b815260206004820152603660248201527f435542455f5374616b696e673a3a696e697469616c697a65643a207374616b6960448201527f6e6720686173206e6f742073746172746564207965740000000000000000000060648201526084016104f6565b42600454116119d35760405162461bcd60e51b815260206004820152602f60248201527f435542455f5374616b696e673a3a6e6f7446696e69736865643a207374616b6960448201527f6e67206861732066696e6973686564000000000000000000000000000000000060648201526084016104f6565b60008311611a235760405162461bcd60e51b815260206004820152601f60248201527f435542455f5374616b696e673a3a7374616b653a20616d6f756e74203d20300060448201526064016104f6565b600080836001811115611a4657634e487b7160e01b600052602160045260246000fd5b14611a515781611a5b565b611a5b824261270d565b90506003548111611ad45760405162461bcd60e51b815260206004820152603760248201527f435542455f5374616b696e673a3a7374616b653a205f6d696e696d756d53746160448201527f6b6554696d657374616d70203c3d20737461727473417400000000000000000060648201526084016104f6565b428111611b495760405162461bcd60e51b815260206004820152603e60248201527f435542455f5374616b696e673a3a7374616b653a205f6d696e696d756d53746160448201527f6b6554696d657374616d70203c3d20626c6f636b2e74696d657374616d70000060648201526084016104f6565b6000611b55428361284f565b9050611b62600080611fa0565b6040805160a08101825286815260208082018581528284018581526007546060850190815260006080860181815233808352600c87529782208054600181810183558285529784208951600590920201908155955186880155935160028601559151600385015590516004909301929092559381529254919291611be6919061284f565b6040517f457b080900000000000000000000000000000000000000000000000000000000815260048101899052602481018590529091506000906001600160a01b037f000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4169063457b08099060440160206040518083038186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca491906125b2565b905080600b6000828254611cb8919061270d565b9250508190555087600a6000828254611cd1919061270d565b90915550611d0c90506001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a21633308b61219c565b60408051838152602081018a905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a250506001600055505050505050565b6000807f000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc46001600160a01b031663457b0809600c6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110611dcc57634e487b7160e01b600052603260045260246000fd5b600091825260208083206005909202909101546001600160a01b0389168352600c9091526040909120805487908110611e1557634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600201546040518363ffffffff1660e01b8152600401611e4d929190918252602082015260400190565b60206040518083038186803b158015611e6557600080fd5b505afa158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d91906125b2565b90506000611ecc7f0000000000000000000000000000000000000000000000000000000000000012600a612788565b6001600160a01b0386166000908152600c60205260409020805486908110611f0457634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160030154611f1e6115bc565b611f28919061284f565b611f329084612830565b611f3c9190612725565b6001600160a01b0386166000908152600c6020526040902080549192509085908110611f7857634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015481611f95919061270d565b925050505b92915050565b611fa86115bc565b600755611fb3610ae8565b6005556001600160a01b0382161561207957611fcf8282611d56565b6001600160a01b0383166000908152600c6020526040902080548390811061200757634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020160040181905550600754600c6000846001600160a01b03166001600160a01b03168152602001908152602001600020828154811061206357634e487b7160e01b600052603260045260246000fd5b9060005260206000209060050201600301819055505b5050565b6001600160a01b0382166000908152600c602052604081208054839081106120b557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600502016004015490506000811115612197576001600160a01b0383166000908152600c6020526040812080548490811061210a57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600460059092020101556121526001600160a01b037f0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a2168483612253565b60408051838152602081018390526001600160a01b038516917fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51910160405180910390a25b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261224d9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261229c565b50505050565b6040516001600160a01b0383166024820152604481018290526121979084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016121e9565b60006122f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166123819092919063ffffffff16565b805190915015612197578080602001905181019061230f919061257a565b6121975760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f6565b6060612390848460008561239a565b90505b9392505050565b6060824710156124125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f6565b6001600160a01b0385163b6124695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f6565b600080866001600160a01b031685876040516124859190612650565b60006040518083038185875af1925050503d80600081146124c2576040519150601f19603f3d011682016040523d82523d6000602084013e6124c7565b606091505b50915091506124d78282866124e2565b979650505050505050565b606083156124f1575081612393565b8251156125015782518084602001fd5b8160405162461bcd60e51b81526004016104f691906126da565b80356001600160a01b038116811461253257600080fd5b919050565b600060208284031215612548578081fd5b6123938261251b565b60008060408385031215612563578081fd5b61256c8361251b565b946020939093013593505050565b60006020828403121561258b578081fd5b81518015158114612393578182fd5b6000602082840312156125ab578081fd5b5035919050565b6000602082840312156125c3578081fd5b5051919050565b6000806000606084860312156125de578081fd5b833592506020840135600281106125f3578182fd5b929592945050506040919091013590565b60008060408385031215612616578182fd5b50508035926020909101359150565b600080600060608486031215612639578283fd5b505081359360208301359350604090920135919050565b60008251612662818460208701612866565b9190910192915050565b602080825282518282018190526000919060409081850190868401855b828110156126cd5781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101612689565b5091979650505050505050565b60208152600082518060208401526126f9816040850160208701612866565b601f01601f19169190910160400192915050565b6000821982111561272057612720612892565b500190565b60008261274057634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561278057816000190482111561276657612766612892565b8085161561277357918102915b93841c939080029061274a565b509250929050565b6000612393838360008261279e57506001611f9a565b816127ab57506000611f9a565b81600181146127c157600281146127cb576127e7565b6001915050611f9a565b60ff8411156127dc576127dc612892565b50506001821b611f9a565b5060208310610133831016604e8410600b841016171561280a575081810a611f9a565b6128148383612745565b806000190482111561282857612828612892565b029392505050565b600081600019048311821515161561284a5761284a612892565b500290565b60008282101561286157612861612892565b500390565b60005b83811015612881578181015183820152602001612869565b8381111561224d5750506000910152565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202523186e9426f7b35f8497e626dc7031e7803b50a048d519e8f8390d34120b7b64736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a20000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a20000000000000000000000000000000000000000000000000000000000000012000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4000000000000000000000000d4c9052f3292cb674c7f353944629c2828d3b4a8
-----Decoded View---------------
Arg [0] : _stakingToken (address): 0x4c989B872E96C37bc6fCB2f0fE5FDcaBeCC405a2
Arg [1] : _rewardToken (address): 0x4c989B872E96C37bc6fCB2f0fE5FDcaBeCC405a2
Arg [2] : _rewardsTokenDecimals (uint256): 18
Arg [3] : _multiplier (address): 0x531f16E674dd8b6b128d697B3491C4E563A45cC4
Arg [4] : _penaltyFeeCalculator (address): 0xD4C9052f3292cB674C7F353944629C2828d3b4a8
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a2
Arg [1] : 0000000000000000000000004c989b872e96c37bc6fcb2f0fe5fdcabecc405a2
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 000000000000000000000000531f16e674dd8b6b128d697b3491c4e563a45cc4
Arg [4] : 000000000000000000000000d4c9052f3292cb674c7f353944629c2828d3b4a8
Deployed Bytecode Sourcemap
22934:11169:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24191:56;;;;;;:::i;:::-;;:::i;:::-;;;;15965:25:1;;;16021:2;16006:18;;15999:34;;;;16049:18;;;16042:34;;;;16107:2;16092:18;;16085:34;16150:3;16135:19;;16128:35;15952:3;15937:19;24191:56:0;;;;;;;;31049:174;;;;;;:::i;:::-;;:::i;:::-;;23619:21;;;;;;;;;15044:25:1;;;15032:2;15017:18;23619:21:0;14999:76:1;23940:27:0;;;;;;23323:58;;;;;;;;-1:-1:-1;;;;;2855:55:1;;;2837:74;;2825:2;2810:18;23323:58:0;2792:125:1;23207:45:0;;;;;31287:1161;;;;;;:::i;:::-;;:::i;23464:30::-;;;;;;23121:36;;;;;32456:249;;;:::i;25996:143::-;;;:::i;24013:26::-;;;;;;26524:131;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;32988:400::-;;;;;;:::i;:::-;;:::i;23390:20::-;;;;;-1:-1:-1;;;;;23390:20:0;;;28598:2070;;;;;;:::i;:::-;;:::i;23546:23::-;;;;;;23890:20;;;;;;;;;;;;4809:14:1;;4802:22;4784:41;;4772:2;4757:18;23890:20:0;4739:92:1;23261:55:0;;;;;23776:31;;;;;;23687:29;;;;;;26147:369;;;:::i;23164:36::-;;;;;23846:35;;;;;;24101:33;;;;;;33396:201;;;;;;:::i;:::-;;:::i;32713:160::-;;;:::i;27142:1448::-;;;;;;:::i;:::-;;:::i;23031:81::-;;23070:42;23031:81;;25415:573;;;;;;:::i;:::-;;:::i;24191:56::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24191:56:0;;-1:-1:-1;24191:56:0;;;:::o;31049:174::-;20105:1;20703:7;;:19;;20695:63;;;;-1:-1:-1;;;20695:63:0;;14338:2:1;20695:63:0;;;14320:21:1;14377:2;14357:18;;;14350:30;14416:33;14396:18;;;14389:61;14467:18;;20695:63:0;;;;;;;;;20105:1;20836:7;:18;31126:39:::1;31140:10;31152:12:::0;31126:13:::1;:39::i;:::-;31176;31190:10;31202:12;31176:13;:39::i;:::-;-1:-1:-1::0;20061:1:0;21015:7;:22;31049:174::o;31287:1161::-;20105:1;20703:7;;:19;;20695:63;;;;-1:-1:-1;;;20695:63:0;;14338:2:1;20695:63:0;;;14320:21:1;14377:2;14357:18;;;14350:30;14416:33;14396:18;;;14389:61;14467:18;;20695:63:0;14310:181:1;20695:63:0;20105:1;20836:7;:18;34031:5:::1;::::0;-1:-1:-1;;;;;34031:5:0::1;34017:10;:19;34009:71;;;::::0;-1:-1:-1;;;34009:71:0;;10698:2:1;34009:71:0::1;::::0;::::1;10680:21:1::0;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:1;;;10820:37;10874:19;;34009:71:0::1;10670:229:1::0;34009:71:0::1;31473:15:::2;31461:9;:27;31453:104;;;::::0;;-1:-1:-1;;;31453:104:0;;10265:2:1;31453:104:0::2;::::0;::::2;10247:21:1::0;10284:18;;;10277:30;;;;10343:34;10323:18;;;10316:62;10414:34;10394:18;;;10387:62;10466:19;;31453:104:0::2;10237:254:1::0;31453:104:0::2;31595:1;31576:16;:20;31568:86;;;::::0;-1:-1:-1;;;31568:86:0;;11876:2:1;31568:86:0::2;::::0;::::2;11858:21:1::0;11915:2;11895:18;;;11888:30;11954:34;11934:18;;;11927:62;12025:23;12005:18;;;11998:51;12066:19;;31568:86:0::2;11848:243:1::0;31568:86:0::2;31683:1;31673:7;:11;31665:68;;;::::0;-1:-1:-1;;;31665:68:0;;8612:2:1;31665:68:0::2;::::0;::::2;8594:21:1::0;8651:2;8631:18;;;8624:30;8690:34;8670:18;;;8663:62;8761:14;8741:18;;;8734:42;8793:19;;31665:68:0::2;8584:234:1::0;31665:68:0::2;31752:8;::::0;:13;31744:82:::2;;;::::0;-1:-1:-1;;;31744:82:0;;6531:2:1;31744:82:0::2;::::0;::::2;6513:21:1::0;6570:2;6550:18;;;6543:30;6609:34;6589:18;;;6582:62;6680:26;6660:18;;;6653:54;6724:19;;31744:82:0::2;6503:246:1::0;31744:82:0::2;31839:28;31861:1;31865::::0;31839:13:::2;:28::i;:::-;31880:15;:34:::0;;;31925:8:::2;:20:::0;;;31965:28:::2;31898:16:::0;31936:9;31965:28:::2;:::i;:::-;31956:6;:37:::0;;;32069::::2;::::0;-1:-1:-1;;;32069:37:0;;32100:4:::2;32069:37:::0;;::::2;2837:74:1::0;;;;32045:21:0::2;::::0;32069:12:::2;-1:-1:-1::0;;;;;32069:22:0::2;::::0;::::2;::::0;2810:18:1;;32069:37:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32045:61:::0;-1:-1:-1;32117:65:0::2;-1:-1:-1::0;;;;;32117:12:0::2;:29;32147:10;32167:4;32174:7:::0;32117:29:::2;:65::i;:::-;32216:37;::::0;-1:-1:-1;;;32216:37:0;;32247:4:::2;32216:37;::::0;::::2;2837:74:1::0;32193:20:0::2;::::0;32256:13;;-1:-1:-1;;;;;32216:12:0::2;:22;::::0;::::2;::::0;2810:18:1;;32216:37:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;32280:12;:27:::0;;;32193:76;-1:-1:-1;32337:31:0::2;32352:16:::0;32193:76;32337:31:::2;:::i;:::-;32318:16;:50:::0;-1:-1:-1;;32424:8:0::2;:16:::0;;-1:-1:-1;;32424:16:0::2;::::0;;-1:-1:-1;;32424:16:0;32435:5:::2;21015:22:::0;-1:-1:-1;31287:1161:0:o;32456:249::-;34031:5;;-1:-1:-1;;;;;34031:5:0;34017:10;:19;34009:71;;;;-1:-1:-1;;;34009:71:0;;10698:2:1;34009:71:0;;;10680:21:1;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:1;;;10820:37;10874:19;;34009:71:0;10670:229:1;34009:71:0;32538:1:::1;32519:16;;:20;32511:76;;;::::0;-1:-1:-1;;;32511:76:0;;7781:2:1;32511:76:0::1;::::0;::::1;7763:21:1::0;7820:2;7800:18;;;7793:30;7859:34;7839:18;;;7832:62;7930:13;7910:18;;;7903:41;7961:19;;32511:76:0::1;7753:233:1::0;32511:76:0::1;32606:8;::::0;::::1;;32598:72;;;::::0;-1:-1:-1;;;32598:72:0;;9845:2:1;32598:72:0::1;::::0;::::1;9827:21:1::0;9884:2;9864:18;;;9857:30;9923:34;9903:18;;;9896:62;9994:21;9974:18;;;9967:49;10033:19;;32598:72:0::1;9817:241:1::0;32598:72:0::1;32681:8;:16:::0;;-1:-1:-1;;32681:16:0::1;::::0;;32456:249::o;25996:143::-;26053:7;26098:6;;26080:15;:24;:51;;-1:-1:-1;26125:6:0;;;25996:143::o;26080:51::-;-1:-1:-1;26107:15:0;;25996:143::o;26524:131::-;-1:-1:-1;;;;;26625:22:0;;;;;;:15;:22;;;;;;;;26618:29;;;;;;;;;;;;;;;;;26585:20;;26618:29;;26625:22;;26618:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26524:131;;;:::o;32988:400::-;34031:5;;-1:-1:-1;;;;;34031:5:0;34017:10;:19;34009:71;;;;-1:-1:-1;;;34009:71:0;;10698:2:1;34009:71:0;;;10680:21:1;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:1;;;10820:37;10874:19;;34009:71:0;10670:229:1;34009:71:0;33115:12:::1;-1:-1:-1::0;;;;;33091:37:0::1;:12;-1:-1:-1::0;;;;;33091:37:0::1;;;33083:83;;;::::0;-1:-1:-1;;;33083:83:0;;14698:2:1;33083:83:0::1;::::0;::::1;14680:21:1::0;14737:2;14717:18;;;14710:30;14776:34;14756:18;;;14749:62;14847:3;14827:18;;;14820:31;14868:19;;33083:83:0::1;14670:223:1::0;33083:83:0::1;33209:12;-1:-1:-1::0;;;;;33185:37:0::1;:12;-1:-1:-1::0;;;;;33185:37:0::1;;;33177:82;;;::::0;-1:-1:-1;;;33177:82:0;;6170:2:1;33177:82:0::1;::::0;::::1;6152:21:1::0;;;6189:18;;;6182:30;6248:34;6228:18;;;6221:62;6300:18;;33177:82:0::1;6142:182:1::0;33177:82:0::1;33304:5;::::0;33270:53:::1;::::0;-1:-1:-1;;;;;33270:33:0;;::::1;::::0;33304:5:::1;33311:11:::0;33270:33:::1;:53::i;:::-;33339:41;::::0;;-1:-1:-1;;;;;3517:55:1;;3499:74;;3604:2;3589:18;;3582:34;;;33339:41:0::1;::::0;3472:18:1;33339:41:0::1;;;;;;;32988:400:::0;;:::o;28598:2070::-;20105:1;20703:7;;:19;;20695:63;;;;-1:-1:-1;;;20695:63:0;;14338:2:1;20695:63:0;;;14320:21:1;14377:2;14357:18;;;14350:30;14416:33;14396:18;;;14389:61;14467:18;;20695:63:0;14310:181:1;20695:63:0;20105:1;20836:7;:18;28695:11;28687:57:::1;;;::::0;-1:-1:-1;;;28687:57:0;;6956:2:1;28687:57:0::1;::::0;::::1;6938:21:1::0;6995:2;6975:18;;;6968:30;7034:34;7014:18;;;7007:62;7105:3;7085:18;;;7078:31;7126:19;;28687:57:0::1;6928:223:1::0;28687:57:0::1;28790:10;28774:27;::::0;;;:15:::1;:27;::::0;;;;:41;;28802:12;;28774:41;::::1;;;-1:-1:-1::0;;;28774:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;28763:7;:65;;28755:119;;;::::0;-1:-1:-1;;;28755:119:0;;11466:2:1;28755:119:0::1;::::0;::::1;11448:21:1::0;11505:2;11485:18;;;11478:30;11544:34;11524:18;;;11517:62;11615:11;11595:18;;;11588:39;11644:19;;28755:119:0::1;11438:231:1::0;28755:119:0::1;28887:39;28901:10;28913:12;28887:13;:39::i;:::-;29034:10;28939:28;29018:27:::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;28970:17:0::1;:33;::::0;::::1;::::0;29046:12;;29018:41;::::1;;;-1:-1:-1::0;;;29018:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:54:::0;29103:10:::1;29087:27:::0;;:15:::1;:27:::0;;;;;;;:41;;29115:12;;29087:41;::::1;;;-1:-1:-1::0;;;29087:41:0::1;;;;;;;;;;;;;;;;;;;:50;;;28970:178;;;;;;;;;;;;;;;15254:25:1::0;;;15310:2;15295:18;;15288:34;15242:2;15227:18;;15209:119;28970:178:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28939:209;;29181:20;29159:18;;:42;;;;;;;:::i;:::-;;;;;;;;29227:7;29212:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;29318:10:0::1;29247:18;29302:27:::0;;;:15:::1;:27;::::0;;;;:41;;29330:12;;29302:41;::::1;;;-1:-1:-1::0;;;29302:41:0::1;;;;;;;;;;;;;;;;;;;:63;;;29284:15;:81;29280:328;;;29451:10;29435:27;::::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;29395:20:0::1;:30;::::0;::::1;::::0;29426:7;;29435:27;29463:12;;29435:41;::::1;;;-1:-1:-1::0;;;29435:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;:50:::1;:41;::::0;;::::1;;:50;::::0;29395:106:::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;15535:25:1::0;;;;15576:18;;;15569:34;29495:4:0::1;15619:18:1::0;;;15612:83;15508:18;;29395:106:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29382:119;;29533:7;29520:10;:20;29516:81;;;-1:-1:-1::0;29574:7:0;29516:81:::1;29636:10;29620:27;::::0;;;:15:::1;:27;::::0;;;;:41;;29678:7;;29620:27;29648:12;;29620:41;::::1;;;-1:-1:-1::0;;;29620:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;:65;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;29718:10:0::1;29702:27;::::0;;;:15:::1;:27;::::0;;;;:41;;29730:12;;29702:41;::::1;;;-1:-1:-1::0;;;29702:41:0::1;;;;;;;;;;;;;;;;;;;:54;;;29760:1;29702:59;29698:701;;;29778:39;29792:10;29804:12;29778:13;:39::i;:::-;29943:10;29927:27;::::0;;;:15:::1;:27;::::0;;;;29955:34;;:38:::1;::::0;29992:1:::1;::::0;29955:38:::1;:::i;:::-;29927:67;;;;;;-1:-1:-1::0;;;29927:67:0::1;;;;;;;;;;;;;;;;;;;29883:15;:27;29899:10;-1:-1:-1::0;;;;;29883:27:0::1;-1:-1:-1::0;;;;;29883:27:0::1;;;;;;;;;;;;29911:12;29883:41;;;;;;-1:-1:-1::0;;;29883: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;;;;30025:10:::1;30009:27:::0;;:15:::1;:27:::0;;;;;;:33;;;::::1;;-1:-1:-1::0;;;30009:33:0::1;;;;;;;;;;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;30009:33:0;;;;;::::1;;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;29698:701:::1;;;30212:10;30117:24;30196:27:::0;;;:15:::1;:27;::::0;;;;:41;;-1:-1:-1;;;;;30144:17:0::1;:33;::::0;::::1;::::0;30224:12;;30196:41;::::1;;;-1:-1:-1::0;;;30196:41:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:54:::0;30285:10:::1;30269:27:::0;;:15:::1;:27:::0;;;;;;;:41;;30297:12;;30269:41;::::1;;;-1:-1:-1::0;;;30269:41:0::1;;;;;;;;;;;;;;;;;;;:50;;;30144:190;;;;;;;;;;;;;;;15254:25:1::0;;;15310:2;15295:18;;15288:34;15242:2;15227:18;;15209:119;30144:190:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30117:217;;30371:16;30349:18;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;29698:701:0::1;30415:14:::0;;30411:134:::1;;30446:51;-1:-1:-1::0;;;;;30446:12:0::1;:25;23070:42;30486:10:::0;30446:25:::1;:51::i;:::-;30512:21;30523:10:::0;30512:21;::::1;:::i;:::-;;;30411:134;30555:46;-1:-1:-1::0;;;;;30555:12:0::1;:25;30581:10;30593:7:::0;30555:25:::1;:46::i;:::-;30617:43;::::0;;15254:25:1;;;15310:2;15295:18;;15288:34;;;30626:10:0::1;::::0;30617:43:::1;::::0;15227:18:1;30617:43:0::1;;;;;;;-1:-1:-1::0;;20061:1:0;21015:7;:22;-1:-1:-1;;28598:2070:0:o;26147:369::-;26194:7;26218:11;;26233:1;26218:16;26214:76;;;-1:-1:-1;26258:20:0;;;26147:369::o;26214:76::-;26300:28;26360:14;;26331:26;:24;:26::i;:::-;:43;;;;:::i;:::-;26489:18;;26300:74;;-1:-1:-1;26460:24:0;26464:20;26460:2;:24;:::i;:::-;26436:20;26417:16;;:39;;;;:::i;:::-;:68;;;;:::i;:::-;26416:91;;;;:::i;:::-;26392:20;;:116;;;;:::i;:::-;26385:123;;;26147:369;:::o;33396:201::-;34031:5;;-1:-1:-1;;;;;34031:5:0;34017:10;:19;34009:71;;;;-1:-1:-1;;;34009:71:0;;10698:2:1;34009:71:0;;;10680:21:1;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:1;;;10820:37;10874:19;;34009:71:0;10670:229:1;34009:71:0;33495:5:::1;::::0;;-1:-1:-1;;;;;33511:17:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;33544:45:::1;::::0;33495:5;::::1;::::0;33511:17;33495:5;;33544:45:::1;::::0;33472:20:::1;::::0;33544:45:::1;34091:1;33396:201:::0;:::o;32713:160::-;34031:5;;-1:-1:-1;;;;;34031:5:0;34017:10;:19;34009:71;;;;-1:-1:-1;;;34009:71:0;;10698:2:1;34009:71:0;;;10680:21:1;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:1;;;10820:37;10874:19;;34009:71:0;10670:229:1;34009:71:0;32776:8:::1;::::0;::::1;;32775:9;32767:72;;;::::0;-1:-1:-1;;;32767:72:0;;8193:2:1;32767:72:0::1;::::0;::::1;8175:21:1::0;8232:2;8212:18;;;8205:30;8271:34;8251:18;;;8244:62;8342:20;8322:18;;;8315:48;8380:19;;32767:72:0::1;8165:240:1::0;32767:72:0::1;32850:8;:15:::0;;-1:-1:-1;;32850:15:0::1;32861:4;32850:15;::::0;;32713:160::o;27142:1448::-;20105:1;20703:7;;:19;;20695:63;;;;-1:-1:-1;;;20695:63:0;;14338:2:1;20695:63:0;;;14320:21:1;14377:2;14357:18;;;14350:30;14416:33;14396:18;;;14389:61;14467:18;;20695:63:0;14310:181:1;20695:63:0;20105:1;20836:7;:18;33692:8:::1;::::0;::::1;;33691:9;33683:66;;;::::0;-1:-1:-1;;;33683:66:0;;9432:2:1;33683:66:0::1;::::0;::::1;9414:21:1::0;9471:2;9451:18;;;9444:30;9510:34;9490:18;;;9483:62;9581:14;9561:18;;;9554:42;9613:19;;33683:66:0::1;9404:234:1::0;33683:66:0::1;33780:15;33768:8;;:27;;33760:94;;;::::0;-1:-1:-1;;;33760:94:0;;7358:2:1;33760:94:0::1;::::0;::::1;7340:21:1::0;7397:2;7377:18;;;7370:30;7436:34;7416:18;;;7409:62;7507:24;7487:18;;;7480:52;7549:19;;33760:94:0::1;7330:244:1::0;33760:94:0::1;33882:15;33873:6;;:24;33865:84;;;::::0;-1:-1:-1;;;33865:84:0;;13498:2:1;33865:84:0::1;::::0;::::1;13480:21:1::0;13537:2;13517:18;;;13510:30;13576:34;13556:18;;;13549:62;13647:17;13627:18;;;13620:45;13682:19;;33865:84:0::1;13470:237:1::0;33865:84:0::1;27327:1:::2;27317:7;:11;27309:55;;;::::0;-1:-1:-1;;;27309:55:0;;11106:2:1;27309:55:0::2;::::0;::::2;11088:21:1::0;11145:2;11125:18;;;11118:30;11184:33;11164:18;;;11157:61;11235:18;;27309:55:0::2;11078:181:1::0;27309:55:0::2;27375:30;::::0;27408:16:::2;:45;;;;;;-1:-1:-1::0;;;27408:45:0::2;;;;;;;;;;:93;;27489:12;27408:93;;;27456:30;27474:12:::0;27456:15:::2;:30;:::i;:::-;27375:126;;27545:8;;27520:22;:33;27512:101;;;::::0;-1:-1:-1;;;27512:101:0;;13914:2:1;27512:101:0::2;::::0;::::2;13896:21:1::0;13953:2;13933:18;;;13926:30;13992:34;13972:18;;;13965:62;14063:25;14043:18;;;14036:53;14106:19;;27512:101:0::2;13886:245:1::0;27512:101:0::2;27657:15;27632:22;:40;27624:115;;;::::0;-1:-1:-1;;;27624:115:0;;12656:2:1;27624:115:0::2;::::0;::::2;12638:21:1::0;12695:2;12675:18;;;12668:30;12734:34;12714:18;;;12707:62;12805:32;12785:18;;;12778:60;12855:19;;27624:115:0::2;12628:252:1::0;27624:115:0::2;27752:22;27777:40;27802:15;27777:22:::0;:40:::2;:::i;:::-;27752:65;;27830:28;27852:1;27856::::0;27830:13:::2;:28::i;:::-;27903:239;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;;;;;;;;;28085:20:::2;::::0;27903:239;;;;;;27869:31:::2;27903:239:::0;;;;;;28169:10:::2;28153: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;;;;28235:27;;;:34;;27903:239;;27869:31;28235:38:::2;::::0;28153:46;28235:38:::2;:::i;:::-;28310:58;::::0;;;;::::2;::::0;::::2;15254:25:1::0;;;15295:18;;;15288:34;;;28212:61:0;;-1:-1:-1;28286:21:0::2;::::0;-1:-1:-1;;;;;28310:17:0::2;:33;::::0;::::2;::::0;15227:18:1;;28310:58:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28286:82;;28401:13;28379:18;;:35;;;;;;;:::i;:::-;;;;;;;;28440:7;28425:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;28460:65:0::2;::::0;-1:-1:-1;;;;;;28460:12:0::2;:29;28490:10;28510:4;28517:7:::0;28460:29:::2;:65::i;:::-;28541:41;::::0;;15254:25:1;;;15310:2;15295:18;;15288:34;;;28548:10:0::2;::::0;28541:41:::2;::::0;15227:18:1;28541:41:0::2;;;;;;;-1:-1:-1::0;;20061:1:0;21015:7;:22;-1:-1:-1;;;;;;27142:1448:0:o;25415:573::-;25497:7;25517:22;25542:17;-1:-1:-1;;;;;25542:33:0;;25590:15;:22;25606:5;-1:-1:-1;;;;;25590:22:0;-1:-1:-1;;;;;25590:22:0;;;;;;;;;;;;25613:12;25590:36;;;;;;-1:-1:-1;;;25590:36:0;;;;;;;;;;;;;;;;;;;;;;;;:49;-1:-1:-1;;;;;25654:22:0;;;;:15;:22;;;;;;;:36;;25677:12;;25654:36;;;;-1:-1:-1;;;25654:36:0;;;;;;;;;;;;;;;;;;;:45;;;25542:168;;;;;;;;;;;;;;;15254:25:1;;;15310:2;15295:18;;15288:34;15242:2;15227:18;;15209:119;25542:168:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25517:193;-1:-1:-1;25721:30:0;25867:24;25871:20;25867:2;:24;:::i;:::-;-1:-1:-1;;;;;25793:22:0;;;;;;:15;:22;;;;;:36;;25816:12;;25793:36;;;;-1:-1:-1;;;25793:36:0;;;;;;;;;;;;;;;;;;;:55;;;25774:16;:14;:16::i;:::-;:74;;;;:::i;:::-;25756:93;;:14;:93;:::i;:::-;25755:137;;;;:::i;:::-;-1:-1:-1;;;;;25936:22:0;;;;;;:15;:22;;;;;:36;;25721:172;;-1:-1:-1;25936:22:0;25959:12;;25936:36;;;;-1:-1:-1;;;25936:36:0;;;;;;;;;;;;;;;;;;;:44;;;25911:22;:69;;;;:::i;:::-;25904:76;;;;25415:573;;;;;:::o;26717:417::-;26819:16;:14;:16::i;:::-;26796:20;:39;26863:26;:24;:26::i;:::-;26846:14;:43;-1:-1:-1;;;;;26904:19:0;;;26900:227;;26987:35;27002:5;27009:12;26987:14;:35::i;:::-;-1:-1:-1;;;;;26940:22:0;;;;;;:15;:22;;;;;:36;;26963:12;;26940:36;;;;-1:-1:-1;;;26940:36:0;;;;;;;;;;;;;;;;;;;:44;;:82;;;;27095:20;;27037:15;:22;27053:5;-1:-1:-1;;;;;27037:22:0;-1:-1:-1;;;;;27037:22:0;;;;;;;;;;;;27060:12;27037:36;;;;;;-1:-1:-1;;;27037:36:0;;;;;;;;;;;;;;;;;;;:55;;:78;;;;26900:227;26717:417;;:::o;30676:365::-;-1:-1:-1;;;;;30772:22:0;;30755:14;30772:22;;;:15;:22;;;;;:36;;30795:12;;30772:36;;;;-1:-1:-1;;;30772:36:0;;;;;;;;;;;;;;;;;;;:44;;;30755:61;;30842:1;30833:6;:10;30829:205;;;-1:-1:-1;;;;;30860:22:0;;30907:1;30860:22;;;:15;:22;;;;;:36;;30883:12;;30860:36;;;;-1:-1:-1;;;30860:36:0;;;;;;;;;;;;;;;;;:44;:36;;;;;:44;:48;30923:40;-1:-1:-1;;;;;30923:12:0;:25;30949:5;30956:6;30923:25;:40::i;:::-;30983:39;;;15254:25:1;;;15310:2;15295:18;;15288:34;;;-1:-1:-1;;;;;30983:39:0;;;;;15227:18:1;30983:39:0;;;;;;;30829:205;30676:365;;;:::o;14724:248::-;14895:68;;-1:-1:-1;;;;;3203:15:1;;;14895:68:0;;;3185:34:1;3255:15;;3235:18;;;3228:43;3287:18;;;3280:34;;;14868:96:0;;14888:5;;14918:27;;3097:18:1;;14895:68:0;;;;-1:-1:-1;;14895:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;14868:19;:96::i;:::-;14724:248;;;;:::o;14505:211::-;14649:58;;-1:-1:-1;;;;;3517:55:1;;14649:58:0;;;3499:74:1;3589:18;;;3582:34;;;14622:86:0;;14642:5;;14672:23;;3472:18:1;;14649:58:0;3454:168:1;17572:716:0;17996:23;18022:69;18050:4;18022:69;;;;;;;;;;;;;;;;;18030:5;-1:-1:-1;;;;;18022:27:0;;;:69;;;;;:::i;:::-;18106:17;;17996:95;;-1:-1:-1;18106:21:0;18102:179;;18203:10;18192:30;;;;;;;;;;;;:::i;:::-;18184:85;;;;-1:-1:-1;;;18184:85:0;;13087:2:1;18184:85:0;;;13069:21:1;13126:2;13106:18;;;13099:30;13165:34;13145:18;;;13138:62;13236:12;13216:18;;;13209:40;13266:19;;18184:85:0;13059:232:1;9218:229:0;9355:12;9387:52;9409:6;9417:4;9423:1;9426:12;9387:21;:52::i;:::-;9380:59;;9218:229;;;;;;:::o;10338:510::-;10508:12;10566:5;10541:21;:30;;10533:81;;;;-1:-1:-1;;;10533:81:0;;9025:2:1;10533:81:0;;;9007:21:1;9064:2;9044:18;;;9037:30;9103:34;9083:18;;;9076:62;9174:8;9154:18;;;9147:36;9200:19;;10533:81:0;8997:228:1;10533:81:0;-1:-1:-1;;;;;6768:19:0;;;10625:60;;;;-1:-1:-1;;;10625:60:0;;12298:2:1;10625:60:0;;;12280:21:1;12337:2;12317:18;;;12310:30;12376:31;12356:18;;;12349:59;12425:18;;10625:60:0;12270:179:1;10625:60:0;10699:12;10713:23;10740:6;-1:-1:-1;;;;;10740:11:0;10759:5;10766:4;10740:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10698:73;;;;10789:51;10806:7;10815:10;10827:12;10789:16;:51::i;:::-;10782:58;10338:510;-1:-1:-1;;;;;;;10338:510:0:o;13024:762::-;13174:12;13203:7;13199:580;;;-1:-1:-1;13234:10:0;13227:17;;13199:580;13348:17;;:21;13344:424;;13596:10;13590:17;13657:15;13644:10;13640:2;13636:19;13629:44;13544:148;13739:12;13732:20;;-1:-1:-1;;;13732: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;5580:383::-;5729:2;5718:9;5711:21;5692:4;5761:6;5755:13;5804:6;5799:2;5788:9;5784:18;5777:34;5820:66;5879:6;5874:2;5863:9;5859:18;5854:2;5846:6;5842:15;5820:66;:::i;:::-;5947:2;5926:15;-1:-1:-1;;5922:29:1;5907:45;;;;5954:2;5903:54;;5701:262;-1:-1:-1;;5701:262:1:o;16174:128::-;16214:3;16245:1;16241:6;16238:1;16235:13;16232:2;;;16251:18;;:::i;:::-;-1:-1:-1;16287:9:1;;16222:80::o;16307:274::-;16347:1;16373;16363:2;;-1:-1:-1;;;16405:1:1;16398:88;16509:4;16506:1;16499:15;16537:4;16534:1;16527:15;16363:2;-1:-1:-1;16566:9:1;;16353:228::o;16586:422::-;16675:1;16718:5;16675:1;16732:270;16753:7;16743:8;16740:21;16732:270;;;16812:4;16808:1;16804:6;16800:17;16794:4;16791:27;16788:2;;;16821:18;;:::i;:::-;16871:7;16861:8;16857:22;16854:2;;;16891:16;;;;16854:2;16970:22;;;;16930:15;;;;16732:270;;;16736:3;16650:358;;;;;:::o;17013:131::-;17073:5;17102:36;17129:8;17123:4;17198:5;17228:8;17218:2;;-1:-1:-1;17269:1:1;17283:5;;17218:2;17317:4;17307:2;;-1:-1:-1;17354:1:1;17368:5;;17307:2;17399:4;17417:1;17412:59;;;;17485:1;17480:130;;;;17392:218;;17412:59;17442:1;17433:10;;17456:5;;;17480:130;17517:3;17507:8;17504:17;17501:2;;;17524:18;;:::i;:::-;-1:-1:-1;;17580:1:1;17566:16;;17595:5;;17392:218;;17694:2;17684:8;17681:16;17675:3;17669:4;17666:13;17662:36;17656:2;17646:8;17643:16;17638:2;17632:4;17629:12;17625:35;17622:77;17619:2;;;-1:-1:-1;17731:19:1;;;17763:5;;17619:2;17810:34;17835:8;17829:4;17810:34;:::i;:::-;17880:6;17876:1;17872:6;17868:19;17859:7;17856:32;17853:2;;;17891:18;;:::i;:::-;17929:20;;17208:747;-1:-1:-1;;;17208:747:1:o;17960:168::-;18000:7;18066:1;18062;18058:6;18054:14;18051:1;18048:21;18043:1;18036:9;18029:17;18025:45;18022:2;;;18073:18;;:::i;:::-;-1:-1:-1;18113:9:1;;18012:116::o;18133:125::-;18173:4;18201:1;18198;18195:8;18192:2;;;18206:18;;:::i;:::-;-1:-1:-1;18243:9:1;;18182:76::o;18263:258::-;18335:1;18345:113;18359:6;18356:1;18353:13;18345:113;;;18435:11;;;18429:18;18416:11;;;18409:39;18381:2;18374:10;18345:113;;;18476:6;18473:1;18470:13;18467:2;;;-1:-1:-1;;18511:1:1;18493:16;;18486:27;18316:205::o;18526:184::-;-1:-1:-1;;;18575:1:1;18568:88;18675:4;18672:1;18665:15;18699:4;18696:1;18689:15
Swarm Source
ipfs://2523186e9426f7b35f8497e626dc7031e7803b50a048d519e8f8390d34120b7b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.