Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
RewardDrippingVault
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 777 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { IWrappedToken } from "./IWrappedToken.sol"; import { RebasingReflectionToken } from "./RebasingReflectionToken.sol"; import { IUniswapV2Router } from "./IUniswapV2Router.sol"; import { IUniswapV2Factory } from "./IUniswapV2Factory.sol"; import { IUniswapV2Pair } from "./IUniswapV2Pair.sol"; uint256 constant M = 1; uint256 constant N = 9; // virtual deposit contract with PLS/pWBTC/pDAI/pGRO rewards, with 11% in and out fees, 1% burned, 7% to drip pool, 1% to boosted stakers (boost by depositing pGRO) 2% instant divs contract RewardDrippingVault is Initializable, Ownable, ReentrancyGuard { using Address for address payable; using SafeERC20 for IERC20; struct AccountInfo { uint256 amount; uint256 burned; uint256[M] drip; uint256[M] boost; uint256[M] accDripDebt; uint256[M] accBoostDebt; uint256[N] reward; uint256[N] accRewardDebt; bool whitelisted; bool exists; uint256 reserved0; uint256 reserved1; uint256 reserved2; } function accountInfoDrip(address _account, uint256 _i) external view returns (uint256 _drip, uint256 _boost, uint256 _accDripDebt, uint256 _accBoostDebt) { AccountInfo storage _accountInfo = accountInfo[_account]; return (_accountInfo.drip[_i], _accountInfo.boost[_i], _accountInfo.accDripDebt[_i], _accountInfo.accBoostDebt[_i]); } function accountInfoReward(address _account, uint256 _i) external view returns (uint256 _reward, uint256 _accRewardDebt) { AccountInfo storage _accountInfo = accountInfo[_account]; return (_accountInfo.reward[_i], _accountInfo.accRewardDebt[_i]); } address constant FURNACE = 0x000000000000000000000000000000000000dEaD; address constant BOOST_ADDRESS = 0x3Ad2234eBFED9dEEfab94B9719aEbc07f8510D47; address constant ROUTER = 0xa6AD18C2aC47803E193F75c3677b14BF19B94883; //v1 router uint256 constant DEFAULT_LAUNCH_TIME = 1740542400; // Thu Jun 06 2024 16:00:00 GMT+0000 uint256 constant DEFAULT_DRIP_RATE_PER_DAY = 1e16; // 1% per day uint256 constant DEFAULT_DRIP_BOOST_RATE_PER_DAY = 1e16; // 1% per day uint256 constant DAY = 1 days; uint256 constant TZ_OFFSET = 16 hours; // UTC-8 address public reserveToken; // WMM address public boostToken; // BoostToken address[M] public dripToken; address[N] public rewardToken; address public wrappedToken; uint256 public launchTime; uint256[M] public dripRatePerDay; uint256[M] public dripBoostRatePerDay; bool public whitelistAll; uint256 public totalStaked; // total staked balance uint256 public totalBurned; // total burned balance uint256[M] public totalDrip; // total drip pool balance uint256[M] public allocDrip; // total drip pool balance allocated uint256[M] public totalBoost; // total boost balance uint256[M] public accDripPerShare; uint256[M] public accBoostPerShare; uint256[N] public totalReward; uint256[N] public accRewardPerShare; uint64 public day; address[] public accountIndex; mapping(address => AccountInfo) public accountInfo; function accountIndexLength() external view returns (uint256 _length) { return accountIndex.length; } function getAccountByIndex(uint256 _index) external view returns (AccountInfo memory _accountInfo) { return accountInfo[accountIndex[_index]]; } function today() public view returns (uint64 _today) { return uint64((block.timestamp + TZ_OFFSET) / DAY); } modifier hasLaunched() { require(block.timestamp >= launchTime, "unavailable"); _; } constructor(address _reserveToken, address[M] memory _dripToken, address[N] memory _rewardToken, address _boostToken, address _wrappedToken) { initialize(msg.sender, _reserveToken, _dripToken, _rewardToken, _boostToken, _wrappedToken); } function initialize(address _owner, address _reserveToken, address[M] memory _dripToken, address[N] memory _rewardToken, address _boostToken, address _wrappedToken) public initializer { _transferOwnership(_owner); launchTime = DEFAULT_LAUNCH_TIME; for (uint256 _i = 0; _i < M; _i++) { dripRatePerDay[_i] = DEFAULT_DRIP_RATE_PER_DAY; dripBoostRatePerDay[_i] = DEFAULT_DRIP_BOOST_RATE_PER_DAY; } whitelistAll = false; totalStaked = 0; totalBurned = 0; for (uint256 _i = 0; _i < M; _i++) { totalDrip[_i] = 0; allocDrip[_i] = 0; totalBoost[_i] = 0; accDripPerShare[_i] = 0; accBoostPerShare[_i] = 0; } for (uint256 _i = 0; _i < N; _i++) { totalReward[_i] = 0; accRewardPerShare[_i] = 0; } day = today(); for (uint256 _i = 0; _i < M; _i++) { for (uint256 _j = 0; _j < _i; _j++) { require(_dripToken[_i] != _dripToken[_j], "invalid token"); } } for (uint256 _i = 0; _i < N; _i++) { for (uint256 _j = 0; _j < _i; _j++) { require(_rewardToken[_i] != _rewardToken[_j], "invalid token"); } } require(_dripToken[0] == _reserveToken, "invalid token"); for (uint256 _i = 1; _i < M; _i++) { bool _found = false; for (uint256 _j = 0; _j < N; _j++) { if (_dripToken[_i] == _rewardToken[_j]) { _found = true; break; } } require(_found, "invalid token"); } for (uint256 _i = 0; _i < N; _i++) { require(_rewardToken[_i] != _reserveToken, "invalid token"); } require(_wrappedToken != _reserveToken, "invalid token"); reserveToken = _reserveToken; boostToken = _boostToken; dripToken = _dripToken; rewardToken = _rewardToken; wrappedToken = _wrappedToken; RebasingReflectionToken(payable(_reserveToken)).updateExcludeFromRewards(false); } // updates the launch time function setLaunchTime(uint256 _launchTime) external onlyOwner { require(block.timestamp < launchTime, "unavailable"); require(_launchTime >= block.timestamp, "invalid time"); launchTime = _launchTime; } // updates the percentual rate of distribution from the drip pool function setDripRatePerDay(uint256 _i, uint256 _dripRatePerDay) external onlyOwner { require(_i < M, "invalid index"); require(_dripRatePerDay + dripBoostRatePerDay[_i] <= 100e16, "invalid rate"); dripRatePerDay[_i] = _dripRatePerDay; } // updates the percentual rate of distribution from the drip pool function setDripBoostRatePerDay(uint256 _i, uint256 _dripBoostRatePerDay) external onlyOwner { require(_i < M, "invalid index"); require(dripRatePerDay[_i] + _dripBoostRatePerDay <= 100e16, "invalid rate"); dripBoostRatePerDay[_i] = _dripBoostRatePerDay; } // flags all accounts for withdrawing without penalty (useful for migration) function updateWhitelistAll(bool _whitelistAll) external onlyOwner { whitelistAll = _whitelistAll; } // flags multiple accounts for withdrawing without penalty function updateWhitelist(address[] calldata _accounts, bool _whitelisted) external onlyOwner { for (uint256 _i; _i < _accounts.length; _i++) { accountInfo[_accounts[_i]].whitelisted = _whitelisted; } } // this is a safety net method for recovering funds that are not being used function recoverFunds(address _token) external onlyOwner nonReentrant { for (uint256 _i = 0; _i < N; _i++) { require(_token != rewardToken[_i], "invalid token"); } uint256 _amount = IERC20(_token).balanceOf(address(this)); if (_token == reserveToken){ _amount -= totalStaked + totalDrip[0] + totalBoost[0]; } require(_amount > 0, "no balance"); IERC20(_token).safeTransfer(msg.sender, _amount); } // burns pGRO function burn(uint256 _amount) external { burnOnBehalfOf(_amount, msg.sender); } // burns pGRO on behalf of another account function burnOnBehalfOf(uint256 _amount, address _account) public hasLaunched nonReentrant { require(_amount > 0, "invalid amount"); _updateDay(); _updateAccount(_account, 0, _amount); totalBurned += _amount; IERC20(boostToken).safeTransferFrom(msg.sender, FURNACE, _amount); emit Burn(_account, boostToken, _amount); } // stakes 4WMM function deposit(uint256 _amount) external hasLaunched nonReentrant { _deposit(msg.sender, _amount, msg.sender); emit Deposit(msg.sender, reserveToken, _amount); } // stakes 4WMM on behalf of another account function depositOnBehalfOf(uint256 _amount, address _account) external hasLaunched nonReentrant { _deposit(msg.sender, _amount, _account); emit Deposit(_account, reserveToken, _amount); } function _deposit(address _sender, uint256 _amount, address _account) internal { require(_amount > 0, "invalid amount"); _updateDay(); if (_sender != address(this)) { uint256 _balance = IERC20(reserveToken).balanceOf(address(this)); IERC20(reserveToken).safeTransferFrom(_sender, address(this), _amount); _amount = IERC20(reserveToken).balanceOf(address(this)) - _balance; } uint256 _1percent = _amount * 1e16 / 100e16; uint256 _dripAmount = 9 * _1percent; uint256 _netAmount = _amount - (11 * _1percent); // 9% accounted for the drip pool totalDrip[0] += _dripAmount; // 2% instant rewards (only 7% actually go to the drip pool) if (totalStaked > 0) { accDripPerShare[0] += (2 * _1percent) * 1e36 / totalStaked; allocDrip[0] += 2 * _1percent; } // rewards users for pGRO burned if (totalBurned > 0) { accBoostPerShare[0] += _1percent * 1e36 / totalBurned; totalBoost[0] += _1percent; } _updateAccount(_account, int256(_netAmount), 0); totalStaked += _netAmount; IERC20(reserveToken).safeTransfer(FURNACE, _1percent); } // unstakes 4WMM function withdraw(uint256 _amount) external nonReentrant { require(_amount > 0, "invalid amount"); AccountInfo storage _accountInfo = accountInfo[msg.sender]; uint256 _available = _accountInfo.amount; require(_amount <= _available, "insufficient balance"); _updateDay(); _updateAccount(msg.sender, -int256(_amount), 0); totalStaked -= _amount; if (_accountInfo.whitelisted || whitelistAll) { IERC20(reserveToken).safeTransfer(msg.sender, _amount); } else { uint256 _1percent = _amount * 1e16 / 100e16; uint256 _dripAmount = 9 * _1percent; uint256 _netAmount = _amount - (11 * _1percent); // 9% accounted for the drip pool totalDrip[0] += _dripAmount; // 2% instant rewards (only 7% actually go to the drip pool) if (totalStaked > 0) { accDripPerShare[0] += (2 * _1percent) * 1e36 / totalStaked; allocDrip[0] += 2 * _1percent; } // rewards users for pGRO burned if (totalBurned > 0) { accBoostPerShare[0] += _1percent * 1e36 / totalBurned; totalBoost[0] += _1percent; } IERC20(reserveToken).safeTransfer(FURNACE, _1percent); IERC20(reserveToken).safeTransfer(msg.sender, _netAmount); } emit Withdraw(msg.sender, reserveToken, _amount); } // claims 4WMM/pDAI function claimDrip(uint256 _i) external nonReentrant returns (uint256 _dripAmount, uint256 _boostAmount) { require(_i < M, "invalid index"); _updateDay(); _updateAccount(msg.sender, 0, 0); AccountInfo storage _accountInfo = accountInfo[msg.sender]; _dripAmount = _accountInfo.drip[_i]; _boostAmount = _accountInfo.boost[_i]; if (_dripAmount > 0) { _accountInfo.drip[_i] = 0; totalDrip[_i] -= _dripAmount; allocDrip[_i] -= _dripAmount; } if (_boostAmount > 0) { _accountInfo.boost[_i] = 0; totalBoost[_i] -= _boostAmount; } uint256 _dripPlusBoostAmount = _dripAmount + _boostAmount; if (_dripPlusBoostAmount > 0) { _safeTransfer(dripToken[_i], msg.sender, _dripPlusBoostAmount); } emit Claim(msg.sender, dripToken[_i], _dripAmount); emit Claim(msg.sender, dripToken[_i], _boostAmount); return (_dripAmount, _boostAmount); } // claims PLS/pWBTC/pDAI/pGRO function claimReward(uint256 _i) external nonReentrant returns (uint256 _rewardAmount) { require(_i < N, "invalid index"); _updateDay(); _updateAccount(msg.sender, 0, 0); AccountInfo storage _accountInfo = accountInfo[msg.sender]; _rewardAmount = _accountInfo.reward[_i]; if (_rewardAmount > 0) { _accountInfo.reward[_i] = 0; totalReward[_i] -= _rewardAmount; } if (_rewardAmount > 0) { _safeTransfer(rewardToken[_i], msg.sender, _rewardAmount); } emit Claim(msg.sender, rewardToken[_i], _rewardAmount); return _rewardAmount; } // claims all (w4MM/pDAI and PLS/pWBTC/pDAI/pGRO) function claimAll() external nonReentrant returns (uint256[M] memory _dripAmount, uint256[M] memory _boostAmount, uint256[N] memory _rewardAmount) { _updateDay(); _updateAccount(msg.sender, 0, 0); AccountInfo storage _accountInfo = accountInfo[msg.sender]; for (uint256 _i = 0; _i < M; _i++) { _dripAmount[_i] = _accountInfo.drip[_i]; _boostAmount[_i] = _accountInfo.boost[_i]; } for (uint256 _i = 0; _i < N; _i++) { _rewardAmount[_i] = _accountInfo.reward[_i]; } for (uint256 _i = 0; _i < M; _i++) { if (_dripAmount[_i] > 0) { _accountInfo.drip[_i] = 0; totalDrip[_i] -= _dripAmount[_i]; allocDrip[_i] -= _dripAmount[_i]; } if (_boostAmount[_i] > 0) { _accountInfo.boost[_i] = 0; totalBoost[_i] -= _boostAmount[_i]; } } for (uint256 _i = 0; _i < N; _i++) { if (_rewardAmount[_i] > 0) { _accountInfo.reward[_i] = 0; totalReward[_i] -= _rewardAmount[_i]; } } for (uint256 _i = 0; _i < M; _i++) { uint256 _dripPlusBoostAmount = _dripAmount[_i] + _boostAmount[_i]; if (_dripPlusBoostAmount > 0) { _safeTransfer(dripToken[_i], msg.sender, _dripPlusBoostAmount); } } for (uint256 _i = 0; _i < N; _i++) { if (_rewardAmount[_i] > 0) { _safeTransfer(rewardToken[_i], msg.sender, _rewardAmount[_i]); } } for (uint256 _i = 0; _i < M; _i++) { emit Claim(msg.sender, dripToken[_i], _dripAmount[_i]); emit Claim(msg.sender, dripToken[_i], _boostAmount[_i]); } for (uint256 _i = 0; _i < N; _i++) { emit Claim(msg.sender, rewardToken[_i], _rewardAmount[_i]); } return (_dripAmount, _boostAmount, _rewardAmount); } // compounds 4WMM function compoundDrip(uint256 _i) external nonReentrant returns (uint256 _dripAmount, uint256 _boostAmount) { require(_i < M, "invalid index"); require(dripToken[_i] == reserveToken, "invalid token"); _updateDay(); _updateAccount(msg.sender, 0, 0); AccountInfo storage _accountInfo = accountInfo[msg.sender]; _dripAmount = _accountInfo.drip[_i]; _boostAmount = _accountInfo.boost[_i]; if (_dripAmount > 0) { _accountInfo.drip[_i] = 0; totalDrip[_i] -= _dripAmount; allocDrip[_i] -= _dripAmount; } if (_boostAmount > 0) { _accountInfo.boost[_i] = 0; totalBoost[_i] -= _boostAmount; } uint256 _dripPlusBoostAmount = _dripAmount + _boostAmount; if (_dripPlusBoostAmount > 0) { _deposit(address(this), _dripPlusBoostAmount, msg.sender); } emit Compound(msg.sender, dripToken[_i], _dripAmount); emit Compound(msg.sender, dripToken[_i], _boostAmount); return (_dripAmount, _boostAmount); } // sends 4WMM/pDAI to the drip pool function donateDrip(uint256 _i, uint256 _amount) external nonReentrant { require(_i < M, "invalid index"); require(_amount > 0, "invalid amount"); _updateDay(); { uint256 _balance = IERC20(dripToken[_i]).balanceOf(address(this)); IERC20(dripToken[_i]).safeTransferFrom(msg.sender, address(this), _amount); _amount = IERC20(dripToken[_i]).balanceOf(address(this)) - _balance; } if (dripToken[_i] == wrappedToken) { IWrappedToken(dripToken[_i]).withdraw(_amount); } totalDrip[_i] += _amount; emit DonateDrip(msg.sender, dripToken[_i], _amount); } // sends PLS/pWBTC/pDAI/pGRO to all stakers function rewardAll(uint256 _i, uint256 _amount) external nonReentrant { require(_i < N, "invalid index"); require(_amount > 0, "invalid amount"); _updateDay(); require (totalStaked > 0, "no deposits"); { uint256 _balance = IERC20(rewardToken[_i]).balanceOf(address(this)); IERC20(rewardToken[_i]).safeTransferFrom(msg.sender, address(this), _amount); _amount = IERC20(rewardToken[_i]).balanceOf(address(this)) - _balance; } if (rewardToken[_i] == wrappedToken) { IWrappedToken(rewardToken[_i]).withdraw(_amount); } accRewardPerShare[_i] += _amount * 1e18 / totalStaked; totalReward[_i] += _amount; emit RewardAll(msg.sender, rewardToken[_i], _amount); } // performs the daily distribution from the drip pool (GRO) function updateDay() external nonReentrant { _updateDay(); } function _updateDay() internal { uint64 _today = today(); if (day == _today) return; for (uint256 _i = 0; _i < M; _i++) { uint256 _ratePerDay = dripRatePerDay[_i] + dripBoostRatePerDay[_i]; if (_ratePerDay > 0) { // calculates the percentage of the drip pool and distributes { // formula: drip_reward = drip_pool_balance * (1 - (1 - drip_rate_per_day) ^ days_ellapsed) uint64 _days = _today - day; uint256 _rate = 100e16 - _exp(100e16 - _ratePerDay, _days); uint256 _amount = (totalDrip[_i] - allocDrip[_i]) * _rate / 100e16; uint256 _amountDrip = _amount * dripRatePerDay[_i] / _ratePerDay; if (totalStaked > 0) { accDripPerShare[_i] += _amountDrip * 1e36 / totalStaked; allocDrip[_i] += _amountDrip; } uint256 _amountBoost = _amount - _amountDrip; if (totalBurned > 0) { accBoostPerShare[_i] += _amountBoost * 1e36 / totalBurned; totalDrip[_i] -= _amountBoost; totalBoost[_i] += _amountBoost; } } } } if (totalStaked > 0) { // claims rewards IERC20(reserveToken).safeTransfer(address(this), 0); for (uint256 _i = 0; _i < N; _i++) { uint256 _amount = _balanceOf(rewardToken[_i], address(this)) - totalReward[_i]; for (uint256 _j = 1; _j < M; _j++) { if (dripToken[_j] == rewardToken[_i]) { _amount -= totalDrip[_j] + totalBoost[_j]; break; } } if (_amount > 0) { accRewardPerShare[_i] += _amount * 1e36 / totalStaked; totalReward[_i] += _amount; } } } day = _today; } // updates the account balances while accumulating reward/drip/boost using PCS distribution algorithm function _updateAccount(address _account, int256 _amount, uint256 _burned) internal { AccountInfo storage _accountInfo = accountInfo[_account]; if (!_accountInfo.exists) { // adds account to index _accountInfo.exists = true; accountIndex.push(_account); } for (uint256 _i = 0; _i < M; _i++) { _accountInfo.drip[_i] += _accountInfo.amount * accDripPerShare[_i] / 1e36 - _accountInfo.accDripDebt[_i]; _accountInfo.boost[_i] += _accountInfo.burned * accBoostPerShare[_i] / 1e36 - _accountInfo.accBoostDebt[_i]; } for (uint256 _i = 0; _i < N; _i++) { _accountInfo.reward[_i] += _accountInfo.amount * accRewardPerShare[_i] / 1e36 - _accountInfo.accRewardDebt[_i]; } if (_amount > 0) { _accountInfo.amount += uint256(_amount); } else if (_amount < 0) { _accountInfo.amount -= uint256(-_amount); } _accountInfo.burned += _burned; for (uint256 _i = 0; _i < M; _i++) { _accountInfo.accDripDebt[_i] = _accountInfo.amount * accDripPerShare[_i] / 1e36; _accountInfo.accBoostDebt[_i] = _accountInfo.burned * accBoostPerShare[_i] / 1e36; } for (uint256 _i = 0; _i < N; _i++) { _accountInfo.accRewardDebt[_i] = _accountInfo.amount * accRewardPerShare[_i] / 1e36; } } function _balanceOf(address _token, address _account) internal view returns (uint256 _balance) { return _token == wrappedToken ? payable(_account).balance : IERC20(_token).balanceOf(_account); } function _safeTransfer(address _token, address _account, uint256 _amount) internal { _token == wrappedToken ? payable(_account).sendValue(_amount) : IERC20(_token).safeTransfer(_account, _amount); } // exponentiation with integer exponent function _exp(uint256 _x, uint256 _n) internal pure returns (uint256 _y) { _y = 1e18; while (_n > 0) { if (_n & 1 != 0) _y = _y * _x / 1e18; _n >>= 1; _x = _x * _x / 1e18; } return _y; } receive() external payable {} event Burn(address indexed _account, address indexed _boostToken, uint256 _amount); event Deposit(address indexed _account, address indexed _reserveToken, uint256 _amount); event Withdraw(address indexed _account, address indexed _reserveToken, uint256 _amount); event Claim(address indexed _account, address indexed _reserveToken, uint256 _amount); event Compound(address indexed _account, address indexed _reserveToken, uint256 _amount); event RewardAll(address indexed _account, address indexed _rewardToken, uint256 _amount); event DonateDrip(address indexed _account, address indexed _reserveToken, uint256 _amount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @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 a proxied contract can't have 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. * * 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 initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; interface IUniswapV2Factory { function getPair(address _tokenA, address _tokenB) external view returns (address _pair); function createPair(address _tokenA, address _tokenB) external returns (address _pair); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; interface IUniswapV2Pair { function sync() external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; interface IUniswapV2Router { function factory() external view returns (address _factory); function swapExactTokensForTokens( uint256 _amountIn, uint256 _amountOutMin, address[] calldata _path, address _to, uint256 _deadline ) external returns (uint256[] memory _amounts); function swapExactTokensForETH( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; interface IWrappedToken { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; function approve(address spender, uint256 value) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { IUniswapV2Router } from "./IUniswapV2Router.sol"; import { IUniswapV2Factory } from "./IUniswapV2Factory.sol"; import { IUniswapV2Pair } from "./IUniswapV2Pair.sol"; import { IWrappedToken } from "./IWrappedToken.sol"; uint256 constant N = 9; contract Silo { using SafeERC20 for IERC20; constructor(address[N] memory _rewardTokens) { for (uint256 _i = 0; _i < N; _i++) { IERC20(_rewardTokens[_i]).safeApprove(msg.sender, type(uint256).max); } } } library LibSilo { function createSilo(address[N] memory _rewardTokens) public returns (address _silo) { return address(new Silo(_rewardTokens)); } } contract RebasingReflectionToken is Ownable, ERC20 { using Address for address; using Address for address payable; using SafeERC20 for IERC20; struct AccountInfo { bool exists; // existence flag bool excludeFromRewards; // whether or not receive rewards uint256 activeBalance; // 0 or user's balance uint256[N] rewardDebt; // base for reward distribution uint256[N] unclaimedReward; // reward balance available for claim uint256[N] minimumRewardBalanceToClaim; // minimum unclaimed balance to auto claim } address constant FURNACE = 0x000000000000000000000000000000000000dEaD; address constant INTERNAL_ADDRESS = address(1); // used internally to record pending rebase balances uint256 constant BUY_FEE = 6e16; // 6% uint256 constant SELL_FEE = 9e16; // 9% uint256 constant DEFAULT_LAUNCH_TIME = 1740542400; // Oct 7th 2PM UTC address public burnToken = 0x3Ad2234eBFED9dEEfab94B9719aEbc07f8510D47; // Daddy bool private bypass_ = false; // internal flag to bypass all token logic bool private inswap_ = false; // internal flag to bypass additional token transfer logic address public router; // router V2 address[N] public pairs; // n pairs liquidity pool adddresses address[][N] public paths; // routes from WMM to reward tokens uint256 public launchTime = DEFAULT_LAUNCH_TIME; // timestamp when the trading starts uint256 public totalActiveSupply = 0; // sum of active balances for all 7WMM holders address[N] public rewardTokens; // n reward tokens uint256[N] public buybackPercents; // buyback percentage of each token address public wrappedToken; // WETH uint256[N] public rewardBalance = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // 8 reward balance uint256[N] public accRewardPerShare = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // accumulated reward per share (double precision) uint256 public minimumFeeBalanceToBuyback = 20000; // need to be more than just dust address public silo; // holds reward balances address[] public accountIndex; // list of all accounts that ever received WMM mapping(address => AccountInfo) public accountInfo; // account attributes function accountIndexLength() external view returns (uint256 _length) { return accountIndex.length; } function accountRewardInfo(address _account, uint256 _i) external view returns (uint256 _rewardDebt, uint256 _unclaimedReward, uint256 _minimumRewardBalanceToClaim) { AccountInfo storage _accountInfo = accountInfo[_account]; return (_accountInfo.rewardDebt[_i], _accountInfo.unclaimedReward[_i], _accountInfo.minimumRewardBalanceToClaim[_i]); } constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) { } function initialize(uint256 _supply, address[N] memory _rewardTokens, address _router, address _wrappedToken, uint256[N] memory _buybackPercents, address _owner) external { require(router == address(0), "already initialized"); router = _router; address _factory = IUniswapV2Router(_router).factory(); uint256 _totalBuybackPercent = 0; for (uint256 _i = 0; _i < N; _i++) { address _rewardToken = _rewardTokens[_i]; uint256 _buybackPercent = _buybackPercents[_i]; address _pair = IUniswapV2Factory(_factory).createPair(_rewardToken, address(this)); address[] memory _path = new address[](2); _path[0] = address(this); _path[1] = _rewardToken; pairs[_i] = _pair; paths[_i] = _path; rewardTokens[_i] = _rewardToken; buybackPercents[_i] = _buybackPercent; _totalBuybackPercent += _buybackPercent; } require(_totalBuybackPercent <= 100e16, "invalid percentages"); wrappedToken = _wrappedToken; silo = LibSilo.createSilo(_rewardTokens); _approve(address(this), _router, type(uint256).max); _mint(_owner, _supply); } function updateLaunchTime(uint256 _launchTime) external onlyOwner { require(_launchTime > block.timestamp, "invalid time"); launchTime = _launchTime; emit UpdateLaunchTime(_launchTime); } function updateMinimumFeeBalanceToBuyback(uint256 _minimumFeeBalanceToBuyback) external onlyOwner { minimumFeeBalanceToBuyback = _minimumFeeBalanceToBuyback; emit UpdateMinimumFeeBalanceToBuyback(_minimumFeeBalanceToBuyback); } function updateMinimumRewardBalanceToClaim(uint256[N] memory _minimumRewardBalanceToClaim) external { AccountInfo storage _accountInfo = accountInfo[msg.sender]; _accountInfo.minimumRewardBalanceToClaim = _minimumRewardBalanceToClaim; emit UpdateMinimumRewardBalanceToClaim(_minimumRewardBalanceToClaim); } function updateExcludeFromRewards(address _account, bool _excludeFromRewards) external onlyOwner { _updateAccount(_account); AccountInfo storage _accountInfo = accountInfo[_account]; _accountInfo.excludeFromRewards = _excludeFromRewards; _postUpdateAccount(_account); emit UpdateExcludeFromRewards(_account, _excludeFromRewards); } function updateExcludeFromRewards(bool _excludeFromRewards) external { _updateAccount(msg.sender); AccountInfo storage _accountInfo = accountInfo[msg.sender]; _accountInfo.excludeFromRewards = _excludeFromRewards; _postUpdateAccount(msg.sender); emit UpdateExcludeFromRewards(msg.sender, _excludeFromRewards); } function _updateAccount(address _account) internal { AccountInfo storage _accountInfo = accountInfo[_account]; if (!_accountInfo.exists) { accountIndex.push(_account); _accountInfo.exists = true; _accountInfo.excludeFromRewards = _account == FURNACE || _account.isContract(); _accountInfo.activeBalance = 0; _accountInfo.rewardDebt = [0, 0, 0, 0, 0, 0, 0, 0, 0]; _accountInfo.unclaimedReward = [0, 0, 0, 0, 0, 0, 0, 0, 0]; _accountInfo.minimumRewardBalanceToClaim = [1, 1, 1, 1, 1, 1, 1, 1, 1]; return; } uint256 _activeBalance = _accountInfo.activeBalance; if (_activeBalance > 0) { for (uint256 _i = 0; _i < N; _i++) { uint256 _rewardDebt = _activeBalance * accRewardPerShare[_i] / 1e36; if (_rewardDebt > _accountInfo.rewardDebt[_i]) { uint256 _rewardAmount = _rewardDebt - _accountInfo.rewardDebt[_i]; _accountInfo.unclaimedReward[_i] += _rewardAmount; _accountInfo.rewardDebt[_i] = _rewardDebt; } } } for (uint256 _i = 0; _i < N; _i++) { uint256 _unclaimedReward = _accountInfo.unclaimedReward[_i]; if (_unclaimedReward >= _accountInfo.minimumRewardBalanceToClaim[_i]) { _accountInfo.unclaimedReward[_i] = 0; rewardBalance[_i] -= _unclaimedReward; address _rewardToken = rewardTokens[_i]; if (_rewardToken != wrappedToken) { IERC20(_rewardToken).safeTransferFrom(silo, _account, _unclaimedReward); } else { IERC20(_rewardToken).safeTransferFrom(silo, address(this), _unclaimedReward); IWrappedToken(_rewardToken).withdraw(_unclaimedReward); payable(_account).sendValue(_unclaimedReward); } } } } function _postUpdateAccount(address _account) internal { AccountInfo storage _accountInfo = accountInfo[_account]; uint256 _oldActiveBalance = _accountInfo.activeBalance; uint256 _newActiveBalance = _accountInfo.excludeFromRewards ? 0 : balanceOf(_account); if (_newActiveBalance != _oldActiveBalance) { _accountInfo.activeBalance = _newActiveBalance; for (uint256 _i = 0; _i < N; _i++) { _accountInfo.rewardDebt[_i] = _newActiveBalance * accRewardPerShare[_i] / 1e36; } totalActiveSupply -= _oldActiveBalance; totalActiveSupply += _newActiveBalance; } } function _transfer(address _from, address _to, uint256 _amount) internal override { if (bypass_) { // internal transfer super._transfer(_from, _to, _amount); return; } if (inswap_) { // fee selling transfer super._transfer(_from, _to, _amount); return; } bool _buying = false; bool _selling = false; for (uint256 _i = 0; _i < N; _i++) { _buying = _buying || _from == pairs[_i]; _selling = _selling || _to == pairs[_i]; } if (_buying || _selling) { // buy/sell bool _restricted = block.timestamp < launchTime && (_buying ? _to : _from) != owner(); require(!_restricted, "unavailable"); // If the sender is not the owner then fee applies uint256 _feeAmount = (_buying ? _to : _from) != owner() ? _amount * (_buying ? BUY_FEE : SELL_FEE) / 100e16 : 0; super._transfer(_from, _to, _amount - _feeAmount); super._transfer(_from, address(this), _feeAmount); return; } // regular transfer super._transfer(_from, _to, _amount); // piggyback buyback operation uint256 _balance = balanceOf(address(this)); if (_balance >= minimumFeeBalanceToBuyback) { inswap_ = true; _approve(address(this), router, _balance); for (uint256 _i = 0; _i < N; _i ++) { uint256 _swapAmount = _balance * buybackPercents[_i] / 100e16; // If the buy back token is the burn token, send it to the furnace if(paths[_i][1] == burnToken) { IUniswapV2Router(router).swapExactTokensForTokens(_swapAmount, 0, paths[_i], FURNACE, block.timestamp); } else { IUniswapV2Router(router).swapExactTokensForTokens(_swapAmount, 0, paths[_i], silo, block.timestamp); } IUniswapV2Pair(pairs[_i]).sync(); } inswap_ = false; if (totalActiveSupply > 0) { for (uint256 _i = 0; _i < N; _i++) { uint256 _rewardBalance = IERC20(rewardTokens[_i]).balanceOf(silo); uint256 _rewardAmount = _rewardBalance - rewardBalance[_i]; if (_rewardAmount > 0) { rewardBalance[_i] = _rewardBalance; accRewardPerShare[_i] += _rewardAmount * 1e36 / totalActiveSupply; } } } } } function _beforeTokenTransfer(address _from, address _to, uint256 _amount) internal override { if (bypass_) return; if (_from != address(0)) { _updateAccount(_from); } if (_to != address(0)) { require(_to != INTERNAL_ADDRESS, "invalid address"); _updateAccount(_to); } _amount; // silences warning } function _afterTokenTransfer(address _from, address _to, uint256 _amount) internal override { if (bypass_) return; if (_from != address(0)) { _postUpdateAccount(_from); } if (_to != address(0)) { _postUpdateAccount(_to); } _amount; // silences warning } receive() external payable {} event UpdateLaunchTime(uint256 _launchTime); event UpdateMinimumFeeBalanceToBuyback(uint256 _minimumFeeBalanceToBuyback); event UpdateMinimumRewardBalanceToClaim(uint256[N] _minimumRewardBalanceToClaim); event UpdateExcludeFromRewards(address indexed _account, bool indexed _excludeFromRewards); }
{ "optimizer": { "enabled": true, "runs": 777 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_reserveToken","type":"address"},{"internalType":"address[1]","name":"_dripToken","type":"address[1]"},{"internalType":"address[9]","name":"_rewardToken","type":"address[9]"},{"internalType":"address","name":"_boostToken","type":"address"},{"internalType":"address","name":"_wrappedToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_boostToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Compound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"DonateDrip","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":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"RewardAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_reserveToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accBoostPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accDripPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accRewardPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accountIndexLength","outputs":[{"internalType":"uint256","name":"_length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"burned","type":"uint256"},{"internalType":"bool","name":"whitelisted","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"reserved0","type":"uint256"},{"internalType":"uint256","name":"reserved1","type":"uint256"},{"internalType":"uint256","name":"reserved2","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"accountInfoDrip","outputs":[{"internalType":"uint256","name":"_drip","type":"uint256"},{"internalType":"uint256","name":"_boost","type":"uint256"},{"internalType":"uint256","name":"_accDripDebt","type":"uint256"},{"internalType":"uint256","name":"_accBoostDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"accountInfoReward","outputs":[{"internalType":"uint256","name":"_reward","type":"uint256"},{"internalType":"uint256","name":"_accRewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allocDrip","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"burnOnBehalfOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAll","outputs":[{"internalType":"uint256[1]","name":"_dripAmount","type":"uint256[1]"},{"internalType":"uint256[1]","name":"_boostAmount","type":"uint256[1]"},{"internalType":"uint256[9]","name":"_rewardAmount","type":"uint256[9]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"claimDrip","outputs":[{"internalType":"uint256","name":"_dripAmount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"claimReward","outputs":[{"internalType":"uint256","name":"_rewardAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"compoundDrip","outputs":[{"internalType":"uint256","name":"_dripAmount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"day","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"depositOnBehalfOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"donateDrip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dripBoostRatePerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dripRatePerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dripToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getAccountByIndex","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"burned","type":"uint256"},{"internalType":"uint256[1]","name":"drip","type":"uint256[1]"},{"internalType":"uint256[1]","name":"boost","type":"uint256[1]"},{"internalType":"uint256[1]","name":"accDripDebt","type":"uint256[1]"},{"internalType":"uint256[1]","name":"accBoostDebt","type":"uint256[1]"},{"internalType":"uint256[9]","name":"reward","type":"uint256[9]"},{"internalType":"uint256[9]","name":"accRewardDebt","type":"uint256[9]"},{"internalType":"bool","name":"whitelisted","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"reserved0","type":"uint256"},{"internalType":"uint256","name":"reserved1","type":"uint256"},{"internalType":"uint256","name":"reserved2","type":"uint256"}],"internalType":"struct RewardDrippingVault.AccountInfo","name":"_accountInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_reserveToken","type":"address"},{"internalType":"address[1]","name":"_dripToken","type":"address[1]"},{"internalType":"address[9]","name":"_rewardToken","type":"address[9]"},{"internalType":"address","name":"_boostToken","type":"address"},{"internalType":"address","name":"_wrappedToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"launchTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rewardAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"},{"internalType":"uint256","name":"_dripBoostRatePerDay","type":"uint256"}],"name":"setDripBoostRatePerDay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"},{"internalType":"uint256","name":"_dripRatePerDay","type":"uint256"}],"name":"setDripRatePerDay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_launchTime","type":"uint256"}],"name":"setLaunchTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"today","outputs":[{"internalType":"uint64","name":"_today","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalDrip","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","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":[],"name":"updateDay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"bool","name":"_whitelisted","type":"bool"}],"name":"updateWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_whitelistAll","type":"bool"}],"name":"updateWhitelistAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162005a9138038062005a9183398101604081905262000034916200094d565b6200003f336200005e565b6001805562000053338686868686620000b9565b505050505062000aa3565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600054610100900460ff1680620000d3575060005460ff16155b6200013c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff161580156200015f576000805461ffff19166101011790555b6200016a876200005e565b6367be91c0600f5560005b6001811015620001d457662386f26fc10000601082600181106200019d576200019d62000a1b565b0155662386f26fc1000060118260018110620001bd57620001bd62000a1b565b015580620001cb8162000a47565b91505062000175565b506012805460ff191690556000601381905560148190555b60018110156200028d576000601582600181106200020e576200020e62000a1b565b015560006016826001811062000228576200022862000a1b565b015560006017826001811062000242576200024262000a1b565b01556000601882600181106200025c576200025c62000a1b565b015560006019826001811062000276576200027662000a1b565b015580620002848162000a47565b915050620001ec565b5060005b6009811015620002e4576000601a8260098110620002b357620002b362000a1b565b0155600060238260098110620002cd57620002cd62000a1b565b015580620002db8162000a47565b91505062000291565b50620002ef62000796565b602c80546001600160401b0319166001600160401b039290921691909117905560005b6001811015620003d95760005b81811015620003c3578681600181106200033d576200033d62000a1b565b60200201516001600160a01b031687836001811062000360576200036062000a1b565b60200201516001600160a01b03161415620003ae5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b80620003ba8162000a47565b9150506200031f565b5080620003d08162000a47565b91505062000312565b5060005b6009811015620004a45760005b818110156200048e5785816009811062000408576200040862000a1b565b60200201516001600160a01b03168683600981106200042b576200042b62000a1b565b60200201516001600160a01b03161415620004795760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b80620004858162000a47565b915050620003ea565b50806200049b8162000a47565b915050620003dd565b5084516001600160a01b03878116911614620004f35760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b60015b6001811015620005d0576000805b60098110156200057a5786816009811062000523576200052362000a1b565b60200201516001600160a01b031688846001811062000546576200054662000a1b565b60200201516001600160a01b031614156200056557600191506200057a565b80620005718162000a47565b91505062000504565b5080620005ba5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b5080620005c78162000a47565b915050620004f6565b5060005b60098110156200066057866001600160a01b0316858260098110620005fd57620005fd62000a1b565b60200201516001600160a01b031614156200064b5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b80620006578162000a47565b915050620005d4565b50856001600160a01b0316826001600160a01b03161415620006b55760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640162000133565b600280546001600160a01b038089166001600160a01b0319928316179092556003805492861692909116919091179055620006f46004866001620007bb565b5062000704600585600962000818565b50600e80546001600160a01b0319166001600160a01b0384811691909117909155604051633d0c1b3360e01b81526000600482015290871690633d0c1b3390602401600060405180830381600087803b1580156200076157600080fd5b505af115801562000776573d6000803e3d6000fd5b5050505080156200078d576000805461ff00191690555b50505050505050565b600062015180620007aa61e1004262000a65565b620007b6919062000a80565b905090565b826001810192821562000806579160200282015b828111156200080657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620007cf565b506200081492915062000862565b5090565b82600981019282156200080657916020028201828111156200080657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620007cf565b5b8082111562000814576000815560010162000863565b80516001600160a01b03811681146200089157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b0381118282101715620008d257620008d262000896565b60405290565b604051602081016001600160401b0381118282101715620008d257620008d262000896565b600062000909620008ac565b9050806101208301848111156200091f57600080fd5b835b818110156200094457620009358162000879565b83526020928301920162000921565b50505092915050565b60008060008060006101a086880312156200096757600080fd5b620009728662000879565b9450602087603f8801126200098657600080fd5b62000990620008d8565b80604089018a811115620009a357600080fd5b838a015b81811015620009c957620009bb8162000879565b8452928401928401620009a7565b508197508a605f8b0112620009dd57600080fd5b620009e98b82620008fd565b965050505050620009fe610160870162000879565b915062000a0f610180870162000879565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141562000a5e5762000a5e62000a31565b5060010190565b6000821982111562000a7b5762000a7b62000a31565b500190565b60008262000a9e57634e487b7160e01b600052601260045260246000fd5b500490565b614fde8062000ab36000396000f3fe6080604052600436106103175760003560e01c80638cbba57a1161019a578063c89ebaec116100e1578063e72f6e301161008a578063f2fde38b11610064578063f2fde38b1461098a578063f4325d67146109aa578063f6d4277a146109ca57600080fd5b8063e72f6e301461091d578063edc017521461093d578063f1ddf8401461096a57600080fd5b8063d89135cd116100bb578063d89135cd146108c7578063e33702d7146108dd578063e4879b88146108fd57600080fd5b8063c89ebaec14610863578063d1058e5914610883578063d5eae1d5146108a757600080fd5b8063ae169a5011610143578063b74e452b1161011d578063b74e452b146107ee578063be80701614610803578063c194efbf1461084357600080fd5b8063ae169a501461078e578063aff177ca146107ae578063b6b55f25146107ce57600080fd5b8063996c6cc311610174578063996c6cc3146106b85780639ff46e74146106d8578063a7310b58146106f857600080fd5b80638cbba57a146106545780638da5cb5b1461067457806392a526131461069857600080fd5b80635d54e6121161025e578063790ca413116102075780637b76ac91116101e15780637b76ac91146105cf578063817b1cd214610609578063895ff41d1461061f57600080fd5b8063790ca413146105795780637b460b2a1461058f5780637b58389e146105af57600080fd5b80636d9873c5116102385780636d9873c51461052f5780636f55184b14610544578063715018a61461056457600080fd5b80635d54e612146104c5578063637eb25b146104ef57806368c958ee1461050f57600080fd5b806336f9825f116102c057806342966c681161029a57806342966c68146104655780634ccc895b14610485578063509b6c3f146104a557600080fd5b806336f9825f146103f85780633a589b971461043057806341632d331461045057600080fd5b806323a6f46e116102f157806323a6f46e146103985780632b653797146103b85780632e1a7d4d146103d857600080fd5b80630b9166de146103235780630f392ad01461035657806322ac7b8f1461037657600080fd5b3661031e57005b600080fd5b34801561032f57600080fd5b5061034361033e3660046149b1565b6109ea565b6040519081526020015b60405180910390f35b34801561036257600080fd5b506103436103713660046149b1565b610a01565b34801561038257600080fd5b506103966103913660046149d8565b610a11565b005b3480156103a457600080fd5b506103436103b33660046149b1565b610a8a565b3480156103c457600080fd5b506103436103d33660046149b1565b610a9a565b3480156103e457600080fd5b506103966103f33660046149b1565b610aaa565b34801561040457600080fd5b506104186104133660046149b1565b610db8565b6040516001600160a01b03909116815260200161034d565b34801561043c57600080fd5b50600354610418906001600160a01b031681565b34801561045c57600080fd5b50602d54610343565b34801561047157600080fd5b506103966104803660046149b1565b610de2565b34801561049157600080fd5b506103966104a03660046149f5565b610def565b3480156104b157600080fd5b506104186104c03660046149b1565b6111dc565b3480156104d157600080fd5b506012546104df9060ff1681565b604051901515815260200161034d565b3480156104fb57600080fd5b5061039661050a366004614ada565b6111fc565b34801561051b57600080fd5b5061039661052a366004614ba5565b611871565b34801561053b57600080fd5b506103966119bc565b34801561055057600080fd5b5061034361055f3660046149b1565b611a10565b34801561057057600080fd5b50610396611a20565b34801561058557600080fd5b50610343600f5481565b34801561059b57600080fd5b506103436105aa3660046149b1565b611a8d565b3480156105bb57600080fd5b506103436105ca3660046149b1565b611a9d565b3480156105db57600080fd5b50602c546105f09067ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161034d565b34801561061557600080fd5b5061034360135481565b34801561062b57600080fd5b5061063f61063a3660046149b1565b611aad565b6040805192835260208301919091520161034d565b34801561066057600080fd5b5061063f61066f366004614bd1565b611d87565b34801561068057600080fd5b506000546201000090046001600160a01b0316610418565b3480156106a457600080fd5b506103966106b33660046149f5565b611ddb565b3480156106c457600080fd5b50600e54610418906001600160a01b031681565b3480156106e457600080fd5b506103966106f33660046149b1565b61210f565b34801561070457600080fd5b50610753610713366004614bfb565b602e6020526000908152604090208054600182015460188301546019840154601a850154601b909501549394929360ff8084169461010090940416929087565b604080519788526020880196909652931515948601949094529015156060850152608084015260a083019190915260c082015260e00161034d565b34801561079a57600080fd5b506103436107a93660046149b1565b612204565b3480156107ba57600080fd5b506103966107c9366004614c16565b61239f565b3480156107da57600080fd5b506103966107e93660046149b1565b61247a565b3480156107fa57600080fd5b506105f0612556565b34801561080f57600080fd5b5061082361081e366004614bd1565b612577565b60408051948552602085019390935291830152606082015260800161034d565b34801561084f57600080fd5b5061034361085e3660046149b1565b612602565b34801561086f57600080fd5b5061041861087e3660046149b1565b612612565b34801561088f57600080fd5b50610898612622565b60405161034d93929190614ce2565b3480156108b357600080fd5b506103966108c23660046149f5565b612bea565b3480156108d357600080fd5b5061034360145481565b3480156108e957600080fd5b506103966108f83660046149f5565b612d0a565b34801561090957600080fd5b506103436109183660046149b1565b612e25565b34801561092957600080fd5b50610396610938366004614bfb565b612e35565b34801561094957600080fd5b5061095d6109583660046149b1565b613084565b60405161034d9190614d0b565b34801561097657600080fd5b50610396610985366004614ba5565b613277565b34801561099657600080fd5b506103966109a5366004614bfb565b61334a565b3480156109b657600080fd5b50600254610418906001600160a01b031681565b3480156109d657600080fd5b5061063f6109e53660046149b1565b613430565b601081600181106109fa57600080fd5b0154905081565b601981600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314610a775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6012805460ff1916911515919091179055565b601a81600981106109fa57600080fd5b601881600181106109fa57600080fd5b60026001541415610aeb5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015580610b2e5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b336000908152602e60205260409020805480831115610b8f5760405162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e63650000000000000000000000006044820152606401610a6e565b610b9761369d565b610bab33610ba485614df0565b6000613b13565b8260136000828254610bbd9190614e0d565b9091555050601882015460ff1680610bd7575060125460ff165b15610bf857600254610bf3906001600160a01b03163385613f1a565b610d6b565b6000670de0b6b3a7640000610c1485662386f26fc10000614e24565b610c1e9190614e43565b90506000610c2d826009614e24565b90506000610c3c83600b614e24565b610c469087614e0d565b90508160156000016000828254610c5d9190614e7b565b909155505060135415610cd657601354610c78846002614e24565b610c91906ec097ce7bc90715b34b9f1000000000614e24565b610c9b9190614e43565b60188054600090610cad908490614e7b565b90915550610cbe9050836002614e24565b60168054600090610cd0908490614e7b565b90915550505b60145415610d3757601454610cfa846ec097ce7bc90715b34b9f1000000000614e24565b610d049190614e43565b60198054600090610d16908490614e7b565b9091555083905060176000016000828254610d319190614e7b565b90915550505b600254610d50906001600160a01b031661dead85613f1a565b600254610d67906001600160a01b03163383613f1a565b5050505b6002546040518481526001600160a01b039091169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060200160405180910390a350506001805550565b602d8181548110610dc857600080fd5b6000918252602090912001546001600160a01b0316905081565b610dec8133611871565b50565b60026001541415610e305760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015560098210610e755760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b60008111610eb65760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b610ebe61369d565b600060135411610f105760405162461bcd60e51b815260206004820152600b60248201527f6e6f206465706f736974730000000000000000000000000000000000000000006044820152606401610a6e565b600060058360098110610f2557610f25614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610f6757600080fd5b505afa158015610f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9f9190614e93565b9050610fcd33308460058760098110610fba57610fba614e65565b01546001600160a01b0316929190613faf565b8060058460098110610fe157610fe1614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561102357600080fd5b505afa158015611037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105b9190614e93565b6110659190614e0d565b600e549092506001600160a01b031690506005836009811061108957611089614e65565b01546001600160a01b0316141561110b57600582600981106110ad576110ad614e65565b0154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156110f257600080fd5b505af1158015611106573d6000803e3d6000fd5b505050505b60135461112082670de0b6b3a7640000614e24565b61112a9190614e43565b6023836009811061113d5761113d614e65565b01600082825461114d9190614e7b565b90915550819050601a836009811061116757611167614e65565b0160008282546111779190614e7b565b9091555060059050826009811061119057611190614e65565b01546040518281526001600160a01b039091169033907f9ed97645fb5853abbbe66e94ac8ed13dac4d3ff7afe85b05c0e2b323b4014193906020015b60405180910390a3505060018055565b600581600981106111ec57600080fd5b01546001600160a01b0316905081565b600054610100900460ff1680611215575060005460ff16155b6112875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a6e565b600054610100900460ff161580156112a9576000805461ffff19166101011790555b6112b287613fe7565b6367be91c0600f5560005b600181101561131257662386f26fc10000601082600181106112e1576112e1614e65565b0155662386f26fc10000601182600181106112fe576112fe614e65565b01558061130a81614eac565b9150506112bd565b506012805460ff191690556000601381905560148190555b60018110156113b85760006015826001811061134857611348614e65565b015560006016826001811061135f5761135f614e65565b015560006017826001811061137657611376614e65565b015560006018826001811061138d5761138d614e65565b01556000601982600181106113a4576113a4614e65565b0155806113b081614eac565b91505061132a565b5060005b6009811015611405576000601a82600981106113da576113da614e65565b01556000602382600981106113f1576113f1614e65565b0155806113fd81614eac565b9150506113bc565b5061140e612556565b602c805467ffffffffffffffff191667ffffffffffffffff9290921691909117905560005b60018110156114ea5760005b818110156114d75786816001811061145957611459614e65565b60200201516001600160a01b031687836001811061147957611479614e65565b60200201516001600160a01b031614156114c55760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b806114cf81614eac565b91505061143f565b50806114e281614eac565b915050611433565b5060005b60098110156115a55760005b818110156115925785816009811061151457611514614e65565b60200201516001600160a01b031686836009811061153457611534614e65565b60200201516001600160a01b031614156115805760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b8061158a81614eac565b9150506114fa565b508061159d81614eac565b9150506114ee565b5084516001600160a01b038781169116146115f25760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b60015b60018110156116bd576000805b600981101561166c5786816009811061161d5761161d614e65565b60200201516001600160a01b031688846001811061163d5761163d614e65565b60200201516001600160a01b0316141561165a576001915061166c565b8061166481614eac565b915050611602565b50806116aa5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b50806116b581614eac565b9150506115f5565b5060005b600981101561174457866001600160a01b03168582600981106116e6576116e6614e65565b60200201516001600160a01b031614156117325760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b8061173c81614eac565b9150506116c1565b50856001600160a01b0316826001600160a01b031614156117975760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b600280546001600160a01b038089166001600160a01b03199283161790925560038054928616929091169190911790556117d46004866001614830565b506117e26005856009614888565b50600e80546001600160a01b0319166001600160a01b0384811691909117909155604051633d0c1b3360e01b81526000600482015290871690633d0c1b3390602401600060405180830381600087803b15801561183e57600080fd5b505af1158015611852573d6000803e3d6000fd5b505050508015611868576000805461ff00191690555b50505050505050565b600f544210156118b15760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156118f25760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155816119355760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b61193d61369d565b61194981600084613b13565b816014600082825461195b9190614e7b565b909155505060035461197a906001600160a01b03163361dead85613faf565b6003546040518381526001600160a01b03918216918316907fbac40739b0d4ca32fa2d82fc91630465ba3eddd1598da6fca393b26fb63b9453906020016111cc565b600260015414156119fd5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155611a0a61369d565b60018055565b601581600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314611a815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b611a8b6000613fe7565b565b601681600181106109fa57600080fd5b601781600181106109fa57600080fd5b60008060026001541415611af15760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260019081558310611b365760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b6002546001600160a01b031660048460018110611b5557611b55614e65565b01546001600160a01b031614611b9d5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b611ba561369d565b611bb133600080613b13565b336000908152602e60205260409020600281018460018110611bd557611bd5614e65565b01549250806003018460018110611bee57611bee614e65565b015491508215611c65576000816002018560018110611c0f57611c0f614e65565b01558260158560018110611c2557611c25614e65565b016000828254611c359190614e0d565b9091555083905060168560018110611c4f57611c4f614e65565b016000828254611c5f9190614e0d565b90915550505b8115611cae576000816003018560018110611c8257611c82614e65565b01558160178560018110611c9857611c98614e65565b016000828254611ca89190614e0d565b90915550505b6000611cba8385614e7b565b90508015611ccd57611ccd308233614058565b60048560018110611ce057611ce0614e65565b01546040518581526001600160a01b039091169033907f6c7e7d4cb83a668aef31739dd35dc3fc3d5f31d62b69e438b7b24d35b40dcc639060200160405180910390a360048560018110611d3657611d36614e65565b01546040518481526001600160a01b039091169033907f6c7e7d4cb83a668aef31739dd35dc3fc3d5f31d62b69e438b7b24d35b40dcc63906020015b60405180910390a35050600180559092909150565b6001600160a01b0382166000908152602e602052604081208190600681018460098110611db657611db6614e65565b015481600f018560098110611dcd57611dcd614e65565b015492509250509250929050565b60026001541415611e1c5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260019081558210611e615760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b60008111611ea25760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b611eaa61369d565b600060048360018110611ebf57611ebf614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611f0157600080fd5b505afa158015611f15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f399190614e93565b9050611f5433308460048760018110610fba57610fba614e65565b8060048460018110611f6857611f68614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611faa57600080fd5b505afa158015611fbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe29190614e93565b611fec9190614e0d565b600e549092506001600160a01b031690506004836001811061201057612010614e65565b01546001600160a01b03161415612092576004826001811061203457612034614e65565b0154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050505b80601583600181106120a6576120a6614e65565b0160008282546120b69190614e7b565b909155506004905082600181106120cf576120cf614e65565b01546040518281526001600160a01b039091169033907f88923243846ae6dc2129c36897f0c50381bac23792669a4ab5bc456dd9976177906020016111cc565b6000546001600160a01b03620100009091041633146121705760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b600f5442106121af5760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b428110156121ff5760405162461bcd60e51b815260206004820152600c60248201527f696e76616c69642074696d6500000000000000000000000000000000000000006044820152606401610a6e565b600f55565b6000600260015414156122475760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b60026001556009821061228c5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b61229461369d565b6122a033600080613b13565b336000908152602e602052604090206006810183600981106122c4576122c4614e65565b0154915081156123115760008160060184600981106122e5576122e5614e65565b015581601a84600981106122fb576122fb614e65565b01600082825461230b9190614e0d565b90915550505b811561233f5761233f6005846009811061232d5761232d614e65565b01546001600160a01b03163384614354565b6005836009811061235257612352614e65565b01546040518381526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a35060018055919050565b6000546001600160a01b03620100009091041633146124005760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60005b828110156124745781602e600086868581811061242257612422614e65565b90506020020160208101906124379190614bfb565b6001600160a01b031681526020810191909152604001600020601801805460ff19169115159190911790558061246c81614eac565b915050612403565b50505050565b600f544210156124ba5760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156124fb5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015561250b338281614058565b6002546040518281526001600160a01b039091169033907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f629060200160405180910390a35060018055565b60006201518061256861e10042614e7b565b6125729190614e43565b905090565b6001600160a01b0382166000908152602e602052604081208190819081906002810186600181106125aa576125aa614e65565b01548160030187600181106125c1576125c1614e65565b01548260040188600181106125d8576125d8614e65565b01548360050189600181106125ef576125ef614e65565b0154929a91995097509095509350505050565b602381600981106109fa57600080fd5b600481600181106111ec57600080fd5b61262a6148cf565b6126326148cf565b61263a6148ed565b6002600154141561267b5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015561268861369d565b61269433600080613b13565b336000908152602e60205260408120905b600181101561271c578160020181600181106126c3576126c3614e65565b01548582600181106126d7576126d7614e65565b60200201526003820181600181106126f1576126f1614e65565b015484826001811061270557612705614e65565b60200201528061271481614eac565b9150506126a5565b5060005b60098110156127695781600601816009811061273e5761273e614e65565b015483826009811061275257612752614e65565b60200201528061276181614eac565b915050612720565b5060005b60018110156128b857600085826001811061278a5761278a614e65565b6020020151111561282e5760008260020182600181106127ac576127ac614e65565b01558481600181106127c0576127c0614e65565b6020020151601582600181106127d8576127d8614e65565b0160008282546127e89190614e0d565b90915550859050816001811061280057612800614e65565b60200201516016826001811061281857612818614e65565b0160008282546128289190614e0d565b90915550505b600084826001811061284257612842614e65565b602002015111156128a657600082600301826001811061286457612864614e65565b015583816001811061287857612878614e65565b60200201516017826001811061289057612890614e65565b0160008282546128a09190614e0d565b90915550505b806128b081614eac565b91505061276d565b5060005b600981101561294f5760008382600981106128d9576128d9614e65565b6020020151111561293d5760008260060182600981106128fb576128fb614e65565b015582816009811061290f5761290f614e65565b6020020151601a826009811061292757612927614e65565b0160008282546129379190614e0d565b90915550505b8061294781614eac565b9150506128bc565b5060005b60018110156129d957600084826001811061297057612970614e65565b602002015186836001811061298757612987614e65565b60200201516129969190614e7b565b905080156129c6576129c6600483600181106129b4576129b4614e65565b01546001600160a01b03163383614354565b50806129d181614eac565b915050612953565b5060005b6009811015612a555760008382600981106129fa576129fa614e65565b60200201511115612a4357612a4360058260098110612a1b57612a1b614e65565b01546001600160a01b031633858460098110612a3957612a39614e65565b6020020151614354565b80612a4d81614eac565b9150506129dd565b5060005b6001811015612b505760048160018110612a7557612a75614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068878460018110612ab457612ab4614e65565b6020020151604051612ac891815260200190565b60405180910390a360048160018110612ae357612ae3614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068868460018110612b2257612b22614e65565b6020020151604051612b3691815260200190565b60405180910390a380612b4881614eac565b915050612a59565b5060005b6009811015612bdd5760058160098110612b7057612b70614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068858460098110612baf57612baf614e65565b6020020151604051612bc391815260200190565b60405180910390a380612bd581614eac565b915050612b54565b5050600180559192909190565b6000546001600160a01b0362010000909104163314612c4b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60018210612c8b5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b670de0b6b3a764000060118360018110612ca757612ca7614e65565b0154612cb39083614e7b565b1115612cf05760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964207261746560a01b6044820152606401610a6e565b8060108360018110612d0457612d04614e65565b01555050565b6000546001600160a01b0362010000909104163314612d6b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60018210612dab5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b670de0b6b3a76400008160108460018110612dc857612dc8614e65565b0154612dd49190614e7b565b1115612e115760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964207261746560a01b6044820152606401610a6e565b8060118360018110612d0457612d04614e65565b601181600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314612e965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60026001541415612ed75760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015560005b6009811015612f5a5760058160098110612efb57612efb614e65565b01546001600160a01b0383811691161415612f485760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b80612f5281614eac565b915050612edf565b506040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015612f9d57600080fd5b505afa158015612fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd59190614e93565b6002549091506001600160a01b0383811691161415613018576017546015546013546130019190614e7b565b61300b9190614e7b565b6130159082614e0d565b90505b600081116130685760405162461bcd60e51b815260206004820152600a60248201527f6e6f2062616c616e6365000000000000000000000000000000000000000000006044820152606401610a6e565b61307c6001600160a01b0383163383613f1a565b505060018055565b61308c61490c565b602e6000602d84815481106130a3576130a3614e65565b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902081516101a08101835281548152600180830154828601528351948501808552919492938501929160028501919082845b8154815260200190600101908083116130fb575050509183525050604080516020808201928390529092019190600384019060019082845b815481526020019060010190808311613133575050509183525050604080516020808201928390529092019190600484019060019082845b81548152602001906001019080831161316b575050509183525050604080516020808201928390529092019190600584019060019082845b8154815260200190600101908083116131a35750505091835250506040805161012081019182905260209092019190600684019060099082845b8154815260200190600101908083116131dd5750505091835250506040805161012081019182905260209092019190600f84019060099082845b815481526020019060010190808311613217575050509183525050601882015460ff80821615156020840152610100909104161515604082015260198201546060820152601a8201546080820152601b9091015460a09091015292915050565b600f544210156132b75760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156132f85760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155613308338383614058565b6002546040518381526001600160a01b03918216918316907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906020016111cc565b6000546001600160a01b03620100009091041633146133ab5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b6001600160a01b0381166134275760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a6e565b610dec81613fe7565b600080600260015414156134745760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600190815583106134b95760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b6134c161369d565b6134cd33600080613b13565b336000908152602e602052604090206002810184600181106134f1576134f1614e65565b0154925080600301846001811061350a5761350a614e65565b01549150821561358157600081600201856001811061352b5761352b614e65565b0155826015856001811061354157613541614e65565b0160008282546135519190614e0d565b909155508390506016856001811061356b5761356b614e65565b01600082825461357b9190614e0d565b90915550505b81156135ca57600081600301856001811061359e5761359e614e65565b015581601785600181106135b4576135b4614e65565b0160008282546135c49190614e0d565b90915550505b60006135d68385614e7b565b905080156135f4576135f4600486600181106129b4576129b4614e65565b6004856001811061360757613607614e65565b01546040518581526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a36004856001811061365d5761365d614e65565b01546040518481526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd98706890602001611d72565b60006136a7612556565b602c5490915067ffffffffffffffff808316911614156136c45750565b60005b600181101561393e576000601182600181106136e5576136e5614e65565b0154601083600181106136fa576136fa614e65565b01546137069190614e7b565b9050801561392b57602c546000906137289067ffffffffffffffff1685614ec7565b9050600061375161374184670de0b6b3a7640000614e0d565b8367ffffffffffffffff16614390565b61376390670de0b6b3a7640000614e0d565b90506000670de0b6b3a7640000826016876001811061378457613784614e65565b01546015886001811061379957613799614e65565b01546137a59190614e0d565b6137af9190614e24565b6137b99190614e43565b9050600084601087600181106137d1576137d1614e65565b01546137dd9084614e24565b6137e79190614e43565b6013549091501561386b5760135461380e826ec097ce7bc90715b34b9f1000000000614e24565b6138189190614e43565b6018876001811061382b5761382b614e65565b01600082825461383b9190614e7b565b909155508190506016876001811061385557613855614e65565b0160008282546138659190614e7b565b90915550505b60006138778284614e0d565b601454909150156139255760145461389e826ec097ce7bc90715b34b9f1000000000614e24565b6138a89190614e43565b601988600181106138bb576138bb614e65565b0160008282546138cb9190614e7b565b90915550819050601588600181106138e5576138e5614e65565b0160008282546138f59190614e0d565b909155508190506017886001811061390f5761390f614e65565b01600082825461391f9190614e7b565b90915550505b50505050505b508061393681614eac565b9150506136c7565b5060135415613aef5760025461395f906001600160a01b0316306000613f1a565b60005b6009811015613aed576000601a826009811061398057613980614e65565b01546139a96005846009811061399857613998614e65565b01546001600160a01b0316306143fa565b6139b39190614e0d565b905060015b6001811015613a5a57600583600981106139d4576139d4614e65565b01546001600160a01b0316600482600181106139f2576139f2614e65565b01546001600160a01b03161415613a485760178160018110613a1657613a16614e65565b015460158260018110613a2b57613a2b614e65565b0154613a379190614e7b565b613a419083614e0d565b9150613a5a565b80613a5281614eac565b9150506139b8565b508015613ada57601354613a7d826ec097ce7bc90715b34b9f1000000000614e24565b613a879190614e43565b60238360098110613a9a57613a9a614e65565b016000828254613aaa9190614e7b565b90915550819050601a8360098110613ac457613ac4614e65565b016000828254613ad49190614e7b565b90915550505b5080613ae581614eac565b915050613962565b505b602c805467ffffffffffffffff191667ffffffffffffffff92909216919091179055565b6001600160a01b0383166000908152602e602052604090206018810154610100900460ff16613b9b5760188101805461ff001916610100179055602d80546001810182556000919091527f4a2cc91ee622da3bc833a54c37ffcb6f3ec23b7793efc5eaf5e71b7b406c5c060180546001600160a01b0386166001600160a01b03199091161790555b60005b6001811015613cc957816004018160018110613bbc57613bbc614e65565b01546ec097ce7bc90715b34b9f100000000060188360018110613be157613be1614e65565b01548454613bef9190614e24565b613bf99190614e43565b613c039190614e0d565b826002018260018110613c1857613c18614e65565b016000828254613c289190614e7b565b9091555050600582018160018110613c4257613c42614e65565b01546ec097ce7bc90715b34b9f100000000060198360018110613c6757613c67614e65565b01548460010154613c789190614e24565b613c829190614e43565b613c8c9190614e0d565b826003018260018110613ca157613ca1614e65565b016000828254613cb19190614e7b565b90915550819050613cc181614eac565b915050613b9e565b5060005b6009811015613d6f5781600f018160098110613ceb57613ceb614e65565b01546ec097ce7bc90715b34b9f100000000060238360098110613d1057613d10614e65565b01548454613d1e9190614e24565b613d289190614e43565b613d329190614e0d565b826006018260098110613d4757613d47614e65565b016000828254613d579190614e7b565b90915550819050613d6781614eac565b915050613ccd565b506000831315613d985782816000016000828254613d8d9190614e7b565b90915550613dc39050565b6000831215613dc357613daa83614df0565b816000016000828254613dbd9190614e0d565b90915550505b81816001016000828254613dd79190614e7b565b90915550600090505b6001811015613ea2576ec097ce7bc90715b34b9f100000000060188260018110613e0c57613e0c614e65565b01548354613e1a9190614e24565b613e249190614e43565b826004018260018110613e3957613e39614e65565b01556ec097ce7bc90715b34b9f100000000060198260018110613e5e57613e5e614e65565b01548360010154613e6f9190614e24565b613e799190614e43565b826005018260018110613e8e57613e8e614e65565b015580613e9a81614eac565b915050613de0565b5060005b6009811015613f13576ec097ce7bc90715b34b9f100000000060238260098110613ed257613ed2614e65565b01548354613ee09190614e24565b613eea9190614e43565b82600f018260098110613eff57613eff614e65565b015580613f0b81614eac565b915050613ea6565b5050505050565b6040516001600160a01b038316602482015260448101829052613faa90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526144a3565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526124749085906323b872dd60e01b90608401613f46565b600080546001600160a01b03838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600082116140995760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b6140a161369d565b6001600160a01b03831630146141d1576002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156140f557600080fd5b505afa158015614109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412d9190614e93565b600254909150614148906001600160a01b0316853086613faf565b6002546040516370a0823160e01b815230600482015282916001600160a01b0316906370a082319060240160206040518083038186803b15801561418b57600080fd5b505afa15801561419f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141c39190614e93565b6141cd9190614e0d565b9250505b6000670de0b6b3a76400006141ed84662386f26fc10000614e24565b6141f79190614e43565b90506000614206826009614e24565b9050600061421583600b614e24565b61421f9086614e0d565b905081601560000160008282546142369190614e7b565b9091555050601354156142af57601354614251846002614e24565b61426a906ec097ce7bc90715b34b9f1000000000614e24565b6142749190614e43565b60188054600090614286908490614e7b565b909155506142979050836002614e24565b601680546000906142a9908490614e7b565b90915550505b60145415614310576014546142d3846ec097ce7bc90715b34b9f1000000000614e24565b6142dd9190614e43565b601980546000906142ef908490614e7b565b909155508390506017600001600082825461430a9190614e7b565b90915550505b61431c84826000613b13565b806013600082825461432e9190614e7b565b909155505060025461434c906001600160a01b031661dead85613f1a565b505050505050565b600e546001600160a01b0384811691161461437d57613faa6001600160a01b0384168383613f1a565b613faa6001600160a01b03831682614588565b670de0b6b3a76400005b81156143f45760018216156143c957670de0b6b3a76400006143bc8483614e24565b6143c69190614e43565b90505b60019190911c90670de0b6b3a76400006143e38480614e24565b6143ed9190614e43565b925061439a565b92915050565b600e546000906001600160a01b03848116911614614490576040516370a0823160e01b81526001600160a01b0383811660048301528416906370a082319060240160206040518083038186803b15801561445357600080fd5b505afa158015614467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061448b9190614e93565b61449c565b816001600160a01b0316315b9392505050565b60006144f8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146a19092919063ffffffff16565b805190915015613faa57808060200190518101906145169190614ef0565b613faa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a6e565b804710156145d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a6e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114614625576040519150601f19603f3d011682016040523d82523d6000602084013e61462a565b606091505b5050905080613faa5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a6e565b60606146b084846000856146b8565b949350505050565b6060824710156147305760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a6e565b843b61477e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a6e565b600080866001600160a01b0316858760405161479a9190614f39565b60006040518083038185875af1925050503d80600081146147d7576040519150601f19603f3d011682016040523d82523d6000602084013e6147dc565b606091505b50915091506147ec8282866147f7565b979650505050505050565b6060831561480657508161449c565b8251156148165782518084602001fd5b8160405162461bcd60e51b8152600401610a6e9190614f55565b8260018101928215614878579160200282015b8281111561487857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614843565b5061488492915061499c565b5090565b8260098101928215614878579160200282018281111561487857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614843565b60405180602001604052806001906020820280368337509192915050565b6040518061012001604052806009906020820280368337509192915050565b604051806101a00160405280600081526020016000815260200161492e6148cf565b815260200161493b6148cf565b81526020016149486148cf565b81526020016149556148cf565b81526020016149626148ed565b815260200161496f6148ed565b81526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b5b80821115614884576000815560010161499d565b6000602082840312156149c357600080fd5b5035919050565b8015158114610dec57600080fd5b6000602082840312156149ea57600080fd5b813561449c816149ca565b60008060408385031215614a0857600080fd5b50508035926020909101359150565b80356001600160a01b0381168114614a2e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6040516020810167ffffffffffffffff81118282101715614a6c57614a6c614a33565b60405290565b600060405161012080820182811067ffffffffffffffff82111715614a9957614a99614a33565b6040529091508190830184811115614ab057600080fd5b835b81811015614ad157614ac381614a17565b835260209283019201614ab2565b50505092915050565b6000806000806000806101c08789031215614af457600080fd5b614afd87614a17565b95506020614b0c818901614a17565b955088605f890112614b1d57600080fd5b614b25614a49565b8060608a018b811115614b3757600080fd5b60408b015b81811015614b5a57614b4d81614a17565b8452928401928401614b3c565b508197508b607f8c0112614b6d57600080fd5b614b778c82614a72565b965050505050614b8a6101808801614a17565b9150614b996101a08801614a17565b90509295509295509295565b60008060408385031215614bb857600080fd5b82359150614bc860208401614a17565b90509250929050565b60008060408385031215614be457600080fd5b614bed83614a17565b946020939093013593505050565b600060208284031215614c0d57600080fd5b61449c82614a17565b600080600060408486031215614c2b57600080fd5b833567ffffffffffffffff80821115614c4357600080fd5b818601915086601f830112614c5757600080fd5b813581811115614c6657600080fd5b8760208260051b8501011115614c7b57600080fd5b60209283019550935050840135614c91816149ca565b809150509250925092565b8060005b6001811015612474578151845260209384019390910190600101614ca0565b8060005b6009811015612474578151845260209384019390910190600101614cc3565b6101608101614cf18286614c9c565b614cfe6020830185614c9c565b6146b06040830184614cbf565b60006103a08201905082518252602083015160208301526040830151614d346040840182614c9c565b506060830151614d476060840182614c9c565b506080830151614d5a6080840182614c9c565b5060a0830151614d6d60a0840182614c9c565b5060c0830151614d8060c0840182614cbf565b5060e0830151614d946101e0840182614cbf565b5061010083015115156103008301526101208301511515610320830152610140830151610340830152610160830151610360830152610180909201516103809091015290565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b821415614e0657614e06614dda565b5060000390565b600082821015614e1f57614e1f614dda565b500390565b6000816000190483118215151615614e3e57614e3e614dda565b500290565b600082614e6057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60008219821115614e8e57614e8e614dda565b500190565b600060208284031215614ea557600080fd5b5051919050565b6000600019821415614ec057614ec0614dda565b5060010190565b600067ffffffffffffffff83811690831681811015614ee857614ee8614dda565b039392505050565b600060208284031215614f0257600080fd5b815161449c816149ca565b60005b83811015614f28578181015183820152602001614f10565b838111156124745750506000910152565b60008251614f4b818460208701614f0d565b9190910192915050565b6020815260008251806020840152614f74816040850160208701614f0d565b601f01601f1916919091016040019291505056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00a26469706673582212206cc4bdca16d904626457cff4a3386dc524e375daccef09d4002e195c25ac493964736f6c634300080900330000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c0000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c0000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d470000000000000000000000003333b97138d4b086720b5ae8a7844b1345a33333000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b00000000000000000000000059524d5667b299c0813ba3c99a11c038a3908fbc00000000000000000000000079bbf4508b1391af3a0f4b30bb5fc4aa9ab0e07c000000000000000000000000a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e70000000000000000000000000f26ff70573ddc8a90bd7865af8d7d70b8ff019bc0000000000000000000000009fdbc3f8abc05fa8f3ad3c17d2f806c1230c45640000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d47000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Deployed Bytecode
0x6080604052600436106103175760003560e01c80638cbba57a1161019a578063c89ebaec116100e1578063e72f6e301161008a578063f2fde38b11610064578063f2fde38b1461098a578063f4325d67146109aa578063f6d4277a146109ca57600080fd5b8063e72f6e301461091d578063edc017521461093d578063f1ddf8401461096a57600080fd5b8063d89135cd116100bb578063d89135cd146108c7578063e33702d7146108dd578063e4879b88146108fd57600080fd5b8063c89ebaec14610863578063d1058e5914610883578063d5eae1d5146108a757600080fd5b8063ae169a5011610143578063b74e452b1161011d578063b74e452b146107ee578063be80701614610803578063c194efbf1461084357600080fd5b8063ae169a501461078e578063aff177ca146107ae578063b6b55f25146107ce57600080fd5b8063996c6cc311610174578063996c6cc3146106b85780639ff46e74146106d8578063a7310b58146106f857600080fd5b80638cbba57a146106545780638da5cb5b1461067457806392a526131461069857600080fd5b80635d54e6121161025e578063790ca413116102075780637b76ac91116101e15780637b76ac91146105cf578063817b1cd214610609578063895ff41d1461061f57600080fd5b8063790ca413146105795780637b460b2a1461058f5780637b58389e146105af57600080fd5b80636d9873c5116102385780636d9873c51461052f5780636f55184b14610544578063715018a61461056457600080fd5b80635d54e612146104c5578063637eb25b146104ef57806368c958ee1461050f57600080fd5b806336f9825f116102c057806342966c681161029a57806342966c68146104655780634ccc895b14610485578063509b6c3f146104a557600080fd5b806336f9825f146103f85780633a589b971461043057806341632d331461045057600080fd5b806323a6f46e116102f157806323a6f46e146103985780632b653797146103b85780632e1a7d4d146103d857600080fd5b80630b9166de146103235780630f392ad01461035657806322ac7b8f1461037657600080fd5b3661031e57005b600080fd5b34801561032f57600080fd5b5061034361033e3660046149b1565b6109ea565b6040519081526020015b60405180910390f35b34801561036257600080fd5b506103436103713660046149b1565b610a01565b34801561038257600080fd5b506103966103913660046149d8565b610a11565b005b3480156103a457600080fd5b506103436103b33660046149b1565b610a8a565b3480156103c457600080fd5b506103436103d33660046149b1565b610a9a565b3480156103e457600080fd5b506103966103f33660046149b1565b610aaa565b34801561040457600080fd5b506104186104133660046149b1565b610db8565b6040516001600160a01b03909116815260200161034d565b34801561043c57600080fd5b50600354610418906001600160a01b031681565b34801561045c57600080fd5b50602d54610343565b34801561047157600080fd5b506103966104803660046149b1565b610de2565b34801561049157600080fd5b506103966104a03660046149f5565b610def565b3480156104b157600080fd5b506104186104c03660046149b1565b6111dc565b3480156104d157600080fd5b506012546104df9060ff1681565b604051901515815260200161034d565b3480156104fb57600080fd5b5061039661050a366004614ada565b6111fc565b34801561051b57600080fd5b5061039661052a366004614ba5565b611871565b34801561053b57600080fd5b506103966119bc565b34801561055057600080fd5b5061034361055f3660046149b1565b611a10565b34801561057057600080fd5b50610396611a20565b34801561058557600080fd5b50610343600f5481565b34801561059b57600080fd5b506103436105aa3660046149b1565b611a8d565b3480156105bb57600080fd5b506103436105ca3660046149b1565b611a9d565b3480156105db57600080fd5b50602c546105f09067ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161034d565b34801561061557600080fd5b5061034360135481565b34801561062b57600080fd5b5061063f61063a3660046149b1565b611aad565b6040805192835260208301919091520161034d565b34801561066057600080fd5b5061063f61066f366004614bd1565b611d87565b34801561068057600080fd5b506000546201000090046001600160a01b0316610418565b3480156106a457600080fd5b506103966106b33660046149f5565b611ddb565b3480156106c457600080fd5b50600e54610418906001600160a01b031681565b3480156106e457600080fd5b506103966106f33660046149b1565b61210f565b34801561070457600080fd5b50610753610713366004614bfb565b602e6020526000908152604090208054600182015460188301546019840154601a850154601b909501549394929360ff8084169461010090940416929087565b604080519788526020880196909652931515948601949094529015156060850152608084015260a083019190915260c082015260e00161034d565b34801561079a57600080fd5b506103436107a93660046149b1565b612204565b3480156107ba57600080fd5b506103966107c9366004614c16565b61239f565b3480156107da57600080fd5b506103966107e93660046149b1565b61247a565b3480156107fa57600080fd5b506105f0612556565b34801561080f57600080fd5b5061082361081e366004614bd1565b612577565b60408051948552602085019390935291830152606082015260800161034d565b34801561084f57600080fd5b5061034361085e3660046149b1565b612602565b34801561086f57600080fd5b5061041861087e3660046149b1565b612612565b34801561088f57600080fd5b50610898612622565b60405161034d93929190614ce2565b3480156108b357600080fd5b506103966108c23660046149f5565b612bea565b3480156108d357600080fd5b5061034360145481565b3480156108e957600080fd5b506103966108f83660046149f5565b612d0a565b34801561090957600080fd5b506103436109183660046149b1565b612e25565b34801561092957600080fd5b50610396610938366004614bfb565b612e35565b34801561094957600080fd5b5061095d6109583660046149b1565b613084565b60405161034d9190614d0b565b34801561097657600080fd5b50610396610985366004614ba5565b613277565b34801561099657600080fd5b506103966109a5366004614bfb565b61334a565b3480156109b657600080fd5b50600254610418906001600160a01b031681565b3480156109d657600080fd5b5061063f6109e53660046149b1565b613430565b601081600181106109fa57600080fd5b0154905081565b601981600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314610a775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6012805460ff1916911515919091179055565b601a81600981106109fa57600080fd5b601881600181106109fa57600080fd5b60026001541415610aeb5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015580610b2e5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b336000908152602e60205260409020805480831115610b8f5760405162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e63650000000000000000000000006044820152606401610a6e565b610b9761369d565b610bab33610ba485614df0565b6000613b13565b8260136000828254610bbd9190614e0d565b9091555050601882015460ff1680610bd7575060125460ff165b15610bf857600254610bf3906001600160a01b03163385613f1a565b610d6b565b6000670de0b6b3a7640000610c1485662386f26fc10000614e24565b610c1e9190614e43565b90506000610c2d826009614e24565b90506000610c3c83600b614e24565b610c469087614e0d565b90508160156000016000828254610c5d9190614e7b565b909155505060135415610cd657601354610c78846002614e24565b610c91906ec097ce7bc90715b34b9f1000000000614e24565b610c9b9190614e43565b60188054600090610cad908490614e7b565b90915550610cbe9050836002614e24565b60168054600090610cd0908490614e7b565b90915550505b60145415610d3757601454610cfa846ec097ce7bc90715b34b9f1000000000614e24565b610d049190614e43565b60198054600090610d16908490614e7b565b9091555083905060176000016000828254610d319190614e7b565b90915550505b600254610d50906001600160a01b031661dead85613f1a565b600254610d67906001600160a01b03163383613f1a565b5050505b6002546040518481526001600160a01b039091169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060200160405180910390a350506001805550565b602d8181548110610dc857600080fd5b6000918252602090912001546001600160a01b0316905081565b610dec8133611871565b50565b60026001541415610e305760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015560098210610e755760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b60008111610eb65760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b610ebe61369d565b600060135411610f105760405162461bcd60e51b815260206004820152600b60248201527f6e6f206465706f736974730000000000000000000000000000000000000000006044820152606401610a6e565b600060058360098110610f2557610f25614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610f6757600080fd5b505afa158015610f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9f9190614e93565b9050610fcd33308460058760098110610fba57610fba614e65565b01546001600160a01b0316929190613faf565b8060058460098110610fe157610fe1614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561102357600080fd5b505afa158015611037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105b9190614e93565b6110659190614e0d565b600e549092506001600160a01b031690506005836009811061108957611089614e65565b01546001600160a01b0316141561110b57600582600981106110ad576110ad614e65565b0154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156110f257600080fd5b505af1158015611106573d6000803e3d6000fd5b505050505b60135461112082670de0b6b3a7640000614e24565b61112a9190614e43565b6023836009811061113d5761113d614e65565b01600082825461114d9190614e7b565b90915550819050601a836009811061116757611167614e65565b0160008282546111779190614e7b565b9091555060059050826009811061119057611190614e65565b01546040518281526001600160a01b039091169033907f9ed97645fb5853abbbe66e94ac8ed13dac4d3ff7afe85b05c0e2b323b4014193906020015b60405180910390a3505060018055565b600581600981106111ec57600080fd5b01546001600160a01b0316905081565b600054610100900460ff1680611215575060005460ff16155b6112875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a6e565b600054610100900460ff161580156112a9576000805461ffff19166101011790555b6112b287613fe7565b6367be91c0600f5560005b600181101561131257662386f26fc10000601082600181106112e1576112e1614e65565b0155662386f26fc10000601182600181106112fe576112fe614e65565b01558061130a81614eac565b9150506112bd565b506012805460ff191690556000601381905560148190555b60018110156113b85760006015826001811061134857611348614e65565b015560006016826001811061135f5761135f614e65565b015560006017826001811061137657611376614e65565b015560006018826001811061138d5761138d614e65565b01556000601982600181106113a4576113a4614e65565b0155806113b081614eac565b91505061132a565b5060005b6009811015611405576000601a82600981106113da576113da614e65565b01556000602382600981106113f1576113f1614e65565b0155806113fd81614eac565b9150506113bc565b5061140e612556565b602c805467ffffffffffffffff191667ffffffffffffffff9290921691909117905560005b60018110156114ea5760005b818110156114d75786816001811061145957611459614e65565b60200201516001600160a01b031687836001811061147957611479614e65565b60200201516001600160a01b031614156114c55760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b806114cf81614eac565b91505061143f565b50806114e281614eac565b915050611433565b5060005b60098110156115a55760005b818110156115925785816009811061151457611514614e65565b60200201516001600160a01b031686836009811061153457611534614e65565b60200201516001600160a01b031614156115805760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b8061158a81614eac565b9150506114fa565b508061159d81614eac565b9150506114ee565b5084516001600160a01b038781169116146115f25760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b60015b60018110156116bd576000805b600981101561166c5786816009811061161d5761161d614e65565b60200201516001600160a01b031688846001811061163d5761163d614e65565b60200201516001600160a01b0316141561165a576001915061166c565b8061166481614eac565b915050611602565b50806116aa5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b50806116b581614eac565b9150506115f5565b5060005b600981101561174457866001600160a01b03168582600981106116e6576116e6614e65565b60200201516001600160a01b031614156117325760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b8061173c81614eac565b9150506116c1565b50856001600160a01b0316826001600160a01b031614156117975760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b600280546001600160a01b038089166001600160a01b03199283161790925560038054928616929091169190911790556117d46004866001614830565b506117e26005856009614888565b50600e80546001600160a01b0319166001600160a01b0384811691909117909155604051633d0c1b3360e01b81526000600482015290871690633d0c1b3390602401600060405180830381600087803b15801561183e57600080fd5b505af1158015611852573d6000803e3d6000fd5b505050508015611868576000805461ff00191690555b50505050505050565b600f544210156118b15760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156118f25760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155816119355760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b61193d61369d565b61194981600084613b13565b816014600082825461195b9190614e7b565b909155505060035461197a906001600160a01b03163361dead85613faf565b6003546040518381526001600160a01b03918216918316907fbac40739b0d4ca32fa2d82fc91630465ba3eddd1598da6fca393b26fb63b9453906020016111cc565b600260015414156119fd5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155611a0a61369d565b60018055565b601581600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314611a815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b611a8b6000613fe7565b565b601681600181106109fa57600080fd5b601781600181106109fa57600080fd5b60008060026001541415611af15760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260019081558310611b365760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b6002546001600160a01b031660048460018110611b5557611b55614e65565b01546001600160a01b031614611b9d5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b611ba561369d565b611bb133600080613b13565b336000908152602e60205260409020600281018460018110611bd557611bd5614e65565b01549250806003018460018110611bee57611bee614e65565b015491508215611c65576000816002018560018110611c0f57611c0f614e65565b01558260158560018110611c2557611c25614e65565b016000828254611c359190614e0d565b9091555083905060168560018110611c4f57611c4f614e65565b016000828254611c5f9190614e0d565b90915550505b8115611cae576000816003018560018110611c8257611c82614e65565b01558160178560018110611c9857611c98614e65565b016000828254611ca89190614e0d565b90915550505b6000611cba8385614e7b565b90508015611ccd57611ccd308233614058565b60048560018110611ce057611ce0614e65565b01546040518581526001600160a01b039091169033907f6c7e7d4cb83a668aef31739dd35dc3fc3d5f31d62b69e438b7b24d35b40dcc639060200160405180910390a360048560018110611d3657611d36614e65565b01546040518481526001600160a01b039091169033907f6c7e7d4cb83a668aef31739dd35dc3fc3d5f31d62b69e438b7b24d35b40dcc63906020015b60405180910390a35050600180559092909150565b6001600160a01b0382166000908152602e602052604081208190600681018460098110611db657611db6614e65565b015481600f018560098110611dcd57611dcd614e65565b015492509250509250929050565b60026001541415611e1c5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260019081558210611e615760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b60008111611ea25760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b611eaa61369d565b600060048360018110611ebf57611ebf614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611f0157600080fd5b505afa158015611f15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f399190614e93565b9050611f5433308460048760018110610fba57610fba614e65565b8060048460018110611f6857611f68614e65565b01546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611faa57600080fd5b505afa158015611fbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe29190614e93565b611fec9190614e0d565b600e549092506001600160a01b031690506004836001811061201057612010614e65565b01546001600160a01b03161415612092576004826001811061203457612034614e65565b0154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050505b80601583600181106120a6576120a6614e65565b0160008282546120b69190614e7b565b909155506004905082600181106120cf576120cf614e65565b01546040518281526001600160a01b039091169033907f88923243846ae6dc2129c36897f0c50381bac23792669a4ab5bc456dd9976177906020016111cc565b6000546001600160a01b03620100009091041633146121705760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b600f5442106121af5760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b428110156121ff5760405162461bcd60e51b815260206004820152600c60248201527f696e76616c69642074696d6500000000000000000000000000000000000000006044820152606401610a6e565b600f55565b6000600260015414156122475760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b60026001556009821061228c5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b61229461369d565b6122a033600080613b13565b336000908152602e602052604090206006810183600981106122c4576122c4614e65565b0154915081156123115760008160060184600981106122e5576122e5614e65565b015581601a84600981106122fb576122fb614e65565b01600082825461230b9190614e0d565b90915550505b811561233f5761233f6005846009811061232d5761232d614e65565b01546001600160a01b03163384614354565b6005836009811061235257612352614e65565b01546040518381526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a35060018055919050565b6000546001600160a01b03620100009091041633146124005760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60005b828110156124745781602e600086868581811061242257612422614e65565b90506020020160208101906124379190614bfb565b6001600160a01b031681526020810191909152604001600020601801805460ff19169115159190911790558061246c81614eac565b915050612403565b50505050565b600f544210156124ba5760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156124fb5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015561250b338281614058565b6002546040518281526001600160a01b039091169033907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f629060200160405180910390a35060018055565b60006201518061256861e10042614e7b565b6125729190614e43565b905090565b6001600160a01b0382166000908152602e602052604081208190819081906002810186600181106125aa576125aa614e65565b01548160030187600181106125c1576125c1614e65565b01548260040188600181106125d8576125d8614e65565b01548360050189600181106125ef576125ef614e65565b0154929a91995097509095509350505050565b602381600981106109fa57600080fd5b600481600181106111ec57600080fd5b61262a6148cf565b6126326148cf565b61263a6148ed565b6002600154141561267b5760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015561268861369d565b61269433600080613b13565b336000908152602e60205260408120905b600181101561271c578160020181600181106126c3576126c3614e65565b01548582600181106126d7576126d7614e65565b60200201526003820181600181106126f1576126f1614e65565b015484826001811061270557612705614e65565b60200201528061271481614eac565b9150506126a5565b5060005b60098110156127695781600601816009811061273e5761273e614e65565b015483826009811061275257612752614e65565b60200201528061276181614eac565b915050612720565b5060005b60018110156128b857600085826001811061278a5761278a614e65565b6020020151111561282e5760008260020182600181106127ac576127ac614e65565b01558481600181106127c0576127c0614e65565b6020020151601582600181106127d8576127d8614e65565b0160008282546127e89190614e0d565b90915550859050816001811061280057612800614e65565b60200201516016826001811061281857612818614e65565b0160008282546128289190614e0d565b90915550505b600084826001811061284257612842614e65565b602002015111156128a657600082600301826001811061286457612864614e65565b015583816001811061287857612878614e65565b60200201516017826001811061289057612890614e65565b0160008282546128a09190614e0d565b90915550505b806128b081614eac565b91505061276d565b5060005b600981101561294f5760008382600981106128d9576128d9614e65565b6020020151111561293d5760008260060182600981106128fb576128fb614e65565b015582816009811061290f5761290f614e65565b6020020151601a826009811061292757612927614e65565b0160008282546129379190614e0d565b90915550505b8061294781614eac565b9150506128bc565b5060005b60018110156129d957600084826001811061297057612970614e65565b602002015186836001811061298757612987614e65565b60200201516129969190614e7b565b905080156129c6576129c6600483600181106129b4576129b4614e65565b01546001600160a01b03163383614354565b50806129d181614eac565b915050612953565b5060005b6009811015612a555760008382600981106129fa576129fa614e65565b60200201511115612a4357612a4360058260098110612a1b57612a1b614e65565b01546001600160a01b031633858460098110612a3957612a39614e65565b6020020151614354565b80612a4d81614eac565b9150506129dd565b5060005b6001811015612b505760048160018110612a7557612a75614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068878460018110612ab457612ab4614e65565b6020020151604051612ac891815260200190565b60405180910390a360048160018110612ae357612ae3614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068868460018110612b2257612b22614e65565b6020020151604051612b3691815260200190565b60405180910390a380612b4881614eac565b915050612a59565b5060005b6009811015612bdd5760058160098110612b7057612b70614e65565b01546001600160a01b0316337f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd987068858460098110612baf57612baf614e65565b6020020151604051612bc391815260200190565b60405180910390a380612bd581614eac565b915050612b54565b5050600180559192909190565b6000546001600160a01b0362010000909104163314612c4b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60018210612c8b5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b670de0b6b3a764000060118360018110612ca757612ca7614e65565b0154612cb39083614e7b565b1115612cf05760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964207261746560a01b6044820152606401610a6e565b8060108360018110612d0457612d04614e65565b01555050565b6000546001600160a01b0362010000909104163314612d6b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60018210612dab5760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b670de0b6b3a76400008160108460018110612dc857612dc8614e65565b0154612dd49190614e7b565b1115612e115760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964207261746560a01b6044820152606401610a6e565b8060118360018110612d0457612d04614e65565b601181600181106109fa57600080fd5b6000546001600160a01b0362010000909104163314612e965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b60026001541415612ed75760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b600260015560005b6009811015612f5a5760058160098110612efb57612efb614e65565b01546001600160a01b0383811691161415612f485760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610a6e565b80612f5281614eac565b915050612edf565b506040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015612f9d57600080fd5b505afa158015612fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd59190614e93565b6002549091506001600160a01b0383811691161415613018576017546015546013546130019190614e7b565b61300b9190614e7b565b6130159082614e0d565b90505b600081116130685760405162461bcd60e51b815260206004820152600a60248201527f6e6f2062616c616e6365000000000000000000000000000000000000000000006044820152606401610a6e565b61307c6001600160a01b0383163383613f1a565b505060018055565b61308c61490c565b602e6000602d84815481106130a3576130a3614e65565b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902081516101a08101835281548152600180830154828601528351948501808552919492938501929160028501919082845b8154815260200190600101908083116130fb575050509183525050604080516020808201928390529092019190600384019060019082845b815481526020019060010190808311613133575050509183525050604080516020808201928390529092019190600484019060019082845b81548152602001906001019080831161316b575050509183525050604080516020808201928390529092019190600584019060019082845b8154815260200190600101908083116131a35750505091835250506040805161012081019182905260209092019190600684019060099082845b8154815260200190600101908083116131dd5750505091835250506040805161012081019182905260209092019190600f84019060099082845b815481526020019060010190808311613217575050509183525050601882015460ff80821615156020840152610100909104161515604082015260198201546060820152601a8201546080820152601b9091015460a09091015292915050565b600f544210156132b75760405162461bcd60e51b815260206004820152600b60248201526a756e617661696c61626c6560a81b6044820152606401610a6e565b600260015414156132f85760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600155613308338383614058565b6002546040518381526001600160a01b03918216918316907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906020016111cc565b6000546001600160a01b03620100009091041633146133ab5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a6e565b6001600160a01b0381166134275760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a6e565b610dec81613fe7565b600080600260015414156134745760405162461bcd60e51b815260206004820152601f6024820152600080516020614f898339815191526044820152606401610a6e565b6002600190815583106134b95760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a6e565b6134c161369d565b6134cd33600080613b13565b336000908152602e602052604090206002810184600181106134f1576134f1614e65565b0154925080600301846001811061350a5761350a614e65565b01549150821561358157600081600201856001811061352b5761352b614e65565b0155826015856001811061354157613541614e65565b0160008282546135519190614e0d565b909155508390506016856001811061356b5761356b614e65565b01600082825461357b9190614e0d565b90915550505b81156135ca57600081600301856001811061359e5761359e614e65565b015581601785600181106135b4576135b4614e65565b0160008282546135c49190614e0d565b90915550505b60006135d68385614e7b565b905080156135f4576135f4600486600181106129b4576129b4614e65565b6004856001811061360757613607614e65565b01546040518581526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a36004856001811061365d5761365d614e65565b01546040518481526001600160a01b039091169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd98706890602001611d72565b60006136a7612556565b602c5490915067ffffffffffffffff808316911614156136c45750565b60005b600181101561393e576000601182600181106136e5576136e5614e65565b0154601083600181106136fa576136fa614e65565b01546137069190614e7b565b9050801561392b57602c546000906137289067ffffffffffffffff1685614ec7565b9050600061375161374184670de0b6b3a7640000614e0d565b8367ffffffffffffffff16614390565b61376390670de0b6b3a7640000614e0d565b90506000670de0b6b3a7640000826016876001811061378457613784614e65565b01546015886001811061379957613799614e65565b01546137a59190614e0d565b6137af9190614e24565b6137b99190614e43565b9050600084601087600181106137d1576137d1614e65565b01546137dd9084614e24565b6137e79190614e43565b6013549091501561386b5760135461380e826ec097ce7bc90715b34b9f1000000000614e24565b6138189190614e43565b6018876001811061382b5761382b614e65565b01600082825461383b9190614e7b565b909155508190506016876001811061385557613855614e65565b0160008282546138659190614e7b565b90915550505b60006138778284614e0d565b601454909150156139255760145461389e826ec097ce7bc90715b34b9f1000000000614e24565b6138a89190614e43565b601988600181106138bb576138bb614e65565b0160008282546138cb9190614e7b565b90915550819050601588600181106138e5576138e5614e65565b0160008282546138f59190614e0d565b909155508190506017886001811061390f5761390f614e65565b01600082825461391f9190614e7b565b90915550505b50505050505b508061393681614eac565b9150506136c7565b5060135415613aef5760025461395f906001600160a01b0316306000613f1a565b60005b6009811015613aed576000601a826009811061398057613980614e65565b01546139a96005846009811061399857613998614e65565b01546001600160a01b0316306143fa565b6139b39190614e0d565b905060015b6001811015613a5a57600583600981106139d4576139d4614e65565b01546001600160a01b0316600482600181106139f2576139f2614e65565b01546001600160a01b03161415613a485760178160018110613a1657613a16614e65565b015460158260018110613a2b57613a2b614e65565b0154613a379190614e7b565b613a419083614e0d565b9150613a5a565b80613a5281614eac565b9150506139b8565b508015613ada57601354613a7d826ec097ce7bc90715b34b9f1000000000614e24565b613a879190614e43565b60238360098110613a9a57613a9a614e65565b016000828254613aaa9190614e7b565b90915550819050601a8360098110613ac457613ac4614e65565b016000828254613ad49190614e7b565b90915550505b5080613ae581614eac565b915050613962565b505b602c805467ffffffffffffffff191667ffffffffffffffff92909216919091179055565b6001600160a01b0383166000908152602e602052604090206018810154610100900460ff16613b9b5760188101805461ff001916610100179055602d80546001810182556000919091527f4a2cc91ee622da3bc833a54c37ffcb6f3ec23b7793efc5eaf5e71b7b406c5c060180546001600160a01b0386166001600160a01b03199091161790555b60005b6001811015613cc957816004018160018110613bbc57613bbc614e65565b01546ec097ce7bc90715b34b9f100000000060188360018110613be157613be1614e65565b01548454613bef9190614e24565b613bf99190614e43565b613c039190614e0d565b826002018260018110613c1857613c18614e65565b016000828254613c289190614e7b565b9091555050600582018160018110613c4257613c42614e65565b01546ec097ce7bc90715b34b9f100000000060198360018110613c6757613c67614e65565b01548460010154613c789190614e24565b613c829190614e43565b613c8c9190614e0d565b826003018260018110613ca157613ca1614e65565b016000828254613cb19190614e7b565b90915550819050613cc181614eac565b915050613b9e565b5060005b6009811015613d6f5781600f018160098110613ceb57613ceb614e65565b01546ec097ce7bc90715b34b9f100000000060238360098110613d1057613d10614e65565b01548454613d1e9190614e24565b613d289190614e43565b613d329190614e0d565b826006018260098110613d4757613d47614e65565b016000828254613d579190614e7b565b90915550819050613d6781614eac565b915050613ccd565b506000831315613d985782816000016000828254613d8d9190614e7b565b90915550613dc39050565b6000831215613dc357613daa83614df0565b816000016000828254613dbd9190614e0d565b90915550505b81816001016000828254613dd79190614e7b565b90915550600090505b6001811015613ea2576ec097ce7bc90715b34b9f100000000060188260018110613e0c57613e0c614e65565b01548354613e1a9190614e24565b613e249190614e43565b826004018260018110613e3957613e39614e65565b01556ec097ce7bc90715b34b9f100000000060198260018110613e5e57613e5e614e65565b01548360010154613e6f9190614e24565b613e799190614e43565b826005018260018110613e8e57613e8e614e65565b015580613e9a81614eac565b915050613de0565b5060005b6009811015613f13576ec097ce7bc90715b34b9f100000000060238260098110613ed257613ed2614e65565b01548354613ee09190614e24565b613eea9190614e43565b82600f018260098110613eff57613eff614e65565b015580613f0b81614eac565b915050613ea6565b5050505050565b6040516001600160a01b038316602482015260448101829052613faa90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526144a3565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526124749085906323b872dd60e01b90608401613f46565b600080546001600160a01b03838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600082116140995760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610a6e565b6140a161369d565b6001600160a01b03831630146141d1576002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156140f557600080fd5b505afa158015614109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412d9190614e93565b600254909150614148906001600160a01b0316853086613faf565b6002546040516370a0823160e01b815230600482015282916001600160a01b0316906370a082319060240160206040518083038186803b15801561418b57600080fd5b505afa15801561419f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141c39190614e93565b6141cd9190614e0d565b9250505b6000670de0b6b3a76400006141ed84662386f26fc10000614e24565b6141f79190614e43565b90506000614206826009614e24565b9050600061421583600b614e24565b61421f9086614e0d565b905081601560000160008282546142369190614e7b565b9091555050601354156142af57601354614251846002614e24565b61426a906ec097ce7bc90715b34b9f1000000000614e24565b6142749190614e43565b60188054600090614286908490614e7b565b909155506142979050836002614e24565b601680546000906142a9908490614e7b565b90915550505b60145415614310576014546142d3846ec097ce7bc90715b34b9f1000000000614e24565b6142dd9190614e43565b601980546000906142ef908490614e7b565b909155508390506017600001600082825461430a9190614e7b565b90915550505b61431c84826000613b13565b806013600082825461432e9190614e7b565b909155505060025461434c906001600160a01b031661dead85613f1a565b505050505050565b600e546001600160a01b0384811691161461437d57613faa6001600160a01b0384168383613f1a565b613faa6001600160a01b03831682614588565b670de0b6b3a76400005b81156143f45760018216156143c957670de0b6b3a76400006143bc8483614e24565b6143c69190614e43565b90505b60019190911c90670de0b6b3a76400006143e38480614e24565b6143ed9190614e43565b925061439a565b92915050565b600e546000906001600160a01b03848116911614614490576040516370a0823160e01b81526001600160a01b0383811660048301528416906370a082319060240160206040518083038186803b15801561445357600080fd5b505afa158015614467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061448b9190614e93565b61449c565b816001600160a01b0316315b9392505050565b60006144f8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146a19092919063ffffffff16565b805190915015613faa57808060200190518101906145169190614ef0565b613faa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a6e565b804710156145d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a6e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114614625576040519150601f19603f3d011682016040523d82523d6000602084013e61462a565b606091505b5050905080613faa5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a6e565b60606146b084846000856146b8565b949350505050565b6060824710156147305760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a6e565b843b61477e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a6e565b600080866001600160a01b0316858760405161479a9190614f39565b60006040518083038185875af1925050503d80600081146147d7576040519150601f19603f3d011682016040523d82523d6000602084013e6147dc565b606091505b50915091506147ec8282866147f7565b979650505050505050565b6060831561480657508161449c565b8251156148165782518084602001fd5b8160405162461bcd60e51b8152600401610a6e9190614f55565b8260018101928215614878579160200282015b8281111561487857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614843565b5061488492915061499c565b5090565b8260098101928215614878579160200282018281111561487857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614843565b60405180602001604052806001906020820280368337509192915050565b6040518061012001604052806009906020820280368337509192915050565b604051806101a00160405280600081526020016000815260200161492e6148cf565b815260200161493b6148cf565b81526020016149486148cf565b81526020016149556148cf565b81526020016149626148ed565b815260200161496f6148ed565b81526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b5b80821115614884576000815560010161499d565b6000602082840312156149c357600080fd5b5035919050565b8015158114610dec57600080fd5b6000602082840312156149ea57600080fd5b813561449c816149ca565b60008060408385031215614a0857600080fd5b50508035926020909101359150565b80356001600160a01b0381168114614a2e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6040516020810167ffffffffffffffff81118282101715614a6c57614a6c614a33565b60405290565b600060405161012080820182811067ffffffffffffffff82111715614a9957614a99614a33565b6040529091508190830184811115614ab057600080fd5b835b81811015614ad157614ac381614a17565b835260209283019201614ab2565b50505092915050565b6000806000806000806101c08789031215614af457600080fd5b614afd87614a17565b95506020614b0c818901614a17565b955088605f890112614b1d57600080fd5b614b25614a49565b8060608a018b811115614b3757600080fd5b60408b015b81811015614b5a57614b4d81614a17565b8452928401928401614b3c565b508197508b607f8c0112614b6d57600080fd5b614b778c82614a72565b965050505050614b8a6101808801614a17565b9150614b996101a08801614a17565b90509295509295509295565b60008060408385031215614bb857600080fd5b82359150614bc860208401614a17565b90509250929050565b60008060408385031215614be457600080fd5b614bed83614a17565b946020939093013593505050565b600060208284031215614c0d57600080fd5b61449c82614a17565b600080600060408486031215614c2b57600080fd5b833567ffffffffffffffff80821115614c4357600080fd5b818601915086601f830112614c5757600080fd5b813581811115614c6657600080fd5b8760208260051b8501011115614c7b57600080fd5b60209283019550935050840135614c91816149ca565b809150509250925092565b8060005b6001811015612474578151845260209384019390910190600101614ca0565b8060005b6009811015612474578151845260209384019390910190600101614cc3565b6101608101614cf18286614c9c565b614cfe6020830185614c9c565b6146b06040830184614cbf565b60006103a08201905082518252602083015160208301526040830151614d346040840182614c9c565b506060830151614d476060840182614c9c565b506080830151614d5a6080840182614c9c565b5060a0830151614d6d60a0840182614c9c565b5060c0830151614d8060c0840182614cbf565b5060e0830151614d946101e0840182614cbf565b5061010083015115156103008301526101208301511515610320830152610140830151610340830152610160830151610360830152610180909201516103809091015290565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b821415614e0657614e06614dda565b5060000390565b600082821015614e1f57614e1f614dda565b500390565b6000816000190483118215151615614e3e57614e3e614dda565b500290565b600082614e6057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60008219821115614e8e57614e8e614dda565b500190565b600060208284031215614ea557600080fd5b5051919050565b6000600019821415614ec057614ec0614dda565b5060010190565b600067ffffffffffffffff83811690831681811015614ee857614ee8614dda565b039392505050565b600060208284031215614f0257600080fd5b815161449c816149ca565b60005b83811015614f28578181015183820152602001614f10565b838111156124745750506000910152565b60008251614f4b818460208701614f0d565b9190910192915050565b6020815260008251806020840152614f74816040850160208701614f0d565b601f01601f1916919091016040019291505056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00a26469706673582212206cc4bdca16d904626457cff4a3386dc524e375daccef09d4002e195c25ac493964736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c0000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c0000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d470000000000000000000000003333b97138d4b086720b5ae8a7844b1345a33333000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b00000000000000000000000059524d5667b299c0813ba3c99a11c038a3908fbc00000000000000000000000079bbf4508b1391af3a0f4b30bb5fc4aa9ab0e07c000000000000000000000000a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e70000000000000000000000000f26ff70573ddc8a90bd7865af8d7d70b8ff019bc0000000000000000000000009fdbc3f8abc05fa8f3ad3c17d2f806c1230c45640000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d47000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
-----Decoded View---------------
Arg [0] : _reserveToken (address): 0x4646050405D9Fa40FEafe8bE11C875dAd8c5d67c
Arg [1] : _dripToken (address[1]): 0x4646050405D9Fa40FEafe8bE11C875dAd8c5d67c
Arg [2] : _rewardToken (address[9]): 0x3Ad2234eBFED9dEEfab94B9719aEbc07f8510D47,0x3333b97138D4b086720b5aE8A7844b1345a33333,0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38,0x50c42dEAcD8Fc9773493ED674b675bE577f2634b,0x59524D5667B299c0813Ba3c99a11C038a3908fBC,0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C,0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70,0xf26Ff70573ddc8a90Bd7865AF8d7d70B8Ff019bC,0x9fDbC3f8Abc05Fa8f3Ad3C17D2F806c1230c4564
Arg [3] : _boostToken (address): 0x3Ad2234eBFED9dEEfab94B9719aEbc07f8510D47
Arg [4] : _wrappedToken (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c
Arg [1] : 0000000000000000000000004646050405d9fa40feafe8be11c875dad8c5d67c
Arg [2] : 0000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d47
Arg [3] : 0000000000000000000000003333b97138d4b086720b5ae8a7844b1345a33333
Arg [4] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [5] : 00000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b
Arg [6] : 00000000000000000000000059524d5667b299c0813ba3c99a11c038a3908fbc
Arg [7] : 00000000000000000000000079bbf4508b1391af3a0f4b30bb5fc4aa9ab0e07c
Arg [8] : 000000000000000000000000a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e70
Arg [9] : 000000000000000000000000f26ff70573ddc8a90bd7865af8d7d70b8ff019bc
Arg [10] : 0000000000000000000000009fdbc3f8abc05fa8f3ad3c17d2f806c1230c4564
Arg [11] : 0000000000000000000000003ad2234ebfed9deefab94b9719aebc07f8510d47
Arg [12] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.