More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DCBLiqLocker
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 9999 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT //** Decubate Liquidity Locking Contract */ //** Author: Aceson 2022.7 */ pragma solidity 0.8.17; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol"; import "@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/interfaces/IERC721EnumerableUpgradeable.sol"; import "./interfaces/IStaking.sol"; contract DCBLiqLocker is Initializable, OwnableUpgradeable, IStaking { using SafeMathUpgradeable for uint256; using SafeMathUpgradeable for uint32; IUniswapV2Router02 public router; Multiplier[] public multis; Pool[] public pools; mapping(uint256 => mapping(address => User)) public users; mapping(uint256 => uint256) public lpValue; mapping(uint256 => mapping(address => uint256)) public stakedTokens; event Lock(uint256 indexed poolId, address indexed user, uint256 lpAmount, uint256 time); event Unlock(uint256 indexed poolId, address indexed user, uint256 lpAmount, uint256 time); event LPAdded(address indexed user, uint256 token0, uint256 token1, uint256 lpAmount); event LPRemoved(address indexed user, uint256 lpAmount, uint256 token0, uint256 token1); // solhint-disable-next-line receive() external payable {} /** * * @dev Transfer dust token out of contract (Also a Fail safe) * * @param _token Address of token * * @return status of transfer * */ function transferToken(address _token) external onlyOwner returns (bool) { if (_token == address(0x0)) { payable(owner()).transfer(address(this).balance); return true; } IERC20Upgradeable token = IERC20Upgradeable(_token); uint256 balance = token.balanceOf(address(this)); token.transfer(owner(), balance); return true; } /** * * @dev add new period to the pool, only available for owner * */ function add( bool _isWithdrawLocked, uint128 _rewardRate, uint16 _lockPeriodInDays, uint32 _endDate, uint256, //_hardCap, To comply with common staking interface address _inputToken, address _rewardToken ) external override onlyOwner { pools.push( Pool({ isWithdrawLocked: _isWithdrawLocked, rewardRate: _rewardRate, lockPeriodInDays: _lockPeriodInDays, totalInvestors: 0, totalInvested: 0, hardCap: type(uint256).max, startDate: uint32(block.timestamp), endDate: _endDate, input: _inputToken, reward: _rewardToken }) ); //Init nft struct with dummy data multis.push( Multiplier({ active: false, name: "", contractAdd: address(0), start: 0, end: 0, multi: 100 }) ); IUniswapV2Pair pair = IUniswapV2Pair(_inputToken); pair.approve(address(router), type(uint256).max); require(_rewardToken == pair.token0() || _rewardToken == pair.token1(), "Invalid reward"); IERC20Upgradeable(pair.token0()).approve(address(router), type(uint256).max); IERC20Upgradeable(pair.token1()).approve(address(router), type(uint256).max); } /** * * @dev update the given pool's Info * */ function set( uint16 _pid, bool _isWithdrawLocked, uint128 _rewardRate, uint16 _lockPeriodInDays, uint32 _endDate, uint256, //_hardCap, To comply with common staking interface address, //_input, To comply with common staking interface address ) external override onlyOwner { require(_pid < pools.length, "Invalid pool Id"); Pool storage pool = pools[_pid]; pool.rewardRate = _rewardRate; pool.isWithdrawLocked = _isWithdrawLocked; pool.lockPeriodInDays = _lockPeriodInDays; pool.endDate = _endDate; } /** * * @dev update the given pool's nft info * */ function setMultiplier( uint16 _pid, string calldata _name, address _contractAdd, bool _isUsed, uint16 _multi, uint128 _start, uint128 _end ) external override onlyOwner { Multiplier storage nft = multis[_pid]; nft.name = _name; nft.contractAdd = _contractAdd; nft.active = _isUsed; nft.multi = _multi; nft.start = _start; nft.end = _end; } function transferStuckToken(address _token) external onlyOwner returns (bool) { IERC20Upgradeable token = IERC20Upgradeable(_token); uint256 balance = token.balanceOf(address(this)); token.transfer(owner(), balance); return true; } function transferStuckNFT(address _nft, uint256 _id) external onlyOwner returns (bool) { IERC721Upgradeable nft = IERC721Upgradeable(_nft); nft.safeTransferFrom(address(this), owner(), _id); return true; } /** * * @dev Adds liquidity and locks lp token * * @param _pid id of the pool * @param _token0Amt Amount of token0 added to liquidity * @param _token1Amt Amount of token1 added to liquidity * * @return status of addition * */ function addLiquidityAndLock( uint8 _pid, uint256 _token0Amt, uint256 _token1Amt ) external payable returns (bool) { uint256 _lpAmount; _claim(_pid, msg.sender); IUniswapV2Pair pair = IUniswapV2Pair(pools[_pid].input); uint8 pos = isWrappedNative(pair); if (pos != 2) { if (pos == 0) { _lpAmount = _addLiquidityETH(pair.token1(), msg.value, _token1Amt); stakedTokens[_pid][msg.sender] += _token1Amt; } else { _lpAmount = _addLiquidityETH(pair.token0(), msg.value, _token0Amt); stakedTokens[_pid][msg.sender] += _token0Amt; } } else { _lpAmount = _addLiquidity(pair, _token0Amt, _token1Amt); stakedTokens[_pid][msg.sender] += pair.token0() == pools[_pid].reward ? _token0Amt : _token1Amt; } if (_lpAmount > 0) { _lockLp(_pid, msg.sender, _lpAmount); } return true; } /** * Unlock LP tokens * * @param _pid id of the pool * @param _amount amount to be unlocked * * @return bool Status of unlock * */ function unlockAndRemoveLP(uint16 _pid, uint256 _amount) external returns (bool) { User storage user = users[_pid][msg.sender]; Pool storage pool = pools[_pid]; require(user.totalInvested >= _amount, "You don't have enough locked"); if (pool.isWithdrawLocked) { require(canClaim(_pid, msg.sender), "Stake still in locked state"); } _claim(_pid, msg.sender); //Removing LP uint256 token0; uint256 token1; IUniswapV2Pair pair = IUniswapV2Pair(pools[_pid].input); uint8 pos = isWrappedNative(pair); if (pos != 2) { if (pos == 0) { (token0, token1) = _removeLiquidityETH(pair.token1(), msg.sender, _amount); } else { (token0, token1) = _removeLiquidityETH(pair.token0(), msg.sender, _amount); } } else { (token0, token1) = _removeLiquidity(_pid, msg.sender, _amount); } emit Unlock(_pid, msg.sender, _amount, block.timestamp); pool.totalInvested = pool.totalInvested.sub(_amount); stakedTokens[_pid][msg.sender] -= (stakedTokens[_pid][msg.sender] * _amount) / user.totalInvested; user.totalWithdrawn = user.totalWithdrawn.add(_amount); user.totalInvested = user.totalInvested.sub(_amount); user.lastPayout = uint32(block.timestamp); unchecked { if (user.totalInvested == 0) { pool.totalInvestors--; } } return true; } /** * * @dev Unlock lp tokens and claim reward * * @param _pid id of the pool * * @return status of unlock * */ function claim(uint16 _pid) external override returns (bool) { bool status = _claim(_pid, msg.sender); require(status, "Claim failed"); return true; } /** * * @dev claim accumulated TOKEN reward from all pools * * Beware of gas fee! * */ function claimAll() external override returns (bool) { uint256 len = pools.length; for (uint16 pid = 0; pid < len; ) { _claim(pid, msg.sender); unchecked { ++pid; } } return true; } /** * * @dev get length of the pools * * @return {uint256} length of the pools * */ function poolLength() external view override returns (uint256) { return pools.length; } /** * * @dev get all pools info * * @return {Pool[]} length of the pools * */ function getPools() external view returns (Pool[] memory) { return pools; } /** * * @dev Constructor for proxy * * @param _router Address of router (Pancake) * */ function initialize(address _router) public initializer { __Ownable_init(); router = IUniswapV2Router02(_router); } function payout(uint16 _pid, address _addr) public view override returns (uint256 rewardAmount) { Pool memory pool = pools[_pid]; User memory user = users[_pid][_addr]; uint256 from = user.lastPayout >= user.depositTime ? user.lastPayout : user.depositTime; uint256 usersLastTime = user.depositTime.add(uint256(pool.lockPeriodInDays) * 1 days); uint256 to = block.timestamp >= usersLastTime ? usersLastTime : block.timestamp; if (to > from) { uint256 amount = stakedTokens[uint256(_pid)][_addr]; uint256 reward = ((to - from) * (amount) * (pool.rewardRate)) / (1000) / (365 days); uint256 multiplier = calcMultiplier(_pid, _addr); reward = (reward * (multiplier)) / (100); rewardAmount = reward * 2; //Both tokens in pair } } /** * * @dev check whether user can Unlock or not * * @param {_pid} id of the pool * @param {_did} id of the deposit * @param {_addr} address of the user * * @return {bool} Status of Unstake * */ function canClaim(uint16 _pid, address _addr) public view override returns (bool) { User memory user = users[_pid][_addr]; Pool memory pool = pools[_pid]; return (block.timestamp >= user.depositTime.add(uint256(pool.lockPeriodInDays) * 1 days)); } /** * * @dev Check whether user owns correct NFT for boost * */ function ownsCorrectMulti(uint16 _pid, address _addr) public view override returns (bool) { Multiplier memory nft = multis[_pid]; uint256[] memory ids = _walletOfOwner(nft.contractAdd, _addr); for (uint256 i = 0; i < ids.length; ) { if (ids[i] >= nft.start && ids[i] <= nft.end) { return true; } unchecked { i++; } } return false; } /** * * @dev check whether user have NFT multiplier * * @param _pid id of the pool * @param _addr address of the user * * @return multi Value of multiplier * */ function calcMultiplier(uint16 _pid, address _addr) public view override returns (uint16 multi) { Multiplier memory nft = multis[_pid]; if (nft.active && ownsCorrectMulti(_pid, _addr)) { multi = nft.multi; } else { multi = 100; } } /** * * @dev check whether the pool is made of native coin * * @param _pair address of pair contract * * @return pos whether it is token0 or token1 * */ function isWrappedNative(IUniswapV2Pair _pair) public view returns (uint8 pos) { if (_pair.token0() == router.WETH()) { pos = 0; } else if (_pair.token1() == router.WETH()) { pos = 1; } else { pos = 2; } } function _addLiquidity( IUniswapV2Pair _pair, uint256 _token0Amt, uint256 _token1Amt ) internal returns (uint256 lpTokens) { IERC20Upgradeable(_pair.token0()).transferFrom(msg.sender, address(this), _token0Amt); IERC20Upgradeable(_pair.token1()).transferFrom(msg.sender, address(this), _token1Amt); (, , lpTokens) = router.addLiquidity( _pair.token0(), _pair.token1(), _token0Amt, _token1Amt, _token0Amt.mul(95).div(100), //5% slippage _token1Amt.mul(95).div(100), //5% slippage address(this), block.timestamp + 100 ); emit LPAdded(msg.sender, _token0Amt, _token1Amt, lpTokens); } function _addLiquidityETH( address _token, uint256 _nativeValue, uint256 _tokenValue ) internal returns (uint256 lpTokens) { IERC20Upgradeable(_token).transferFrom(msg.sender, address(this), _tokenValue); (, , lpTokens) = router.addLiquidityETH{ value: _nativeValue }( _token, _tokenValue, _tokenValue.mul(95).div(100), _nativeValue.mul(95).div(100), address(this), block.timestamp + 100 ); emit LPAdded(msg.sender, _nativeValue, _tokenValue, lpTokens); } function _removeLiquidity( uint16 _pid, address _user, uint256 _amount ) internal returns (uint256 _amount0, uint256 _amount1) { IUniswapV2Pair pair = IUniswapV2Pair(pools[_pid].input); (_amount0, _amount1) = router.removeLiquidity( pair.token0(), pair.token1(), _amount, 0, 0, _user, block.timestamp + 100 ); emit LPRemoved(msg.sender, _amount, _amount0, _amount1); } function _removeLiquidityETH( address _token, address _user, uint256 _amount ) internal returns (uint256 _amount0, uint256 _amount1) { (_amount0, _amount1) = router.removeLiquidityETH( _token, _amount, 0, 0, _user, block.timestamp + 100 ); emit LPRemoved(msg.sender, _amount, _amount0, _amount1); } function _claim(uint16 _pid, address _user) internal returns (bool) { Pool storage pool = pools[_pid]; User storage user = users[_pid][_user]; if (!pool.isWithdrawLocked && !canClaim(_pid, _user)) { return false; } uint256 amount = payout(_pid, _user); if (amount > 0) { _safeTOKENTransfer(pool.reward, _user, amount); user.totalClaimed = user.totalClaimed.add(amount); } user.lastPayout = uint32(block.timestamp); emit Claim(_pid, _user, amount, block.timestamp); return true; } function _lockLp(uint8 _pid, address _sender, uint256 _lpAmount) internal { Pool storage pool = pools[_pid]; User storage user = users[_pid][_sender]; uint256 stopDepo = pool.endDate.sub(uint256(pool.lockPeriodInDays) * 1 days); require(block.timestamp <= stopDepo, "Locking is disabled for this pool"); if (user.totalInvested == 0) { unchecked { pool.totalInvestors++; } } user.totalInvested = user.totalInvested.add(_lpAmount); pool.totalInvested = pool.totalInvested.add(_lpAmount); user.depositTime = uint32(block.timestamp); user.lastPayout = uint32(block.timestamp); emit Lock(_pid, _sender, _lpAmount, block.timestamp); } function _safeTOKENTransfer(address _token, address _to, uint256 _amount) internal { IERC20Upgradeable token = IERC20Upgradeable(_token); uint256 bal = token.balanceOf(address(this)); require(bal >= _amount, "Not enough funds in treasury"); if (_amount > 0) { token.transfer(_to, _amount); } } /** * * @dev Fetching nfts owned by a user * */ function _walletOfOwner( address _contract, address _owner ) internal view returns (uint256[] memory) { IERC721EnumerableUpgradeable nft = IERC721EnumerableUpgradeable(_contract); uint256 tokenCount = nft.balanceOf(_owner); uint256[] memory tokensId = new uint256[](tokenCount); for (uint256 i; i < tokenCount; ) { tokensId[i] = nft.tokenOfOwnerByIndex(_owner, i); unchecked { i++; } } return tokensId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IStaking { struct Multiplier { string name; address contractAdd; bool active; uint16 multi; uint128 start; uint128 end; } struct User { uint256 totalInvested; uint256 totalWithdrawn; uint32 lastPayout; uint32 depositTime; uint256 totalClaimed; } struct Pool { bool isWithdrawLocked; uint16 lockPeriodInDays; uint32 totalInvestors; uint32 startDate; uint32 endDate; uint128 rewardRate; uint256 totalInvested; uint256 hardCap; address input; address reward; } event Claim(uint16 pid, address indexed addr, uint256 amount, uint256 time); function setMultiplier( uint16 _pid, string calldata _name, address _contractAdd, bool _isUsed, uint16 _multiplier, uint128 _startIdx, uint128 _endIdx ) external; function add( bool _isWithdrawLocked, uint128 _rewardRate, uint16 _lockPeriodInDays, uint32 _endDate, uint256 _hardCap, address _inputToken, address _rewardToken ) external; function set( uint16 _pid, bool _isWithdrawLocked, uint128 _rewardRate, uint16 _lockPeriodInDays, uint32 _endDate, uint256 _hardCap, address _inputToken, address _rewardToken ) external; function claim(uint16 _pid) external returns (bool); function claimAll() external returns (bool); function transferStuckNFT(address _nft, uint256 _id) external returns (bool); function transferStuckToken(address _token) external returns (bool); function canClaim(uint16 _pid, address _addr) external view returns (bool); function calcMultiplier(uint16 _pid, address _addr) external view returns (uint16); function ownsCorrectMulti(uint16 _pid, address _addr) external view returns (bool); function poolLength() external view returns (uint256); function payout(uint16 _pid, address _addr) external view returns (uint256 value); }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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) { return a + b; } /** * @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 a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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 a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../token/ERC721/extensions/IERC721EnumerableUpgradeable.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20Upgradeable.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 9999 }, "evmVersion": "london", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"pid","type":"uint16"},{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"token0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"}],"name":"LPAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1","type":"uint256"}],"name":"LPRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Lock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Unlock","type":"event"},{"inputs":[{"internalType":"bool","name":"_isWithdrawLocked","type":"bool"},{"internalType":"uint128","name":"_rewardRate","type":"uint128"},{"internalType":"uint16","name":"_lockPeriodInDays","type":"uint16"},{"internalType":"uint32","name":"_endDate","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"uint256","name":"_token0Amt","type":"uint256"},{"internalType":"uint256","name":"_token1Amt","type":"uint256"}],"name":"addLiquidityAndLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"address","name":"_addr","type":"address"}],"name":"calcMultiplier","outputs":[{"internalType":"uint16","name":"multi","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"address","name":"_addr","type":"address"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"}],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPools","outputs":[{"components":[{"internalType":"bool","name":"isWithdrawLocked","type":"bool"},{"internalType":"uint16","name":"lockPeriodInDays","type":"uint16"},{"internalType":"uint32","name":"totalInvestors","type":"uint32"},{"internalType":"uint32","name":"startDate","type":"uint32"},{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"uint128","name":"rewardRate","type":"uint128"},{"internalType":"uint256","name":"totalInvested","type":"uint256"},{"internalType":"uint256","name":"hardCap","type":"uint256"},{"internalType":"address","name":"input","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"internalType":"struct IStaking.Pool[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniswapV2Pair","name":"_pair","type":"address"}],"name":"isWrappedNative","outputs":[{"internalType":"uint8","name":"pos","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lpValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"multis","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAdd","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint16","name":"multi","type":"uint16"},{"internalType":"uint128","name":"start","type":"uint128"},{"internalType":"uint128","name":"end","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"address","name":"_addr","type":"address"}],"name":"ownsCorrectMulti","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"address","name":"_addr","type":"address"}],"name":"payout","outputs":[{"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"bool","name":"isWithdrawLocked","type":"bool"},{"internalType":"uint16","name":"lockPeriodInDays","type":"uint16"},{"internalType":"uint32","name":"totalInvestors","type":"uint32"},{"internalType":"uint32","name":"startDate","type":"uint32"},{"internalType":"uint32","name":"endDate","type":"uint32"},{"internalType":"uint128","name":"rewardRate","type":"uint128"},{"internalType":"uint256","name":"totalInvested","type":"uint256"},{"internalType":"uint256","name":"hardCap","type":"uint256"},{"internalType":"address","name":"input","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"bool","name":"_isWithdrawLocked","type":"bool"},{"internalType":"uint128","name":"_rewardRate","type":"uint128"},{"internalType":"uint16","name":"_lockPeriodInDays","type":"uint16"},{"internalType":"uint32","name":"_endDate","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_contractAdd","type":"address"},{"internalType":"bool","name":"_isUsed","type":"bool"},{"internalType":"uint16","name":"_multi","type":"uint16"},{"internalType":"uint128","name":"_start","type":"uint128"},{"internalType":"uint128","name":"_end","type":"uint128"}],"name":"setMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"stakedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"transferStuckNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"transferStuckToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"transferToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_pid","type":"uint16"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlockAndRemoveLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"totalInvested","type":"uint256"},{"internalType":"uint256","name":"totalWithdrawn","type":"uint256"},{"internalType":"uint32","name":"lastPayout","type":"uint32"},{"internalType":"uint32","name":"depositTime","type":"uint32"},{"internalType":"uint256","name":"totalClaimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b506144d7806100206000396000f3fe6080604052600436106101b05760003560e01c8063a6ebb133116100ec578063d1058e591161008a578063edac5f3e11610064578063edac5f3e146105d7578063f2fde38b146105f7578063f887ea4014610617578063f9d22af91461063757600080fd5b8063d1058e591461058f578063db4e9906146105a4578063deebeac9146105b757600080fd5b8063b9d02df4116100c6578063b9d02df41461049e578063bab666c81461052f578063c4d66de81461054f578063c99e8fd81461056f57600080fd5b8063a6ebb133146103b3578063a76b114f146103d3578063ac4afa381461040557600080fd5b806356eeafd911610159578063681ce73e11610133578063681ce73e1461031f578063715018a61461033f5780638813bf9e146103545780638da5cb5b1461038157600080fd5b806356eeafd9146102a55780636439be5f146102dd578063673a2a1f146102fd57600080fd5b80632fae37111161018a5780632fae371114610222578063443153e61461025257806351258c401461027257600080fd5b8063081e3eda146101bc57806313e9cb98146101e0578063181c5acb1461020257600080fd5b366101b757005b600080fd5b3480156101c857600080fd5b506067545b6040519081526020015b60405180910390f35b3480156101ec57600080fd5b506102006101fb366004613bec565b610669565b005b34801561020e57600080fd5b5061020061021d366004613c73565b610dfe565b34801561022e57600080fd5b5061024261023d366004613d49565b610f17565b60405190151581526020016101d7565b34801561025e57600080fd5b5061020061026d366004613d73565b6112ac565b34801561027e57600080fd5b5061029261028d366004613e0b565b61142a565b60405161ffff90911681526020016101d7565b3480156102b157600080fd5b506101cd6102c0366004613e42565b606a60209081526000928352604080842090915290825290205481565b3480156102e957600080fd5b506101cd6102f8366004613e0b565b6115ba565b34801561030957600080fd5b5061031261195c565b6040516101d79190613e67565b34801561032b57600080fd5b5061024261033a366004613e0b565b611a77565b34801561034b57600080fd5b50610200611c87565b34801561036057600080fd5b506101cd61036f366004613f3e565b60696020526000908152604090205481565b34801561038d57600080fd5b506033546001600160a01b03165b6040516001600160a01b0390911681526020016101d7565b3480156103bf57600080fd5b506102426103ce366004613f57565b611c9b565b3480156103df57600080fd5b506103f36103ee366004613f3e565b611de4565b6040516101d796959493929190613f74565b34801561041157600080fd5b50610425610420366004613f3e565b611f15565b604080519a15158b5261ffff90991660208b015263ffffffff978816988a019890985294861660608901529490921660808701526fffffffffffffffffffffffffffffffff1660a086015260c085015260e08401919091526001600160a01b0390811661010084015216610120820152610140016101d7565b3480156104aa57600080fd5b506104fe6104b9366004613e42565b606860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909163ffffffff808316926401000000009004169085565b60408051958652602086019490945263ffffffff92831693850193909352166060830152608082015260a0016101d7565b34801561053b57600080fd5b5061024261054a366004614029565b611fc8565b34801561055b57600080fd5b5061020061056a366004613f57565b61207e565b34801561057b57600080fd5b5061024261058a366004613e0b565b61222a565b34801561059b57600080fd5b506102426123bf565b6102426105b2366004614047565b6123ef565b3480156105c357600080fd5b506102426105d2366004613f57565b6126b8565b3480156105e357600080fd5b506102426105f2366004614082565b612712565b34801561060357600080fd5b50610200610612366004613f57565b61276e565b34801561062357600080fd5b5060655461039b906001600160a01b031681565b34801561064357600080fd5b50610657610652366004613f57565b6127fe565b60405160ff90911681526020016101d7565b610671612a06565b606760405180610140016040528089151581526020018761ffff168152602001600063ffffffff1681526020014263ffffffff1681526020018663ffffffff168152602001886fffffffffffffffffffffffffffffffff168152602001600081526020016000198152602001846001600160a01b03168152602001836001600160a01b0316815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c0820151816001015560e082015181600201556101008201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101208201518160040160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505060666040518060c0016040528060405180602001604052806000815250815260200160006001600160a01b03168152602001600015158152602001606461ffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001908161093f919061416a565b506020820151600182018054604080860151606087015161ffff167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff91151574010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009094166001600160a01b0396871617939093171691909117909155608084015160a0909401516fffffffffffffffffffffffffffffffff9081167001000000000000000000000000000000000294169390931760029092019190915560655491517f095ea7b300000000000000000000000000000000000000000000000000000000815284928383169263095ea7b392610a869290911690600019906004016001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015610aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac99190614248565b50806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c9190614265565b6001600160a01b0316826001600160a01b03161480610bbd5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190614265565b6001600160a01b0316826001600160a01b0316145b610c0e5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642072657761726400000000000000000000000000000000000060448201526064015b60405180910390fd5b806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190614265565b6065546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015610cdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d009190614248565b50806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d639190614265565b6065546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015610dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df39190614248565b505050505050505050565b610e06612a06565b600060668961ffff1681548110610e1f57610e1f614282565b60009182526020909120600390910201905080610e3d888a836142b1565b5060018101805461ffff9095167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff96151574010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009096166001600160a01b03909816979097179490941794909416949094179091556fffffffffffffffffffffffffffffffff92831670010000000000000000000000000000000002921691909117600290910155505050565b61ffff82166000818152606860209081526040808320338452909152812060678054929391928492908110610f4e57610f4e614282565b906000526020600020906005020190508382600001541015610fb25760405162461bcd60e51b815260206004820152601c60248201527f596f7520646f6e2774206861766520656e6f756768206c6f636b6564000000006044820152606401610c05565b805460ff161561101257610fc6853361222a565b6110125760405162461bcd60e51b815260206004820152601b60248201527f5374616b65207374696c6c20696e206c6f636b656420737461746500000000006044820152606401610c05565b61101c8533612a60565b50600080600060678861ffff168154811061103957611039614282565b600091825260208220600360059092020101546001600160a01b03169150611060826127fe565b90508060ff1660021461112f578060ff166000036110ee576110e4826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dd9190614265565b338a612baf565b9094509250611140565b6110e4826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d6000803e3d6000fd5b61113a89338a612cce565b90945092505b60408051898152426020820152339161ffff8c16917f0c93b9eaa1d0d374b80a5eaae0d66cb1f2eb8bb85c6dc5155edc99c7e4eb6b56910160405180910390a3600185015461118f9089612f02565b6001860155855461ffff8a166000908152606a602090815260408083203384529091529020546111c0908a906143be565b6111ca91906143d5565b61ffff8a166000908152606a60209081526040808320338452909152812080549091906111f8908490614410565b9091555050600186015461120c9089612f15565b6001870155855461121d9089612f02565b8087556002870180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff1617905560000361129b57845460001963ffffffff630100000080840482169290920116027fffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffff9091161785555b600196505050505050505b92915050565b6112b4612a06565b60675461ffff8916106113095760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420706f6f6c20496400000000000000000000000000000000006044820152606401610c05565b600060678961ffff168154811061132257611322614282565b60009182526020909120600590910201805463ffffffff9096166b010000000000000000000000027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff61ffff90981661010002979097167fffffffffffffffffffffffffffffffffff00000000ffffffffffffffff0000ff9915157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006fffffffffffffffffffffffffffffffff909a166f0100000000000000000000000000000002999099167fff00000000000000000000000000000000ffffffffffffffffffffffffffff0090971696909617979097179790971693909317939093179093555050505050565b60008060668461ffff168154811061144457611444614282565b90600052602060002090600302016040518060c001604052908160008201805461146d906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611499906140cc565b80156114e65780601f106114bb576101008083540402835291602001916114e6565b820191906000526020600020905b8154815290600101906020018083116114c957829003601f168201915b505050918352505060018201546001600160a01b038116602083015274010000000000000000000000000000000000000000810460ff161515604080840191909152750100000000000000000000000000000000000000000090910461ffff1660608301526002909201546fffffffffffffffffffffffffffffffff80821660808401527001000000000000000000000000000000009091041660a090910152810151909150801561159d575061159d8484611a77565b156115ae57806060015191506115b3565b606491505b5092915050565b60008060678461ffff16815481106115d4576115d4614282565b9060005260206000209060050201604051806101400160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900461ffff1661ffff1661ffff1681526020016000820160039054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160079054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600b9054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016004820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152505090506000606860008661ffff1681526020019081526020016000206000856001600160a01b03166001600160a01b031681526020019081526020016000206040518060a001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160038201548152505090506000816060015163ffffffff16826040015163ffffffff16101561183457816060015161183a565b81604001515b63ffffffff1690506000611877846020015161ffff166201518061185e91906143be565b846060015163ffffffff16612f1590919063ffffffff16565b9050600081421015611889574261188b565b815b9050828111156119515761ffff88166000908152606a602090815260408083206001600160a01b038b16845290915281205460a08701519091906301e13380906103e8906fffffffffffffffffffffffffffffffff16846118ec8988614410565b6118f691906143be565b61190091906143be565b61190a91906143d5565b61191491906143d5565b905060006119228b8b61142a565b61ffff169050606461193482846143be565b61193e91906143d5565b915061194b8260026143be565b98505050505b505050505092915050565b60606067805480602002602001604051908101604052809291908181526020016000905b82821015611a6e576000848152602090819020604080516101408101825260058602909201805460ff81161515845261010080820461ffff16858701526301000000820463ffffffff908116948601949094526701000000000000008204841660608601526b010000000000000000000000820490931660808501526f0100000000000000000000000000000090046fffffffffffffffffffffffffffffffff1660a084015260018082015460c0850152600282015460e085015260038201546001600160a01b03908116938501939093526004909101549091166101208301529083529092019101611980565b50505050905090565b60008060668461ffff1681548110611a9157611a91614282565b90600052602060002090600302016040518060c0016040529081600082018054611aba906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611ae6906140cc565b8015611b335780601f10611b0857610100808354040283529160200191611b33565b820191906000526020600020905b815481529060010190602001808311611b1657829003601f168201915b505050918352505060018201546001600160a01b03811660208084019190915274010000000000000000000000000000000000000000820460ff1615156040840152750100000000000000000000000000000000000000000090910461ffff1660608301526002909201546fffffffffffffffffffffffffffffffff80821660808401527001000000000000000000000000000000009091041660a090910152810151909150600090611be69085612f21565b905060005b8151811015611c7b5782608001516fffffffffffffffffffffffffffffffff16828281518110611c1d57611c1d614282565b602002602001015110158015611c6257508260a001516fffffffffffffffffffffffffffffffff16828281518110611c5757611c57614282565b602002602001015111155b15611c7357600193505050506112a6565b600101611beb565b50600095945050505050565b611c8f612a06565b611c9960006130ba565b565b6000611ca5612a06565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015282906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2b9190614423565b9050816001600160a01b031663a9059cbb611d4e6033546001600160a01b031690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd79190614248565b506001925050505b919050565b60668181548110611df457600080fd5b9060005260206000209060030201600091509050806000018054611e17906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611e43906140cc565b8015611e905780601f10611e6557610100808354040283529160200191611e90565b820191906000526020600020905b815481529060010190602001808311611e7357829003601f168201915b50505050600183015460029093015491926001600160a01b0381169274010000000000000000000000000000000000000000820460ff169250750100000000000000000000000000000000000000000090910461ffff16906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041686565b60678181548110611f2557600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015460ff84169550610100840461ffff16946301000000850463ffffffff9081169567010000000000000081048216956b0100000000000000000000008204909216946f010000000000000000000000000000009091046fffffffffffffffffffffffffffffffff1693919290916001600160a01b0391821691168a565b6000611fd2612a06565b826001600160a01b0381166342842e0e30611ff56033546001600160a01b031690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561205c57600080fd5b505af1158015612070573d6000803e3d6000fd5b506001979650505050505050565b600054610100900460ff161580801561209e5750600054600160ff909116105b806120b85750303b1580156120b8575060005460ff166001145b61212a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610c05565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561218857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612190613124565b606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038416179055801561222657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b61ffff821660008181526068602090815260408083206001600160a01b03861684528252808320815160a08101835281548152600182015493810193909352600281015463ffffffff8082169385019390935264010000000090049091166060830152600301546080820152606780549293919284929081106122af576122af614282565b60009182526020918290206040805161014081018252600593909302909101805460ff81161515845261010080820461ffff169585018690526301000000820463ffffffff908116948601949094526701000000000000008204841660608601526b010000000000000000000000820490931660808501526f0100000000000000000000000000000090046fffffffffffffffffffffffffffffffff1660a0840152600181015460c0840152600281015460e084015260038101546001600160a01b0390811692840192909252600401541661012082015291506123b39061239a90620151806143be565b836060015163ffffffff16612f1590919063ffffffff16565b42101595945050505050565b606754600090815b818161ffff1610156123e6576123dd8133612a60565b506001016123c7565b50600191505090565b6000806123ff8560ff1633612a60565b50600060678660ff168154811061241857612418614282565b600091825260208220600360059092020101546001600160a01b0316915061243f826127fe565b90508060ff1660021461259e578060ff16600003612500576124c3826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bc9190614265565b34876131a9565b60ff88166000908152606a602090815260408083203384529091528120805492955087929091906124f590849061443c565b9091555061269a9050565b61256c826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125659190614265565b34886131a9565b60ff88166000908152606a602090815260408083203384529091528120805492955088929091906124f590849061443c565b6125a982878761337c565b925060678760ff16815481106125c1576125c1614282565b906000526020600020906005020160040160009054906101000a90046001600160a01b03166001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561262d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126519190614265565b6001600160a01b0316146126655784612667565b855b60ff88166000908152606a602090815260408083203384529091528120805490919061269490849061443c565b90915550505b82156126ab576126ab873385613736565b5060019695505050505050565b60006126c2612a06565b6001600160a01b038216611ca5576033546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015612709573d6000803e3d6000fd5b50600192915050565b60008061271f8333612a60565b9050806127095760405162461bcd60e51b815260206004820152600c60248201527f436c61696d206661696c656400000000000000000000000000000000000000006044820152606401610c05565b612776612a06565b6001600160a01b0381166127f25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c05565b6127fb816130ba565b50565b606554604080517fad5c464800000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190614265565b6001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f09190614265565b6001600160a01b03160361290657506000919050565b606560009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297d9190614265565b6001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e89190614265565b6001600160a01b0316036129fe57506001919050565b506002919050565b6033546001600160a01b03163314611c995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c05565b60008060678461ffff1681548110612a7a57612a7a614282565b6000918252602080832061ffff881684526068825260408085206001600160a01b038916865290925292206005909102909101805490925060ff16158015612ac95750612ac7858561222a565b155b15612ad9576000925050506112a6565b6000612ae586866115ba565b90508015612b1b576004830154612b06906001600160a01b0316868361395c565b6003820154612b159082612f15565b60038301555b6002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff8116919091179091556040805161ffff8916815260208101849052908101919091526001600160a01b038616907fb299203e77a9a60499d10972f673079d610c1ac2c27d43c9b246f943b79e100f9060600160405180910390a250600195945050505050565b60655460009081906001600160a01b03166302751cec8685848089612bd542606461443c565b60405160e088901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160408051808303816000875af1158015612c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7e919061444f565b6040805186815260208101849052908101829052919350915033907f1bf2330b04d3770179ff4c475fb32cda09298555b3bd18994e447ef40554a0b99060600160405180910390a2935093915050565b600080600060678661ffff1681548110612cea57612cea614282565b600091825260209182902060036005909202010154606554604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516001600160a01b039384169550919092169263baa2abde928592630dfe1681926004808401939192918290030181865afa158015612d6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d919190614265565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df39190614265565b876000808b612e0342606461443c565b60405160e089901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039788166004820152958716602487015260448601949094526064850192909252608484015290921660a482015260c481019190915260e40160408051808303816000875af1158015612e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb1919061444f565b6040805187815260208101849052908101829052919450925033907f1bf2330b04d3770179ff4c475fb32cda09298555b3bd18994e447ef40554a0b99060600160405180910390a250935093915050565b6000612f0e8284614410565b9392505050565b6000612f0e828461443c565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526060918491600091908316906370a0823190602401602060405180830381865afa158015612f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fad9190614423565b905060008167ffffffffffffffff811115612fca57612fca61409d565b604051908082528060200260200182016040528015612ff3578160200160208202803683370190505b50905060005b828110156130b0576040517f2f745c590000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260248201839052851690632f745c5990604401602060405180830381865afa158015613067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308b9190614423565b82828151811061309d5761309d614282565b6020908102919091010152600101612ff9565b5095945050505050565b603380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166131a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610c05565b611c99613acf565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290526000906001600160a01b038516906323b872dd906064016020604051808303816000875af1158015613218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323c9190614248565b506065546001600160a01b031663f305d719848685613267606461326183605f613b55565b90613b61565b61327760646132618b605f613b55565b3061328342606461443c565b60405160e089901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160606040518083038185885af1158015613308573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061332d9190614473565b60408051878152602081018790529081018290529093503392507f7f3ebde46b99ef944a759c852815fad5951c91c558260560ea6c25e61a04cc61915060600160405180910390a29392505050565b6000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e09190614265565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590526001600160a01b0391909116906323b872dd906064016020604051808303816000875af115801561344e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134729190614248565b50836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d59190614265565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490526001600160a01b0391909116906323b872dd906064016020604051808303816000875af1158015613543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135679190614248565b50606560009054906101000a90046001600160a01b03166001600160a01b031663e8e33700856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ee9190614265565b866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561362c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136509190614265565b8686613662606461326184605f613b55565b61367260646132618b605f613b55565b3061367e42606461443c565b60405160e08a901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039889166004820152968816602488015260448701959095526064860193909352608485019190915260a484015290921660c482015260e4810191909152610104016060604051808303816000875af1158015613712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332d9190614473565b600060678460ff168154811061374e5761374e614282565b6000918252602080832060ff881684526068825260408085206001600160a01b038916865290925290832060059092020180549093509091906137c3906137a29061ffff61010090910416620151806143be565b845463ffffffff6b01000000000000000000000090910481169190612f0216565b90508042111561383b5760405162461bcd60e51b815260206004820152602160248201527f4c6f636b696e672069732064697361626c656420666f72207468697320706f6f60448201527f6c000000000000000000000000000000000000000000000000000000000000006064820152608401610c05565b8154600003613885578254600163ffffffff630100000080840482169290920116027fffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffff9091161783555b81546138919085612f15565b825560018301546138a29085612f15565b60018401556002820180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166401000000004263ffffffff81169182027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001692909217179091556040805186815260208101929092526001600160a01b0387169160ff8916917f04981a7093b262296689153516ee896fb28dcb9f6532bf9cc0b65990c186afbf910160405180910390a3505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015283906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156139be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139e29190614423565b905082811015613a345760405162461bcd60e51b815260206004820152601c60248201527f4e6f7420656e6f7567682066756e647320696e207472656173757279000000006044820152606401610c05565b8215613ac8576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301526024820185905283169063a9059cbb906044016020604051808303816000875af1158015613aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac69190614248565b505b5050505050565b600054610100900460ff16613b4c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610c05565b611c99336130ba565b6000612f0e82846143be565b6000612f0e82846143d5565b80151581146127fb57600080fd5b8035611ddf81613b6d565b80356fffffffffffffffffffffffffffffffff81168114611ddf57600080fd5b803561ffff81168114611ddf57600080fd5b803563ffffffff81168114611ddf57600080fd5b6001600160a01b03811681146127fb57600080fd5b8035611ddf81613bcc565b600080600080600080600060e0888a031215613c0757600080fd5b8735613c1281613b6d565b9650613c2060208901613b86565b9550613c2e60408901613ba6565b9450613c3c60608901613bb8565b93506080880135925060a0880135613c5381613bcc565b915060c0880135613c6381613bcc565b8091505092959891949750929550565b60008060008060008060008060e0898b031215613c8f57600080fd5b613c9889613ba6565b9750602089013567ffffffffffffffff80821115613cb557600080fd5b818b0191508b601f830112613cc957600080fd5b813581811115613cd857600080fd5b8c6020828501011115613cea57600080fd5b602083019950809850505050613d0260408a01613be1565b9450613d1060608a01613b7b565b9350613d1e60808a01613ba6565b9250613d2c60a08a01613b86565b9150613d3a60c08a01613b86565b90509295985092959890939650565b60008060408385031215613d5c57600080fd5b613d6583613ba6565b946020939093013593505050565b600080600080600080600080610100898b031215613d9057600080fd5b613d9989613ba6565b97506020890135613da981613b6d565b9650613db760408a01613b86565b9550613dc560608a01613ba6565b9450613dd360808a01613bb8565b935060a0890135925060c0890135613dea81613bcc565b915060e0890135613dfa81613bcc565b809150509295985092959890939650565b60008060408385031215613e1e57600080fd5b613e2783613ba6565b91506020830135613e3781613bcc565b809150509250929050565b60008060408385031215613e5557600080fd5b823591506020830135613e3781613bcc565b602080825282518282018190526000919060409081850190868401855b82811015613f315781518051151585528681015161ffff16878601528581015163ffffffff908116878701526060808301518216908701526080808301519091169086015260a0808201516fffffffffffffffffffffffffffffffff169086015260c0808201519086015260e08082015190860152610100808201516001600160a01b03908116918701919091526101209182015116908501526101409093019290850190600101613e84565b5091979650505050505050565b600060208284031215613f5057600080fd5b5035919050565b600060208284031215613f6957600080fd5b8135612f0e81613bcc565b60c08152600087518060c084015260005b81811015613fa2576020818b0181015160e0868401015201613f85565b50600060e0828501015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050613fef60208301886001600160a01b03169052565b941515604082015261ffff9390931660608401526fffffffffffffffffffffffffffffffff91821660808401521660a09091015292915050565b6000806040838503121561403c57600080fd5b8235613d6581613bcc565b60008060006060848603121561405c57600080fd5b833560ff8116811461406d57600080fd5b95602085013595506040909401359392505050565b60006020828403121561409457600080fd5b612f0e82613ba6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806140e057607f821691505b602082108103614119577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561416557600081815260208120601f850160051c810160208610156141465750805b601f850160051c820191505b81811015613ac657828155600101614152565b505050565b815167ffffffffffffffff8111156141845761418461409d565b6141988161419284546140cc565b8461411f565b602080601f8311600181146141cd57600084156141b55750858301515b600019600386901b1c1916600185901b178555613ac6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561421a578886015182559484019460019091019084016141fb565b50858210156142385787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121561425a57600080fd5b8151612f0e81613b6d565b60006020828403121561427757600080fd5b8151612f0e81613bcc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8311156142c9576142c961409d565b6142dd836142d783546140cc565b8361411f565b6000601f84116001811461431157600085156142f95750838201355b600019600387901b1c1916600186901b178355613ac8565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156143605786850135825560209485019460019092019101614340565b508682101561437d5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112a6576112a661438f565b60008261440b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156112a6576112a661438f565b60006020828403121561443557600080fd5b5051919050565b808201808211156112a6576112a661438f565b6000806040838503121561446257600080fd5b505080516020909101519092909150565b60008060006060848603121561448857600080fd5b835192506020840151915060408401519050925092509256fea2646970667358221220068ac8ecc8b72b05b916dd9e36f22e611957c9124e8046abe0ec855c1d905adf64736f6c63430008110033
Deployed Bytecode
0x6080604052600436106101b05760003560e01c8063a6ebb133116100ec578063d1058e591161008a578063edac5f3e11610064578063edac5f3e146105d7578063f2fde38b146105f7578063f887ea4014610617578063f9d22af91461063757600080fd5b8063d1058e591461058f578063db4e9906146105a4578063deebeac9146105b757600080fd5b8063b9d02df4116100c6578063b9d02df41461049e578063bab666c81461052f578063c4d66de81461054f578063c99e8fd81461056f57600080fd5b8063a6ebb133146103b3578063a76b114f146103d3578063ac4afa381461040557600080fd5b806356eeafd911610159578063681ce73e11610133578063681ce73e1461031f578063715018a61461033f5780638813bf9e146103545780638da5cb5b1461038157600080fd5b806356eeafd9146102a55780636439be5f146102dd578063673a2a1f146102fd57600080fd5b80632fae37111161018a5780632fae371114610222578063443153e61461025257806351258c401461027257600080fd5b8063081e3eda146101bc57806313e9cb98146101e0578063181c5acb1461020257600080fd5b366101b757005b600080fd5b3480156101c857600080fd5b506067545b6040519081526020015b60405180910390f35b3480156101ec57600080fd5b506102006101fb366004613bec565b610669565b005b34801561020e57600080fd5b5061020061021d366004613c73565b610dfe565b34801561022e57600080fd5b5061024261023d366004613d49565b610f17565b60405190151581526020016101d7565b34801561025e57600080fd5b5061020061026d366004613d73565b6112ac565b34801561027e57600080fd5b5061029261028d366004613e0b565b61142a565b60405161ffff90911681526020016101d7565b3480156102b157600080fd5b506101cd6102c0366004613e42565b606a60209081526000928352604080842090915290825290205481565b3480156102e957600080fd5b506101cd6102f8366004613e0b565b6115ba565b34801561030957600080fd5b5061031261195c565b6040516101d79190613e67565b34801561032b57600080fd5b5061024261033a366004613e0b565b611a77565b34801561034b57600080fd5b50610200611c87565b34801561036057600080fd5b506101cd61036f366004613f3e565b60696020526000908152604090205481565b34801561038d57600080fd5b506033546001600160a01b03165b6040516001600160a01b0390911681526020016101d7565b3480156103bf57600080fd5b506102426103ce366004613f57565b611c9b565b3480156103df57600080fd5b506103f36103ee366004613f3e565b611de4565b6040516101d796959493929190613f74565b34801561041157600080fd5b50610425610420366004613f3e565b611f15565b604080519a15158b5261ffff90991660208b015263ffffffff978816988a019890985294861660608901529490921660808701526fffffffffffffffffffffffffffffffff1660a086015260c085015260e08401919091526001600160a01b0390811661010084015216610120820152610140016101d7565b3480156104aa57600080fd5b506104fe6104b9366004613e42565b606860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909163ffffffff808316926401000000009004169085565b60408051958652602086019490945263ffffffff92831693850193909352166060830152608082015260a0016101d7565b34801561053b57600080fd5b5061024261054a366004614029565b611fc8565b34801561055b57600080fd5b5061020061056a366004613f57565b61207e565b34801561057b57600080fd5b5061024261058a366004613e0b565b61222a565b34801561059b57600080fd5b506102426123bf565b6102426105b2366004614047565b6123ef565b3480156105c357600080fd5b506102426105d2366004613f57565b6126b8565b3480156105e357600080fd5b506102426105f2366004614082565b612712565b34801561060357600080fd5b50610200610612366004613f57565b61276e565b34801561062357600080fd5b5060655461039b906001600160a01b031681565b34801561064357600080fd5b50610657610652366004613f57565b6127fe565b60405160ff90911681526020016101d7565b610671612a06565b606760405180610140016040528089151581526020018761ffff168152602001600063ffffffff1681526020014263ffffffff1681526020018663ffffffff168152602001886fffffffffffffffffffffffffffffffff168152602001600081526020016000198152602001846001600160a01b03168152602001836001600160a01b0316815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c0820151816001015560e082015181600201556101008201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101208201518160040160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505060666040518060c0016040528060405180602001604052806000815250815260200160006001600160a01b03168152602001600015158152602001606461ffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001908161093f919061416a565b506020820151600182018054604080860151606087015161ffff167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff91151574010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009094166001600160a01b0396871617939093171691909117909155608084015160a0909401516fffffffffffffffffffffffffffffffff9081167001000000000000000000000000000000000294169390931760029092019190915560655491517f095ea7b300000000000000000000000000000000000000000000000000000000815284928383169263095ea7b392610a869290911690600019906004016001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015610aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac99190614248565b50806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c9190614265565b6001600160a01b0316826001600160a01b03161480610bbd5750806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190614265565b6001600160a01b0316826001600160a01b0316145b610c0e5760405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642072657761726400000000000000000000000000000000000060448201526064015b60405180910390fd5b806001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190614265565b6065546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015610cdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d009190614248565b50806001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d639190614265565b6065546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015610dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df39190614248565b505050505050505050565b610e06612a06565b600060668961ffff1681548110610e1f57610e1f614282565b60009182526020909120600390910201905080610e3d888a836142b1565b5060018101805461ffff9095167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff96151574010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009096166001600160a01b03909816979097179490941794909416949094179091556fffffffffffffffffffffffffffffffff92831670010000000000000000000000000000000002921691909117600290910155505050565b61ffff82166000818152606860209081526040808320338452909152812060678054929391928492908110610f4e57610f4e614282565b906000526020600020906005020190508382600001541015610fb25760405162461bcd60e51b815260206004820152601c60248201527f596f7520646f6e2774206861766520656e6f756768206c6f636b6564000000006044820152606401610c05565b805460ff161561101257610fc6853361222a565b6110125760405162461bcd60e51b815260206004820152601b60248201527f5374616b65207374696c6c20696e206c6f636b656420737461746500000000006044820152606401610c05565b61101c8533612a60565b50600080600060678861ffff168154811061103957611039614282565b600091825260208220600360059092020101546001600160a01b03169150611060826127fe565b90508060ff1660021461112f578060ff166000036110ee576110e4826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dd9190614265565b338a612baf565b9094509250611140565b6110e4826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d6000803e3d6000fd5b61113a89338a612cce565b90945092505b60408051898152426020820152339161ffff8c16917f0c93b9eaa1d0d374b80a5eaae0d66cb1f2eb8bb85c6dc5155edc99c7e4eb6b56910160405180910390a3600185015461118f9089612f02565b6001860155855461ffff8a166000908152606a602090815260408083203384529091529020546111c0908a906143be565b6111ca91906143d5565b61ffff8a166000908152606a60209081526040808320338452909152812080549091906111f8908490614410565b9091555050600186015461120c9089612f15565b6001870155855461121d9089612f02565b8087556002870180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff1617905560000361129b57845460001963ffffffff630100000080840482169290920116027fffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffff9091161785555b600196505050505050505b92915050565b6112b4612a06565b60675461ffff8916106113095760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420706f6f6c20496400000000000000000000000000000000006044820152606401610c05565b600060678961ffff168154811061132257611322614282565b60009182526020909120600590910201805463ffffffff9096166b010000000000000000000000027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff61ffff90981661010002979097167fffffffffffffffffffffffffffffffffff00000000ffffffffffffffff0000ff9915157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006fffffffffffffffffffffffffffffffff909a166f0100000000000000000000000000000002999099167fff00000000000000000000000000000000ffffffffffffffffffffffffffff0090971696909617979097179790971693909317939093179093555050505050565b60008060668461ffff168154811061144457611444614282565b90600052602060002090600302016040518060c001604052908160008201805461146d906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611499906140cc565b80156114e65780601f106114bb576101008083540402835291602001916114e6565b820191906000526020600020905b8154815290600101906020018083116114c957829003601f168201915b505050918352505060018201546001600160a01b038116602083015274010000000000000000000000000000000000000000810460ff161515604080840191909152750100000000000000000000000000000000000000000090910461ffff1660608301526002909201546fffffffffffffffffffffffffffffffff80821660808401527001000000000000000000000000000000009091041660a090910152810151909150801561159d575061159d8484611a77565b156115ae57806060015191506115b3565b606491505b5092915050565b60008060678461ffff16815481106115d4576115d4614282565b9060005260206000209060050201604051806101400160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900461ffff1661ffff1661ffff1681526020016000820160039054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160079054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600b9054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016004820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152505090506000606860008661ffff1681526020019081526020016000206000856001600160a01b03166001600160a01b031681526020019081526020016000206040518060a001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160038201548152505090506000816060015163ffffffff16826040015163ffffffff16101561183457816060015161183a565b81604001515b63ffffffff1690506000611877846020015161ffff166201518061185e91906143be565b846060015163ffffffff16612f1590919063ffffffff16565b9050600081421015611889574261188b565b815b9050828111156119515761ffff88166000908152606a602090815260408083206001600160a01b038b16845290915281205460a08701519091906301e13380906103e8906fffffffffffffffffffffffffffffffff16846118ec8988614410565b6118f691906143be565b61190091906143be565b61190a91906143d5565b61191491906143d5565b905060006119228b8b61142a565b61ffff169050606461193482846143be565b61193e91906143d5565b915061194b8260026143be565b98505050505b505050505092915050565b60606067805480602002602001604051908101604052809291908181526020016000905b82821015611a6e576000848152602090819020604080516101408101825260058602909201805460ff81161515845261010080820461ffff16858701526301000000820463ffffffff908116948601949094526701000000000000008204841660608601526b010000000000000000000000820490931660808501526f0100000000000000000000000000000090046fffffffffffffffffffffffffffffffff1660a084015260018082015460c0850152600282015460e085015260038201546001600160a01b03908116938501939093526004909101549091166101208301529083529092019101611980565b50505050905090565b60008060668461ffff1681548110611a9157611a91614282565b90600052602060002090600302016040518060c0016040529081600082018054611aba906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611ae6906140cc565b8015611b335780601f10611b0857610100808354040283529160200191611b33565b820191906000526020600020905b815481529060010190602001808311611b1657829003601f168201915b505050918352505060018201546001600160a01b03811660208084019190915274010000000000000000000000000000000000000000820460ff1615156040840152750100000000000000000000000000000000000000000090910461ffff1660608301526002909201546fffffffffffffffffffffffffffffffff80821660808401527001000000000000000000000000000000009091041660a090910152810151909150600090611be69085612f21565b905060005b8151811015611c7b5782608001516fffffffffffffffffffffffffffffffff16828281518110611c1d57611c1d614282565b602002602001015110158015611c6257508260a001516fffffffffffffffffffffffffffffffff16828281518110611c5757611c57614282565b602002602001015111155b15611c7357600193505050506112a6565b600101611beb565b50600095945050505050565b611c8f612a06565b611c9960006130ba565b565b6000611ca5612a06565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015282906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2b9190614423565b9050816001600160a01b031663a9059cbb611d4e6033546001600160a01b031690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd79190614248565b506001925050505b919050565b60668181548110611df457600080fd5b9060005260206000209060030201600091509050806000018054611e17906140cc565b80601f0160208091040260200160405190810160405280929190818152602001828054611e43906140cc565b8015611e905780601f10611e6557610100808354040283529160200191611e90565b820191906000526020600020905b815481529060010190602001808311611e7357829003601f168201915b50505050600183015460029093015491926001600160a01b0381169274010000000000000000000000000000000000000000820460ff169250750100000000000000000000000000000000000000000090910461ffff16906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041686565b60678181548110611f2557600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015460ff84169550610100840461ffff16946301000000850463ffffffff9081169567010000000000000081048216956b0100000000000000000000008204909216946f010000000000000000000000000000009091046fffffffffffffffffffffffffffffffff1693919290916001600160a01b0391821691168a565b6000611fd2612a06565b826001600160a01b0381166342842e0e30611ff56033546001600160a01b031690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561205c57600080fd5b505af1158015612070573d6000803e3d6000fd5b506001979650505050505050565b600054610100900460ff161580801561209e5750600054600160ff909116105b806120b85750303b1580156120b8575060005460ff166001145b61212a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610c05565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561218857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612190613124565b606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038416179055801561222657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b61ffff821660008181526068602090815260408083206001600160a01b03861684528252808320815160a08101835281548152600182015493810193909352600281015463ffffffff8082169385019390935264010000000090049091166060830152600301546080820152606780549293919284929081106122af576122af614282565b60009182526020918290206040805161014081018252600593909302909101805460ff81161515845261010080820461ffff169585018690526301000000820463ffffffff908116948601949094526701000000000000008204841660608601526b010000000000000000000000820490931660808501526f0100000000000000000000000000000090046fffffffffffffffffffffffffffffffff1660a0840152600181015460c0840152600281015460e084015260038101546001600160a01b0390811692840192909252600401541661012082015291506123b39061239a90620151806143be565b836060015163ffffffff16612f1590919063ffffffff16565b42101595945050505050565b606754600090815b818161ffff1610156123e6576123dd8133612a60565b506001016123c7565b50600191505090565b6000806123ff8560ff1633612a60565b50600060678660ff168154811061241857612418614282565b600091825260208220600360059092020101546001600160a01b0316915061243f826127fe565b90508060ff1660021461259e578060ff16600003612500576124c3826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bc9190614265565b34876131a9565b60ff88166000908152606a602090815260408083203384529091528120805492955087929091906124f590849061443c565b9091555061269a9050565b61256c826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125659190614265565b34886131a9565b60ff88166000908152606a602090815260408083203384529091528120805492955088929091906124f590849061443c565b6125a982878761337c565b925060678760ff16815481106125c1576125c1614282565b906000526020600020906005020160040160009054906101000a90046001600160a01b03166001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561262d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126519190614265565b6001600160a01b0316146126655784612667565b855b60ff88166000908152606a602090815260408083203384529091528120805490919061269490849061443c565b90915550505b82156126ab576126ab873385613736565b5060019695505050505050565b60006126c2612a06565b6001600160a01b038216611ca5576033546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015612709573d6000803e3d6000fd5b50600192915050565b60008061271f8333612a60565b9050806127095760405162461bcd60e51b815260206004820152600c60248201527f436c61696d206661696c656400000000000000000000000000000000000000006044820152606401610c05565b612776612a06565b6001600160a01b0381166127f25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c05565b6127fb816130ba565b50565b606554604080517fad5c464800000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190614265565b6001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f09190614265565b6001600160a01b03160361290657506000919050565b606560009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297d9190614265565b6001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e89190614265565b6001600160a01b0316036129fe57506001919050565b506002919050565b6033546001600160a01b03163314611c995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c05565b60008060678461ffff1681548110612a7a57612a7a614282565b6000918252602080832061ffff881684526068825260408085206001600160a01b038916865290925292206005909102909101805490925060ff16158015612ac95750612ac7858561222a565b155b15612ad9576000925050506112a6565b6000612ae586866115ba565b90508015612b1b576004830154612b06906001600160a01b0316868361395c565b6003820154612b159082612f15565b60038301555b6002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff8116919091179091556040805161ffff8916815260208101849052908101919091526001600160a01b038616907fb299203e77a9a60499d10972f673079d610c1ac2c27d43c9b246f943b79e100f9060600160405180910390a250600195945050505050565b60655460009081906001600160a01b03166302751cec8685848089612bd542606461443c565b60405160e088901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160408051808303816000875af1158015612c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7e919061444f565b6040805186815260208101849052908101829052919350915033907f1bf2330b04d3770179ff4c475fb32cda09298555b3bd18994e447ef40554a0b99060600160405180910390a2935093915050565b600080600060678661ffff1681548110612cea57612cea614282565b600091825260209182902060036005909202010154606554604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290516001600160a01b039384169550919092169263baa2abde928592630dfe1681926004808401939192918290030181865afa158015612d6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d919190614265565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df39190614265565b876000808b612e0342606461443c565b60405160e089901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039788166004820152958716602487015260448601949094526064850192909252608484015290921660a482015260c481019190915260e40160408051808303816000875af1158015612e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb1919061444f565b6040805187815260208101849052908101829052919450925033907f1bf2330b04d3770179ff4c475fb32cda09298555b3bd18994e447ef40554a0b99060600160405180910390a250935093915050565b6000612f0e8284614410565b9392505050565b6000612f0e828461443c565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526060918491600091908316906370a0823190602401602060405180830381865afa158015612f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fad9190614423565b905060008167ffffffffffffffff811115612fca57612fca61409d565b604051908082528060200260200182016040528015612ff3578160200160208202803683370190505b50905060005b828110156130b0576040517f2f745c590000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260248201839052851690632f745c5990604401602060405180830381865afa158015613067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308b9190614423565b82828151811061309d5761309d614282565b6020908102919091010152600101612ff9565b5095945050505050565b603380546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166131a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610c05565b611c99613acf565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290526000906001600160a01b038516906323b872dd906064016020604051808303816000875af1158015613218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323c9190614248565b506065546001600160a01b031663f305d719848685613267606461326183605f613b55565b90613b61565b61327760646132618b605f613b55565b3061328342606461443c565b60405160e089901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160606040518083038185885af1158015613308573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061332d9190614473565b60408051878152602081018790529081018290529093503392507f7f3ebde46b99ef944a759c852815fad5951c91c558260560ea6c25e61a04cc61915060600160405180910390a29392505050565b6000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e09190614265565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590526001600160a01b0391909116906323b872dd906064016020604051808303816000875af115801561344e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134729190614248565b50836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d59190614265565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490526001600160a01b0391909116906323b872dd906064016020604051808303816000875af1158015613543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135679190614248565b50606560009054906101000a90046001600160a01b03166001600160a01b031663e8e33700856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ee9190614265565b866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561362c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136509190614265565b8686613662606461326184605f613b55565b61367260646132618b605f613b55565b3061367e42606461443c565b60405160e08a901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039889166004820152968816602488015260448701959095526064860193909352608485019190915260a484015290921660c482015260e4810191909152610104016060604051808303816000875af1158015613712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332d9190614473565b600060678460ff168154811061374e5761374e614282565b6000918252602080832060ff881684526068825260408085206001600160a01b038916865290925290832060059092020180549093509091906137c3906137a29061ffff61010090910416620151806143be565b845463ffffffff6b01000000000000000000000090910481169190612f0216565b90508042111561383b5760405162461bcd60e51b815260206004820152602160248201527f4c6f636b696e672069732064697361626c656420666f72207468697320706f6f60448201527f6c000000000000000000000000000000000000000000000000000000000000006064820152608401610c05565b8154600003613885578254600163ffffffff630100000080840482169290920116027fffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffff9091161783555b81546138919085612f15565b825560018301546138a29085612f15565b60018401556002820180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166401000000004263ffffffff81169182027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001692909217179091556040805186815260208101929092526001600160a01b0387169160ff8916917f04981a7093b262296689153516ee896fb28dcb9f6532bf9cc0b65990c186afbf910160405180910390a3505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015283906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156139be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139e29190614423565b905082811015613a345760405162461bcd60e51b815260206004820152601c60248201527f4e6f7420656e6f7567682066756e647320696e207472656173757279000000006044820152606401610c05565b8215613ac8576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301526024820185905283169063a9059cbb906044016020604051808303816000875af1158015613aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac69190614248565b505b5050505050565b600054610100900460ff16613b4c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610c05565b611c99336130ba565b6000612f0e82846143be565b6000612f0e82846143d5565b80151581146127fb57600080fd5b8035611ddf81613b6d565b80356fffffffffffffffffffffffffffffffff81168114611ddf57600080fd5b803561ffff81168114611ddf57600080fd5b803563ffffffff81168114611ddf57600080fd5b6001600160a01b03811681146127fb57600080fd5b8035611ddf81613bcc565b600080600080600080600060e0888a031215613c0757600080fd5b8735613c1281613b6d565b9650613c2060208901613b86565b9550613c2e60408901613ba6565b9450613c3c60608901613bb8565b93506080880135925060a0880135613c5381613bcc565b915060c0880135613c6381613bcc565b8091505092959891949750929550565b60008060008060008060008060e0898b031215613c8f57600080fd5b613c9889613ba6565b9750602089013567ffffffffffffffff80821115613cb557600080fd5b818b0191508b601f830112613cc957600080fd5b813581811115613cd857600080fd5b8c6020828501011115613cea57600080fd5b602083019950809850505050613d0260408a01613be1565b9450613d1060608a01613b7b565b9350613d1e60808a01613ba6565b9250613d2c60a08a01613b86565b9150613d3a60c08a01613b86565b90509295985092959890939650565b60008060408385031215613d5c57600080fd5b613d6583613ba6565b946020939093013593505050565b600080600080600080600080610100898b031215613d9057600080fd5b613d9989613ba6565b97506020890135613da981613b6d565b9650613db760408a01613b86565b9550613dc560608a01613ba6565b9450613dd360808a01613bb8565b935060a0890135925060c0890135613dea81613bcc565b915060e0890135613dfa81613bcc565b809150509295985092959890939650565b60008060408385031215613e1e57600080fd5b613e2783613ba6565b91506020830135613e3781613bcc565b809150509250929050565b60008060408385031215613e5557600080fd5b823591506020830135613e3781613bcc565b602080825282518282018190526000919060409081850190868401855b82811015613f315781518051151585528681015161ffff16878601528581015163ffffffff908116878701526060808301518216908701526080808301519091169086015260a0808201516fffffffffffffffffffffffffffffffff169086015260c0808201519086015260e08082015190860152610100808201516001600160a01b03908116918701919091526101209182015116908501526101409093019290850190600101613e84565b5091979650505050505050565b600060208284031215613f5057600080fd5b5035919050565b600060208284031215613f6957600080fd5b8135612f0e81613bcc565b60c08152600087518060c084015260005b81811015613fa2576020818b0181015160e0868401015201613f85565b50600060e0828501015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050613fef60208301886001600160a01b03169052565b941515604082015261ffff9390931660608401526fffffffffffffffffffffffffffffffff91821660808401521660a09091015292915050565b6000806040838503121561403c57600080fd5b8235613d6581613bcc565b60008060006060848603121561405c57600080fd5b833560ff8116811461406d57600080fd5b95602085013595506040909401359392505050565b60006020828403121561409457600080fd5b612f0e82613ba6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806140e057607f821691505b602082108103614119577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561416557600081815260208120601f850160051c810160208610156141465750805b601f850160051c820191505b81811015613ac657828155600101614152565b505050565b815167ffffffffffffffff8111156141845761418461409d565b6141988161419284546140cc565b8461411f565b602080601f8311600181146141cd57600084156141b55750858301515b600019600386901b1c1916600185901b178555613ac6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561421a578886015182559484019460019091019084016141fb565b50858210156142385787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121561425a57600080fd5b8151612f0e81613b6d565b60006020828403121561427757600080fd5b8151612f0e81613bcc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8311156142c9576142c961409d565b6142dd836142d783546140cc565b8361411f565b6000601f84116001811461431157600085156142f95750838201355b600019600387901b1c1916600186901b178355613ac8565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156143605786850135825560209485019460019092019101614340565b508682101561437d5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112a6576112a661438f565b60008261440b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156112a6576112a661438f565b60006020828403121561443557600080fd5b5051919050565b808201808211156112a6576112a661438f565b6000806040838503121561446257600080fd5b505080516020909101519092909150565b60008060006060848603121561448857600080fd5b835192506020840151915060408401519050925092509256fea2646970667358221220068ac8ecc8b72b05b916dd9e36f22e611957c9124e8046abe0ec855c1d905adf64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.