Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13093728 | 1183 days ago | IN | 0 ETH | 0.39105375 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakeTONUpgrade2
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; pragma abicoder v2; import "../interfaces/IStakeTON.sol"; import {IIStake1Vault} from "../interfaces/IIStake1Vault.sol"; import {IIERC20} from "../interfaces/IIERC20.sol"; import {IWTON} from "../interfaces/IWTON.sol"; import "../libraries/LibTokenStake1.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "../connection/TokamakStakeUpgrade2.sol"; // import { // ERC165Checker // } from "@openzeppelin/contracts/introspection/ERC165Checker.sol"; // import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; /// @title Stake Contract /// @notice It can be staked in Tokamak. Can be swapped using Uniswap. /// Stake contracts can interact with the vault to claim tos tokens contract StakeTONUpgrade2 is TokamakStakeUpgrade2, IStakeTON { using SafeMath for uint256; /// @dev event on staking /// @param to the sender /// @param amount the amount of staking event Staked(address indexed to, uint256 amount); /// @dev event on claim /// @param to the sender /// @param amount the amount of claim /// @param claimBlock the block of claim event Claimed(address indexed to, uint256 amount, uint256 claimBlock); /// @dev event on withdrawal /// @param to the sender /// @param tonAmount the amount of TON withdrawal /// @param tosAmount the amount of TOS withdrawal event Withdrawal(address indexed to, uint256 tonAmount, uint256 tosAmount); /// @dev constructor of StakeTON constructor() {} /// @dev This contract cannot stake Ether. receive() external payable { revert("cannot stake Ether"); } /// @dev withdraw function withdraw() external override { require(endBlock > 0 && endBlock < block.number, "StakeTON: not end"); ( address ton, address wton, address depositManager, address seigManager, ) = ITokamakRegistry2(stakeRegistry).getTokamak(); require( ton != address(0) && wton != address(0) && depositManager != address(0) && seigManager != address(0), "StakeTON: ITokamakRegistry zero" ); if (tokamakLayer2 != address(0)) { require( IISeigManager(seigManager).stakeOf( tokamakLayer2, address(this) ) == 0 && IIIDepositManager(depositManager).pendingUnstaked( tokamakLayer2, address(this) ) == 0, "StakeTON: remain amount in tokamak" ); } LibTokenStake1.StakedAmount storage staked = userStaked[msg.sender]; require(!staked.released, "StakeTON: Already withdraw"); if (!withdrawFlag) { withdrawFlag = true; if (paytoken == ton) { swappedAmountTOS = IIERC20(token).balanceOf(address(this)); finalBalanceWTON = IIERC20(wton).balanceOf(address(this)); finalBalanceTON = IIERC20(ton).balanceOf(address(this)); require( finalBalanceWTON.div(10**9).add(finalBalanceTON) >= totalStakedAmount, "StakeTON: finalBalance is lack" ); } } uint256 amount = staked.amount; require(amount > 0, "StakeTON: Amount wrong"); staked.releasedBlock = block.number; staked.released = true; if (paytoken == ton) { uint256 tonAmount = 0; uint256 wtonAmount = 0; uint256 tosAmount = 0; if (finalBalanceTON > 0) tonAmount = finalBalanceTON.mul(amount).div(totalStakedAmount); if (finalBalanceWTON > 0) wtonAmount = finalBalanceWTON.mul(amount).div( totalStakedAmount ); if (swappedAmountTOS > 0) tosAmount = swappedAmountTOS.mul(amount).div(totalStakedAmount); staked.releasedTOSAmount = tosAmount; if (wtonAmount > 0) staked.releasedAmount = wtonAmount.div(10**9).add(tonAmount); else staked.releasedAmount = tonAmount; tonWithdraw(ton, wton, tonAmount, wtonAmount, tosAmount); } else if (paytoken == address(0)) { require(staked.releasedAmount <= amount, "StakeTON: Amount wrong"); staked.releasedAmount = amount; address payable self = address(uint160(address(this))); require(self.balance >= amount, "StakeTON: insuffient ETH"); (bool success, ) = msg.sender.call{value: amount}(""); require(success, "StakeTON: withdraw failed."); } else { require(staked.releasedAmount <= amount, "StakeTON: Amount wrong"); staked.releasedAmount = amount; require( IIERC20(paytoken).transfer(msg.sender, amount), "StakeTON: transfer fail" ); } emit Withdrawal( msg.sender, staked.releasedAmount, staked.releasedTOSAmount ); } /// @dev withdraw TON /// @param ton TON address /// @param wton WTON address /// @param tonAmount the amount of TON to be withdrawn to msg.sender /// @param wtonAmount the amount of WTON to be withdrawn to msg.sender /// @param tosAmount the amount of TOS to be withdrawn to msg.sender function tonWithdraw( address ton, address wton, uint256 tonAmount, uint256 wtonAmount, uint256 tosAmount ) internal { if (tonAmount > 0) { require( IIERC20(ton).balanceOf(address(this)) >= tonAmount, "StakeTON: ton balance is lack" ); require( IIERC20(ton).transfer(msg.sender, tonAmount), "StakeTON: transfer ton fail" ); } if (wtonAmount > 0) { require( IIERC20(wton).balanceOf(address(this)) >= wtonAmount, "StakeTON: wton balance is lack" ); require( IWTON(wton).swapToTONAndTransfer(msg.sender, wtonAmount), "StakeTON: transfer wton fail" ); } if (tosAmount > 0) { require( IIERC20(token).balanceOf(address(this)) >= tosAmount, "StakeTON: tos balance is lack" ); require( IIERC20(token).transfer(msg.sender, tosAmount), "StakeTON: transfer tos fail" ); } } /// @dev Claim for reward function claim() external override lock { require(IIStake1Vault(vault).saleClosed(), "StakeTON: not closed"); uint256 rewardClaim = 0; LibTokenStake1.StakedAmount storage staked = userStaked[msg.sender]; require( staked.amount > 0 && staked.claimedBlock < endBlock, "StakeTON: claimed" ); rewardClaim = canRewardAmount(msg.sender, block.number); require(rewardClaim > 0, "StakeTON: reward is zero"); uint256 rewardTotal = IIStake1Vault(vault).totalRewardAmount(address(this)); require( rewardClaimedTotal.add(rewardClaim) <= rewardTotal, "StakeTON: total reward exceeds" ); staked.claimedBlock = block.number; staked.claimedAmount = staked.claimedAmount.add(rewardClaim); rewardClaimedTotal = rewardClaimedTotal.add(rewardClaim); require( IIStake1Vault(vault).claim(msg.sender, rewardClaim), "StakeTON: fail claim from vault" ); emit Claimed(msg.sender, rewardClaim, block.number); } /// @dev Returns the amount that can be rewarded /// @param account the account that claimed reward /// @param specificBlock the block that claimed reward /// @return reward the reward amount that can be taken function canRewardAmount(address account, uint256 specificBlock) public view override returns (uint256) { uint256 reward = 0; if (specificBlock > endBlock) specificBlock = endBlock; if ( specificBlock < startBlock || userStaked[account].amount == 0 || userStaked[account].claimedBlock > endBlock || userStaked[account].claimedBlock > specificBlock ) { reward = 0; } else { uint256 startR = startBlock; uint256 endR = endBlock; if (startR < userStaked[account].claimedBlock) startR = userStaked[account].claimedBlock; if (specificBlock < endR) endR = specificBlock; uint256[] memory orderedEndBlocks = IIStake1Vault(vault).orderedEndBlocksAll(); if (orderedEndBlocks.length > 0) { uint256 _end = 0; uint256 _start = startR; uint256 _total = 0; uint256 blockTotalReward = 0; blockTotalReward = IIStake1Vault(vault).blockTotalReward(); address user = account; uint256 amount = userStaked[user].amount; for (uint256 i = 0; i < orderedEndBlocks.length; i++) { _end = orderedEndBlocks[i]; _total = IIStake1Vault(vault).stakeEndBlockTotal(_end); if (_start > _end) {} else if (endR <= _end) { if (_total > 0) { uint256 _period1 = endR.sub(startR); reward = reward.add( blockTotalReward.mul(_period1).mul(amount).div( _total ) ); } break; } else { if (_total > 0) { uint256 _period2 = _end.sub(startR); reward = reward.add( blockTotalReward.mul(_period2).mul(amount).div( _total ) ); } startR = _end; } } } } return reward; } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; pragma abicoder v2; import "../libraries/LibTokenStake1.sol"; interface IStakeTON { /// @dev Stake amount /// @param amount the amount of staked //function stake(uint256 amount) external payable; /// @dev Claim for reward function claim() external; /// @dev withdraw function withdraw() external; /// @dev Returns the amount that can be rewarded /// @param account the account that claimed reward /// @param specificBlock the block that claimed reward /// @return reward the reward amount that can be taken function canRewardAmount(address account, uint256 specificBlock) external view returns (uint256); }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; interface IIStake1Vault { function closeSale() external; function totalRewardAmount(address _account) external view returns (uint256); function claim(address _to, uint256 _amount) external returns (bool); function orderedEndBlocksAll() external view returns (uint256[] memory); function blockTotalReward() external view returns (uint256); function stakeEndBlockTotal(uint256 endblock) external view returns (uint256 totalStakedAmount); function saleClosed() external view returns (bool); }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; interface IIERC20 { event Approval( address indexed owner, address indexed spender, uint256 value ); event Transfer(address indexed from, address indexed to, uint256 value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; interface IWTON { function balanceOf(address account) external view returns (uint256); function onApprove( address owner, address spender, uint256 tonAmount, bytes calldata data ) external returns (bool); function burnFrom(address account, uint256 amount) external; function swapToTON(uint256 wtonAmount) external returns (bool); function swapFromTON(uint256 tonAmount) external returns (bool); function swapToTONAndTransfer(address to, uint256 wtonAmount) external returns (bool); function swapFromTONAndTransfer(address to, uint256 tonAmount) external returns (bool); function renounceTonMinter() external; function approve(address spender, uint256 amount) external returns (bool); }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; library LibTokenStake1 { enum DefiStatus { NONE, APPROVE, DEPOSITED, REQUESTWITHDRAW, REQUESTWITHDRAWALL, WITHDRAW, END } struct DefiInfo { string name; address router; address ext1; address ext2; uint256 fee; address routerV2; } struct StakeInfo { string name; uint256 startBlock; uint256 endBlock; uint256 balance; uint256 totalRewardAmount; uint256 claimRewardAmount; } struct StakedAmount { uint256 amount; uint256 claimedBlock; uint256 claimedAmount; uint256 releasedBlock; uint256 releasedAmount; uint256 releasedTOSAmount; bool released; } struct StakedAmountForSTOS { uint256 amount; uint256 startBlock; uint256 periodBlock; uint256 rewardPerBlock; uint256 claimedBlock; uint256 claimedAmount; uint256 releasedBlock; uint256 releasedAmount; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; pragma abicoder v2; import "../interfaces/ITokamakStaker.sol"; import {ITON} from "../interfaces/ITON.sol"; import {IIStake1Vault} from "../interfaces/IIStake1Vault.sol"; import {IIIDepositManager} from "../interfaces/IIIDepositManager.sol"; import {IISeigManager} from "../interfaces/IISeigManager.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "../common/AccessibleCommon.sol"; import "../stake/StakeTONStorage.sol"; import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; interface IERC20BASE2 { function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); } interface IIWTON2 { function swapToTON(uint256 wtonAmount) external returns (bool); } interface ITokamakRegistry2 { function getTokamak() external view returns ( address, address, address, address, address ); function getUniswap() external view returns ( address, address, address, uint256, address ); } /// @title The connector that integrates tokamak contract TokamakStakeUpgrade2 is StakeTONStorage, AccessibleCommon, ITokamakStaker { using SafeMath for uint256; modifier nonZero(address _addr) { require(_addr != address(0), "TokamakStaker: zero address"); _; } modifier sameTokamakLayer(address _addr) { require(tokamakLayer2 == _addr, "TokamakStaker:different layer"); _; } modifier lock() { require(_lock == 0, "TokamakStaker:LOCKED"); _lock = 1; _; _lock = 0; } modifier onlyClosed() { require(IIStake1Vault(vault).saleClosed(), "TokamakStaker: not closed"); _; } /// @dev event on set the registry address /// @param registry the registry address event SetRegistry(address registry); /// @dev event on set the tokamak Layer2 address /// @param layer2 the tokamak Layer2 address event SetTokamakLayer2(address layer2); /// @dev event on staking the staked TON in layer2 in tokamak /// @param layer2 the layer2 address in tokamak /// @param amount the amount that stake to layer2 event TokamakStaked(address layer2, uint256 amount); /// @dev event on request unstaking the wtonAmount in layer2 in tokamak /// @param layer2 the layer2 address in tokamak /// @param amount the amount requested to unstaking event TokamakRequestedUnStaking(address layer2, uint256 amount); /// @dev event on process unstaking in layer2 in tokamak /// @param layer2 the layer2 address in tokamak /// @param rn the number of requested unstaking /// @param receiveTON if is true ,TON , else is WTON event TokamakProcessedUnStaking( address layer2, uint256 rn, bool receiveTON ); /// @dev event on request unstaking the amount of all in layer2 in tokamak /// @param layer2 the layer2 address in tokamak event TokamakRequestedUnStakingAll(address layer2); /// @dev exchange WTON to TOS using uniswap v3 /// @param caller the sender /// @param amountIn the input amount /// @return amountOut the amount of exchanged out token event ExchangedWTONtoTOS( address caller, uint256 amountIn, uint256 amountOut ); /// @dev set registry address /// @param _registry new registry address function setRegistry(address _registry) external onlyOwner nonZero(_registry) { stakeRegistry = _registry; emit SetRegistry(stakeRegistry); } /// @dev set the tokamak Layer2 address /// @param _layer2 new the tokamak Layer2 address function setTokamakLayer2(address _layer2) external override onlyOwner { require( _layer2 != address(0) && tokamakLayer2 != _layer2, "TokamakStaker:tokamakLayer2 zero " ); tokamakLayer2 = _layer2; emit SetTokamakLayer2(_layer2); } /// @dev get the addresses that used in uniswap interfaces /// @return uniswapRouter the address of uniswapRouter /// @return npm the address of positionManagerAddress /// @return ext the address of ext /// @return fee the amount of fee function getUniswapInfo() external view override returns ( address uniswapRouter, address npm, address ext, uint256 fee, address uniswapRouterV2 ) { return ITokamakRegistry2(stakeRegistry).getUniswap(); } /// @dev Change the TON holded in contract have to WTON, or change WTON to TON. /// @param amount the amount to be changed /// @param toWTON if it's true, TON->WTON , else WTON->TON function swapTONtoWTON(uint256 amount, bool toWTON) external override lock { checkTokamak(); if (toWTON) { require( swapProxy != address(0), "TokamakStaker: swapProxy is zero" ); require( IERC20BASE2(ton).balanceOf(address(this)) >= amount, "TokamakStaker: swapTONtoWTON ton balance is insufficient" ); bytes memory data = abi.encode(swapProxy, swapProxy); require( ITON(ton).approveAndCall(wton, amount, data), "TokamakStaker:swapTONtoWTON approveAndCall fail" ); } else { require( IERC20BASE2(wton).balanceOf(address(this)) >= amount, "TokamakStaker: swapTONtoWTON wton balance is insufficient" ); require( IIWTON2(wton).swapToTON(amount), "TokamakStaker:swapToTON fail" ); } } /// @dev If the tokamak addresses is not set, set the addresses. function checkTokamak() public { if (ton == address(0)) { ( address _ton, address _wton, address _depositManager, address _seigManager, address _swapProxy ) = ITokamakRegistry2(stakeRegistry).getTokamak(); ton = _ton; wton = _wton; depositManager = _depositManager; seigManager = _seigManager; swapProxy = _swapProxy; } require( ton != address(0) && wton != address(0) && seigManager != address(0) && depositManager != address(0) && swapProxy != address(0), "TokamakStaker:tokamak zero" ); } /// @dev staking the staked TON in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak /// @param stakeAmount the amount that stake to layer2 function tokamakStaking(address _layer2, uint256 stakeAmount) external override lock nonZero(stakeRegistry) nonZero(_layer2) onlyClosed { require(block.number <= endBlock, "TokamakStaker:period end"); require(stakeAmount > 0, "TokamakStaker:stakeAmount is zero"); defiStatus = uint256(LibTokenStake1.DefiStatus.DEPOSITED); checkTokamak(); uint256 globalWithdrawalDelay = IIIDepositManager(depositManager).globalWithdrawalDelay(); require( block.number < endBlock.sub(globalWithdrawalDelay), "TokamakStaker:period(withdrawalDelay) end" ); if (tokamakLayer2 == address(0)) tokamakLayer2 = _layer2; else { if ( IISeigManager(seigManager).stakeOf( tokamakLayer2, address(this) ) > 0 || IIIDepositManager(depositManager).pendingUnstaked( tokamakLayer2, address(this) ) > 0 ) { require( tokamakLayer2 == _layer2, "TokamakStaker:different layer" ); } else { if (tokamakLayer2 != _layer2) tokamakLayer2 = _layer2; } } require( IERC20BASE2(ton).balanceOf(address(this)) >= stakeAmount, "TokamakStaker: ton balance is insufficient" ); toTokamak = toTokamak.add(stakeAmount); bytes memory data = abi.encode(depositManager, _layer2); require( ITON(ton).approveAndCall(wton, stakeAmount, data), "TokamakStaker:approveAndCall fail" ); emit TokamakStaked(_layer2, stakeAmount); } function version() external pure returns (string memory) { return "phase1.upgrade.v2"; } /// @dev request unstaking the amount excluding principal in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak /// @param wtonAmount Exists for existing interfaces. not used. function tokamakRequestUnStaking(address _layer2, uint256 wtonAmount) external override lock nonZero(stakeRegistry) nonZero(_layer2) onlyClosed sameTokamakLayer(_layer2) { defiStatus = uint256(LibTokenStake1.DefiStatus.REQUESTWITHDRAW); requestNum = requestNum.add(1); checkTokamak(); uint256 stakeOf = IISeigManager(seigManager).stakeOf(_layer2, address(this)); require(stakeOf > 0, "TokamakStaker: stakeOf is zero"); uint256 principalAmount = totalStakedAmount.mul(10**9); uint256 availableAmount = 0; if (principalAmount > 0 && principalAmount < stakeOf.sub(100)) { availableAmount = stakeOf.sub(principalAmount).sub(100); } require( availableAmount > 0, "TokamakStaker: no withdraw-able amount not yet" ); IIIDepositManager(depositManager).requestWithdrawal( _layer2, availableAmount ); emit TokamakRequestedUnStaking(_layer2, availableAmount); } /// @dev Check whether unstaking is possible in layer2 /// @param _layer2 the layer2 address in tokamak /// @return canUnStakingAmount available unStaking amount function canTokamakRequestUnStaking(address _layer2) external view returns (uint256 canUnStakingAmount) { canUnStakingAmount = 0; if ( tokamakLayer2 != address(0) && tokamakLayer2 == _layer2 && seigManager != address(0) ) { uint256 stakeOf = IISeigManager(seigManager).stakeOf(_layer2, address(this)); if ( stakeOf > 0 && totalStakedAmount > 0 && totalStakedAmount.mul(10**9) < stakeOf ) { canUnStakingAmount = stakeOf.sub(totalStakedAmount.mul(10**9)); } } } /// @dev request unstaking the amount of all in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak function tokamakRequestUnStakingAll(address _layer2) external override lock nonZero(stakeRegistry) nonZero(_layer2) onlyClosed sameTokamakLayer(_layer2) { defiStatus = uint256(LibTokenStake1.DefiStatus.REQUESTWITHDRAW); requestNum = requestNum.add(1); checkTokamak(); uint256 globalWithdrawalDelay = IIIDepositManager(depositManager).globalWithdrawalDelay(); uint256 stakeOf = IISeigManager(seigManager).stakeOf(_layer2, address(this)); require(stakeOf > 0, "TokamakStaker: stakeOf is zero"); uint256 interval = globalWithdrawalDelay / 14; require( block.number > endBlock.sub(globalWithdrawalDelay).sub(interval), "TokamakStaker:The executable block has not passed" ); IIIDepositManager(depositManager).requestWithdrawalAll(_layer2); emit TokamakRequestedUnStakingAll(_layer2); } /// @dev Check whether unstakingAll is possible in layer2 /// @param _layer2 the layer2 address in tokamak /// @return can whether can tokamakRequestUnStakingAll function canTokamakRequestUnStakingAll(address _layer2) external view returns (bool can) { can = false; if ( tokamakLayer2 != address(0) && tokamakLayer2 == _layer2 && depositManager != address(0) && seigManager != address(0) ) { uint256 globalWithdrawalDelay = IIIDepositManager(depositManager).globalWithdrawalDelay(); uint256 interval = globalWithdrawalDelay / 14; uint256 stakeOf = IISeigManager(seigManager).stakeOf(_layer2, address(this)); if ( stakeOf > 0 && block.number > endBlock.sub(globalWithdrawalDelay).sub(interval) ) can = true; } } /// @dev Check whether unstakingAll is possible in layer2 /// @param _layer2 the layer2 address in tokamak /// @return _block the block to can tokamakRequestUnStakingAll function canTokamakRequestUnStakingAllBlock(address _layer2) external view returns (uint256 _block) { if ( tokamakLayer2 != address(0) && tokamakLayer2 == _layer2 && depositManager != address(0) ) { uint256 globalWithdrawalDelay = IIIDepositManager(depositManager).globalWithdrawalDelay(); uint256 interval = globalWithdrawalDelay / 14; if (endBlock > globalWithdrawalDelay.add(interval)) _block = endBlock.sub(globalWithdrawalDelay).sub(interval); } } /// @dev process unstaking in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak function tokamakProcessUnStaking(address _layer2) external override lock nonZero(stakeRegistry) onlyClosed sameTokamakLayer(_layer2) { defiStatus = uint256(LibTokenStake1.DefiStatus.WITHDRAW); checkTokamak(); uint256 num = 0; uint256 pamount = 0; (num, pamount) = canTokamakProcessUnStakingCount(_layer2); require(num > 0 && pamount > 0, "TokamakStaker: no able request"); fromTokamak = fromTokamak.add(pamount); if (requestNum >= num) requestNum = requestNum.sub(num); // receiveTON = false . to WTON IIIDepositManager(depositManager).processRequests(_layer2, num, true); emit TokamakProcessedUnStaking(_layer2, num, true); } /// @dev TokamakProcessUnStaking Number and amount of withdrawals possible /// @param _layer2 the layer2 address in tokamak function canTokamakProcessUnStakingCount(address _layer2) public view nonZero(stakeRegistry) nonZero(_layer2) onlyClosed sameTokamakLayer(_layer2) returns (uint256 count, uint256 amount) { uint128 num = 0; uint128 pamount = 0; uint256 startIndex = IIIDepositManager(depositManager).withdrawalRequestIndex( _layer2, address(this) ); uint256 numPendingRequests = IIIDepositManager(depositManager) .numPendingRequests(_layer2, address(this)) .add(startIndex); for (uint256 i = startIndex; i < numPendingRequests; i++) { uint128 _block = 0; uint128 _amount = 0; bool processed = false; (_block, _amount, processed) = IIIDepositManager(depositManager) .withdrawalRequest(_layer2, address(this), i); if ( processed == false && (uint256(_block) > 0 && uint256(_block) < block.number) ) { num++; pamount += _amount; } else { break; } } return (uint256(num), uint256(pamount)); } /// @dev exchange holded WTON to TOS using uniswap /// @param _amountIn the input amount /// @param _amountOutMinimum the minimun output amount /// @param _deadline deadline /// @param _sqrtPriceLimitX96 sqrtPriceLimitX96 /// @param _kind the function type, if 0, use exactInputSingle function, else if, use exactInput function /// @return amountOut the amount of exchanged out token function exchangeWTONtoTOS( uint256 _amountIn, uint256 _amountOutMinimum, uint256 _deadline, uint160 _sqrtPriceLimitX96, uint256 _kind ) external override lock onlyClosed returns (uint256 amountOut) { require(block.number <= endBlock, "TokamakStaker: period end"); require(_kind < 2, "TokamakStaker: not available kind"); checkTokamak(); { uint256 _amountWTON = IERC20BASE2(wton).balanceOf(address(this)); uint256 _amountTON = IERC20BASE2(ton).balanceOf(address(this)); uint256 stakeOf = 0; if (tokamakLayer2 != address(0)) { stakeOf = IISeigManager(seigManager).stakeOf( tokamakLayer2, address(this) ); stakeOf = stakeOf.add( IIIDepositManager(depositManager).pendingUnstaked( tokamakLayer2, address(this) ) ); } uint256 holdAmount = _amountWTON; if (_amountTON > 0) holdAmount = holdAmount.add(_amountTON.mul(10**9)); require( holdAmount >= _amountIn, "TokamakStaker: wton insufficient" ); if (stakeOf > 0) holdAmount = holdAmount.add(stakeOf); require( holdAmount > totalStakedAmount.mul(10**9) && holdAmount.sub(totalStakedAmount.mul(10**9)) >= _amountIn, "TokamakStaker:insufficient" ); if (_amountWTON < _amountIn) { bytes memory data = abi.encode(swapProxy, swapProxy); uint256 swapTON = _amountIn.sub(_amountWTON).div(10**9); require( ITON(ton).approveAndCall(wton, swapTON, data), "TokamakStaker:exchangeWTONtoTOS approveAndCall fail" ); } } toUniswapWTON = toUniswapWTON.add(_amountIn); (address uniswapRouter, , , uint256 _fee, ) = ITokamakRegistry2(stakeRegistry).getUniswap(); require(uniswapRouter != address(0), "TokamakStaker:uniswap zero"); require( IERC20BASE2(wton).approve(uniswapRouter, _amountIn), "TokamakStaker:can't approve uniswapRouter" ); //if (_kind == 0) { ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ tokenIn: wton, tokenOut: token, fee: uint24(_fee), recipient: address(this), deadline: _deadline, amountIn: _amountIn, amountOutMinimum: _amountOutMinimum, sqrtPriceLimitX96: _sqrtPriceLimitX96 }); amountOut = ISwapRouter(uniswapRouter).exactInputSingle(params); /* } else if (_kind == 1) { ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({ path: abi.encodePacked( wton, uint24(_fee), wethAddress, uint24(_fee), token ), recipient: address(this), deadline: _deadline, amountIn: _amountIn, amountOutMinimum: _amountOutMinimum }); amountOut = ISwapRouter(uniswapRouter).exactInput(params); } */ emit ExchangedWTONtoTOS(msg.sender, _amountIn, amountOut); } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; interface ITokamakStaker { /// @dev set the tokamak Layer2 address /// @param _layer2 new the tokamak Layer2 address function setTokamakLayer2(address _layer2) external; /// @dev get the addresses yhat used in uniswap interfaces /// @return uniswapRouter the address of uniswapV3 Router /// @return npm the address of positionManagerAddress /// @return ext the address of ext /// @return fee the amount of fee /// @return uniswapV2Router uniswapV2 router address function getUniswapInfo() external view returns ( address uniswapRouter, address npm, address ext, uint256 fee, address uniswapV2Router ); /// @dev Change the TON holded in contract have to WTON, or change WTON to TON. /// @param amount the amount to be changed /// @param toWTON if it's true, TON->WTON , else WTON->TON function swapTONtoWTON(uint256 amount, bool toWTON) external; /// @dev staking the staked TON in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak /// @param stakeAmount the amount that stake to layer2 function tokamakStaking(address _layer2, uint256 stakeAmount) external; /// @dev request unstaking the wtonAmount in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak /// @param wtonAmount the amount requested to unstaking function tokamakRequestUnStaking(address _layer2, uint256 wtonAmount) external; /// @dev request unstaking the wtonAmount in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak function tokamakRequestUnStakingAll(address _layer2) external; /// @dev process unstaking in layer2 in tokamak /// @param _layer2 the layer2 address in tokamak function tokamakProcessUnStaking(address _layer2) external; /// @dev exchange holded WTON to TOS using uniswap-v3 /// @param _amountIn the input amount /// @param _amountOutMinimum the minimun output amount /// @param _deadline deadline /// @param _sqrtPriceLimitX96 sqrtPriceLimitX96 /// @param _kind the function type, if 0, use exactInputSingle function, else if, use exactInput function function exchangeWTONtoTOS( uint256 _amountIn, uint256 _amountOutMinimum, uint256 _deadline, uint160 _sqrtPriceLimitX96, uint256 _kind ) external returns (uint256 amountOut); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; interface ITON { function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); function approveAndCall( address spender, uint256 amount, bytes memory data ) external returns (bool); function balanceOf(address account) external view returns (uint256); function onApprove( address owner, address spender, uint256 tonAmount, bytes calldata data ) external returns (bool); function burnFrom(address account, uint256 amount) external; function swapToTON(uint256 wtonAmount) external returns (bool); function swapFromTON(uint256 tonAmount) external returns (bool); function swapToTONAndTransfer(address to, uint256 wtonAmount) external returns (bool); function swapFromTONAndTransfer(address to, uint256 tonAmount) external returns (bool); function renounceTonMinter() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; interface IIIDepositManager { function globalWithdrawalDelay() external view returns (uint256 withdrawalDelay); function accStaked(address layer2, address account) external view returns (uint256 wtonAmount); function accStakedLayer2(address layer2) external view returns (uint256 wtonAmount); function accStakedAccount(address account) external view returns (uint256 wtonAmount); function pendingUnstaked(address layer2, address account) external view returns (uint256 wtonAmount); function pendingUnstakedLayer2(address layer2) external view returns (uint256 wtonAmount); function pendingUnstakedAccount(address account) external view returns (uint256 wtonAmount); function accUnstaked(address layer2, address account) external view returns (uint256 wtonAmount); function accUnstakedLayer2(address layer2) external view returns (uint256 wtonAmount); function accUnstakedAccount(address account) external view returns (uint256 wtonAmount); function withdrawalRequestIndex(address layer2, address account) external view returns (uint256 index); // solhint-disable-next-line max-line-length function withdrawalRequest( address layer2, address account, uint256 index ) external view returns ( uint128 withdrawableBlockNumber, uint128 amount, bool processed ); function WITHDRAWAL_DELAY() external view returns (uint256); function deposit(address layer2, uint256 amount) external returns (bool); function requestWithdrawal(address layer2, uint256 amount) external returns (bool); function processRequest(address layer2, bool receiveTON) external returns (bool); function requestWithdrawalAll(address layer2) external returns (bool); function processRequests( address layer2, uint256 n, bool receiveTON ) external returns (bool); function numRequests(address layer2, address account) external view returns (uint256); function numPendingRequests(address layer2, address account) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; interface IISeigManager { function stakeOf(address layer2, address account) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; import "@openzeppelin/contracts/access/AccessControl.sol"; import "./AccessRoleCommon.sol"; contract AccessibleCommon is AccessRoleCommon, AccessControl { modifier onlyOwner() { require(isAdmin(msg.sender), "Accessible: Caller is not an admin"); _; } /// @dev add admin /// @param account address to add function addAdmin(address account) public virtual onlyOwner { grantRole(ADMIN_ROLE, account); } /// @dev remove admin /// @param account address to remove function removeAdmin(address account) public virtual onlyOwner { renounceRole(ADMIN_ROLE, account); } /// @dev transfer admin /// @param newAdmin new admin address function transferAdmin(address newAdmin) external virtual onlyOwner { require(newAdmin != address(0), "Accessible: zero address"); require(msg.sender != newAdmin, "Accessible: same admin"); grantRole(ADMIN_ROLE, newAdmin); renounceRole(ADMIN_ROLE, msg.sender); } /// @dev whether admin /// @param account address to check function isAdmin(address account) public view virtual returns (bool) { return hasRole(ADMIN_ROLE, account); } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; import "./Stake1Storage.sol"; /// @title the storage of StakeTONStorage contract StakeTONStorage is Stake1Storage { /// @dev TON address address public ton; /// @dev WTON address address public wton; /// @dev SeigManager address address public seigManager; /// @dev DepositManager address address public depositManager; /// @dev swapProxy address address public swapProxy; /// @dev the layer2 address in Tokamak address public tokamakLayer2; /// @dev the accumulated TON amount staked into tokamak , in wei unit uint256 public toTokamak; /// @dev the accumulated WTON amount unstaked from tokamak , in ray unit uint256 public fromTokamak; /// @dev the accumulated WTON amount swapped using uniswap , in ray unit uint256 public toUniswapWTON; /// @dev the TOS balance in this contract uint256 public swappedAmountTOS; /// @dev the TON balance in this contract when withdraw at first uint256 public finalBalanceTON; /// @dev the WTON balance in this contract when withdraw at first uint256 public finalBalanceWTON; /// @dev defi status uint256 public defiStatus; /// @dev the number of requesting unstaking to tokamak , when process unstaking, reset zero. uint256 public requestNum; /// @dev the withdraw flag, when withdraw at first, set true bool public withdrawFlag; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/EnumerableSet.sol"; import "../utils/Address.sol"; import "../GSN/Context.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; contract AccessRoleCommon { bytes32 public constant ADMIN_ROLE = keccak256("ADMIN"); bytes32 public constant MINTER_ROLE = keccak256("MINTER"); bytes32 public constant BURNER_ROLE = keccak256("BURNER"); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.7.6; import "../libraries/LibTokenStake1.sol"; /// @title The base storage of stakeContract contract Stake1Storage { /// @dev reward token : TOS address public token; /// @dev registry address public stakeRegistry; /// @dev paytoken is the token that the user stakes. ( if paytoken is ether, paytoken is address(0) ) address public paytoken; /// @dev A vault that holds TOS rewards. address public vault; /// @dev the start block for sale. uint256 public saleStartBlock; /// @dev the staking start block, once staking starts, users can no longer apply for staking. uint256 public startBlock; /// @dev the staking end block. uint256 public endBlock; /// @dev the total amount claimed uint256 public rewardClaimedTotal; /// @dev the total staked amount uint256 public totalStakedAmount; /// @dev information staked by user mapping(address => LibTokenStake1.StakedAmount) public userStaked; /// @dev total stakers uint256 public totalStakers; uint256 internal _lock; /// @dev flag for pause proxy bool public pauseProxy; /// @dev extra address storage address public defiAddr; ///@dev for migrate L2 bool public migratedL2; /// @dev user's staked information function getUserStaked(address user) external view returns ( uint256 amount, uint256 claimedBlock, uint256 claimedAmount, uint256 releasedBlock, uint256 releasedAmount, uint256 releasedTOSAmount, bool released ) { return ( userStaked[user].amount, userStaked[user].claimedBlock, userStaked[user].claimedAmount, userStaked[user].releasedBlock, userStaked[user].releasedAmount, userStaked[user].releasedTOSAmount, userStaked[user].released ); } /// @dev Give the infomation of this stakeContracts /// @return paytoken, vault, [saleStartBlock, startBlock, endBlock], rewardClaimedTotal, totalStakedAmount, totalStakers function infos() external view returns ( address, address, uint256[3] memory, uint256, uint256, uint256 ) { return ( paytoken, vault, [saleStartBlock, startBlock, endBlock], rewardClaimedTotal, totalStakedAmount, totalStakers ); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimBlock","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"ExchangedWTONtoTOS","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"registry","type":"address"}],"name":"SetRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"layer2","type":"address"}],"name":"SetTokamakLayer2","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"layer2","type":"address"},{"indexed":false,"internalType":"uint256","name":"rn","type":"uint256"},{"indexed":false,"internalType":"bool","name":"receiveTON","type":"bool"}],"name":"TokamakProcessedUnStaking","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"layer2","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokamakRequestedUnStaking","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"layer2","type":"address"}],"name":"TokamakRequestedUnStakingAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"layer2","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokamakStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tonAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tosAmount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"specificBlock","type":"uint256"}],"name":"canRewardAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"canTokamakProcessUnStakingCount","outputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"canTokamakRequestUnStaking","outputs":[{"internalType":"uint256","name":"canUnStakingAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"canTokamakRequestUnStakingAll","outputs":[{"internalType":"bool","name":"can","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"canTokamakRequestUnStakingAllBlock","outputs":[{"internalType":"uint256","name":"_block","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkTokamak","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defiAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defiStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_amountOutMinimum","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint160","name":"_sqrtPriceLimitX96","type":"uint160"},{"internalType":"uint256","name":"_kind","type":"uint256"}],"name":"exchangeWTONtoTOS","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalBalanceTON","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalBalanceWTON","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fromTokamak","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUniswapInfo","outputs":[{"internalType":"address","name":"uniswapRouter","type":"address"},{"internalType":"address","name":"npm","type":"address"},{"internalType":"address","name":"ext","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"uniswapRouterV2","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserStaked","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"claimedBlock","type":"uint256"},{"internalType":"uint256","name":"claimedAmount","type":"uint256"},{"internalType":"uint256","name":"releasedBlock","type":"uint256"},{"internalType":"uint256","name":"releasedAmount","type":"uint256"},{"internalType":"uint256","name":"releasedTOSAmount","type":"uint256"},{"internalType":"bool","name":"released","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"infos","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[3]","name":"","type":"uint256[3]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migratedL2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseProxy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paytoken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardClaimedTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"seigManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_registry","type":"address"}],"name":"setRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"setTokamakLayer2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"toWTON","type":"bool"}],"name":"swapTONtoWTON","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swappedAmountTOS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toTokamak","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toUniswapWTON","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokamakLayer2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"tokamakProcessUnStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"},{"internalType":"uint256","name":"wtonAmount","type":"uint256"}],"name":"tokamakRequestUnStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"}],"name":"tokamakRequestUnStakingAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layer2","type":"address"},{"internalType":"uint256","name":"stakeAmount","type":"uint256"}],"name":"tokamakStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ton","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userStaked","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"claimedBlock","type":"uint256"},{"internalType":"uint256","name":"claimedAmount","type":"uint256"},{"internalType":"uint256","name":"releasedBlock","type":"uint256"},{"internalType":"uint256","name":"releasedAmount","type":"uint256"},{"internalType":"uint256","name":"releasedTOSAmount","type":"uint256"},{"internalType":"bool","name":"released","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wton","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50615d5880620000216000396000f3fe6080604052600436106103475760003560e01c806373c0db8d116101b2578063acc3a939116100ed578063e09974b911610090578063e09974b91461098f578063e58e2747146109a4578063e6a7bc87146109b9578063f0cdfa53146109ce578063fbfa77cf146109ee578063fc0c546a14610a03578063fd7fa46014610a18578063ff75878814610a2d5761036d565b8063acc3a9391461089d578063b2d4d6a3146108d0578063ca15c873146108e5578063cc48b94714610905578063ce681ce61461091a578063d53913931461093a578063d547741f1461094f578063dac3fc3f1461096f5761036d565b806392ea3b4c1161015557806392ea3b4c146107c25780639a88be2f146107d75780639d84ca35146107fe578063a1f5f50e14610813578063a217fddf14610828578063a6e8670e1461083d578063a85217561461085d578063a91ee0dc1461087d5761036d565b806373c0db8d146106d557806375829def1461070357806375b238fc146107235780637df3f40c1461073857806386989038146107585780638d62d9491461076d5780639010d07c1461078257806391d14854146107a25761036d565b806348cd4cb1116102825780636c7ac9d8116102255780636c7ac9d81461060c5780636e7cf534146106215780636ec4be90146106365780636fb7f5581461064b578063704802751461066057806371def0b31461068057806372285326146106a0578063730464a9146106b55761036d565b806348cd4cb1146105415780634e71d92d1461055657806354fd4d501461056b578063567e98f91461058d57806363a8fd89146105a257806367cf3e18146105b757806368304835146105d7578063687b53be146105ec5761036d565b8063248a9ca3116102ea578063248a9ca31461046057806324d7806c14610480578063282c51f3146104a05780632995fa0e146104b55780632f2ff15d146104ca57806336568abe146104ea5780633ccfd60b1461050a57806343b0934a1461051f5761036d565b806305871b7814610372578063065c43131461039d578063083c6323146103bf5780630ac8e0f3146103d45780630ea3d9c9146103e95780631785f53c146103fe578063200272751461041e5780632335a6b2146104335761036d565b3661036d5760405162461bcd60e51b815260040161036490615a97565b60405180910390fd5b600080fd5b34801561037e57600080fd5b50610387610a53565b6040516103949190615022565b60405180910390f35b3480156103a957600080fd5b506103bd6103b8366004614c2e565b610a59565b005b3480156103cb57600080fd5b50610387610fec565b3480156103e057600080fd5b50610387610ff2565b3480156103f557600080fd5b50610387610ff8565b34801561040a57600080fd5b506103bd610419366004614b42565b610ffe565b34801561042a57600080fd5b5061038761105d565b34801561043f57600080fd5b5061045361044e366004614b42565b611063565b6040516103949190615017565b34801561046c57600080fd5b5061038761047b366004614d23565b611208565b34801561048c57600080fd5b5061045361049b366004614b42565b61121d565b3480156104ac57600080fd5b5061038761123d565b3480156104c157600080fd5b506103bd611261565b3480156104d657600080fd5b506103bd6104e5366004614d3b565b6113e6565b3480156104f657600080fd5b506103bd610505366004614d3b565b61144d565b34801561051657600080fd5b506103bd6114ae565b34801561052b57600080fd5b50610534611c3e565b6040516103949190614ea3565b34801561054d57600080fd5b50610387611c4d565b34801561056257600080fd5b506103bd611c53565b34801561057757600080fd5b50610580611f4b565b604051610394919061502b565b34801561059957600080fd5b50610387611f76565b3480156105ae57600080fd5b50610453611f7c565b3480156105c357600080fd5b506103876105d2366004614c2e565b611f85565b3480156105e357600080fd5b506105346122db565b3480156105f857600080fd5b50610387610607366004614b42565b6122ea565b34801561061857600080fd5b5061053461240c565b34801561062d57600080fd5b5061045361241b565b34801561064257600080fd5b50610534612424565b34801561065757600080fd5b50610534612433565b34801561066c57600080fd5b506103bd61067b366004614b42565b612442565b34801561068c57600080fd5b506103bd61069b366004614b42565b61249e565b3480156106ac57600080fd5b50610387612827565b3480156106c157600080fd5b506103bd6106d0366004614b42565b61282d565b3480156106e157600080fd5b506106f56106f0366004614b42565b612a8f565b604051610394929190615bac565b34801561070f57600080fd5b506103bd61071e366004614b42565b612de3565b34801561072f57600080fd5b50610387612f04565b34801561074457600080fd5b506103bd610753366004614de9565b612f16565b34801561076457600080fd5b50610387613233565b34801561077957600080fd5b50610534613239565b34801561078e57600080fd5b5061053461079d366004614d6a565b613248565b3480156107ae57600080fd5b506104536107bd366004614d3b565b613260565b3480156107ce57600080fd5b50610534613278565b3480156107e357600080fd5b506107ec613287565b60405161039496959493929190614f3b565b34801561080a57600080fd5b506105346132dd565b34801561081f57600080fd5b506104536132f1565b34801561083457600080fd5b50610387613301565b34801561084957600080fd5b506103bd610858366004614b42565b613306565b34801561086957600080fd5b50610387610878366004614b42565b6133e2565b34801561088957600080fd5b506103bd610898366004614b42565b6134e0565b3480156108a957600080fd5b506108bd6108b8366004614b42565b6135a8565b6040516103949796959493929190615bba565b3480156108dc57600080fd5b506103876135e8565b3480156108f157600080fd5b50610387610900366004614d23565b6135ee565b34801561091157600080fd5b50610534613605565b34801561092657600080fd5b506103bd610935366004614c2e565b613614565b34801561094657600080fd5b50610387613951565b34801561095b57600080fd5b506103bd61096a366004614d3b565b613975565b34801561097b57600080fd5b506108bd61098a366004614b42565b6139ce565b34801561099b57600080fd5b50610387613a17565b3480156109b057600080fd5b50610387613a1d565b3480156109c557600080fd5b50610387613a23565b3480156109da57600080fd5b506103876109e9366004614e0d565b613a29565b3480156109fa57600080fd5b50610534614194565b348015610a0f57600080fd5b506105346141a3565b348015610a2457600080fd5b506103876141b2565b348015610a3957600080fd5b50610a426141b8565b604051610394959493929190614f0b565b60155481565b600b5415610a795760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b031680610aa75760405162461bcd60e51b81526004016103649061503e565b826001600160a01b038116610ace5760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1c57600080fd5b505afa158015610b30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b549190614d07565b610b705760405162461bcd60e51b815260040161036490615a64565b600654431115610b925760405162461bcd60e51b8152600401610364906151f3565b60008311610bb25760405162461bcd60e51b81526004016103649061580e565b6002601955610bbf611261565b60105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b158015610c0457600080fd5b505afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3c9190614dd1565b600654909150610c4c9082614257565b4310610c6a5760405162461bcd60e51b81526004016103649061525c565b6012546001600160a01b0316610c9a57601280546001600160a01b0319166001600160a01b038716179055610e1f565b600f546012546040516367265c3b60e11b81526000926001600160a01b039081169263ce4cb87692610cd492909116903090600401614ef1565b60206040518083038186803b158015610cec57600080fd5b505afa158015610d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d249190614dd1565b1180610db75750601054601254604051632638fdf560e01b81526000926001600160a01b0390811692632638fdf592610d6592909116903090600401614ef1565b60206040518083038186803b158015610d7d57600080fd5b505afa158015610d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db59190614dd1565b115b15610dee576012546001600160a01b03868116911614610de95760405162461bcd60e51b815260040161036490615634565b610e1f565b6012546001600160a01b03868116911614610e1f57601280546001600160a01b0319166001600160a01b0387161790555b600d546040516370a0823160e01b815285916001600160a01b0316906370a0823190610e4f903090600401614ea3565b60206040518083038186803b158015610e6757600080fd5b505afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190614dd1565b1015610ebd5760405162461bcd60e51b81526004016103649061571f565b601354610eca9085614299565b601355601054604051600091610ef0916001600160a01b03909116908890602001614ef1565b60408051601f1981840301815290829052600d54600e5463cae9ca5160e01b84529193506001600160a01b039081169263cae9ca5192610f3892169089908690600401614fe7565b602060405180830381600087803b158015610f5257600080fd5b505af1158015610f66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8a9190614d07565b610fa65760405162461bcd60e51b8152600401610364906154d0565b7f36f1e081b7e687a2472c2fbd52bc97993ddc788b19c74010f11e25f3c917d2dd8686604051610fd7929190614eb7565b60405180910390a150506000600b5550505050565b60065481565b60145481565b60165481565b6110073361121d565b6110425760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b61105a600080516020615cd48339815191528261144d565b50565b60045481565b6012546000906001600160a01b03161580159061108d57506012546001600160a01b038381169116145b80156110a357506010546001600160a01b031615155b80156110b95750600f546001600160a01b031615155b156112035760105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561110357600080fd5b505afa158015611117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113b9190614dd1565b600f546040516367265c3b60e11b8152919250600e8304916000916001600160a01b03169063ce4cb876906111769088903090600401614ef1565b60206040518083038186803b15801561118e57600080fd5b505afa1580156111a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c69190614dd1565b90506000811180156111f557506111f2826111ec8560065461425790919063ffffffff16565b90614257565b43115b156111ff57600193505b5050505b919050565b6000908152601c602052604090206002015490565b6000611237600080516020615cd483398151915283613260565b92915050565b7f9667e80708b6eeeb0053fa0cca44e028ff548e2a9f029edfeac87c118b08b7c881565b600d546001600160a01b0316611362576000806000806000600160009054906101000a90046001600160a01b03166001600160a01b031663a782ebd56040518163ffffffff1660e01b815260040160a06040518083038186803b1580156112c757600080fd5b505afa1580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ff9190614b5e565b600d80546001600160a01b03199081166001600160a01b0397881617909155600e805482169587169590951790945560108054851693861693909317909255600f8054841691851691909117905560118054909216921691909117905550505050505b600d546001600160a01b0316158015906113865750600e546001600160a01b031615155b801561139c5750600f546001600160a01b031615155b80156113b257506010546001600160a01b031615155b80156113c857506011546001600160a01b031615155b6113e45760405162461bcd60e51b8152600401610364906157d7565b565b6000828152601c6020526040902060020154611404906107bd6142f3565b61143f5760405162461bcd60e51b815260040180806020018281038252602f815260200180615c32602f913960400191505060405180910390fd5b61144982826142f7565b5050565b6114556142f3565b6001600160a01b0316816001600160a01b0316146114a45760405162461bcd60e51b815260040180806020018281038252602f815260200180615cf4602f913960400191505060405180910390fd5b6114498282614360565b60006006541180156114c1575043600654105b6114dd5760405162461bcd60e51b8152600401610364906159cb565b600080600080600160009054906101000a90046001600160a01b03166001600160a01b031663a782ebd56040518163ffffffff1660e01b815260040160a06040518083038186803b15801561153157600080fd5b505afa158015611545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115699190614b5e565b50929650909450925090506001600160a01b0384161580159061159457506001600160a01b03831615155b80156115a857506001600160a01b03821615155b80156115bc57506001600160a01b03811615155b6115d85760405162461bcd60e51b8152600401610364906152a5565b6012546001600160a01b031615611717576012546040516367265c3b60e11b81526001600160a01b038381169263ce4cb8769261161d92909116903090600401614ef1565b60206040518083038186803b15801561163557600080fd5b505afa158015611649573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166d9190614dd1565b1580156116fb5750601254604051632638fdf560e01b81526001600160a01b0384811692632638fdf5926116a992909116903090600401614ef1565b60206040518083038186803b1580156116c157600080fd5b505afa1580156116d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f99190614dd1565b155b6117175760405162461bcd60e51b815260040161036490615457565b336000908152600960205260409020600681015460ff161561174b5760405162461bcd60e51b8152600401610364906150ac565b601b5460ff1661193a57601b805460ff191660011790556002546001600160a01b03908116908616141561193a576000546040516370a0823160e01b81526001600160a01b03909116906370a08231906117a9903090600401614ea3565b60206040518083038186803b1580156117c157600080fd5b505afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f99190614dd1565b6016556040516370a0823160e01b81526001600160a01b038516906370a0823190611828903090600401614ea3565b60206040518083038186803b15801561184057600080fd5b505afa158015611854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118789190614dd1565b6018556040516370a0823160e01b81526001600160a01b038616906370a08231906118a7903090600401614ea3565b60206040518083038186803b1580156118bf57600080fd5b505afa1580156118d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f79190614dd1565b6017819055600854601854909161191c9161191690633b9aca006143c9565b90614299565b101561193a5760405162461bcd60e51b815260040161036490615499565b8054806119595760405162461bcd60e51b8152600401610364906156ef565b43600383015560068201805460ff191660011790556002546001600160a01b039081169087161415611a4a5760008060008060175411156119b8576119b56008546119af8660175461440b90919063ffffffff16565b906143c9565b92505b601854156119de576119db6008546119af8660185461440b90919063ffffffff16565b91505b60165415611a0457611a016008546119af8660165461440b90919063ffffffff16565b90505b600585018190558115611a2d57611a238361191684633b9aca006143c9565b6004860155611a35565b600485018390555b611a428989858585614464565b505050611bf4565b6002546001600160a01b0316611b2a578082600401541115611a7e5760405162461bcd60e51b8152600401610364906156ef565b60048201819055308031821115611aa75760405162461bcd60e51b81526004016103649061584f565b6000336001600160a01b031683604051611ac090614ea0565b60006040518083038185875af1925050503d8060008114611afd576040519150601f19603f3d011682016040523d82523d6000602084013e611b02565b606091505b5050905080611b235760405162461bcd60e51b8152600401610364906155c6565b5050611bf4565b8082600401541115611b4e5760405162461bcd60e51b8152600401610364906156ef565b600480830182905560025460405163a9059cbb60e01b81526001600160a01b039091169163a9059cbb91611b86913391869101614eb7565b602060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd89190614d07565b611bf45760405162461bcd60e51b81526004016103649061518b565b6004820154600583015460405133927fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb92611c2e92615bac565b60405180910390a2505050505050565b6002546001600160a01b031681565b60055481565b600b5415611c735760405162461bcd60e51b815260040161036490615429565b6001600b5560035460408051631718ecd760e31b815290516001600160a01b039092169163b8c766b891600480820192602092909190829003018186803b158015611cbd57600080fd5b505afa158015611cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf59190614d07565b611d115760405162461bcd60e51b8152600401610364906152dc565b336000908152600960205260408120805415801590611d3557506006548160010154105b611d515760405162461bcd60e51b815260040161036490615564565b611d5b3343611f85565b915060008211611d7d5760405162461bcd60e51b8152600401610364906150e3565b60035460405163032f7adb60e61b81526000916001600160a01b03169063cbdeb6c090611dae903090600401614ea3565b60206040518083038186803b158015611dc657600080fd5b505afa158015611dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfe9190614dd1565b905080611e168460075461429990919063ffffffff16565b1115611e345760405162461bcd60e51b815260040161036490615b0c565b4360018301556002820154611e499084614299565b6002830155600754611e5b9084614299565b600755600354604051635569f64b60e11b81526001600160a01b039091169063aad3ec9690611e909033908790600401614eb7565b602060405180830381600087803b158015611eaa57600080fd5b505af1158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee29190614d07565b611efe5760405162461bcd60e51b815260040161036490615769565b336001600160a01b03167f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a8443604051611f39929190615bac565b60405180910390a250506000600b5550565b604080518082019091526011815270383430b9b298973ab833b930b232973b1960791b602082015290565b60085481565b600c5460ff1681565b6006546000908190831115611f9a5760065492505b600554831080611fc057506001600160a01b038416600090815260096020526040902054155b80611fe757506006546001600160a01b038516600090815260096020526040902060010154115b8061200c57506001600160a01b03841660009081526009602052604090206001015483105b15612019575060006122d4565b6005546006546001600160a01b038616600090815260096020526040902060010154821015612061576001600160a01b03861660009081526009602052604090206001015491505b8085101561206c5750835b6003546040805163c1b422fd60e01b815290516000926001600160a01b03169163c1b422fd9160048083019286929190829003018186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120ec9190810190614c59565b8051909150156122d0576003546040805163d105bf8560e01b815290516000928692849283926001600160a01b03169163d105bf85916004808301926020929190829003018186803b15801561214157600080fd5b505afa158015612155573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121799190614dd1565b6001600160a01b038c166000908152600960205260408120549192508c91905b87518110156122c8578781815181106121ae57fe5b6020908102919091010151600354604051632f8deb1560e11b81529198506001600160a01b031690635f1bd62a906121ea908a90600401615022565b60206040518083038186803b15801561220257600080fd5b505afa158015612216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223a9190614dd1565b945086861115612249576122c0565b86891161228f57841561228a5760006122628a8c614257565b905061228661227f876119af866122798a8761440b565b9061440b565b8d90614299565b9b50505b6122c8565b84156122bc5760006122a1888c614257565b90506122b861227f876119af866122798a8761440b565b9b50505b8699505b600101612199565b505050505050505b5050505b9392505050565b6001546001600160a01b031681565b6012546000906001600160a01b03161580159061231457506012546001600160a01b038381169116145b801561232a5750600f546001600160a01b031615155b1561120357600f546040516367265c3b60e11b81526000916001600160a01b03169063ce4cb876906123629086903090600401614ef1565b60206040518083038186803b15801561237a57600080fd5b505afa15801561238e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b29190614dd1565b90506000811180156123c657506000600854115b80156123e2575060085481906123e090633b9aca0061440b565b105b1561240657600854612403906123fc90633b9aca0061440b565b8290614257565b91505b50919050565b6010546001600160a01b031681565b601b5460ff1681565b6011546001600160a01b031681565b600f546001600160a01b031681565b61244b3361121d565b6124865760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b61105a600080516020615cd4833981519152826113e6565b600b54156124be5760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b0316806124ec5760405162461bcd60e51b81526004016103649061503e565b816001600160a01b0381166125135760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b15801561256157600080fd5b505afa158015612575573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125999190614d07565b6125b55760405162461bcd60e51b815260040161036490615a64565b60125483906001600160a01b038083169116146125e45760405162461bcd60e51b815260040161036490615634565b6003601955601a546125f7906001614299565b601a55612602611261565b60105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561264757600080fd5b505afa15801561265b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267f9190614dd1565b600f546040516367265c3b60e11b81529192506000916001600160a01b039091169063ce4cb876906126b79089903090600401614ef1565b60206040518083038186803b1580156126cf57600080fd5b505afa1580156126e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127079190614dd1565b9050600081116127295760405162461bcd60e51b8152600401610364906151bc565b600654600e8304906127419082906111ec9086614257565b431161275f5760405162461bcd60e51b815260040161036490615881565b601054604051636b2160b760e01b81526001600160a01b0390911690636b2160b79061278f908a90600401614ea3565b602060405180830381600087803b1580156127a957600080fd5b505af11580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e19190614d07565b507fd1c4e96e0fd22936ea8aebe0b8e06b19f1c4a836b141a34cf9e925d2afb20523876040516128119190614ea3565b60405180910390a150506000600b555050505050565b60195481565b600b541561284d5760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b03168061287b5760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b1580156128c957600080fd5b505afa1580156128dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129019190614d07565b61291d5760405162461bcd60e51b815260040161036490615a64565b60125482906001600160a01b0380831691161461294c5760405162461bcd60e51b815260040161036490615634565b6005601955612959611261565b60008061296585612a8f565b909250905081158015906129795750600081115b6129955760405162461bcd60e51b81526004016103649061558f565b6014546129a29082614299565b601455601a5482116129bf57601a546129bb9083614257565b601a555b60105460405163fb0713b160e01b81526001600160a01b039091169063fb0713b1906129f49088908690600190600401614fc4565b602060405180830381600087803b158015612a0e57600080fd5b505af1158015612a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a469190614d07565b507f76d210b2dc3da8be1904d8b5da9feb5cdd21af436261626c4ec607e2123b417d85836001604051612a7b93929190614fc4565b60405180910390a150506000600b55505050565b60015460009081906001600160a01b031680612abd5760405162461bcd60e51b81526004016103649061503e565b836001600160a01b038116612ae45760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b158015612b3257600080fd5b505afa158015612b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6a9190614d07565b612b865760405162461bcd60e51b815260040161036490615a64565b60125485906001600160a01b03808316911614612bb55760405162461bcd60e51b815260040161036490615634565b601054604051636323f93760e11b8152600091829182916001600160a01b03169063c647f26e90612bec908c903090600401614ef1565b60206040518083038186803b158015612c0457600080fd5b505afa158015612c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3c9190614dd1565b601054604051635c0df46b60e01b8152919250600091612cca9184916001600160a01b0390911690635c0df46b90612c7a908f903090600401614ef1565b60206040518083038186803b158015612c9257600080fd5b505afa158015612ca6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119169190614dd1565b9050815b81811015612dc8576000806000601060009054906101000a90046001600160a01b03166001600160a01b0316638fbef2d08f30876040518463ffffffff1660e01b8152600401612d2093929190614fa0565b60606040518083038186803b158015612d3857600080fd5b505afa158015612d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d709190614d8b565b9194509250905080158015612da157506000836001600160801b0316118015612da1575043836001600160801b0316105b15612db55760019097019695810195612dbd565b505050612dc8565b505050600101612cce565b50506001600160801b03928316975050169350505050915091565b612dec3361121d565b612e275760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b6001600160a01b038116612e7d576040805162461bcd60e51b815260206004820152601860248201527741636365737369626c653a207a65726f206164647265737360401b604482015290519081900360640190fd5b336001600160a01b0382161415612ed4576040805162461bcd60e51b815260206004820152601660248201527520b1b1b2b9b9b4b136329d1039b0b6b29030b236b4b760511b604482015290519081900360640190fd5b612eec600080516020615cd4833981519152826113e6565b61105a600080516020615cd48339815191523361144d565b600080516020615cd483398151915281565b600b5415612f365760405162461bcd60e51b815260040161036490615429565b6001600b55612f43611261565b80156130ee576011546001600160a01b0316612f715760405162461bcd60e51b815260040161036490615156565b600d546040516370a0823160e01b815283916001600160a01b0316906370a0823190612fa1903090600401614ea3565b60206040518083038186803b158015612fb957600080fd5b505afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190614dd1565b101561300f5760405162461bcd60e51b815260040161036490615341565b601154604051600091613032916001600160a01b03909116908190602001614ef1565b60408051601f1981840301815290829052600d54600e5463cae9ca5160e01b84529193506001600160a01b039081169263cae9ca519261307a92169087908690600401614fe7565b602060405180830381600087803b15801561309457600080fd5b505af11580156130a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130cc9190614d07565b6130e85760405162461bcd60e51b8152600401610364906156a0565b5061322a565b600e546040516370a0823160e01b815283916001600160a01b0316906370a082319061311e903090600401614ea3565b60206040518083038186803b15801561313657600080fd5b505afa15801561314a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061316e9190614dd1565b101561318c5760405162461bcd60e51b8152600401610364906153d0565b600e5460405163f53fe70f60e01b81526001600160a01b039091169063f53fe70f906131bc908590600401615022565b602060405180830381600087803b1580156131d657600080fd5b505af11580156131ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320e9190614d07565b61322a5760405162461bcd60e51b8152600401610364906157a0565b50506000600b55565b600a5481565b600e546001600160a01b031681565b6000828152601c602052604081206122d4908361482b565b6000828152601c602052604081206122d49083614837565b6012546001600160a01b031681565b600080613292614b0d565b5050600254600354604080516060810182526004548152600554602082015260065491810191909152600754600854600a546001600160a01b03958616979590941695509193909290565b600c5461010090046001600160a01b031681565b600c54600160a81b900460ff1681565b600081565b61330f3361121d565b61334a5760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b6001600160a01b0381161580159061337057506012546001600160a01b03828116911614155b61338c5760405162461bcd60e51b815260040161036490615115565b601280546001600160a01b0319166001600160a01b0383161790556040517fbcf2b04f5517cca822ae60e21bb6e3889b8d8307ea062c5266c63a014386c990906133d7908390614ea3565b60405180910390a150565b6012546000906001600160a01b03161580159061340c57506012546001600160a01b038381169116145b801561342257506010546001600160a01b031615155b156112035760105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561346c57600080fd5b505afa158015613480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a49190614dd1565b9050600e81046134b48282614299565b60065411156134d9576134d6816111ec8460065461425790919063ffffffff16565b92505b5050919050565b6134e93361121d565b6135245760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b806001600160a01b03811661354b5760405162461bcd60e51b81526004016103649061503e565b600180546001600160a01b0319166001600160a01b0384811691909117918290556040517f278c70ced5f3e0e5eeb385b5ff9cb735748ba00a625147e66065ed48fc1562cd9261359c921690614ea3565b60405180910390a15050565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919060ff1687565b60075481565b6000818152601c602052604081206112379061484c565b600d546001600160a01b031681565b600b54156136345760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b0316806136625760405162461bcd60e51b81526004016103649061503e565b826001600160a01b0381166136895760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b1580156136d757600080fd5b505afa1580156136eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370f9190614d07565b61372b5760405162461bcd60e51b815260040161036490615a64565b60125484906001600160a01b0380831691161461375a5760405162461bcd60e51b815260040161036490615634565b6003601955601a5461376d906001614299565b601a55613778611261565b600f546040516367265c3b60e11b81526000916001600160a01b03169063ce4cb876906137ab9089903090600401614ef1565b60206040518083038186803b1580156137c357600080fd5b505afa1580156137d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137fb9190614dd1565b90506000811161381d5760405162461bcd60e51b8152600401610364906151bc565b60085460009061383190633b9aca0061440b565b90506000808211801561384d575061384a836064614257565b82105b156138645761386160646111ec8585614257565b90505b600081116138845760405162461bcd60e51b81526004016103649061594a565b60105460405163da95ebf760e01b81526001600160a01b039091169063da95ebf7906138b6908b908590600401614eb7565b602060405180830381600087803b1580156138d057600080fd5b505af11580156138e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139089190614d07565b507f2a23e23c116b511f71c9f0c2648b0372e6bbcb1f559a7cbfaed5c55933ea6c4e888260405161393a929190614eb7565b60405180910390a150506000600b55505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6000828152601c6020526040902060020154613993906107bd6142f3565b6114a45760405162461bcd60e51b8152600401808060200182810382526030815260200180615c836030913960400191505060405180910390fd5b6001600160a01b03166000908152600960205260409020805460018201546002830154600384015460048501546005860154600690960154949693959294919390929160ff1690565b601a5481565b60175481565b60185481565b6000600b54600014613a4d5760405162461bcd60e51b815260040161036490615429565b6001600b5560035460408051631718ecd760e31b815290516001600160a01b039092169163b8c766b891600480820192602092909190829003018186803b158015613a9757600080fd5b505afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614d07565b613aeb5760405162461bcd60e51b815260040161036490615a64565b600654431115613b0d5760405162461bcd60e51b815260040161036490615998565b60028210613b2d5760405162461bcd60e51b815260040161036490615909565b613b35611261565b600e546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613b66903090600401614ea3565b60206040518083038186803b158015613b7e57600080fd5b505afa158015613b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb69190614dd1565b600d546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190613bec903090600401614ea3565b60206040518083038186803b158015613c0457600080fd5b505afa158015613c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c3c9190614dd1565b6012549091506000906001600160a01b031615613d7057600f546012546040516367265c3b60e11b81526001600160a01b039283169263ce4cb87692613c89929116903090600401614ef1565b60206040518083038186803b158015613ca157600080fd5b505afa158015613cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd99190614dd1565b601054601254604051632638fdf560e01b8152929350613d6d926001600160a01b0392831692632638fdf592613d16929116903090600401614ef1565b60206040518083038186803b158015613d2e57600080fd5b505afa158015613d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d669190614dd1565b8290614299565b90505b828215613d8b57613d88613d6684633b9aca0061440b565b90505b89811015613dab5760405162461bcd60e51b81526004016103649061566b565b8115613dbe57613dbb8183614299565b90505b600854613dcf90633b9aca0061440b565b81118015613dff575089613dfc613df5633b9aca0060085461440b90919063ffffffff16565b8390614257565b10155b613e1b5760405162461bcd60e51b8152600401610364906155fd565b89841015613f1757601154604051600091613e46916001600160a01b03909116908190602001614ef1565b60408051601f1981840301815291905290506000613e6c633b9aca006119af8e89614257565b600d54600e5460405163cae9ca5160e01b81529293506001600160a01b039182169263cae9ca5192613ea692169085908790600401614fe7565b602060405180830381600087803b158015613ec057600080fd5b505af1158015613ed4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef89190614d07565b613f145760405162461bcd60e51b815260040161036490615511565b50505b5050601554613f299250905087614299565b60155560015460408051630141158f60e61b8152905160009283926001600160a01b039091169163504563c09160048082019260a092909190829003018186803b158015613f7657600080fd5b505afa158015613f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fae9190614bd2565b5092945091925050506001600160a01b038216613fdd5760405162461bcd60e51b815260040161036490615075565b600e5460405163095ea7b360e01b81526001600160a01b039091169063095ea7b39061400f9085908c90600401614eb7565b602060405180830381600087803b15801561402957600080fd5b505af115801561403d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140619190614d07565b61407d5760405162461bcd60e51b815260040161036490615ac3565b6040805161010081018252600e546001600160a01b0390811682526000548116602083015262ffffff8416828401523060608301526080820189905260a082018b905260c082018a905287811660e0830152915163414bf38960e01b8152909184169063414bf389906140f4908490600401615b43565b602060405180830381600087803b15801561410e57600080fd5b505af1158015614122573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141469190614dd1565b93507f6ad50db5d488c314f9077fc5c41c7d8bcdd86ddc409871512ddd009f21067d32338a8660405161417b93929190614ed0565b60405180910390a150506000600b555095945050505050565b6003546001600160a01b031681565b6000546001600160a01b031681565b60135481565b6000806000806000600160009054906101000a90046001600160a01b03166001600160a01b031663504563c06040518163ffffffff1660e01b815260040160a06040518083038186803b15801561420e57600080fd5b505afa158015614222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142469190614bd2565b945094509450945094509091929394565b60006122d483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614857565b6000828201838110156122d4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6000828152601c6020526040902061430f90826148ee565b156114495761431c6142f3565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152601c602052604090206143789082614903565b15611449576143856142f3565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006122d483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614918565b60008261441a57506000611237565b8282028284828161442757fe5b04146122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180615cb36021913960400191505060405180910390fd5b82156145a2576040516370a0823160e01b815283906001600160a01b038716906370a0823190614498903090600401614ea3565b60206040518083038186803b1580156144b057600080fd5b505afa1580156144c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144e89190614dd1565b10156145065760405162461bcd60e51b815260040161036490615a2d565b60405163a9059cbb60e01b81526001600160a01b0386169063a9059cbb906145349033908790600401614eb7565b602060405180830381600087803b15801561454e57600080fd5b505af1158015614562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145869190614d07565b6145a25760405162461bcd60e51b81526004016103649061530a565b81156146e0576040516370a0823160e01b815282906001600160a01b038616906370a08231906145d6903090600401614ea3565b60206040518083038186803b1580156145ee57600080fd5b505afa158015614602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146269190614dd1565b10156146445760405162461bcd60e51b8152600401610364906159f6565b60405163e3b99e8560e01b81526001600160a01b0385169063e3b99e85906146729033908690600401614eb7565b602060405180830381600087803b15801561468c57600080fd5b505af11580156146a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146c49190614d07565b6146e05760405162461bcd60e51b815260040161036490615399565b8015614824576000546040516370a0823160e01b815282916001600160a01b0316906370a0823190614716903090600401614ea3565b60206040518083038186803b15801561472e57600080fd5b505afa158015614742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147669190614dd1565b10156147845760405162461bcd60e51b8152600401610364906158d2565b60005460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906147b69033908590600401614eb7565b602060405180830381600087803b1580156147d057600080fd5b505af11580156147e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148089190614d07565b6148245760405162461bcd60e51b815260040161036490615225565b5050505050565b60006122d4838361497d565b60006122d4836001600160a01b0384166149e1565b6000611237826149f9565b600081848411156148e65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148ab578181015183820152602001614893565b50505050905090810190601f1680156148d85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006122d4836001600160a01b0384166149fd565b60006122d4836001600160a01b038416614a47565b600081836149675760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156148ab578181015183820152602001614893565b50600083858161497357fe5b0495945050505050565b815460009082106149bf5760405162461bcd60e51b8152600401808060200182810382526022815260200180615c106022913960400191505060405180910390fd5b8260000182815481106149ce57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000614a0983836149e1565b614a3f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611237565b506000611237565b60008181526001830160205260408120548015614b035783546000198083019190810190600090879083908110614a7a57fe5b9060005260206000200154905080876000018481548110614a9757fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614ac757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611237565b6000915050611237565b60405180606001604052806003906020820280368337509192915050565b80516001600160801b038116811461120357600080fd5b600060208284031215614b53578081fd5b81356122d481615bec565b600080600080600060a08688031215614b75578081fd5b8551614b8081615bec565b6020870151909550614b9181615bec565b6040870151909450614ba281615bec565b6060870151909350614bb381615bec565b6080870151909250614bc481615bec565b809150509295509295909350565b600080600080600060a08688031215614be9578081fd5b8551614bf481615bec565b6020870151909550614c0581615bec565b6040870151909450614c1681615bec565b606087015160808801519194509250614bc481615bec565b60008060408385031215614c40578182fd5b8235614c4b81615bec565b946020939093013593505050565b60006020808385031215614c6b578182fd5b825167ffffffffffffffff80821115614c82578384fd5b818501915085601f830112614c95578384fd5b815181811115614ca157fe5b83810260405185828201018181108582111715614cba57fe5b604052828152858101935084860182860187018a1015614cd8578788fd5b8795505b83861015614cfa578051855260019590950194938601938601614cdc565b5098975050505050505050565b600060208284031215614d18578081fd5b81516122d481615c01565b600060208284031215614d34578081fd5b5035919050565b60008060408385031215614d4d578182fd5b823591506020830135614d5f81615bec565b809150509250929050565b60008060408385031215614d7c578182fd5b50508035926020909101359150565b600080600060608486031215614d9f578283fd5b614da884614b2b565b9250614db660208501614b2b565b91506040840151614dc681615c01565b809150509250925092565b600060208284031215614de2578081fd5b5051919050565b60008060408385031215614dfb578182fd5b823591506020830135614d5f81615c01565b600080600080600060a08688031215614e24578283fd5b8535945060208601359350604086013592506060860135614e4481615bec565b949793965091946080013592915050565b60008151808452815b81811015614e7a57602081850181015186830182015201614e5e565b81811115614e8b5782602083870101525b50601f01601f19169290920160200192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039586168152938516602085015291841660408401526060830152909116608082015260a00190565b6001600160a01b038781168252861660208083019190915261010082019060408301908760005b6003811015614f7f57815184529282019290820190600101614f62565b505050508460a08301528360c08301528260e0830152979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060018060a01b03851682528360208301526060604083015261500e6060830184614e55565b95945050505050565b901515815260200190565b90815260200190565b6000602082526122d46020830184614e55565b6020808252601b908201527f546f6b616d616b5374616b65723a207a65726f20616464726573730000000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a756e6973776170207a65726f000000000000604082015260600190565b6020808252601a908201527f5374616b65544f4e3a20416c7265616479207769746864726177000000000000604082015260600190565b6020808252601890820152775374616b65544f4e3a20726577617264206973207a65726f60401b604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a746f6b616d616b4c6179657232207a65726f6040820152600160fd1b606082015260800190565b6020808252818101527f546f6b616d616b5374616b65723a207377617050726f7879206973207a65726f604082015260600190565b60208082526017908201527614dd185ad95513d38e881d1c985b9cd9995c8819985a5b604a1b604082015260600190565b6020808252601e908201527f546f6b616d616b5374616b65723a207374616b654f66206973207a65726f0000604082015260600190565b602080825260189082015277151bdad85b585ad4dd185ad95c8e9c195c9a5bd908195b9960421b604082015260600190565b6020808252601b908201527f5374616b65544f4e3a207472616e7366657220746f73206661696c0000000000604082015260600190565b60208082526029908201527f546f6b616d616b5374616b65723a706572696f64287769746864726177616c44604082015268195b185e4a48195b9960ba1b606082015260800190565b6020808252601f908201527f5374616b65544f4e3a2049546f6b616d616b5265676973747279207a65726f00604082015260600190565b60208082526014908201527314dd185ad95513d38e881b9bdd0818db1bdcd95960621b604082015260600190565b6020808252601b908201527f5374616b65544f4e3a207472616e7366657220746f6e206661696c0000000000604082015260600190565b60208082526038908201527f546f6b616d616b5374616b65723a2073776170544f4e746f57544f4e20746f6e6040820152770818985b185b98d9481a5cc81a5b9cdd59999a58da595b9d60421b606082015260800190565b6020808252601c908201527f5374616b65544f4e3a207472616e736665722077746f6e206661696c00000000604082015260600190565b60208082526039908201527f546f6b616d616b5374616b65723a2073776170544f4e746f57544f4e2077746f6040820152781b8818985b185b98d9481a5cc81a5b9cdd59999a58da595b9d603a1b606082015260800190565b602080825260149082015273151bdad85b585ad4dd185ad95c8e9313d0d2d15160621b604082015260600190565b60208082526022908201527f5374616b65544f4e3a2072656d61696e20616d6f756e7420696e20746f6b616d604082015261616b60f01b606082015260800190565b6020808252601e908201527f5374616b65544f4e3a2066696e616c42616c616e6365206973206c61636b0000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a617070726f7665416e6443616c6c206661696040820152601b60fa1b606082015260800190565b60208082526033908201527f546f6b616d616b5374616b65723a65786368616e676557544f4e746f544f5320604082015272185c1c1c9bdd99505b9910d85b1b0819985a5b606a1b606082015260800190565b60208082526011908201527014dd185ad95513d38e8818db185a5b5959607a1b604082015260600190565b6020808252601e908201527f546f6b616d616b5374616b65723a206e6f2061626c6520726571756573740000604082015260600190565b6020808252601a908201527f5374616b65544f4e3a207769746864726177206661696c65642e000000000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a696e73756666696369656e74000000000000604082015260600190565b6020808252601d908201527f546f6b616d616b5374616b65723a646966666572656e74206c61796572000000604082015260600190565b6020808252818101527f546f6b616d616b5374616b65723a2077746f6e20696e73756666696369656e74604082015260600190565b6020808252602f908201527f546f6b616d616b5374616b65723a73776170544f4e746f57544f4e206170707260408201526e1bdd99505b9910d85b1b0819985a5b608a1b606082015260800190565b6020808252601690820152755374616b65544f4e3a20416d6f756e742077726f6e6760501b604082015260600190565b6020808252602a908201527f546f6b616d616b5374616b65723a20746f6e2062616c616e636520697320696e6040820152691cdd59999a58da595b9d60b21b606082015260800190565b6020808252601f908201527f5374616b65544f4e3a206661696c20636c61696d2066726f6d207661756c7400604082015260600190565b6020808252601c908201527f546f6b616d616b5374616b65723a73776170546f544f4e206661696c00000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a746f6b616d616b207a65726f000000000000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a7374616b65416d6f756e74206973207a65726040820152606f60f81b606082015260800190565b6020808252601890820152770a6e8c2d6caa89e9c7440d2dce6eaccccd2cadce8408aa8960431b604082015260600190565b60208082526031908201527f546f6b616d616b5374616b65723a5468652065786563757461626c6520626c6f60408201527018dac81a185cc81b9bdd081c185cdcd959607a1b606082015260800190565b6020808252601d908201527f5374616b65544f4e3a20746f732062616c616e6365206973206c61636b000000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a206e6f7420617661696c61626c65206b696e6040820152601960fa1b606082015260800190565b6020808252602e908201527f546f6b616d616b5374616b65723a206e6f2077697468647261772d61626c652060408201526d185b5bdd5b9d081b9bdd081e595d60921b606082015260800190565b602080825260199082015278151bdad85b585ad4dd185ad95c8e881c195c9a5bd908195b99603a1b604082015260600190565b60208082526011908201527014dd185ad95513d38e881b9bdd08195b99607a1b604082015260600190565b6020808252601e908201527f5374616b65544f4e3a2077746f6e2062616c616e6365206973206c61636b0000604082015260600190565b6020808252601d908201527f5374616b65544f4e3a20746f6e2062616c616e6365206973206c61636b000000604082015260600190565b602080825260199082015278151bdad85b585ad4dd185ad95c8e881b9bdd0818db1bdcd959603a1b604082015260600190565b60208082526012908201527131b0b73737ba1039ba30b5b29022ba3432b960711b604082015260600190565b60208082526029908201527f546f6b616d616b5374616b65723a63616e277420617070726f766520756e69736040820152683bb0b82937baba32b960b91b606082015260800190565b6020808252601e908201527f5374616b65544f4e3a20746f74616c2072657761726420657863656564730000604082015260600190565b81516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b918252602082015260400190565b968752602087019590955260408601939093526060850191909152608084015260a0830152151560c082015260e00190565b6001600160a01b038116811461105a57600080fd5b801515811461105a57600080fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7441636365737369626c653a2043616c6c6572206973206e6f7420616e2061646d696e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77df8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212209716ba2067000c8d0c4e48dbda1972d1435530379c877c5bb4fbd02f67dce82564736f6c63430007060033
Deployed Bytecode
0x6080604052600436106103475760003560e01c806373c0db8d116101b2578063acc3a939116100ed578063e09974b911610090578063e09974b91461098f578063e58e2747146109a4578063e6a7bc87146109b9578063f0cdfa53146109ce578063fbfa77cf146109ee578063fc0c546a14610a03578063fd7fa46014610a18578063ff75878814610a2d5761036d565b8063acc3a9391461089d578063b2d4d6a3146108d0578063ca15c873146108e5578063cc48b94714610905578063ce681ce61461091a578063d53913931461093a578063d547741f1461094f578063dac3fc3f1461096f5761036d565b806392ea3b4c1161015557806392ea3b4c146107c25780639a88be2f146107d75780639d84ca35146107fe578063a1f5f50e14610813578063a217fddf14610828578063a6e8670e1461083d578063a85217561461085d578063a91ee0dc1461087d5761036d565b806373c0db8d146106d557806375829def1461070357806375b238fc146107235780637df3f40c1461073857806386989038146107585780638d62d9491461076d5780639010d07c1461078257806391d14854146107a25761036d565b806348cd4cb1116102825780636c7ac9d8116102255780636c7ac9d81461060c5780636e7cf534146106215780636ec4be90146106365780636fb7f5581461064b578063704802751461066057806371def0b31461068057806372285326146106a0578063730464a9146106b55761036d565b806348cd4cb1146105415780634e71d92d1461055657806354fd4d501461056b578063567e98f91461058d57806363a8fd89146105a257806367cf3e18146105b757806368304835146105d7578063687b53be146105ec5761036d565b8063248a9ca3116102ea578063248a9ca31461046057806324d7806c14610480578063282c51f3146104a05780632995fa0e146104b55780632f2ff15d146104ca57806336568abe146104ea5780633ccfd60b1461050a57806343b0934a1461051f5761036d565b806305871b7814610372578063065c43131461039d578063083c6323146103bf5780630ac8e0f3146103d45780630ea3d9c9146103e95780631785f53c146103fe578063200272751461041e5780632335a6b2146104335761036d565b3661036d5760405162461bcd60e51b815260040161036490615a97565b60405180910390fd5b600080fd5b34801561037e57600080fd5b50610387610a53565b6040516103949190615022565b60405180910390f35b3480156103a957600080fd5b506103bd6103b8366004614c2e565b610a59565b005b3480156103cb57600080fd5b50610387610fec565b3480156103e057600080fd5b50610387610ff2565b3480156103f557600080fd5b50610387610ff8565b34801561040a57600080fd5b506103bd610419366004614b42565b610ffe565b34801561042a57600080fd5b5061038761105d565b34801561043f57600080fd5b5061045361044e366004614b42565b611063565b6040516103949190615017565b34801561046c57600080fd5b5061038761047b366004614d23565b611208565b34801561048c57600080fd5b5061045361049b366004614b42565b61121d565b3480156104ac57600080fd5b5061038761123d565b3480156104c157600080fd5b506103bd611261565b3480156104d657600080fd5b506103bd6104e5366004614d3b565b6113e6565b3480156104f657600080fd5b506103bd610505366004614d3b565b61144d565b34801561051657600080fd5b506103bd6114ae565b34801561052b57600080fd5b50610534611c3e565b6040516103949190614ea3565b34801561054d57600080fd5b50610387611c4d565b34801561056257600080fd5b506103bd611c53565b34801561057757600080fd5b50610580611f4b565b604051610394919061502b565b34801561059957600080fd5b50610387611f76565b3480156105ae57600080fd5b50610453611f7c565b3480156105c357600080fd5b506103876105d2366004614c2e565b611f85565b3480156105e357600080fd5b506105346122db565b3480156105f857600080fd5b50610387610607366004614b42565b6122ea565b34801561061857600080fd5b5061053461240c565b34801561062d57600080fd5b5061045361241b565b34801561064257600080fd5b50610534612424565b34801561065757600080fd5b50610534612433565b34801561066c57600080fd5b506103bd61067b366004614b42565b612442565b34801561068c57600080fd5b506103bd61069b366004614b42565b61249e565b3480156106ac57600080fd5b50610387612827565b3480156106c157600080fd5b506103bd6106d0366004614b42565b61282d565b3480156106e157600080fd5b506106f56106f0366004614b42565b612a8f565b604051610394929190615bac565b34801561070f57600080fd5b506103bd61071e366004614b42565b612de3565b34801561072f57600080fd5b50610387612f04565b34801561074457600080fd5b506103bd610753366004614de9565b612f16565b34801561076457600080fd5b50610387613233565b34801561077957600080fd5b50610534613239565b34801561078e57600080fd5b5061053461079d366004614d6a565b613248565b3480156107ae57600080fd5b506104536107bd366004614d3b565b613260565b3480156107ce57600080fd5b50610534613278565b3480156107e357600080fd5b506107ec613287565b60405161039496959493929190614f3b565b34801561080a57600080fd5b506105346132dd565b34801561081f57600080fd5b506104536132f1565b34801561083457600080fd5b50610387613301565b34801561084957600080fd5b506103bd610858366004614b42565b613306565b34801561086957600080fd5b50610387610878366004614b42565b6133e2565b34801561088957600080fd5b506103bd610898366004614b42565b6134e0565b3480156108a957600080fd5b506108bd6108b8366004614b42565b6135a8565b6040516103949796959493929190615bba565b3480156108dc57600080fd5b506103876135e8565b3480156108f157600080fd5b50610387610900366004614d23565b6135ee565b34801561091157600080fd5b50610534613605565b34801561092657600080fd5b506103bd610935366004614c2e565b613614565b34801561094657600080fd5b50610387613951565b34801561095b57600080fd5b506103bd61096a366004614d3b565b613975565b34801561097b57600080fd5b506108bd61098a366004614b42565b6139ce565b34801561099b57600080fd5b50610387613a17565b3480156109b057600080fd5b50610387613a1d565b3480156109c557600080fd5b50610387613a23565b3480156109da57600080fd5b506103876109e9366004614e0d565b613a29565b3480156109fa57600080fd5b50610534614194565b348015610a0f57600080fd5b506105346141a3565b348015610a2457600080fd5b506103876141b2565b348015610a3957600080fd5b50610a426141b8565b604051610394959493929190614f0b565b60155481565b600b5415610a795760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b031680610aa75760405162461bcd60e51b81526004016103649061503e565b826001600160a01b038116610ace5760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1c57600080fd5b505afa158015610b30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b549190614d07565b610b705760405162461bcd60e51b815260040161036490615a64565b600654431115610b925760405162461bcd60e51b8152600401610364906151f3565b60008311610bb25760405162461bcd60e51b81526004016103649061580e565b6002601955610bbf611261565b60105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b158015610c0457600080fd5b505afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3c9190614dd1565b600654909150610c4c9082614257565b4310610c6a5760405162461bcd60e51b81526004016103649061525c565b6012546001600160a01b0316610c9a57601280546001600160a01b0319166001600160a01b038716179055610e1f565b600f546012546040516367265c3b60e11b81526000926001600160a01b039081169263ce4cb87692610cd492909116903090600401614ef1565b60206040518083038186803b158015610cec57600080fd5b505afa158015610d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d249190614dd1565b1180610db75750601054601254604051632638fdf560e01b81526000926001600160a01b0390811692632638fdf592610d6592909116903090600401614ef1565b60206040518083038186803b158015610d7d57600080fd5b505afa158015610d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db59190614dd1565b115b15610dee576012546001600160a01b03868116911614610de95760405162461bcd60e51b815260040161036490615634565b610e1f565b6012546001600160a01b03868116911614610e1f57601280546001600160a01b0319166001600160a01b0387161790555b600d546040516370a0823160e01b815285916001600160a01b0316906370a0823190610e4f903090600401614ea3565b60206040518083038186803b158015610e6757600080fd5b505afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190614dd1565b1015610ebd5760405162461bcd60e51b81526004016103649061571f565b601354610eca9085614299565b601355601054604051600091610ef0916001600160a01b03909116908890602001614ef1565b60408051601f1981840301815290829052600d54600e5463cae9ca5160e01b84529193506001600160a01b039081169263cae9ca5192610f3892169089908690600401614fe7565b602060405180830381600087803b158015610f5257600080fd5b505af1158015610f66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8a9190614d07565b610fa65760405162461bcd60e51b8152600401610364906154d0565b7f36f1e081b7e687a2472c2fbd52bc97993ddc788b19c74010f11e25f3c917d2dd8686604051610fd7929190614eb7565b60405180910390a150506000600b5550505050565b60065481565b60145481565b60165481565b6110073361121d565b6110425760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b61105a600080516020615cd48339815191528261144d565b50565b60045481565b6012546000906001600160a01b03161580159061108d57506012546001600160a01b038381169116145b80156110a357506010546001600160a01b031615155b80156110b95750600f546001600160a01b031615155b156112035760105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561110357600080fd5b505afa158015611117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113b9190614dd1565b600f546040516367265c3b60e11b8152919250600e8304916000916001600160a01b03169063ce4cb876906111769088903090600401614ef1565b60206040518083038186803b15801561118e57600080fd5b505afa1580156111a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c69190614dd1565b90506000811180156111f557506111f2826111ec8560065461425790919063ffffffff16565b90614257565b43115b156111ff57600193505b5050505b919050565b6000908152601c602052604090206002015490565b6000611237600080516020615cd483398151915283613260565b92915050565b7f9667e80708b6eeeb0053fa0cca44e028ff548e2a9f029edfeac87c118b08b7c881565b600d546001600160a01b0316611362576000806000806000600160009054906101000a90046001600160a01b03166001600160a01b031663a782ebd56040518163ffffffff1660e01b815260040160a06040518083038186803b1580156112c757600080fd5b505afa1580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ff9190614b5e565b600d80546001600160a01b03199081166001600160a01b0397881617909155600e805482169587169590951790945560108054851693861693909317909255600f8054841691851691909117905560118054909216921691909117905550505050505b600d546001600160a01b0316158015906113865750600e546001600160a01b031615155b801561139c5750600f546001600160a01b031615155b80156113b257506010546001600160a01b031615155b80156113c857506011546001600160a01b031615155b6113e45760405162461bcd60e51b8152600401610364906157d7565b565b6000828152601c6020526040902060020154611404906107bd6142f3565b61143f5760405162461bcd60e51b815260040180806020018281038252602f815260200180615c32602f913960400191505060405180910390fd5b61144982826142f7565b5050565b6114556142f3565b6001600160a01b0316816001600160a01b0316146114a45760405162461bcd60e51b815260040180806020018281038252602f815260200180615cf4602f913960400191505060405180910390fd5b6114498282614360565b60006006541180156114c1575043600654105b6114dd5760405162461bcd60e51b8152600401610364906159cb565b600080600080600160009054906101000a90046001600160a01b03166001600160a01b031663a782ebd56040518163ffffffff1660e01b815260040160a06040518083038186803b15801561153157600080fd5b505afa158015611545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115699190614b5e565b50929650909450925090506001600160a01b0384161580159061159457506001600160a01b03831615155b80156115a857506001600160a01b03821615155b80156115bc57506001600160a01b03811615155b6115d85760405162461bcd60e51b8152600401610364906152a5565b6012546001600160a01b031615611717576012546040516367265c3b60e11b81526001600160a01b038381169263ce4cb8769261161d92909116903090600401614ef1565b60206040518083038186803b15801561163557600080fd5b505afa158015611649573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166d9190614dd1565b1580156116fb5750601254604051632638fdf560e01b81526001600160a01b0384811692632638fdf5926116a992909116903090600401614ef1565b60206040518083038186803b1580156116c157600080fd5b505afa1580156116d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f99190614dd1565b155b6117175760405162461bcd60e51b815260040161036490615457565b336000908152600960205260409020600681015460ff161561174b5760405162461bcd60e51b8152600401610364906150ac565b601b5460ff1661193a57601b805460ff191660011790556002546001600160a01b03908116908616141561193a576000546040516370a0823160e01b81526001600160a01b03909116906370a08231906117a9903090600401614ea3565b60206040518083038186803b1580156117c157600080fd5b505afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f99190614dd1565b6016556040516370a0823160e01b81526001600160a01b038516906370a0823190611828903090600401614ea3565b60206040518083038186803b15801561184057600080fd5b505afa158015611854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118789190614dd1565b6018556040516370a0823160e01b81526001600160a01b038616906370a08231906118a7903090600401614ea3565b60206040518083038186803b1580156118bf57600080fd5b505afa1580156118d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f79190614dd1565b6017819055600854601854909161191c9161191690633b9aca006143c9565b90614299565b101561193a5760405162461bcd60e51b815260040161036490615499565b8054806119595760405162461bcd60e51b8152600401610364906156ef565b43600383015560068201805460ff191660011790556002546001600160a01b039081169087161415611a4a5760008060008060175411156119b8576119b56008546119af8660175461440b90919063ffffffff16565b906143c9565b92505b601854156119de576119db6008546119af8660185461440b90919063ffffffff16565b91505b60165415611a0457611a016008546119af8660165461440b90919063ffffffff16565b90505b600585018190558115611a2d57611a238361191684633b9aca006143c9565b6004860155611a35565b600485018390555b611a428989858585614464565b505050611bf4565b6002546001600160a01b0316611b2a578082600401541115611a7e5760405162461bcd60e51b8152600401610364906156ef565b60048201819055308031821115611aa75760405162461bcd60e51b81526004016103649061584f565b6000336001600160a01b031683604051611ac090614ea0565b60006040518083038185875af1925050503d8060008114611afd576040519150601f19603f3d011682016040523d82523d6000602084013e611b02565b606091505b5050905080611b235760405162461bcd60e51b8152600401610364906155c6565b5050611bf4565b8082600401541115611b4e5760405162461bcd60e51b8152600401610364906156ef565b600480830182905560025460405163a9059cbb60e01b81526001600160a01b039091169163a9059cbb91611b86913391869101614eb7565b602060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd89190614d07565b611bf45760405162461bcd60e51b81526004016103649061518b565b6004820154600583015460405133927fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb92611c2e92615bac565b60405180910390a2505050505050565b6002546001600160a01b031681565b60055481565b600b5415611c735760405162461bcd60e51b815260040161036490615429565b6001600b5560035460408051631718ecd760e31b815290516001600160a01b039092169163b8c766b891600480820192602092909190829003018186803b158015611cbd57600080fd5b505afa158015611cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf59190614d07565b611d115760405162461bcd60e51b8152600401610364906152dc565b336000908152600960205260408120805415801590611d3557506006548160010154105b611d515760405162461bcd60e51b815260040161036490615564565b611d5b3343611f85565b915060008211611d7d5760405162461bcd60e51b8152600401610364906150e3565b60035460405163032f7adb60e61b81526000916001600160a01b03169063cbdeb6c090611dae903090600401614ea3565b60206040518083038186803b158015611dc657600080fd5b505afa158015611dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfe9190614dd1565b905080611e168460075461429990919063ffffffff16565b1115611e345760405162461bcd60e51b815260040161036490615b0c565b4360018301556002820154611e499084614299565b6002830155600754611e5b9084614299565b600755600354604051635569f64b60e11b81526001600160a01b039091169063aad3ec9690611e909033908790600401614eb7565b602060405180830381600087803b158015611eaa57600080fd5b505af1158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee29190614d07565b611efe5760405162461bcd60e51b815260040161036490615769565b336001600160a01b03167f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a8443604051611f39929190615bac565b60405180910390a250506000600b5550565b604080518082019091526011815270383430b9b298973ab833b930b232973b1960791b602082015290565b60085481565b600c5460ff1681565b6006546000908190831115611f9a5760065492505b600554831080611fc057506001600160a01b038416600090815260096020526040902054155b80611fe757506006546001600160a01b038516600090815260096020526040902060010154115b8061200c57506001600160a01b03841660009081526009602052604090206001015483105b15612019575060006122d4565b6005546006546001600160a01b038616600090815260096020526040902060010154821015612061576001600160a01b03861660009081526009602052604090206001015491505b8085101561206c5750835b6003546040805163c1b422fd60e01b815290516000926001600160a01b03169163c1b422fd9160048083019286929190829003018186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120ec9190810190614c59565b8051909150156122d0576003546040805163d105bf8560e01b815290516000928692849283926001600160a01b03169163d105bf85916004808301926020929190829003018186803b15801561214157600080fd5b505afa158015612155573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121799190614dd1565b6001600160a01b038c166000908152600960205260408120549192508c91905b87518110156122c8578781815181106121ae57fe5b6020908102919091010151600354604051632f8deb1560e11b81529198506001600160a01b031690635f1bd62a906121ea908a90600401615022565b60206040518083038186803b15801561220257600080fd5b505afa158015612216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223a9190614dd1565b945086861115612249576122c0565b86891161228f57841561228a5760006122628a8c614257565b905061228661227f876119af866122798a8761440b565b9061440b565b8d90614299565b9b50505b6122c8565b84156122bc5760006122a1888c614257565b90506122b861227f876119af866122798a8761440b565b9b50505b8699505b600101612199565b505050505050505b5050505b9392505050565b6001546001600160a01b031681565b6012546000906001600160a01b03161580159061231457506012546001600160a01b038381169116145b801561232a5750600f546001600160a01b031615155b1561120357600f546040516367265c3b60e11b81526000916001600160a01b03169063ce4cb876906123629086903090600401614ef1565b60206040518083038186803b15801561237a57600080fd5b505afa15801561238e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b29190614dd1565b90506000811180156123c657506000600854115b80156123e2575060085481906123e090633b9aca0061440b565b105b1561240657600854612403906123fc90633b9aca0061440b565b8290614257565b91505b50919050565b6010546001600160a01b031681565b601b5460ff1681565b6011546001600160a01b031681565b600f546001600160a01b031681565b61244b3361121d565b6124865760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b61105a600080516020615cd4833981519152826113e6565b600b54156124be5760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b0316806124ec5760405162461bcd60e51b81526004016103649061503e565b816001600160a01b0381166125135760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b15801561256157600080fd5b505afa158015612575573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125999190614d07565b6125b55760405162461bcd60e51b815260040161036490615a64565b60125483906001600160a01b038083169116146125e45760405162461bcd60e51b815260040161036490615634565b6003601955601a546125f7906001614299565b601a55612602611261565b60105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561264757600080fd5b505afa15801561265b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267f9190614dd1565b600f546040516367265c3b60e11b81529192506000916001600160a01b039091169063ce4cb876906126b79089903090600401614ef1565b60206040518083038186803b1580156126cf57600080fd5b505afa1580156126e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127079190614dd1565b9050600081116127295760405162461bcd60e51b8152600401610364906151bc565b600654600e8304906127419082906111ec9086614257565b431161275f5760405162461bcd60e51b815260040161036490615881565b601054604051636b2160b760e01b81526001600160a01b0390911690636b2160b79061278f908a90600401614ea3565b602060405180830381600087803b1580156127a957600080fd5b505af11580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e19190614d07565b507fd1c4e96e0fd22936ea8aebe0b8e06b19f1c4a836b141a34cf9e925d2afb20523876040516128119190614ea3565b60405180910390a150506000600b555050505050565b60195481565b600b541561284d5760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b03168061287b5760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b1580156128c957600080fd5b505afa1580156128dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129019190614d07565b61291d5760405162461bcd60e51b815260040161036490615a64565b60125482906001600160a01b0380831691161461294c5760405162461bcd60e51b815260040161036490615634565b6005601955612959611261565b60008061296585612a8f565b909250905081158015906129795750600081115b6129955760405162461bcd60e51b81526004016103649061558f565b6014546129a29082614299565b601455601a5482116129bf57601a546129bb9083614257565b601a555b60105460405163fb0713b160e01b81526001600160a01b039091169063fb0713b1906129f49088908690600190600401614fc4565b602060405180830381600087803b158015612a0e57600080fd5b505af1158015612a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a469190614d07565b507f76d210b2dc3da8be1904d8b5da9feb5cdd21af436261626c4ec607e2123b417d85836001604051612a7b93929190614fc4565b60405180910390a150506000600b55505050565b60015460009081906001600160a01b031680612abd5760405162461bcd60e51b81526004016103649061503e565b836001600160a01b038116612ae45760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b158015612b3257600080fd5b505afa158015612b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6a9190614d07565b612b865760405162461bcd60e51b815260040161036490615a64565b60125485906001600160a01b03808316911614612bb55760405162461bcd60e51b815260040161036490615634565b601054604051636323f93760e11b8152600091829182916001600160a01b03169063c647f26e90612bec908c903090600401614ef1565b60206040518083038186803b158015612c0457600080fd5b505afa158015612c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3c9190614dd1565b601054604051635c0df46b60e01b8152919250600091612cca9184916001600160a01b0390911690635c0df46b90612c7a908f903090600401614ef1565b60206040518083038186803b158015612c9257600080fd5b505afa158015612ca6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119169190614dd1565b9050815b81811015612dc8576000806000601060009054906101000a90046001600160a01b03166001600160a01b0316638fbef2d08f30876040518463ffffffff1660e01b8152600401612d2093929190614fa0565b60606040518083038186803b158015612d3857600080fd5b505afa158015612d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d709190614d8b565b9194509250905080158015612da157506000836001600160801b0316118015612da1575043836001600160801b0316105b15612db55760019097019695810195612dbd565b505050612dc8565b505050600101612cce565b50506001600160801b03928316975050169350505050915091565b612dec3361121d565b612e275760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b6001600160a01b038116612e7d576040805162461bcd60e51b815260206004820152601860248201527741636365737369626c653a207a65726f206164647265737360401b604482015290519081900360640190fd5b336001600160a01b0382161415612ed4576040805162461bcd60e51b815260206004820152601660248201527520b1b1b2b9b9b4b136329d1039b0b6b29030b236b4b760511b604482015290519081900360640190fd5b612eec600080516020615cd4833981519152826113e6565b61105a600080516020615cd48339815191523361144d565b600080516020615cd483398151915281565b600b5415612f365760405162461bcd60e51b815260040161036490615429565b6001600b55612f43611261565b80156130ee576011546001600160a01b0316612f715760405162461bcd60e51b815260040161036490615156565b600d546040516370a0823160e01b815283916001600160a01b0316906370a0823190612fa1903090600401614ea3565b60206040518083038186803b158015612fb957600080fd5b505afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190614dd1565b101561300f5760405162461bcd60e51b815260040161036490615341565b601154604051600091613032916001600160a01b03909116908190602001614ef1565b60408051601f1981840301815290829052600d54600e5463cae9ca5160e01b84529193506001600160a01b039081169263cae9ca519261307a92169087908690600401614fe7565b602060405180830381600087803b15801561309457600080fd5b505af11580156130a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130cc9190614d07565b6130e85760405162461bcd60e51b8152600401610364906156a0565b5061322a565b600e546040516370a0823160e01b815283916001600160a01b0316906370a082319061311e903090600401614ea3565b60206040518083038186803b15801561313657600080fd5b505afa15801561314a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061316e9190614dd1565b101561318c5760405162461bcd60e51b8152600401610364906153d0565b600e5460405163f53fe70f60e01b81526001600160a01b039091169063f53fe70f906131bc908590600401615022565b602060405180830381600087803b1580156131d657600080fd5b505af11580156131ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320e9190614d07565b61322a5760405162461bcd60e51b8152600401610364906157a0565b50506000600b55565b600a5481565b600e546001600160a01b031681565b6000828152601c602052604081206122d4908361482b565b6000828152601c602052604081206122d49083614837565b6012546001600160a01b031681565b600080613292614b0d565b5050600254600354604080516060810182526004548152600554602082015260065491810191909152600754600854600a546001600160a01b03958616979590941695509193909290565b600c5461010090046001600160a01b031681565b600c54600160a81b900460ff1681565b600081565b61330f3361121d565b61334a5760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b6001600160a01b0381161580159061337057506012546001600160a01b03828116911614155b61338c5760405162461bcd60e51b815260040161036490615115565b601280546001600160a01b0319166001600160a01b0383161790556040517fbcf2b04f5517cca822ae60e21bb6e3889b8d8307ea062c5266c63a014386c990906133d7908390614ea3565b60405180910390a150565b6012546000906001600160a01b03161580159061340c57506012546001600160a01b038381169116145b801561342257506010546001600160a01b031615155b156112035760105460408051633761ead760e11b815290516000926001600160a01b031691636ec3d5ae916004808301926020929190829003018186803b15801561346c57600080fd5b505afa158015613480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a49190614dd1565b9050600e81046134b48282614299565b60065411156134d9576134d6816111ec8460065461425790919063ffffffff16565b92505b5050919050565b6134e93361121d565b6135245760405162461bcd60e51b8152600401808060200182810382526022815260200180615c616022913960400191505060405180910390fd5b806001600160a01b03811661354b5760405162461bcd60e51b81526004016103649061503e565b600180546001600160a01b0319166001600160a01b0384811691909117918290556040517f278c70ced5f3e0e5eeb385b5ff9cb735748ba00a625147e66065ed48fc1562cd9261359c921690614ea3565b60405180910390a15050565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919060ff1687565b60075481565b6000818152601c602052604081206112379061484c565b600d546001600160a01b031681565b600b54156136345760405162461bcd60e51b815260040161036490615429565b6001600b819055546001600160a01b0316806136625760405162461bcd60e51b81526004016103649061503e565b826001600160a01b0381166136895760405162461bcd60e51b81526004016103649061503e565b600360009054906101000a90046001600160a01b03166001600160a01b031663b8c766b86040518163ffffffff1660e01b815260040160206040518083038186803b1580156136d757600080fd5b505afa1580156136eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370f9190614d07565b61372b5760405162461bcd60e51b815260040161036490615a64565b60125484906001600160a01b0380831691161461375a5760405162461bcd60e51b815260040161036490615634565b6003601955601a5461376d906001614299565b601a55613778611261565b600f546040516367265c3b60e11b81526000916001600160a01b03169063ce4cb876906137ab9089903090600401614ef1565b60206040518083038186803b1580156137c357600080fd5b505afa1580156137d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137fb9190614dd1565b90506000811161381d5760405162461bcd60e51b8152600401610364906151bc565b60085460009061383190633b9aca0061440b565b90506000808211801561384d575061384a836064614257565b82105b156138645761386160646111ec8585614257565b90505b600081116138845760405162461bcd60e51b81526004016103649061594a565b60105460405163da95ebf760e01b81526001600160a01b039091169063da95ebf7906138b6908b908590600401614eb7565b602060405180830381600087803b1580156138d057600080fd5b505af11580156138e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139089190614d07565b507f2a23e23c116b511f71c9f0c2648b0372e6bbcb1f559a7cbfaed5c55933ea6c4e888260405161393a929190614eb7565b60405180910390a150506000600b55505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6000828152601c6020526040902060020154613993906107bd6142f3565b6114a45760405162461bcd60e51b8152600401808060200182810382526030815260200180615c836030913960400191505060405180910390fd5b6001600160a01b03166000908152600960205260409020805460018201546002830154600384015460048501546005860154600690960154949693959294919390929160ff1690565b601a5481565b60175481565b60185481565b6000600b54600014613a4d5760405162461bcd60e51b815260040161036490615429565b6001600b5560035460408051631718ecd760e31b815290516001600160a01b039092169163b8c766b891600480820192602092909190829003018186803b158015613a9757600080fd5b505afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614d07565b613aeb5760405162461bcd60e51b815260040161036490615a64565b600654431115613b0d5760405162461bcd60e51b815260040161036490615998565b60028210613b2d5760405162461bcd60e51b815260040161036490615909565b613b35611261565b600e546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613b66903090600401614ea3565b60206040518083038186803b158015613b7e57600080fd5b505afa158015613b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb69190614dd1565b600d546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190613bec903090600401614ea3565b60206040518083038186803b158015613c0457600080fd5b505afa158015613c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c3c9190614dd1565b6012549091506000906001600160a01b031615613d7057600f546012546040516367265c3b60e11b81526001600160a01b039283169263ce4cb87692613c89929116903090600401614ef1565b60206040518083038186803b158015613ca157600080fd5b505afa158015613cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd99190614dd1565b601054601254604051632638fdf560e01b8152929350613d6d926001600160a01b0392831692632638fdf592613d16929116903090600401614ef1565b60206040518083038186803b158015613d2e57600080fd5b505afa158015613d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d669190614dd1565b8290614299565b90505b828215613d8b57613d88613d6684633b9aca0061440b565b90505b89811015613dab5760405162461bcd60e51b81526004016103649061566b565b8115613dbe57613dbb8183614299565b90505b600854613dcf90633b9aca0061440b565b81118015613dff575089613dfc613df5633b9aca0060085461440b90919063ffffffff16565b8390614257565b10155b613e1b5760405162461bcd60e51b8152600401610364906155fd565b89841015613f1757601154604051600091613e46916001600160a01b03909116908190602001614ef1565b60408051601f1981840301815291905290506000613e6c633b9aca006119af8e89614257565b600d54600e5460405163cae9ca5160e01b81529293506001600160a01b039182169263cae9ca5192613ea692169085908790600401614fe7565b602060405180830381600087803b158015613ec057600080fd5b505af1158015613ed4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef89190614d07565b613f145760405162461bcd60e51b815260040161036490615511565b50505b5050601554613f299250905087614299565b60155560015460408051630141158f60e61b8152905160009283926001600160a01b039091169163504563c09160048082019260a092909190829003018186803b158015613f7657600080fd5b505afa158015613f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fae9190614bd2565b5092945091925050506001600160a01b038216613fdd5760405162461bcd60e51b815260040161036490615075565b600e5460405163095ea7b360e01b81526001600160a01b039091169063095ea7b39061400f9085908c90600401614eb7565b602060405180830381600087803b15801561402957600080fd5b505af115801561403d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140619190614d07565b61407d5760405162461bcd60e51b815260040161036490615ac3565b6040805161010081018252600e546001600160a01b0390811682526000548116602083015262ffffff8416828401523060608301526080820189905260a082018b905260c082018a905287811660e0830152915163414bf38960e01b8152909184169063414bf389906140f4908490600401615b43565b602060405180830381600087803b15801561410e57600080fd5b505af1158015614122573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141469190614dd1565b93507f6ad50db5d488c314f9077fc5c41c7d8bcdd86ddc409871512ddd009f21067d32338a8660405161417b93929190614ed0565b60405180910390a150506000600b555095945050505050565b6003546001600160a01b031681565b6000546001600160a01b031681565b60135481565b6000806000806000600160009054906101000a90046001600160a01b03166001600160a01b031663504563c06040518163ffffffff1660e01b815260040160a06040518083038186803b15801561420e57600080fd5b505afa158015614222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142469190614bd2565b945094509450945094509091929394565b60006122d483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614857565b6000828201838110156122d4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6000828152601c6020526040902061430f90826148ee565b156114495761431c6142f3565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152601c602052604090206143789082614903565b15611449576143856142f3565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006122d483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614918565b60008261441a57506000611237565b8282028284828161442757fe5b04146122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180615cb36021913960400191505060405180910390fd5b82156145a2576040516370a0823160e01b815283906001600160a01b038716906370a0823190614498903090600401614ea3565b60206040518083038186803b1580156144b057600080fd5b505afa1580156144c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144e89190614dd1565b10156145065760405162461bcd60e51b815260040161036490615a2d565b60405163a9059cbb60e01b81526001600160a01b0386169063a9059cbb906145349033908790600401614eb7565b602060405180830381600087803b15801561454e57600080fd5b505af1158015614562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145869190614d07565b6145a25760405162461bcd60e51b81526004016103649061530a565b81156146e0576040516370a0823160e01b815282906001600160a01b038616906370a08231906145d6903090600401614ea3565b60206040518083038186803b1580156145ee57600080fd5b505afa158015614602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146269190614dd1565b10156146445760405162461bcd60e51b8152600401610364906159f6565b60405163e3b99e8560e01b81526001600160a01b0385169063e3b99e85906146729033908690600401614eb7565b602060405180830381600087803b15801561468c57600080fd5b505af11580156146a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146c49190614d07565b6146e05760405162461bcd60e51b815260040161036490615399565b8015614824576000546040516370a0823160e01b815282916001600160a01b0316906370a0823190614716903090600401614ea3565b60206040518083038186803b15801561472e57600080fd5b505afa158015614742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147669190614dd1565b10156147845760405162461bcd60e51b8152600401610364906158d2565b60005460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906147b69033908590600401614eb7565b602060405180830381600087803b1580156147d057600080fd5b505af11580156147e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148089190614d07565b6148245760405162461bcd60e51b815260040161036490615225565b5050505050565b60006122d4838361497d565b60006122d4836001600160a01b0384166149e1565b6000611237826149f9565b600081848411156148e65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148ab578181015183820152602001614893565b50505050905090810190601f1680156148d85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006122d4836001600160a01b0384166149fd565b60006122d4836001600160a01b038416614a47565b600081836149675760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156148ab578181015183820152602001614893565b50600083858161497357fe5b0495945050505050565b815460009082106149bf5760405162461bcd60e51b8152600401808060200182810382526022815260200180615c106022913960400191505060405180910390fd5b8260000182815481106149ce57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000614a0983836149e1565b614a3f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611237565b506000611237565b60008181526001830160205260408120548015614b035783546000198083019190810190600090879083908110614a7a57fe5b9060005260206000200154905080876000018481548110614a9757fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614ac757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611237565b6000915050611237565b60405180606001604052806003906020820280368337509192915050565b80516001600160801b038116811461120357600080fd5b600060208284031215614b53578081fd5b81356122d481615bec565b600080600080600060a08688031215614b75578081fd5b8551614b8081615bec565b6020870151909550614b9181615bec565b6040870151909450614ba281615bec565b6060870151909350614bb381615bec565b6080870151909250614bc481615bec565b809150509295509295909350565b600080600080600060a08688031215614be9578081fd5b8551614bf481615bec565b6020870151909550614c0581615bec565b6040870151909450614c1681615bec565b606087015160808801519194509250614bc481615bec565b60008060408385031215614c40578182fd5b8235614c4b81615bec565b946020939093013593505050565b60006020808385031215614c6b578182fd5b825167ffffffffffffffff80821115614c82578384fd5b818501915085601f830112614c95578384fd5b815181811115614ca157fe5b83810260405185828201018181108582111715614cba57fe5b604052828152858101935084860182860187018a1015614cd8578788fd5b8795505b83861015614cfa578051855260019590950194938601938601614cdc565b5098975050505050505050565b600060208284031215614d18578081fd5b81516122d481615c01565b600060208284031215614d34578081fd5b5035919050565b60008060408385031215614d4d578182fd5b823591506020830135614d5f81615bec565b809150509250929050565b60008060408385031215614d7c578182fd5b50508035926020909101359150565b600080600060608486031215614d9f578283fd5b614da884614b2b565b9250614db660208501614b2b565b91506040840151614dc681615c01565b809150509250925092565b600060208284031215614de2578081fd5b5051919050565b60008060408385031215614dfb578182fd5b823591506020830135614d5f81615c01565b600080600080600060a08688031215614e24578283fd5b8535945060208601359350604086013592506060860135614e4481615bec565b949793965091946080013592915050565b60008151808452815b81811015614e7a57602081850181015186830182015201614e5e565b81811115614e8b5782602083870101525b50601f01601f19169290920160200192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039586168152938516602085015291841660408401526060830152909116608082015260a00190565b6001600160a01b038781168252861660208083019190915261010082019060408301908760005b6003811015614f7f57815184529282019290820190600101614f62565b505050508460a08301528360c08301528260e0830152979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060018060a01b03851682528360208301526060604083015261500e6060830184614e55565b95945050505050565b901515815260200190565b90815260200190565b6000602082526122d46020830184614e55565b6020808252601b908201527f546f6b616d616b5374616b65723a207a65726f20616464726573730000000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a756e6973776170207a65726f000000000000604082015260600190565b6020808252601a908201527f5374616b65544f4e3a20416c7265616479207769746864726177000000000000604082015260600190565b6020808252601890820152775374616b65544f4e3a20726577617264206973207a65726f60401b604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a746f6b616d616b4c6179657232207a65726f6040820152600160fd1b606082015260800190565b6020808252818101527f546f6b616d616b5374616b65723a207377617050726f7879206973207a65726f604082015260600190565b60208082526017908201527614dd185ad95513d38e881d1c985b9cd9995c8819985a5b604a1b604082015260600190565b6020808252601e908201527f546f6b616d616b5374616b65723a207374616b654f66206973207a65726f0000604082015260600190565b602080825260189082015277151bdad85b585ad4dd185ad95c8e9c195c9a5bd908195b9960421b604082015260600190565b6020808252601b908201527f5374616b65544f4e3a207472616e7366657220746f73206661696c0000000000604082015260600190565b60208082526029908201527f546f6b616d616b5374616b65723a706572696f64287769746864726177616c44604082015268195b185e4a48195b9960ba1b606082015260800190565b6020808252601f908201527f5374616b65544f4e3a2049546f6b616d616b5265676973747279207a65726f00604082015260600190565b60208082526014908201527314dd185ad95513d38e881b9bdd0818db1bdcd95960621b604082015260600190565b6020808252601b908201527f5374616b65544f4e3a207472616e7366657220746f6e206661696c0000000000604082015260600190565b60208082526038908201527f546f6b616d616b5374616b65723a2073776170544f4e746f57544f4e20746f6e6040820152770818985b185b98d9481a5cc81a5b9cdd59999a58da595b9d60421b606082015260800190565b6020808252601c908201527f5374616b65544f4e3a207472616e736665722077746f6e206661696c00000000604082015260600190565b60208082526039908201527f546f6b616d616b5374616b65723a2073776170544f4e746f57544f4e2077746f6040820152781b8818985b185b98d9481a5cc81a5b9cdd59999a58da595b9d603a1b606082015260800190565b602080825260149082015273151bdad85b585ad4dd185ad95c8e9313d0d2d15160621b604082015260600190565b60208082526022908201527f5374616b65544f4e3a2072656d61696e20616d6f756e7420696e20746f6b616d604082015261616b60f01b606082015260800190565b6020808252601e908201527f5374616b65544f4e3a2066696e616c42616c616e6365206973206c61636b0000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a617070726f7665416e6443616c6c206661696040820152601b60fa1b606082015260800190565b60208082526033908201527f546f6b616d616b5374616b65723a65786368616e676557544f4e746f544f5320604082015272185c1c1c9bdd99505b9910d85b1b0819985a5b606a1b606082015260800190565b60208082526011908201527014dd185ad95513d38e8818db185a5b5959607a1b604082015260600190565b6020808252601e908201527f546f6b616d616b5374616b65723a206e6f2061626c6520726571756573740000604082015260600190565b6020808252601a908201527f5374616b65544f4e3a207769746864726177206661696c65642e000000000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a696e73756666696369656e74000000000000604082015260600190565b6020808252601d908201527f546f6b616d616b5374616b65723a646966666572656e74206c61796572000000604082015260600190565b6020808252818101527f546f6b616d616b5374616b65723a2077746f6e20696e73756666696369656e74604082015260600190565b6020808252602f908201527f546f6b616d616b5374616b65723a73776170544f4e746f57544f4e206170707260408201526e1bdd99505b9910d85b1b0819985a5b608a1b606082015260800190565b6020808252601690820152755374616b65544f4e3a20416d6f756e742077726f6e6760501b604082015260600190565b6020808252602a908201527f546f6b616d616b5374616b65723a20746f6e2062616c616e636520697320696e6040820152691cdd59999a58da595b9d60b21b606082015260800190565b6020808252601f908201527f5374616b65544f4e3a206661696c20636c61696d2066726f6d207661756c7400604082015260600190565b6020808252601c908201527f546f6b616d616b5374616b65723a73776170546f544f4e206661696c00000000604082015260600190565b6020808252601a908201527f546f6b616d616b5374616b65723a746f6b616d616b207a65726f000000000000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a7374616b65416d6f756e74206973207a65726040820152606f60f81b606082015260800190565b6020808252601890820152770a6e8c2d6caa89e9c7440d2dce6eaccccd2cadce8408aa8960431b604082015260600190565b60208082526031908201527f546f6b616d616b5374616b65723a5468652065786563757461626c6520626c6f60408201527018dac81a185cc81b9bdd081c185cdcd959607a1b606082015260800190565b6020808252601d908201527f5374616b65544f4e3a20746f732062616c616e6365206973206c61636b000000604082015260600190565b60208082526021908201527f546f6b616d616b5374616b65723a206e6f7420617661696c61626c65206b696e6040820152601960fa1b606082015260800190565b6020808252602e908201527f546f6b616d616b5374616b65723a206e6f2077697468647261772d61626c652060408201526d185b5bdd5b9d081b9bdd081e595d60921b606082015260800190565b602080825260199082015278151bdad85b585ad4dd185ad95c8e881c195c9a5bd908195b99603a1b604082015260600190565b60208082526011908201527014dd185ad95513d38e881b9bdd08195b99607a1b604082015260600190565b6020808252601e908201527f5374616b65544f4e3a2077746f6e2062616c616e6365206973206c61636b0000604082015260600190565b6020808252601d908201527f5374616b65544f4e3a20746f6e2062616c616e6365206973206c61636b000000604082015260600190565b602080825260199082015278151bdad85b585ad4dd185ad95c8e881b9bdd0818db1bdcd959603a1b604082015260600190565b60208082526012908201527131b0b73737ba1039ba30b5b29022ba3432b960711b604082015260600190565b60208082526029908201527f546f6b616d616b5374616b65723a63616e277420617070726f766520756e69736040820152683bb0b82937baba32b960b91b606082015260800190565b6020808252601e908201527f5374616b65544f4e3a20746f74616c2072657761726420657863656564730000604082015260600190565b81516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b918252602082015260400190565b968752602087019590955260408601939093526060850191909152608084015260a0830152151560c082015260e00190565b6001600160a01b038116811461105a57600080fd5b801515811461105a57600080fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7441636365737369626c653a2043616c6c6572206973206e6f7420616e2061646d696e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77df8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212209716ba2067000c8d0c4e48dbda1972d1435530379c877c5bb4fbd02f67dce82564736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.