Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- FarmPriceUpdater
- Optimization enabled
- true
- Compiler version
- v0.8.11+commit.d7f03943
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-08-22T06:52:08.464795Z
Constructor Arguments
000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f0000000000000000000000009db69cc8db5b3bf22127734c609add56b6c77ae7
Arg [0] (address) : 0xf15bf479a5711f9411595c6289a9e7c36f24ad2f
Arg [1] (address) : 0x9db69cc8db5b3bf22127734c609add56b6c77ae7
Contract source code
// File contracts/interfaces/IArtStudio.sol // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface IArtStudio { struct TokenInfo { address rewarder; // Address of rewarder for token address strategy; // Address of strategy for token uint256 lastRewardTime; // Last time that KANVAS distribution occurred for this token uint256 lastCumulativeReward; // Value of cumulativeAvgSkanvasPerWeightedDollar at last update uint256 storedPrice; // Latest value of token uint256 accSKANVASPerShare; // Accumulated KANVAS per share, times ACC_KANVAS_PRECISION. uint256 totalShares; //total number of shares for the token uint256 totalTokens; //total number of tokens deposited uint128 multiplier; // multiplier for this token uint16 withdrawFeeBP; // Withdrawal fee in basis points } function KANVAS() external view returns (address); function strategyPool() external view returns (address); function performanceFeeAddress() external view returns (address); function updatePrice(address token, uint256 newPrice) external; function updatePrices(address[] calldata tokens, uint256[] calldata newPrices) external; function tokenList() external view returns (address[] memory); function tokenParameters(address tokenAddress) external view returns (TokenInfo memory); function deposit(address token, uint256 amount, address to) external; function harvest(address token, address to) external; function withdraw(address token, uint256 amountShares, address to) external; } // File contracts/interfaces/IUniswapV2TWAP.sol pragma solidity >=0.5.0; interface IUniswapV2TWAP { function consult(address tokenA, address tokenB, address tokenIn, uint256 amountIn) external view returns (uint256 amountOut); function consultWithUpdate(address tokenA, address tokenB, address tokenIn, uint256 amountIn) external returns (uint256 amountOut); } // File @uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol@v1.0.0 pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.3.3 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); } // File @openzeppelin/contracts/utils/Context.sol@v4.3.3 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; } } // File @openzeppelin/contracts/access/Ownable.sol@v4.3.3 pragma solidity ^0.8.0; /** * @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() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File contracts/FarmPriceUpdater.sol //based on: https://github.com/Uniswap/uniswap-v2-periphery/tree/master/contracts/examples pragma solidity ^0.8.6; contract FarmPriceUpdater is Ownable { address constant WKAVA = 0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b; //whitelist of addresses that can call this contract mapping(address => bool) public whitelist; //tracks whether a token is an LP or not mapping(address => bool) public lpTokens; //tracks whether a token is a staked token like xSUSHI or not mapping(address => bool) public stakedTokens; //underlying tokens of staked tokens mapping(address => address) public underlyingTokenOfStakedTokens; //address of oracle to consult address public oracle; //address of ArtStudio address public immutable artStudio; event OracleSet(); modifier onlyWhitelist() { require(whitelist[msg.sender], "only callable by whitelisted addresses"); _; } constructor(address _artStudio, address _oracle) { artStudio = _artStudio; setOracle(_oracle); whitelist[msg.sender] = true; } //VIEW FUNCTIONS function getTokenPriceView(address token) public view returns (uint256) { //NOTE: return value is SCALED UP by 1e18, as this is the input amount in consulting the oracle if (token != WKAVA) { return IUniswapV2TWAP(oracle).consult(token, WKAVA, token, 1e18); } else { return 1e18; } } function getPriceOfLPView(address lpToken) public view returns (uint256) { address token0 = IUniswapV2Pair(lpToken).token0(); address token1 = IUniswapV2Pair(lpToken).token1(); uint256 priceToken0 = getTokenPriceView(token0); uint256 priceToken1 = getTokenPriceView(token1); (uint256 balanceToken0, uint256 balanceToken1, ) = IUniswapV2Pair(lpToken).getReserves(); uint256 lpTVL = (priceToken0 * balanceToken0) + (priceToken1 * balanceToken1); return lpTVL / IUniswapV2Pair(lpToken).totalSupply(); } function getPriceOfStakedTokenView(address stakedToken) public view returns (uint256) { address underlyingToken = underlyingTokenOfStakedTokens[stakedToken]; uint256 underlyingTokenBalance = IERC20(underlyingToken).balanceOf(stakedToken); uint256 totalSupplyOfStakedToken = IERC20(stakedToken).totalSupply(); if (totalSupplyOfStakedToken != 0) { uint256 underlyingTokenPrice = getTokenPriceView(underlyingToken); return (underlyingTokenPrice * underlyingTokenBalance) / totalSupplyOfStakedToken; } else { return 0; } } //PUBLIC WRITE FUNCTIONS function getTokenPrice(address token) public returns (uint256) { //NOTE: return value is SCALED UP by 1e18, as this is the input amount in consulting the oracle if (token != WKAVA) { return IUniswapV2TWAP(oracle).consultWithUpdate(token, WKAVA, token, 1e18); } else { return 1e18; } } function getPriceOfLP(address lpToken) public returns (uint256) { address token0 = IUniswapV2Pair(lpToken).token0(); address token1 = IUniswapV2Pair(lpToken).token1(); uint256 priceToken0 = getTokenPrice(token0); uint256 priceToken1 = getTokenPrice(token1); (uint256 balanceToken0, uint256 balanceToken1, ) = IUniswapV2Pair(lpToken).getReserves(); uint256 lpTVL = (priceToken0 * balanceToken0) + (priceToken1 * balanceToken1); return lpTVL / IUniswapV2Pair(lpToken).totalSupply(); } function getPriceOfStakedToken(address stakedToken) public returns (uint256) { address underlyingToken = underlyingTokenOfStakedTokens[stakedToken]; uint256 underlyingTokenBalance = IERC20(underlyingToken).balanceOf(stakedToken); uint256 totalSupplyOfStakedToken = IERC20(stakedToken).totalSupply(); if (totalSupplyOfStakedToken != 0) { uint256 underlyingTokenPrice = getTokenPrice(underlyingToken); return (underlyingTokenPrice * underlyingTokenBalance) / totalSupplyOfStakedToken; } else { return 0; } } //OWNER-ONLY FUNCTIONS function setOracle(address _oracle) public onlyOwner { oracle = _oracle; } function modifyWhitelist(address[] calldata addresses, bool[] calldata statuses) external onlyOwner { require(addresses.length == statuses.length, "input length mismatch"); for (uint256 i = 0; i < addresses.length; i++) { whitelist[addresses[i]] = statuses[i]; } } function addLPTokens(address[] calldata tokens) external onlyOwner { for (uint256 i = 0; i < tokens.length; i++) { require(IUniswapV2Pair(tokens[i]).factory() != address(0), "not an LP token"); lpTokens[tokens[i]] = true; } } function removeLPTokens(address[] calldata tokens) external onlyOwner { for (uint256 i = 0; i < tokens.length; i++) { lpTokens[tokens[i]] = false; } } function addStakedToken(address _stakedToken, address _underlyingToken) external onlyOwner { stakedTokens[_stakedToken] = true; underlyingTokenOfStakedTokens[_stakedToken] = _underlyingToken; } function removeStakedToken(address _stakedToken) external onlyOwner { stakedTokens[_stakedToken] = false; underlyingTokenOfStakedTokens[_stakedToken] = address(0); } //WHITELIST-ONLY FUNCTIONS function setPrice(address token) public onlyWhitelist { uint256 tokenPrice; if(lpTokens[token]) { tokenPrice = getPriceOfLP(token); } else if(stakedTokens[token]) { tokenPrice = getPriceOfStakedToken(token); } else { tokenPrice = getTokenPrice(token); } IArtStudio(artStudio).updatePrice(token, tokenPrice); } function setPrices(address[] memory tokens) public onlyWhitelist { uint256[] memory tokenPrices = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { if(lpTokens[tokens[i]]) { tokenPrices[i] = getPriceOfLP(tokens[i]); } else if (stakedTokens[tokens[i]]) { tokenPrices[i] = getPriceOfStakedToken(tokens[i]); } else { tokenPrices[i] = getTokenPrice(tokens[i]); } } IArtStudio(artStudio).updatePrices(tokens, tokenPrices); } function setAllPrices() external onlyWhitelist { address[] memory tokens = IArtStudio(artStudio).tokenList(); setPrices(tokens); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_artStudio","internalType":"address"},{"type":"address","name":"_oracle","internalType":"address"}]},{"type":"event","name":"OracleSet","inputs":[],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addLPTokens","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addStakedToken","inputs":[{"type":"address","name":"_stakedToken","internalType":"address"},{"type":"address","name":"_underlyingToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"artStudio","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceOfLP","inputs":[{"type":"address","name":"lpToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceOfLPView","inputs":[{"type":"address","name":"lpToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceOfStakedToken","inputs":[{"type":"address","name":"stakedToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceOfStakedTokenView","inputs":[{"type":"address","name":"stakedToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTokenPrice","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTokenPriceView","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"lpTokens","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"modifyWhitelist","inputs":[{"type":"address[]","name":"addresses","internalType":"address[]"},{"type":"bool[]","name":"statuses","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeLPTokens","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeStakedToken","inputs":[{"type":"address","name":"_stakedToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAllPrices","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setOracle","inputs":[{"type":"address","name":"_oracle","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPrice","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPrices","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"stakedTokens","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"underlyingTokenOfStakedTokens","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"whitelist","inputs":[{"type":"address","name":"","internalType":"address"}]}]
Contract Creation Code
0x60a06040523480156200001157600080fd5b5060405162001ae938038062001ae983398101604081905262000034916200016a565b6200003f336200007c565b6001600160a01b0382166080526200005781620000cc565b5050336000908152600160208190526040909120805460ff19169091179055620001a2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146200012b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200016557600080fd5b919050565b600080604083850312156200017e57600080fd5b62000189836200014d565b915062000199602084016200014d565b90509250929050565b608051611916620001d3600039600081816103080152818161059301528181610b4b015261106601526119166000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063a4117ddb116100c3578063dc633cf01161007c578063dc633cf01461033d578063dc96fe2714610350578063eb4349a514610363578063ee121cf71461036b578063f2fde38b1461037e578063f81bfc261461039157600080fd5b8063a4117ddb14610297578063a5b39cfb146102aa578063b17b658d146102cd578063c0982cc5146102f0578063cfd3464e14610303578063d02641a01461032a57600080fd5b8063715018a611610115578063715018a6146101e457806378605827146101ec5780637adbf9731461022d5780637dc0d1d0146102405780638da5cb5b146102535780639b19251a1461026457600080fd5b80631ee9489c1461015d5780633b3247901461018357806345d5bb1014610198578063509d2192146101ab57806352bc49dd146101be578063579269d3146101d1575b600080fd5b61017061016b366004611392565b6103a4565b6040519081526020015b60405180910390f35b610196610191366004611392565b6104ce565b005b6101706101a6366004611392565b6105f4565b6101706101b9366004611392565b6107ec565b6101966101cc366004611402565b6108d1565b6101966101df3660046114af565b610972565b610196610b82565b6102156101fa366004611392565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161017a565b61019661023b366004611392565b610bb8565b600554610215906001600160a01b031681565b6000546001600160a01b0316610215565b610287610272366004611392565b60016020526000908152604090205460ff1681565b604051901515815260200161017a565b6101966102a536600461154e565b610c04565b6102876102b8366004611392565b60036020526000908152604090205460ff1681565b6102876102db366004611392565b60026020526000908152604090205460ff1681565b6101966102fe366004611402565b610d13565b6102157f000000000000000000000000000000000000000000000000000000000000000081565b610170610338366004611392565b610e82565b61019661034b366004611392565b610f61565b61019661035e3660046115ba565b610fc4565b610196611033565b610170610379366004611392565b6110f8565b61019661038c366004611392565b611197565b61017061039f366004611392565b61122f565b6001600160a01b0381811660008181526004602081905260408083205490516370a0823160e01b81529182019390935290929190911690829082906370a0823190602401602060405180830381865afa158015610405573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042991906115f3565b90506000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561046b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048f91906115f3565b905080156104c35760006104a284610e82565b9050816104af8483611622565b6104b99190611641565b9695505050505050565b506000949350505050565b3360009081526001602052604090205460ff166105065760405162461bcd60e51b81526004016104fd90611663565b60405180910390fd5b6001600160a01b03811660009081526002602052604081205460ff161561053757610530826105f4565b905061056d565b6001600160a01b03821660009081526003602052604090205460ff161561056157610530826103a4565b61056a82610e82565b90505b6040516322bcb96f60e11b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063457972de906044015b600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b505050505050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065991906116a9565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561069b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bf91906116a9565b905060006106cc83610e82565b905060006106d983610e82565b9050600080876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561071c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074091906116dd565b506001600160701b039182169350169050600061075d8285611622565b6107678487611622565b610771919061172d565b9050886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d591906115f3565b6107df9082611641565b9998505050505050505050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085191906116a9565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b791906116a9565b905060006108c4836110f8565b905060006106d9836110f8565b6000546001600160a01b031633146108fb5760405162461bcd60e51b81526004016104fd90611745565b60005b8181101561096d5760006002600085858581811061091e5761091e61177a565b90506020020160208101906109339190611392565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061096581611790565b9150506108fe565b505050565b3360009081526001602052604090205460ff166109a15760405162461bcd60e51b81526004016104fd90611663565b6000815167ffffffffffffffff8111156109bd576109bd611444565b6040519080825280602002602001820160405280156109e6578160200160208202803683370190505b50905060005b8251811015610b335760026000848381518110610a0b57610a0b61177a565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615610a7c57610a59838281518110610a4c57610a4c61177a565b60200260200101516105f4565b828281518110610a6b57610a6b61177a565b602002602001018181525050610b21565b60036000848381518110610a9257610a9261177a565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615610ae057610a59838281518110610ad357610ad361177a565b60200260200101516103a4565b610b02838281518110610af557610af561177a565b6020026020010151610e82565b828281518110610b1457610b1461177a565b6020026020010181815250505b80610b2b81611790565b9150506109ec565b506040516304b7bb8360e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906396f77060906105be90859085906004016117ab565b6000546001600160a01b03163314610bac5760405162461bcd60e51b81526004016104fd90611745565b610bb6600061132d565b565b6000546001600160a01b03163314610be25760405162461bcd60e51b81526004016104fd90611745565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610c2e5760405162461bcd60e51b81526004016104fd90611745565b828114610c755760405162461bcd60e51b81526020600482015260156024820152740d2dce0eae840d8cadccee8d040dad2e6dac2e8c6d605b1b60448201526064016104fd565b60005b83811015610d0c57828282818110610c9257610c9261177a565b9050602002016020810190610ca7919061182f565b60016000878785818110610cbd57610cbd61177a565b9050602002016020810190610cd29190611392565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610d0481611790565b915050610c78565b5050505050565b6000546001600160a01b03163314610d3d5760405162461bcd60e51b81526004016104fd90611745565b60005b8181101561096d576000838383818110610d5c57610d5c61177a565b9050602002016020810190610d719190611392565b6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd291906116a9565b6001600160a01b03161415610e1b5760405162461bcd60e51b815260206004820152600f60248201526e3737ba1030b7102628103a37b5b2b760891b60448201526064016104fd565b600160026000858585818110610e3357610e3361177a565b9050602002016020810190610e489190611392565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610e7a81611790565b915050610d40565b60006001600160a01b03821673c86c7c0efbd6a49b35e8714c5f59d99de09a225b14610f4d576005546040516396e6c33760e01b81526001600160a01b038481166004830181905273c86c7c0efbd6a49b35e8714c5f59d99de09a225b60248401526044830152670de0b6b3a76400006064830152909116906396e6c337906084016020604051808303816000875af1158015610f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4791906115f3565b92915050565b50670de0b6b3a7640000919050565b919050565b6000546001600160a01b03163314610f8b5760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b03166000908152600360209081526040808320805460ff191690556004909152902080546001600160a01b0319169055565b6000546001600160a01b03163314610fee5760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b039182166000908152600360209081526040808320805460ff19166001179055600490915290208054919092166001600160a01b0319909116179055565b3360009081526001602052604090205460ff166110625760405162461bcd60e51b81526004016104fd90611663565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639e2c58ca6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110ea9190810190611851565b90506110f581610972565b50565b60006001600160a01b03821673c86c7c0efbd6a49b35e8714c5f59d99de09a225b14610f4d57600554604051630a7d1a3f60e21b81526001600160a01b038481166004830181905273c86c7c0efbd6a49b35e8714c5f59d99de09a225b60248401526044830152670de0b6b3a76400006064830152909116906329f468fc90608401602060405180830381865afa158015610f23573d6000803e3d6000fd5b6000546001600160a01b031633146111c15760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b0381166112265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104fd565b6110f58161132d565b6001600160a01b0381811660008181526004602081905260408083205490516370a0823160e01b81529182019390935290929190911690829082906370a0823190602401602060405180830381865afa158015611290573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b491906115f3565b90506000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131a91906115f3565b905080156104c35760006104a2846110f8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146110f557600080fd5b6000602082840312156113a457600080fd5b81356113af8161137d565b9392505050565b60008083601f8401126113c857600080fd5b50813567ffffffffffffffff8111156113e057600080fd5b6020830191508360208260051b85010111156113fb57600080fd5b9250929050565b6000806020838503121561141557600080fd5b823567ffffffffffffffff81111561142c57600080fd5b611438858286016113b6565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561148357611483611444565b604052919050565b600067ffffffffffffffff8211156114a5576114a5611444565b5060051b60200190565b600060208083850312156114c257600080fd5b823567ffffffffffffffff8111156114d957600080fd5b8301601f810185136114ea57600080fd5b80356114fd6114f88261148b565b61145a565b81815260059190911b8201830190838101908783111561151c57600080fd5b928401925b828410156115435783356115348161137d565b82529284019290840190611521565b979650505050505050565b6000806000806040858703121561156457600080fd5b843567ffffffffffffffff8082111561157c57600080fd5b611588888389016113b6565b909650945060208701359150808211156115a157600080fd5b506115ae878288016113b6565b95989497509550505050565b600080604083850312156115cd57600080fd5b82356115d88161137d565b915060208301356115e88161137d565b809150509250929050565b60006020828403121561160557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561163c5761163c61160c565b500290565b60008261165e57634e487b7160e01b600052601260045260246000fd5b500490565b60208082526026908201527f6f6e6c792063616c6c61626c652062792077686974656c69737465642061646460408201526572657373657360d01b606082015260800190565b6000602082840312156116bb57600080fd5b81516113af8161137d565b80516001600160701b0381168114610f5c57600080fd5b6000806000606084860312156116f257600080fd5b6116fb846116c6565b9250611709602085016116c6565b9150604084015163ffffffff8116811461172257600080fd5b809150509250925092565b600082198211156117405761174061160c565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156117a4576117a461160c565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156117ed5781516001600160a01b0316845292840192908401906001016117c8565b5050508381038285015284518082528583019183019060005b8181101561182257835183529284019291840191600101611806565b5090979650505050505050565b60006020828403121561184157600080fd5b813580151581146113af57600080fd5b6000602080838503121561186457600080fd5b825167ffffffffffffffff81111561187b57600080fd5b8301601f8101851361188c57600080fd5b805161189a6114f88261148b565b81815260059190911b820183019083810190878311156118b957600080fd5b928401925b828410156115435783516118d18161137d565b825292840192908401906118be56fea264697066735822122055dede6bc2ca4f501e3f97a0aa613be7cc3033488dce782ad58dc2f744423d6a64736f6c634300080b0033000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f0000000000000000000000009db69cc8db5b3bf22127734c609add56b6c77ae7
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063a4117ddb116100c3578063dc633cf01161007c578063dc633cf01461033d578063dc96fe2714610350578063eb4349a514610363578063ee121cf71461036b578063f2fde38b1461037e578063f81bfc261461039157600080fd5b8063a4117ddb14610297578063a5b39cfb146102aa578063b17b658d146102cd578063c0982cc5146102f0578063cfd3464e14610303578063d02641a01461032a57600080fd5b8063715018a611610115578063715018a6146101e457806378605827146101ec5780637adbf9731461022d5780637dc0d1d0146102405780638da5cb5b146102535780639b19251a1461026457600080fd5b80631ee9489c1461015d5780633b3247901461018357806345d5bb1014610198578063509d2192146101ab57806352bc49dd146101be578063579269d3146101d1575b600080fd5b61017061016b366004611392565b6103a4565b6040519081526020015b60405180910390f35b610196610191366004611392565b6104ce565b005b6101706101a6366004611392565b6105f4565b6101706101b9366004611392565b6107ec565b6101966101cc366004611402565b6108d1565b6101966101df3660046114af565b610972565b610196610b82565b6102156101fa366004611392565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161017a565b61019661023b366004611392565b610bb8565b600554610215906001600160a01b031681565b6000546001600160a01b0316610215565b610287610272366004611392565b60016020526000908152604090205460ff1681565b604051901515815260200161017a565b6101966102a536600461154e565b610c04565b6102876102b8366004611392565b60036020526000908152604090205460ff1681565b6102876102db366004611392565b60026020526000908152604090205460ff1681565b6101966102fe366004611402565b610d13565b6102157f000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f81565b610170610338366004611392565b610e82565b61019661034b366004611392565b610f61565b61019661035e3660046115ba565b610fc4565b610196611033565b610170610379366004611392565b6110f8565b61019661038c366004611392565b611197565b61017061039f366004611392565b61122f565b6001600160a01b0381811660008181526004602081905260408083205490516370a0823160e01b81529182019390935290929190911690829082906370a0823190602401602060405180830381865afa158015610405573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042991906115f3565b90506000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561046b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048f91906115f3565b905080156104c35760006104a284610e82565b9050816104af8483611622565b6104b99190611641565b9695505050505050565b506000949350505050565b3360009081526001602052604090205460ff166105065760405162461bcd60e51b81526004016104fd90611663565b60405180910390fd5b6001600160a01b03811660009081526002602052604081205460ff161561053757610530826105f4565b905061056d565b6001600160a01b03821660009081526003602052604090205460ff161561056157610530826103a4565b61056a82610e82565b90505b6040516322bcb96f60e11b81526001600160a01b038381166004830152602482018390527f000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f169063457972de906044015b600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b505050505050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065991906116a9565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561069b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bf91906116a9565b905060006106cc83610e82565b905060006106d983610e82565b9050600080876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561071c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074091906116dd565b506001600160701b039182169350169050600061075d8285611622565b6107678487611622565b610771919061172d565b9050886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d591906115f3565b6107df9082611641565b9998505050505050505050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085191906116a9565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b791906116a9565b905060006108c4836110f8565b905060006106d9836110f8565b6000546001600160a01b031633146108fb5760405162461bcd60e51b81526004016104fd90611745565b60005b8181101561096d5760006002600085858581811061091e5761091e61177a565b90506020020160208101906109339190611392565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061096581611790565b9150506108fe565b505050565b3360009081526001602052604090205460ff166109a15760405162461bcd60e51b81526004016104fd90611663565b6000815167ffffffffffffffff8111156109bd576109bd611444565b6040519080825280602002602001820160405280156109e6578160200160208202803683370190505b50905060005b8251811015610b335760026000848381518110610a0b57610a0b61177a565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615610a7c57610a59838281518110610a4c57610a4c61177a565b60200260200101516105f4565b828281518110610a6b57610a6b61177a565b602002602001018181525050610b21565b60036000848381518110610a9257610a9261177a565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615610ae057610a59838281518110610ad357610ad361177a565b60200260200101516103a4565b610b02838281518110610af557610af561177a565b6020026020010151610e82565b828281518110610b1457610b1461177a565b6020026020010181815250505b80610b2b81611790565b9150506109ec565b506040516304b7bb8360e51b81526001600160a01b037f000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f16906396f77060906105be90859085906004016117ab565b6000546001600160a01b03163314610bac5760405162461bcd60e51b81526004016104fd90611745565b610bb6600061132d565b565b6000546001600160a01b03163314610be25760405162461bcd60e51b81526004016104fd90611745565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610c2e5760405162461bcd60e51b81526004016104fd90611745565b828114610c755760405162461bcd60e51b81526020600482015260156024820152740d2dce0eae840d8cadccee8d040dad2e6dac2e8c6d605b1b60448201526064016104fd565b60005b83811015610d0c57828282818110610c9257610c9261177a565b9050602002016020810190610ca7919061182f565b60016000878785818110610cbd57610cbd61177a565b9050602002016020810190610cd29190611392565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610d0481611790565b915050610c78565b5050505050565b6000546001600160a01b03163314610d3d5760405162461bcd60e51b81526004016104fd90611745565b60005b8181101561096d576000838383818110610d5c57610d5c61177a565b9050602002016020810190610d719190611392565b6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd291906116a9565b6001600160a01b03161415610e1b5760405162461bcd60e51b815260206004820152600f60248201526e3737ba1030b7102628103a37b5b2b760891b60448201526064016104fd565b600160026000858585818110610e3357610e3361177a565b9050602002016020810190610e489190611392565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610e7a81611790565b915050610d40565b60006001600160a01b03821673c86c7c0efbd6a49b35e8714c5f59d99de09a225b14610f4d576005546040516396e6c33760e01b81526001600160a01b038481166004830181905273c86c7c0efbd6a49b35e8714c5f59d99de09a225b60248401526044830152670de0b6b3a76400006064830152909116906396e6c337906084016020604051808303816000875af1158015610f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4791906115f3565b92915050565b50670de0b6b3a7640000919050565b919050565b6000546001600160a01b03163314610f8b5760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b03166000908152600360209081526040808320805460ff191690556004909152902080546001600160a01b0319169055565b6000546001600160a01b03163314610fee5760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b039182166000908152600360209081526040808320805460ff19166001179055600490915290208054919092166001600160a01b0319909116179055565b3360009081526001602052604090205460ff166110625760405162461bcd60e51b81526004016104fd90611663565b60007f000000000000000000000000f15bf479a5711f9411595c6289a9e7c36f24ad2f6001600160a01b0316639e2c58ca6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110ea9190810190611851565b90506110f581610972565b50565b60006001600160a01b03821673c86c7c0efbd6a49b35e8714c5f59d99de09a225b14610f4d57600554604051630a7d1a3f60e21b81526001600160a01b038481166004830181905273c86c7c0efbd6a49b35e8714c5f59d99de09a225b60248401526044830152670de0b6b3a76400006064830152909116906329f468fc90608401602060405180830381865afa158015610f23573d6000803e3d6000fd5b6000546001600160a01b031633146111c15760405162461bcd60e51b81526004016104fd90611745565b6001600160a01b0381166112265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104fd565b6110f58161132d565b6001600160a01b0381811660008181526004602081905260408083205490516370a0823160e01b81529182019390935290929190911690829082906370a0823190602401602060405180830381865afa158015611290573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b491906115f3565b90506000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131a91906115f3565b905080156104c35760006104a2846110f8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146110f557600080fd5b6000602082840312156113a457600080fd5b81356113af8161137d565b9392505050565b60008083601f8401126113c857600080fd5b50813567ffffffffffffffff8111156113e057600080fd5b6020830191508360208260051b85010111156113fb57600080fd5b9250929050565b6000806020838503121561141557600080fd5b823567ffffffffffffffff81111561142c57600080fd5b611438858286016113b6565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561148357611483611444565b604052919050565b600067ffffffffffffffff8211156114a5576114a5611444565b5060051b60200190565b600060208083850312156114c257600080fd5b823567ffffffffffffffff8111156114d957600080fd5b8301601f810185136114ea57600080fd5b80356114fd6114f88261148b565b61145a565b81815260059190911b8201830190838101908783111561151c57600080fd5b928401925b828410156115435783356115348161137d565b82529284019290840190611521565b979650505050505050565b6000806000806040858703121561156457600080fd5b843567ffffffffffffffff8082111561157c57600080fd5b611588888389016113b6565b909650945060208701359150808211156115a157600080fd5b506115ae878288016113b6565b95989497509550505050565b600080604083850312156115cd57600080fd5b82356115d88161137d565b915060208301356115e88161137d565b809150509250929050565b60006020828403121561160557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561163c5761163c61160c565b500290565b60008261165e57634e487b7160e01b600052601260045260246000fd5b500490565b60208082526026908201527f6f6e6c792063616c6c61626c652062792077686974656c69737465642061646460408201526572657373657360d01b606082015260800190565b6000602082840312156116bb57600080fd5b81516113af8161137d565b80516001600160701b0381168114610f5c57600080fd5b6000806000606084860312156116f257600080fd5b6116fb846116c6565b9250611709602085016116c6565b9150604084015163ffffffff8116811461172257600080fd5b809150509250925092565b600082198211156117405761174061160c565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156117a4576117a461160c565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156117ed5781516001600160a01b0316845292840192908401906001016117c8565b5050508381038285015284518082528583019183019060005b8181101561182257835183529284019291840191600101611806565b5090979650505050505050565b60006020828403121561184157600080fd5b813580151581146113af57600080fd5b6000602080838503121561186457600080fd5b825167ffffffffffffffff81111561187b57600080fd5b8301601f8101851361188c57600080fd5b805161189a6114f88261148b565b81815260059190911b820183019083810190878311156118b957600080fd5b928401925b828410156115435783516118d18161137d565b825292840192908401906118be56fea264697066735822122055dede6bc2ca4f501e3f97a0aa613be7cc3033488dce782ad58dc2f744423d6a64736f6c634300080b0033