ERC-20
Overview
Max Total Supply
41.834015801886970582 XT-2
Holders
55
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.000000006726247485 XT-2Value
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xb2b7BeDd...4c73C210d The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
CoFiXPair
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 6666 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-10-12 */ // SPDX-License-Identifier: GPL-3.0-or-later /** Author: CoFiX Core, https://cofix.io Commit hash: v0.9.5-1-g7141c43 Repository: https://github.com/Computable-Finance/CoFiX Issues: https://github.com/Computable-Finance/CoFiX/issues */ pragma experimental ABIEncoderV2; pragma solidity 0.6.12; // interface ICoFiXERC20 { 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; } // interface ICoFiXPair is ICoFiXERC20 { struct OraclePrice { uint256 ethAmount; uint256 erc20Amount; uint256 blockNum; uint256 K; uint256 theta; } // All pairs: {ETH <-> ERC20 Token} event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, address outToken, uint outAmount, address indexed to); event Swap( address indexed sender, uint amountIn, uint amountOut, address outToken, 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); function mint(address to) external payable returns (uint liquidity, uint oracleFeeChange); function burn(address outToken, address to) external payable returns (uint amountOut, uint oracleFeeChange); function swapWithExact(address outToken, address to) external payable returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo); function swapForExact(address outToken, uint amountOutExact, address to) external payable returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo); function skim(address to) external; function sync() external; function initialize(address, address, string memory, string memory) external; /// @dev get Net Asset Value Per Share /// @param ethAmount ETH side of Oracle price {ETH <-> ERC20 Token} /// @param erc20Amount Token side of Oracle price {ETH <-> ERC20 Token} /// @return navps The Net Asset Value Per Share (liquidity) represents function getNAVPerShare(uint256 ethAmount, uint256 erc20Amount) external view returns (uint256 navps); } // interface ICoFiXFactory { // All pairs: {ETH <-> ERC20 Token} event PairCreated(address indexed token, address pair, uint256); event NewGovernance(address _new); event NewController(address _new); event NewFeeReceiver(address _new); event NewFeeVaultForLP(address token, address feeVault); event NewVaultForLP(address _new); event NewVaultForTrader(address _new); event NewVaultForCNode(address _new); /// @dev Create a new token pair for trading /// @param token the address of token to trade /// @return pair the address of new token pair function createPair( address token ) external returns (address pair); function getPair(address token) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function getTradeMiningStatus(address token) external view returns (bool status); function setTradeMiningStatus(address token, bool status) external; function getFeeVaultForLP(address token) external view returns (address feeVault); // for LPs function setFeeVaultForLP(address token, address feeVault) external; function setGovernance(address _new) external; function setController(address _new) external; function setFeeReceiver(address _new) external; function setVaultForLP(address _new) external; function setVaultForTrader(address _new) external; function setVaultForCNode(address _new) external; function getController() external view returns (address controller); function getFeeReceiver() external view returns (address feeReceiver); // For CoFi Holders function getVaultForLP() external view returns (address vaultForLP); function getVaultForTrader() external view returns (address vaultForTrader); function getVaultForCNode() external view returns (address vaultForCNode); } // interface ICoFiXController { event NewK(address token, int128 K, int128 sigma, uint256 T, uint256 ethAmount, uint256 erc20Amount, uint256 blockNum, uint256 tIdx, uint256 sigmaIdx, int128 K0); event NewGovernance(address _new); event NewOracle(address _priceOracle); event NewKTable(address _kTable); event NewTimespan(uint256 _timeSpan); event NewKRefreshInterval(uint256 _interval); event NewKLimit(int128 maxK0); event NewGamma(int128 _gamma); event NewTheta(address token, uint32 theta); function addCaller(address caller) external; function queryOracle(address token, uint8 op, bytes memory data) external payable returns (uint256 k, uint256 ethAmount, uint256 erc20Amount, uint256 blockNum, uint256 theta); } // /** * @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); } // /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // // ERC20 token implementation, inherited by CoFiXPair contract, no owner or governance contract CoFiXERC20 is ICoFiXERC20 { using SafeMath for uint; string public constant nameForDomain = 'CoFiX Pool Token'; uint8 public override constant decimals = 18; uint public override totalSupply; mapping(address => uint) public override balanceOf; mapping(address => mapping(address => uint)) public override allowance; bytes32 public override DOMAIN_SEPARATOR; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint) public override nonces; event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); constructor() public { uint chainId; assembly { chainId := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), keccak256(bytes(nameForDomain)), keccak256(bytes('1')), chainId, address(this) ) ); } function _mint(address to, uint value) internal { totalSupply = totalSupply.add(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint value) internal { balanceOf[from] = balanceOf[from].sub(value); totalSupply = totalSupply.sub(value); emit Transfer(from, address(0), value); } function _approve(address owner, address spender, uint value) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer(address from, address to, uint value) private { balanceOf[from] = balanceOf[from].sub(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(from, to, value); } function approve(address spender, uint value) external override returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint value) external override returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom(address from, address to, uint value) external override returns (bool) { if (allowance[from][msg.sender] != uint(-1)) { allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); } _transfer(from, to, value); return true; } function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external override { require(deadline >= block.timestamp, 'CERC20: EXPIRED'); bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', DOMAIN_SEPARATOR, keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, 'CERC20: INVALID_SIGNATURE'); _approve(owner, spender, value); } } // // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } } // // Pair contract for each trading pair, storing assets and handling settlement // No owner or governance contract CoFiXPair is ICoFiXPair, CoFiXERC20 { using SafeMath for uint; enum CoFiX_OP { QUERY, MINT, BURN, SWAP_WITH_EXACT, SWAP_FOR_EXACT } // operations in CoFiX uint public override constant MINIMUM_LIQUIDITY = 10**9; // it's negligible because we calc liquidity in ETH bytes4 private constant SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)"))); uint256 constant public K_BASE = 1E8; // K uint256 constant public NAVPS_BASE = 1E18; // NAVPS (Net Asset Value Per Share), need accuracy uint256 constant public THETA_BASE = 1E8; // theta string public name; string public symbol; address public override immutable factory; address public override token0; // WETH token address public override token1; // any ERC20 token uint112 private reserve0; // uses single storage slot, accessible via getReserves uint112 private reserve1; // uses single storage slot, accessible via getReserves uint private unlocked = 1; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, address outToken, uint outAmount, address indexed to); event Swap( address indexed sender, uint amountIn, uint amountOut, address outToken, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); modifier lock() { require(unlocked == 1, "CPair: LOCKED"); unlocked = 0; _; unlocked = 1; } constructor() public { factory = msg.sender; } receive() external payable {} // called once by the factory at time of deployment function initialize(address _token0, address _token1, string memory _name, string memory _symbol) external override { require(msg.sender == factory, "CPair: FORBIDDEN"); // sufficient check token0 = _token0; token1 = _token1; name = _name; symbol = _symbol; } function getReserves() public override view returns (uint112 _reserve0, uint112 _reserve1) { _reserve0 = reserve0; _reserve1 = reserve1; } function _safeTransfer(address token, address to, uint value) private { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "CPair: TRANSFER_FAILED"); } // update reserves function _update(uint balance0, uint balance1) private { require(balance0 <= uint112(-1) && balance1 <= uint112(-1), "CPair: OVERFLOW"); reserve0 = uint112(balance0); reserve1 = uint112(balance1); emit Sync(reserve0, reserve1); } // this low-level function should be called from a contract which performs important safety checks function mint(address to) external payable override lock returns (uint liquidity, uint oracleFeeChange) { address _token0 = token0; // gas savings address _token1 = token1; // gas savings (uint112 _reserve0, uint112 _reserve1) = getReserves(); // gas savings uint balance0 = IERC20(_token0).balanceOf(address(this)); uint balance1 = IERC20(_token1).balanceOf(address(this)); uint amount0 = balance0.sub(_reserve0); uint amount1 = balance1.sub(_reserve1); uint256 _ethBalanceBefore = address(this).balance; { // scope for ethAmount/erc20Amount/blockNum to avoid stack too deep error bytes memory data = abi.encode(msg.sender, to, amount0, amount1); // query price OraclePrice memory _op; (_op.K, _op.ethAmount, _op.erc20Amount, _op.blockNum, _op.theta) = _queryOracle(_token1, CoFiX_OP.MINT, data); uint256 navps = calcNAVPerShareForMint(_reserve0, _reserve1, _op); if (totalSupply == 0) { liquidity = calcLiquidity(amount0, amount1, navps, _op).sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens } else { liquidity = calcLiquidity(amount0, amount1, navps, _op); } } oracleFeeChange = msg.value.sub(_ethBalanceBefore.sub(address(this).balance)); require(liquidity > 0, "CPair: SHORT_LIQUIDITY_MINTED"); _mint(to, liquidity); _update(balance0, balance1); if (oracleFeeChange > 0) TransferHelper.safeTransferETH(msg.sender, oracleFeeChange); emit Mint(msg.sender, amount0, amount1); } // this low-level function should be called from a contract which performs important safety checks function burn(address outToken, address to) external payable override lock returns (uint amountOut, uint oracleFeeChange) { address _token0 = token0; // gas savings address _token1 = token1; // gas savings uint balance0 = IERC20(_token0).balanceOf(address(this)); uint balance1 = IERC20(_token1).balanceOf(address(this)); uint liquidity = balanceOf[address(this)]; uint256 _ethBalanceBefore = address(this).balance; uint256 fee; { bytes memory data = abi.encode(msg.sender, outToken, to, liquidity); // query price OraclePrice memory _op; (_op.K, _op.ethAmount, _op.erc20Amount, _op.blockNum, _op.theta) = _queryOracle(_token1, CoFiX_OP.BURN, data); if (outToken == _token0) { (amountOut, fee) = calcOutToken0ForBurn(liquidity, _op); // navps calculated } else if (outToken == _token1) { (amountOut, fee) = calcOutToken1ForBurn(liquidity, _op); // navps calculated } else { revert("CPair: wrong outToken"); } } oracleFeeChange = msg.value.sub(_ethBalanceBefore.sub(address(this).balance)); require(amountOut > 0, "CPair: SHORT_LIQUIDITY_BURNED"); _burn(address(this), liquidity); _safeTransfer(outToken, to, amountOut); if (fee > 0) { if (ICoFiXFactory(factory).getTradeMiningStatus(_token1)) { // only transfer fee to protocol feeReceiver when trade mining is enabled for this trading pair _safeSendFeeForCoFiHolder(_token0, fee); } else { _safeSendFeeForLP(_token0, _token1, fee); } } balance0 = IERC20(_token0).balanceOf(address(this)); balance1 = IERC20(_token1).balanceOf(address(this)); _update(balance0, balance1); if (oracleFeeChange > 0) TransferHelper.safeTransferETH(msg.sender, oracleFeeChange); emit Burn(msg.sender, outToken, amountOut, to); } // this low-level function should be called from a contract which performs important safety checks function swapWithExact(address outToken, address to) external payable override lock returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo) { // tradeInfo[0]: thetaFee, tradeInfo[1]: x, tradeInfo[2]: y, tradeInfo[3]: navps address _token0 = token0; address _token1 = token1; uint256 balance0 = IERC20(_token0).balanceOf(address(this)); uint256 balance1 = IERC20(_token1).balanceOf(address(this)); // uint256 fee; { // scope for ethAmount/erc20Amount/blockNum to avoid stack too deep error uint256 _ethBalanceBefore = address(this).balance; (uint112 _reserve0, uint112 _reserve1) = getReserves(); // gas savings // calc amountIn if (outToken == _token1) { amountIn = balance0.sub(_reserve0); } else if (outToken == _token0) { amountIn = balance1.sub(_reserve1); } else { revert("CPair: wrong outToken"); } require(amountIn > 0, "CPair: wrong amountIn"); bytes memory data = abi.encode(msg.sender, outToken, to, amountIn); // query price OraclePrice memory _op; (_op.K, _op.ethAmount, _op.erc20Amount, _op.blockNum, _op.theta) = _queryOracle(_token1, CoFiX_OP.SWAP_WITH_EXACT, data); if (outToken == _token1) { (amountOut, tradeInfo[0]) = calcOutToken1(amountIn, _op); tradeInfo[1] = _reserve0; // swap token0 for token1 out tradeInfo[2] = uint256(_reserve1).mul(_op.ethAmount).div(_op.erc20Amount); // _reserve1 value as _reserve0 } else if (outToken == _token0) { (amountOut, tradeInfo[0]) = calcOutToken0(amountIn, _op); tradeInfo[1] = uint256(_reserve1).mul(_op.ethAmount).div(_op.erc20Amount); // _reserve1 value as _reserve0 tradeInfo[2] = _reserve0; // swap token1 for token0 out } oracleFeeChange = msg.value.sub(_ethBalanceBefore.sub(address(this).balance)); tradeInfo[3] = calcNAVPerShare(_reserve0, _reserve1, _op.ethAmount, _op.erc20Amount); } require(to != _token0 && to != _token1, "CPair: INVALID_TO"); _safeTransfer(outToken, to, amountOut); // optimistically transfer tokens if (tradeInfo[0] > 0) { if (ICoFiXFactory(factory).getTradeMiningStatus(_token1)) { // only transfer fee to protocol feeReceiver when trade mining is enabled for this trading pair _safeSendFeeForCoFiHolder(_token0, tradeInfo[0]); } else { _safeSendFeeForLP(_token0, _token1, tradeInfo[0]); tradeInfo[0] = 0; // so router won't go into the trade mining logic (reduce one more call gas cost) } } balance0 = IERC20(_token0).balanceOf(address(this)); balance1 = IERC20(_token1).balanceOf(address(this)); _update(balance0, balance1); if (oracleFeeChange > 0) TransferHelper.safeTransferETH(msg.sender, oracleFeeChange); emit Swap(msg.sender, amountIn, amountOut, outToken, to); } // this low-level function should be called from a contract which performs important safety checks function swapForExact(address outToken, uint amountOutExact, address to) external payable override lock returns (uint amountIn, uint amountOut, uint oracleFeeChange, uint256[4] memory tradeInfo) { // tradeInfo[0]: thetaFee, tradeInfo[1]: x, tradeInfo[2]: y, tradeInfo[3]: navps address _token0 = token0; address _token1 = token1; OraclePrice memory _op; // uint256 fee; { // scope for ethAmount/erc20Amount/blockNum to avoid stack too deep error uint256 _ethBalanceBefore = address(this).balance; bytes memory data = abi.encode(msg.sender, outToken, amountOutExact, to); // query price (_op.K, _op.ethAmount, _op.erc20Amount, _op.blockNum, _op.theta) = _queryOracle(_token1, CoFiX_OP.SWAP_FOR_EXACT, data); oracleFeeChange = msg.value.sub(_ethBalanceBefore.sub(address(this).balance)); } { // calc and check amountIn, also outToken uint256 balance0 = IERC20(_token0).balanceOf(address(this)); uint256 balance1 = IERC20(_token1).balanceOf(address(this)); (uint112 _reserve0, uint112 _reserve1) = getReserves(); // gas savings if (outToken == _token1) { amountIn = balance0.sub(_reserve0); tradeInfo[1] = _reserve0; // swap token0 for token1 out tradeInfo[2] = uint256(_reserve1).mul(_op.ethAmount).div(_op.erc20Amount); // _reserve1 value as _reserve0 } else if (outToken == _token0) { amountIn = balance1.sub(_reserve1); tradeInfo[1] = uint256(_reserve1).mul(_op.ethAmount).div(_op.erc20Amount); // _reserve1 value as _reserve0 tradeInfo[2] = _reserve0; // swap token1 for token0 out } else { revert("CPair: wrong outToken"); } require(amountIn > 0, "CPair: wrong amountIn"); tradeInfo[3] = calcNAVPerShare(_reserve0, _reserve1, _op.ethAmount, _op.erc20Amount); } { // split with branch upbove to make code more clear uint _amountInNeeded; uint _amountInLeft; if (outToken == _token1) { (_amountInNeeded, tradeInfo[0]) = calcInNeededToken0(amountOutExact, _op); _amountInLeft = amountIn.sub(_amountInNeeded); if (_amountInLeft > 0) { _safeTransfer(_token0, to, _amountInLeft); // send back the amount0 token change } } else if (outToken == _token0) { (_amountInNeeded, tradeInfo[0]) = calcInNeededToken1(amountOutExact, _op); _amountInLeft = amountIn.sub(_amountInNeeded); if (_amountInLeft > 0) { _safeTransfer(_token1, to, _amountInLeft); // send back the amount1 token change } } require(_amountInNeeded <= amountIn, "CPair: insufficient amountIn"); require(_amountInNeeded > 0, "CPair: wrong amountIn needed"); } { require(to != _token0 && to != _token1, "CPair: INVALID_TO"); amountOut = amountOutExact; _safeTransfer(outToken, to, amountOut); // optimistically transfer tokens if (tradeInfo[0] > 0) { if (ICoFiXFactory(factory).getTradeMiningStatus(_token1)) { // only transfer fee to protocol feeReceiver when trade mining is enabled for this trading pair _safeSendFeeForCoFiHolder(_token0, tradeInfo[0]); } else { _safeSendFeeForLP(_token0, _token1, tradeInfo[0]); tradeInfo[0] = 0; // so router won't go into the trade mining logic (reduce one more call gas cost) } } uint256 balance0 = IERC20(_token0).balanceOf(address(this)); uint256 balance1 = IERC20(_token1).balanceOf(address(this)); _update(balance0, balance1); if (oracleFeeChange > 0) TransferHelper.safeTransferETH(msg.sender, oracleFeeChange); } emit Swap(msg.sender, amountIn, amountOut, outToken, to); } // force balances to match reserves function skim(address to) external override lock { address _token0 = token0; // gas savings address _token1 = token1; // gas savings _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0)); _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1)); } // force reserves to match balances function sync() external override lock { _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this))); } // calc Net Asset Value Per Share for mint // use it in this contract, for optimized gas usage function calcNAVPerShareForMint(uint256 balance0, uint256 balance1, OraclePrice memory _op) public view returns (uint256 navps) { uint _totalSupply = totalSupply; if (_totalSupply == 0) { navps = NAVPS_BASE; } else { /* N_{p} &= (A_{u}/P_{s}^{'} + A_{e})/S \\\\ &= (A_{u}/(P * (1 - K)) + A_{e})/S \\\\ &= (\frac{A_{u}}{\frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} - k)}{(k_{BASE})}} + A_{e})/S \\\\ &= (\frac{A_{u}*ethAmount*k_{BASE}}{erc20Amount*(k_{BASE} - k)}+ A_{e}) / S \\\\ &= (A_{u}*ethAmount*k_{BASE}+ A_{e}*erc20Amount*(k_{BASE} - k)) / S / (erc20Amount*(k_{BASE} - k)) \\\\ N_{p} &= NAVPS_{BASE}*(A_{u}*ethAmount*k_{BASE}+ A_{e}*erc20Amount*(k_{BASE} - k)) / S / (erc20Amount*(k_{BASE} - k)) \\\\ // navps = NAVPS_BASE * ( (balance1*_op.ethAmount*K_BASE) + (balance0*_op.erc20Amount*(K_BASE-_op.K)) ) / _totalSupply / _op.erc20Amount / (K_BASE-_op.K); */ uint256 kbaseSubK = K_BASE.sub(_op.K); uint256 balance1MulEthKbase = balance1.mul(_op.ethAmount).mul(K_BASE); uint256 balance0MulErcKbsk = balance0.mul(_op.erc20Amount).mul(kbaseSubK); navps = NAVPS_BASE.mul( (balance1MulEthKbase).add(balance0MulErcKbsk) ).div(_totalSupply).div(_op.erc20Amount).div(kbaseSubK); } } // calc Net Asset Value Per Share for burn // use it in this contract, for optimized gas usage function calcNAVPerShareForBurn(uint256 balance0, uint256 balance1, OraclePrice memory _op) public view returns (uint256 navps) { uint _totalSupply = totalSupply; if (_totalSupply == 0) { navps = NAVPS_BASE; } else { /* N_{p}^{'} &= (A_{u}/P_{b}^{'} + A_{e})/S \\\\ &= (A_{u}/(P * (1 + K)) + A_{e})/S \\\\ &= (\frac{A_{u}}{\frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} + k)}{(k_{BASE})}} + A_{e})/S \\\\ &= (\frac{A_{u}*ethAmount*k_{BASE}}{erc20Amount*(k_{BASE} + k)}+ A_{e}) / S \\\\ &= (A_{u}*ethAmount*k_{BASE}+ A_{e}*erc20Amount*(k_{BASE} + k)) / S / (erc20Amount*(k_{BASE} + k)) \\\\ N_{p}^{'} &= NAVPS_{BASE}*(A_{u}*ethAmount*k_{BASE}+ A_{e}*erc20Amount*(k_{BASE} + k)) / S / (erc20Amount*(k_{BASE} + k)) \\\\ // navps = NAVPS_BASE * ( (balance1*_op.ethAmount*K_BASE) + (balance0*_op.erc20Amount*(K_BASE+_op.K)) ) / _totalSupply / _op.erc20Amount / (K_BASE+_op.K); */ uint256 kbaseAddK = K_BASE.add(_op.K); uint256 balance1MulEthKbase = balance1.mul(_op.ethAmount).mul(K_BASE); uint256 balance0MulErcKbsk = balance0.mul(_op.erc20Amount).mul(kbaseAddK); navps = NAVPS_BASE.mul( (balance1MulEthKbase).add(balance0MulErcKbsk) ).div(_totalSupply).div(_op.erc20Amount).div(kbaseAddK); } } // calc Net Asset Value Per Share (no K) // use it in this contract, for optimized gas usage function calcNAVPerShare(uint256 balance0, uint256 balance1, uint256 ethAmount, uint256 erc20Amount) public view returns (uint256 navps) { uint _totalSupply = totalSupply; if (_totalSupply == 0) { navps = NAVPS_BASE; } else { /* N_{p}^{'} &= (A_{u}/P + A_{e})/S \\\\ &= (\frac{A_{u}}{\frac{erc20Amount}{ethAmount}} + A_{e})/S \\\\ &= (\frac{A_{u}*ethAmount}{erc20Amount}+ A_{e}) / S \\\\ &= (A_{u}*ethAmount+ A_{e}*erc20Amount) / S / (erc20Amount) \\\\ N_{p}^{'} &= NAVPS_{BASE}*(A_{u}*ethAmount+ A_{e}*erc20Amount) / S / (erc20Amount) \\\\ // navps = NAVPS_BASE * ( (balance1*_op.ethAmount) + (balance0*_op.erc20Amount) ) / _totalSupply / _op.erc20Amount; */ uint256 balance1MulEth = balance1.mul(ethAmount); uint256 balance0MulErc = balance0.mul(erc20Amount); navps = NAVPS_BASE.mul( (balance1MulEth).add(balance0MulErc) ).div(_totalSupply).div(erc20Amount); } } // use it in this contract, for optimized gas usage function calcLiquidity(uint256 amount0, uint256 amount1, uint256 navps, OraclePrice memory _op) public pure returns (uint256 liquidity) { /* s_{1} &= a / (N_{p} / NAVPS_{BASE}) \\\\ &= a * NAVPS_{BASE} / N_{p} \\\\ s_{2} &= b / P_{b}^{'} / (N_{p} / NAVPS_{BASE}) \\\\ &= b / (N_{p} / NAVPS_{BASE}) / P_{b}^{'} \\\\ &= b * NAVPS_{BASE} / N_{p} / P_{b}^{'} \\\\ &= b * NAVPS_{BASE} / N_{p} / (\frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} + k)}{(k_{BASE})}) \\\\ &= b * NAVPS_{BASE} * ethAmount * k_{BASE} / N_{p} / (erc20Amount * (k_{BASE} + k)) s &= s_1 + s_2 \\\\ &= a * NAVPS_{BASE} / N_{p} + b * NAVPS_{BASE} / N_{p} / P_{b}^{'} \\\\ &= a * NAVPS_{BASE} / N_{p} + b * NAVPS_{BASE} * ethAmount * k_{BASE} / N_{p} / (erc20Amount * (k_{BASE} + k)) \\\\ // liquidity = (amount0 * NAVPS_BASE / navps) + (amount1 * NAVPS_BASE * _op.ethAmount * K_BASE / navps / _op.erc20Amount / (K_BASE + _op.K)); */ uint256 amnt0MulNbaseDivN = amount0.mul(NAVPS_BASE).div(navps); uint256 amnt1MulNbaseEthKbase = amount1.mul(NAVPS_BASE).mul(_op.ethAmount).mul(K_BASE); liquidity = ( amnt0MulNbaseDivN ).add( amnt1MulNbaseEthKbase.div(navps).div(_op.erc20Amount).div(K_BASE.add(_op.K)) ); } // get Net Asset Value Per Share for mint // only for read, could cost more gas if use it directly in contract function getNAVPerShareForMint(OraclePrice memory _op) public view returns (uint256 navps) { return calcNAVPerShareForMint(reserve0, reserve1, _op); } // get Net Asset Value Per Share for burn // only for read, could cost more gas if use it directly in contract function getNAVPerShareForBurn(OraclePrice memory _op) external view returns (uint256 navps) { return calcNAVPerShareForBurn(reserve0, reserve1, _op); } // get Net Asset Value Per Share // only for read, could cost more gas if use it directly in contract function getNAVPerShare(uint256 ethAmount, uint256 erc20Amount) external override view returns (uint256 navps) { return calcNAVPerShare(reserve0, reserve1, ethAmount, erc20Amount); } // get estimated liquidity amount (it represents the amount of pool tokens will be minted if someone provide liquidity to the pool) // only for read, could cost more gas if use it directly in contract function getLiquidity(uint256 amount0, uint256 amount1, OraclePrice memory _op) external view returns (uint256 liquidity) { uint256 navps = getNAVPerShareForMint(_op); return calcLiquidity(amount0, amount1, navps, _op); } // calc amountOut for token0 (WETH) when send liquidity token to pool for burning function calcOutToken0ForBurn(uint256 liquidity, OraclePrice memory _op) public view returns (uint256 amountOut, uint256 fee) { /* e &= c * (N_{p}^{'} / NAVPS_{BASE}) * (THETA_{BASE} - \theta)/THETA_{BASE} \\\\ &= c * \frac{N_{p}^{'}}{NAVPS_{BASE}} * \frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= c * N_{p}^{'} * (THETA_{BASE} - \theta) / NAVPS_{BASE} / THETA_{BASE} \\\\ // amountOut = liquidity * navps * (THETA_BASE - _op.theta) / NAVPS_BASE / THETA_BASE; */ uint256 navps = calcNAVPerShareForBurn(reserve0, reserve1, _op); amountOut = liquidity.mul(navps).mul(THETA_BASE.sub(_op.theta)).div(NAVPS_BASE).div(THETA_BASE); if (_op.theta != 0) { // fee = liquidity * navps * (_op.theta) / NAVPS_BASE / THETA_BASE; fee = liquidity.mul(navps).mul(_op.theta).div(NAVPS_BASE).div(THETA_BASE); } return (amountOut, fee); } // calc amountOut for token1 (ERC20 token) when send liquidity token to pool for burning function calcOutToken1ForBurn(uint256 liquidity, OraclePrice memory _op) public view returns (uint256 amountOut, uint256 fee) { /* u &= c * (N_{p}^{'} / NAVPS_{BASE}) * P_{s}^{'} * (THETA_{BASE} - \theta)/THETA_{BASE} \\\\ &= c * \frac{N_{p}^{'}}{NAVPS_{BASE}} * \frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} - k)}{(k_{BASE})} * \frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= \frac{c * N_{p}^{'} * erc20Amount * (k_{BASE} - k) * (THETA_{BASE} - \theta)}{NAVPS_{BASE}*ethAmount*k_{BASE}*THETA_{BASE}} // amountOut = liquidity * navps * _op.erc20Amount * (K_BASE - _op.K) * (THETA_BASE - _op.theta) / NAVPS_BASE / _op.ethAmount / K_BASE / THETA_BASE; */ uint256 navps = calcNAVPerShareForBurn(reserve0, reserve1, _op); uint256 liqMulMany = liquidity.mul(navps).mul(_op.erc20Amount).mul(K_BASE.sub(_op.K)).mul(THETA_BASE.sub(_op.theta)); amountOut = liqMulMany.div(NAVPS_BASE).div(_op.ethAmount).div(K_BASE).div(THETA_BASE); if (_op.theta != 0) { // fee = liquidity * navps * (_op.theta) / NAVPS_BASE / THETA_BASE; fee = liquidity.mul(navps).mul(_op.theta).div(NAVPS_BASE).div(THETA_BASE); } return (amountOut, fee); } // get estimated amountOut for token0 (WETH) when swapWithExact function calcOutToken0(uint256 amountIn, OraclePrice memory _op) public pure returns (uint256 amountOut, uint256 fee) { /* x &= (a/P_{b}^{'})*\frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= a / (\frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} + k)}{(k_{BASE})}) * \frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= \frac{a*ethAmount*k_{BASE}}{erc20Amount*(k_{BASE} + k)} * \frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= \frac{a*ethAmount*k_{BASE}*(THETA_{BASE} - \theta)}{erc20Amount*(k_{BASE} + k)*THETA_{BASE}} \\\\ // amountOut = amountIn * _op.ethAmount * K_BASE * (THETA_BASE - _op.theta) / _op.erc20Amount / (K_BASE + _op.K) / THETA_BASE; */ amountOut = amountIn.mul(_op.ethAmount).mul(K_BASE).mul(THETA_BASE.sub(_op.theta)).div(_op.erc20Amount).div(K_BASE.add(_op.K)).div(THETA_BASE); if (_op.theta != 0) { // fee = amountIn * _op.ethAmount * K_BASE * (_op.theta) / _op.erc20Amount / (K_BASE + _op.K) / THETA_BASE; fee = amountIn.mul(_op.ethAmount).mul(K_BASE).mul(_op.theta).div(_op.erc20Amount).div(K_BASE.add(_op.K)).div(THETA_BASE); } return (amountOut, fee); } // get estimated amountOut for token1 (ERC20 token) when swapWithExact function calcOutToken1(uint256 amountIn, OraclePrice memory _op) public pure returns (uint256 amountOut, uint256 fee) { /* y &= b*P_{s}^{'}*\frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= b * \frac{erc20Amount}{ethAmount} * \frac{(k_{BASE} - k)}{(k_{BASE})} * \frac{THETA_{BASE} - \theta}{THETA_{BASE}} \\\\ &= \frac{b*erc20Amount*(k_{BASE} - k)*(THETA_{BASE} - \theta)}{ethAmount*k_{BASE}*THETA_{BASE}} \\\\ // amountOut = amountIn * _op.erc20Amount * (K_BASE - _op.K) * (THETA_BASE - _op.theta) / _op.ethAmount / K_BASE / THETA_BASE; */ amountOut = amountIn.mul(_op.erc20Amount).mul(K_BASE.sub(_op.K)).mul(THETA_BASE.sub(_op.theta)).div(_op.ethAmount).div(K_BASE).div(THETA_BASE); if (_op.theta != 0) { // fee = amountIn * _op.theta / THETA_BASE; fee = amountIn.mul(_op.theta).div(THETA_BASE); } return (amountOut, fee); } // get estimate amountInNeeded for token0 (WETH) when swapForExact function calcInNeededToken0(uint256 amountOut, OraclePrice memory _op) public pure returns (uint256 amountInNeeded, uint256 fee) { // inverse of calcOutToken1 // amountOut = amountIn.mul(_op.erc20Amount).mul(K_BASE.sub(_op.K)).mul(THETA_BASE.sub(_op.theta)).div(_op.ethAmount).div(K_BASE).div(THETA_BASE); amountInNeeded = amountOut.mul(_op.ethAmount).mul(K_BASE).mul(THETA_BASE).div(_op.erc20Amount).div(K_BASE.sub(_op.K)).div(THETA_BASE.sub(_op.theta)); if (_op.theta != 0) { // fee = amountIn * _op.theta / THETA_BASE; fee = amountInNeeded.mul(_op.theta).div(THETA_BASE); } return (amountInNeeded, fee); } // get estimate amountInNeeded for token1 (ERC20 token) when swapForExact function calcInNeededToken1(uint256 amountOut, OraclePrice memory _op) public pure returns (uint256 amountInNeeded, uint256 fee) { // inverse of calcOutToken0 // amountOut = amountIn.mul(_op.ethAmount).mul(K_BASE).mul(THETA_BASE.sub(_op.theta)).div(_op.erc20Amount).div(K_BASE.add(_op.K)).div(THETA_BASE); amountInNeeded = amountOut.mul(_op.erc20Amount).mul(K_BASE.add(_op.K)).mul(THETA_BASE).div(_op.ethAmount).div(K_BASE).div(THETA_BASE.sub(_op.theta)); if (_op.theta != 0) { // fee = amountIn * _op.ethAmount * K_BASE * (_op.theta) / _op.erc20Amount / (K_BASE + _op.K) / THETA_BASE; fee = amountInNeeded.mul(_op.ethAmount).mul(K_BASE).mul(_op.theta).div(_op.erc20Amount).div(K_BASE.add(_op.K)).div(THETA_BASE); } return (amountInNeeded, fee); } function _queryOracle(address token, CoFiX_OP op, bytes memory data) internal returns (uint256, uint256, uint256, uint256, uint256) { return ICoFiXController(ICoFiXFactory(factory).getController()).queryOracle{value: msg.value}(token, uint8(op), data); } // Safe WETH transfer function, just in case not having enough WETH. CoFi holder will earn these fees. function _safeSendFeeForCoFiHolder(address _token0, uint256 _fee) internal { address feeReceiver = ICoFiXFactory(factory).getFeeReceiver(); if (feeReceiver == address(0)) { return; // if feeReceiver not set, theta fee keeps in pair pool } _safeSendFee(_token0, feeReceiver, _fee); // transfer fee to protocol fee reward pool for CoFi holders } // Safe WETH transfer function, just in case not having enough WETH. LP will earn these fees. function _safeSendFeeForLP(address _token0, address _token1, uint256 _fee) internal { address feeVault = ICoFiXFactory(factory).getFeeVaultForLP(_token1); if (feeVault == address(0)) { return; // if fee vault not set, theta fee keeps in pair pool } _safeSendFee(_token0, feeVault, _fee); // transfer fee to protocol fee reward pool for LP } function _safeSendFee(address _token0, address _receiver, uint256 _fee) internal { uint256 wethBal = IERC20(_token0).balanceOf(address(this)); if (_fee > wethBal) { _fee = wethBal; } if (_fee > 0) _safeTransfer(_token0, _receiver, _fee); } } // UNI & CoFi Rocks
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"outToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"outToken","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint112","name":"reserve0","type":"uint112"},{"indexed":false,"internalType":"uint112","name":"reserve1","type":"uint112"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"K_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAVPS_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"THETA_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"outToken","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"oracleFeeChange","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcInNeededToken0","outputs":[{"internalType":"uint256","name":"amountInNeeded","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcInNeededToken1","outputs":[{"internalType":"uint256","name":"amountInNeeded","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"uint256","name":"navps","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance0","type":"uint256"},{"internalType":"uint256","name":"balance1","type":"uint256"},{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"}],"name":"calcNAVPerShare","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance0","type":"uint256"},{"internalType":"uint256","name":"balance1","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcNAVPerShareForBurn","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance0","type":"uint256"},{"internalType":"uint256","name":"balance1","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcNAVPerShareForMint","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcOutToken0","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcOutToken0ForBurn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcOutToken1","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"calcOutToken1ForBurn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"getLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"}],"name":"getNAVPerShare","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"getNAVPerShareForBurn","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"erc20Amount","type":"uint256"},{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"K","type":"uint256"},{"internalType":"uint256","name":"theta","type":"uint256"}],"internalType":"struct ICoFiXPair.OraclePrice","name":"_op","type":"tuple"}],"name":"getNAVPerShareForMint","outputs":[{"internalType":"uint256","name":"navps","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"_reserve0","type":"uint112"},{"internalType":"uint112","name":"_reserve1","type":"uint112"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"oracleFeeChange","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nameForDomain","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"outToken","type":"address"},{"internalType":"uint256","name":"amountOutExact","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"swapForExact","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"oracleFeeChange","type":"uint256"},{"internalType":"uint256[4]","name":"tradeInfo","type":"uint256[4]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"outToken","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"swapWithExact","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"oracleFeeChange","type":"uint256"},{"internalType":"uint256[4]","name":"tradeInfo","type":"uint256[4]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040526001600a553480156200001657600080fd5b50604080518082018252601081526f21b7a334ac102837b7b6102a37b5b2b760811b6020918201528151808301835260018152603160f81b9082015290514691620000cc917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f917f70f1d8d3a2b874a116643bbbdb7e2937ce56e0359f9c3070aac2ec77a8354ccc917fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6918691309101620000f5565b60408051601f198184030181529190528051602090910120600355503360601b60805262000121565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b60805160601c61410362000162600039806108db5280610d115280611a0052806120a652806125ae5280612c885280612fbd52806130a652506141036000f3fe6080604052600436106102e05760003560e01c806395d89b4111610184578063bc25cf77116100d6578063d505accf1161008a578063e5eac39011610064578063e5eac39014610776578063eb77289914610796578063fff6cae9146107b6576102e7565b8063d505accf14610716578063dd2e0a3114610736578063dd62ed3e14610756576102e7565b8063bf36aac2116100bb578063bf36aac2146106cc578063c45a0155146106ec578063d21220a714610701576102e7565b8063bc25cf771461068c578063be5b32f8146106ac576102e7565b8063a661dbda11610138578063b2874f8711610112578063b2874f8714610637578063b72bda4a14610657578063ba9a7a5614610677576102e7565b8063a661dbda14610602578063a9059cbb14610617578063aaf07e9214610465576102e7565b80639c673c52116101695780639c673c52146105ac5780639f44296a146105cc578063a12db6cc146105ef576102e7565b806395d89b411461057757806399f45e481461058c576102e7565b8063313ce5671161023d5780634f6ec2dd116101f15780636a627842116101cb5780636a6278421461052457806370a08231146105375780637ecebe0014610557576102e7565b80634f6ec2dd146104cf5780635ad6bd30146104e4578063663eda1f14610504576102e7565b80633644e515116102225780633644e5151461047a57806339818b661461048f57806349a23da0146104af576102e7565b8063313ce567146104435780633298613114610465576102e7565b80632016a0d21161029457806324334be81161027957806324334be8146103ed57806327fc84a31461040d57806330adf81f1461042e576102e7565b80632016a0d2146103ab57806323b872dd146103cd576102e7565b8063095ea7b3116102c5578063095ea7b31461033a5780630dfe16811461036757806318160ddd14610389576102e7565b806306fdde03146102ec5780630902f1ac14610317576102e7565b366102e757005b600080fd5b3480156102f857600080fd5b506103016107cb565b60405161030e9190613bed565b60405180910390f35b34801561032357600080fd5b5061032c610877565b60405161030e929190613fbc565b34801561034657600080fd5b5061035a61035536600461384b565b6108a4565b60405161030e9190613b87565b34801561037357600080fd5b5061037c6108bb565b60405161030e9190613ab1565b34801561039557600080fd5b5061039e6108ca565b60405161030e9190613b92565b3480156103b757600080fd5b506103cb6103c6366004613710565b6108d0565b005b3480156103d957600080fd5b5061035a6103e8366004613796565b610997565b3480156103f957600080fd5b5061039e61040836600461392d565b610a49565b61042061041b3660046136d8565b610a87565b60405161030e929190613fdd565b34801561043a57600080fd5b5061039e610f2f565b34801561044f57600080fd5b50610458610f53565b60405161030e9190614054565b34801561047157600080fd5b5061039e610f58565b34801561048657600080fd5b5061039e610f60565b34801561049b57600080fd5b5061039e6104aa3660046138d7565b610f66565b3480156104bb57600080fd5b5061039e6104ca36600461394e565b610f98565b3480156104db57600080fd5b5061039e611061565b3480156104f057600080fd5b506104206104ff36600461390a565b61106d565b34801561051057600080fd5b5061039e61051f366004613983565b611112565b6104206105323660046136a0565b6111a0565b34801561054357600080fd5b5061039e6105523660046136a0565b6114a0565b34801561056357600080fd5b5061039e6105723660046136a0565b6114b2565b34801561058357600080fd5b506103016114c4565b34801561059857600080fd5b5061039e6105a73660046139c3565b61153d565b3480156105b857600080fd5b506104206105c736600461390a565b611593565b6105df6105da3660046136d8565b611627565b60405161030e949392919061400a565b6105df6105fd366004613876565b611c33565b34801561060e57600080fd5b506103016122d3565b34801561062357600080fd5b5061035a61063236600461384b565b61230c565b34801561064357600080fd5b5061039e61065236600461394e565b612319565b34801561066357600080fd5b5061039e61067236600461394e565b61233c565b34801561068357600080fd5b5061039e612372565b34801561069857600080fd5b506103cb6106a73660046136a0565b61237a565b3480156106b857600080fd5b5061039e6106c73660046138d7565b6124bc565b3480156106d857600080fd5b506104206106e736600461390a565b6124f2565b3480156106f857600080fd5b5061037c6125ac565b34801561070d57600080fd5b5061037c6125d0565b34801561072257600080fd5b506103cb6107313660046137d6565b6125df565b34801561074257600080fd5b5061042061075136600461390a565b61274e565b34801561076257600080fd5b5061039e6107713660046136d8565b612857565b34801561078257600080fd5b5061042061079136600461390a565b612874565b3480156107a257600080fd5b506104206107b136600461390a565b61293b565b3480156107c257600080fd5b506103cb6129fb565b6005805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b820191906000526020600020905b81548152906001019060200180831161085257829003601f168201915b505050505081565b6009546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000009092041690565b60006108b1338484612b30565b5060015b92915050565b6007546001600160a01b031681565b60005481565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109215760405162461bcd60e51b815260040161091890613e83565b60405180910390fd5b600780546001600160a01b038087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556008805492861692909116919091179055815161097c906005906020850190613508565b508051610990906006906020840190613508565b5050505050565b6001600160a01b03831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610a34576001600160a01b0384166000908152600260209081526040808320338452909152902054610a0f9083612b98565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b610a3f848484612bda565b5060019392505050565b600954600090610a80906dffffffffffffffffffffffffffff808216916e010000000000000000000000000000900416858561153d565b9392505050565b600080600a54600114610aac5760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546040516370a0823160e01b81526001600160a01b0392831693919092169183906370a0823190610aed903090600401613ab1565b60206040518083038186803b158015610b0557600080fd5b505afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d91906138f2565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b6d9190613ab1565b60206040518083038186803b158015610b8557600080fd5b505afa158015610b99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbd91906138f2565b30600090815260016020908152604080832054905193945092479291606091610bee9133918f918f91899101613ac5565b6040516020818303038152906040529050610c07613586565b610c1388600284612c7e565b608086015260408501526020840152825260608201526001600160a01b038d8116908a161415610c5157610c47858261293b565b909b509250610c8d565b876001600160a01b03168d6001600160a01b03161415610c7557610c47858261274e565b60405162461bcd60e51b815260040161091890613dde565b50610ca49050610c9d8347612b98565b3490612b98565b975060008911610cc65760405162461bcd60e51b815260040161091890613e15565b610cd03084612db8565b610cdb8b8b8b612e4e565b8015610db5576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906380feb39890610d46908990600401613ab1565b60206040518083038186803b158015610d5e57600080fd5b505afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9691906138b7565b15610daa57610da58782612fb9565b610db5565b610db5878783613073565b6040516370a0823160e01b81526001600160a01b038816906370a0823190610de1903090600401613ab1565b60206040518083038186803b158015610df957600080fd5b505afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3191906138f2565b6040516370a0823160e01b81529095506001600160a01b038716906370a0823190610e60903090600401613ab1565b60206040518083038186803b158015610e7857600080fd5b505afa158015610e8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb091906138f2565b9350610ebc8585613152565b8715610ecc57610ecc3389613258565b896001600160a01b0316336001600160a01b03167f3dd1df88dc92e2788892542d81f999d720a44b4c127065d45c128f4f59fdc3738d8c604051610f11929190613b43565b60405180910390a3505050505050506001600a819055509250929050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6305f5e10081565b60035481565b6009546000906108b5906dffffffffffffffffffffffffffff808216916e010000000000000000000000000000900416845b6000805480610fb157670de0b6b3a76400009150611059565b6000610fce84606001516305f5e100612b9890919063ffffffff16565b90506000610ff76305f5e100610ff18760000151896132e590919063ffffffff16565b906132e5565b9050600061101683610ff188602001518b6132e590919063ffffffff16565b90506110538361104d886020015161104d8861104d61103e888a61331f90919063ffffffff16565b670de0b6b3a7640000906132e5565b90613344565b94505050505b509392505050565b670de0b6b3a764000081565b6000806110db61108e84608001516305f5e100612b9890919063ffffffff16565b61104d6110ac86606001516305f5e100612b9890919063ffffffff16565b61104d876020015161104d6305f5e100610ff16305f5e100610ff18d600001518f6132e590919063ffffffff16565b9150826080015160001461110b576111086305f5e10061104d8560800151856132e590919063ffffffff16565b90505b9250929050565b60008061112b8461104d88670de0b6b3a76400006132e5565b9050600061115a6305f5e100610ff18660000151610ff1670de0b6b3a76400008b6132e590919063ffffffff16565b905061119561118e61117d86606001516305f5e10061331f90919063ffffffff16565b602087015161104d9081868b613344565b839061331f565b979650505050505050565b600080600a546001146111c55760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546001600160a01b0391821692911690806111ea610877565b915091506000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161121c9190613ab1565b60206040518083038186803b15801561123457600080fd5b505afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c91906138f2565b90506000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161129c9190613ab1565b60206040518083038186803b1580156112b457600080fd5b505afa1580156112c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ec91906138f2565b9050600061130a836dffffffffffffffffffffffffffff8716612b98565b90506000611328836dffffffffffffffffffffffffffff8716612b98565b905060004790506060338d85856040516020016113489493929190613b1a565b6040516020818303038152906040529050611361613586565b61136d8a600184612c7e565b6080860152604085015260208401528252606082015260006113a36dffffffffffffffffffffffffffff808c16908b1684610f98565b9050600054600014156113e0576113ca633b9aca006113c488888587611112565b90612b98565b9d506113db6000633b9aca00613386565b6113ef565b6113ec86868385611112565b9d505b506114019150610c9d90508247612b98565b995060008b116114235760405162461bcd60e51b815260040161091890613e4c565b61142d8c8c613386565b6114378585613152565b891561144757611447338b613258565b336001600160a01b03167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8484604051611482929190613fdd565b60405180910390a25050505050505050506001600a81905550915091565b60016020526000908152604090205481565b60046020526000908152604090205481565b6006805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b600080548061155657670de0b6b3a7640000915061158a565b600061156286866132e5565b9050600061157088866132e5565b90506115858561104d858161103e878761331f565b935050505b50949350505050565b6000806115fa6305f5e10061104d6305f5e10061104d876000015161104d6115cc8a608001516305f5e100612b9890919063ffffffff16565b610ff16115ea8c606001516305f5e100612b9890919063ffffffff16565b60208d0151610ff1908f906132e5565b9150826080015160001461110b576111086305f5e10061104d8560800151876132e590919063ffffffff16565b60008060006116346135b5565b600a546001146116565760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546040516370a0823160e01b81526001600160a01b0392831693919092169183906370a0823190611697903090600401613ab1565b60206040518083038186803b1580156116af57600080fd5b505afa1580156116c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e791906138f2565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016117179190613ab1565b60206040518083038186803b15801561172f57600080fd5b505afa158015611743573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176791906138f2565b905047600080611775610877565b91509150856001600160a01b03168d6001600160a01b031614156117b4576117ad856dffffffffffffffffffffffffffff8416612b98565b9a506117e8565b866001600160a01b03168d6001600160a01b03161415610c75576117ad846dffffffffffffffffffffffffffff8316612b98565b60008b116118085760405162461bcd60e51b815260040161091890613f85565b6060338e8e8e6040516020016118219493929190613ac5565b604051602081830303815290604052905061183a613586565b61184688600384612c7e565b608086015260408501526020840152825260608201526001600160a01b038f811690891614156118bc5761187a8d82611593565b8b526dffffffffffffffffffffffffffff8581166020808e01919091528301518351929e506118b292909161104d91908716906132e5565b60408b0152611927565b886001600160a01b03168f6001600160a01b03161415611927576118e08d82612874565b8b5260208201518251919d5061190b9161104d906dffffffffffffffffffffffffffff8716906132e5565b60208b01526dffffffffffffffffffffffffffff841660408b01525b611934610c9d8647612b98565b9a5061196a846dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff168360000151846020015161153d565b60608b015250505050506001600160a01b03848116908a16148015906119a25750826001600160a01b0316896001600160a01b031614155b6119be5760405162461bcd60e51b815260040161091890613cdc565b6119c98a8a89612e4e565b845115611ab9576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906380feb39890611a35908690600401613ab1565b60206040518083038186803b158015611a4d57600080fd5b505afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8591906138b7565b15611aa157611a9c848660005b6020020151612fb9565b611ab9565b611ab484848760005b6020020151613073565b600085525b6040516370a0823160e01b81526001600160a01b038516906370a0823190611ae5903090600401613ab1565b60206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3591906138f2565b6040516370a0823160e01b81529092506001600160a01b038416906370a0823190611b64903090600401613ab1565b60206040518083038186803b158015611b7c57600080fd5b505afa158015611b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb491906138f2565b9050611bc08282613152565b8515611bd057611bd03387613258565b886001600160a01b0316336001600160a01b03167f053d794b2310b8d186a24ae24a65ee066983a52a6efa6bd3df09a7601a3cb4f38a8a8e604051611c1793929190613feb565b60405180910390a350506001600a555093969295509093509150565b6000806000611c406135b5565b600a54600114611c625760405162461bcd60e51b815260040161091890613c00565b6000600a556007546008546001600160a01b039182169116611c82613586565b6040514790606090611c9e9033908e908e908e90602001613aef565b6040516020818303038152906040529050611cbb84600483612c7e565b60808801526040870152602086015284526060840152611cde610c9d8347612b98565b965050506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611d109190613ab1565b60206040518083038186803b158015611d2857600080fd5b505afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6091906138f2565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611d909190613ab1565b60206040518083038186803b158015611da857600080fd5b505afa158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de091906138f2565b9050600080611ded610877565b91509150856001600160a01b03168e6001600160a01b03161415611e6957611e25846dffffffffffffffffffffffffffff8416612b98565b6dffffffffffffffffffffffffffff8381166020808c01919091528701518751929d50611e5b92909161104d91908516906132e5565b8860025b6020020152611ee4565b866001600160a01b03168e6001600160a01b03161415610c7557611e9d836dffffffffffffffffffffffffffff8316612b98565b60208601518651919c50611ec69161104d906dffffffffffffffffffffffffffff8516906132e5565b60208901526dffffffffffffffffffffffffffff8216886002611e5f565b60008b11611f045760405162461bcd60e51b815260040161091890613f85565b611f38826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff168760000151886020015161153d565b60608901525060009250829150506001600160a01b03848116908d161415611f8a57611f648b8461106d565b87529150611f728983612b98565b90508015611f8557611f85858b83612e4e565b611fcf565b846001600160a01b03168c6001600160a01b03161415611fcf57611fae8b846124f2565b87529150611fbc8983612b98565b90508015611fcf57611fcf848b83612e4e565b88821115611fef5760405162461bcd60e51b815260040161091890613ca5565b6000821161200f5760405162461bcd60e51b815260040161091890613d70565b5050826001600160a01b0316886001600160a01b0316141580156120455750816001600160a01b0316886001600160a01b031614155b6120615760405162461bcd60e51b815260040161091890613cdc565b88955061206f8a8988612e4e565b835115612153576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906380feb398906120db908590600401613ab1565b60206040518083038186803b1580156120f357600080fd5b505afa158015612107573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212b91906138b7565b156121415761213c83856000611a92565b612153565b61214e8383866000611aaa565b600084525b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190612182903090600401613ab1565b60206040518083038186803b15801561219a57600080fd5b505afa1580156121ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d291906138f2565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016122029190613ab1565b60206040518083038186803b15801561221a57600080fd5b505afa15801561222e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225291906138f2565b905061225e8282613152565b861561226e5761226e3388613258565b5050876001600160a01b0316336001600160a01b03167f053d794b2310b8d186a24ae24a65ee066983a52a6efa6bd3df09a7601a3cb4f389898e6040516122b793929190613feb565b60405180910390a35050506001600a8190555093509350935093565b6040518060400160405280601081526020017f436f46695820506f6f6c20546f6b656e0000000000000000000000000000000081525081565b60006108b1338484612bda565b60008061232583610f66565b905061233385858386611112565b95945050505050565b600080548061235557670de0b6b3a76400009150611059565b6000610fce84606001516305f5e10061331f90919063ffffffff16565b633b9aca0081565b600a5460011461239c5760405162461bcd60e51b815260040161091890613c00565b6000600a556007546008546009546040516370a0823160e01b81526001600160a01b039384169390921691612451918491869161244c916dffffffffffffffffffffffffffff9091169084906370a08231906123fc903090600401613ab1565b60206040518083038186803b15801561241457600080fd5b505afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c491906138f2565b612e4e565b6124b2818461244c6009600e9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16856001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016123fc9190613ab1565b50506001600a5550565b6009546000906108b5906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168461233c565b60008061254961251384608001516305f5e100612b9890919063ffffffff16565b61104d6305f5e10061104d876000015161104d6305f5e100610ff16115ea8c606001516305f5e10061331f90919063ffffffff16565b9150826080015160001461110b576111086305f5e10061104d61257d86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d8960800151610ff16305f5e100610ff18d600001518d6132e590919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000081565b6008546001600160a01b031681565b428410156125ff5760405162461bcd60e51b815260040161091890613da7565b6003546001600160a01b03881660009081526004602090815260408083208054600181019091559051929392612660927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928d928d928d92918d9101613b9b565b60405160208183030381529060405280519060200120604051602001612687929190613a7b565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516126c49493929190613bcf565b6020604051602081039080840390855afa1580156126e6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061271c5750886001600160a01b0316816001600160a01b0316145b6127385760405162461bcd60e51b815260040161091890613c37565b612743898989612b30565b505050505050505050565b60095460009081908190612788906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168661233c565b905060006127d96127aa86608001516305f5e100612b9890919063ffffffff16565b610ff16127c888606001516305f5e100612b9890919063ffffffff16565b6020890151610ff190818c896132e5565b905061280e6305f5e10061104d6305f5e10061104d896000015161104d670de0b6b3a76400008861334490919063ffffffff16565b9350846080015160001461284e5761284b6305f5e10061104d670de0b6b3a764000061104d8960800151610ff1888d6132e590919063ffffffff16565b92505b50509250929050565b600260209081526000928352604080842090915290825290205481565b6000806128d86305f5e10061104d61289d86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d6128c38a608001516305f5e100612b9890919063ffffffff16565b8a51610ff1906305f5e1009082908f906132e5565b9150826080015160001461110b576111086305f5e10061104d61290c86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d8960800151610ff16305f5e100610ff18d600001518f6132e590919063ffffffff16565b60095460009081908190612975906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168661233c565b90506129b36305f5e10061104d670de0b6b3a764000061104d6129a989608001516305f5e100612b9890919063ffffffff16565b610ff18b886132e5565b925083608001516000146129f3576129f06305f5e10061104d670de0b6b3a764000061104d8860800151610ff1878c6132e590919063ffffffff16565b91505b509250929050565b600a54600114612a1d5760405162461bcd60e51b815260040161091890613c00565b6000600a556007546040516370a0823160e01b8152612b29916001600160a01b0316906370a0823190612a54903090600401613ab1565b60206040518083038186803b158015612a6c57600080fd5b505afa158015612a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa491906138f2565b6008546040516370a0823160e01b81526001600160a01b03909116906370a0823190612ad4903090600401613ab1565b60206040518083038186803b158015612aec57600080fd5b505afa158015612b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2491906138f2565b613152565b6001600a55565b6001600160a01b0380841660008181526002602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612b8b908590613b92565b60405180910390a3505050565b6000610a8083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613407565b6001600160a01b038316600090815260016020526040902054612bfd9082612b98565b6001600160a01b038085166000908152600160205260408082209390935590841681522054612c2c908261331f565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612b8b908590613b92565b60008060008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612cdf57600080fd5b505afa158015612cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1791906136bc565b6001600160a01b0316638dba9329348a8a6004811115612d3357fe5b8a6040518563ffffffff1660e01b8152600401612d5293929190613b5c565b60a0604051808303818588803b158015612d6b57600080fd5b505af1158015612d7f573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612da491906139f4565b939c929b5090995097509095509350505050565b6001600160a01b038216600090815260016020526040902054612ddb9082612b98565b6001600160a01b03831660009081526001602052604081209190915554612e029082612b98565b60009081556040516001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e42908590613b92565b60405180910390a35050565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602090910152516000906060906001600160a01b038616907fa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b90612ec69087908790602401613b43565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051612f319190613a5f565b6000604051808303816000865af19150503d8060008114612f6e576040519150601f19603f3d011682016040523d82523d6000602084013e612f73565b606091505b5091509150818015612f9d575080511580612f9d575080806020019051810190612f9d91906138b7565b6109905760405162461bcd60e51b815260040161091890613f17565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8a353926040518163ffffffff1660e01b815260040160206040518083038186803b15801561301457600080fd5b505afa158015613028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304c91906136bc565b90506001600160a01b038116613062575061306f565b61306d838284613433565b505b5050565b6040517f72b8cbcc0000000000000000000000000000000000000000000000000000000081526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906372b8cbcc906130db908690600401613ab1565b60206040518083038186803b1580156130f357600080fd5b505afa158015613107573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312b91906136bc565b90506001600160a01b038116613141575061306d565b61314c848284613433565b50505050565b6dffffffffffffffffffffffffffff821180159061317e57506dffffffffffffffffffffffffffff8111155b61319a5760405162461bcd60e51b815260040161091890613f4e565b600980547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff848116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e010000000000000000000000000000848316810291909117928390556040517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad19361324c93818116939091041690613fbc565b60405180910390a15050565b604080516000808252602082019092526001600160a01b0384169083906040516132829190613a5f565b60006040518083038185875af1925050503d80600081146132bf576040519150601f19603f3d011682016040523d82523d6000602084013e6132c4565b606091505b505090508061306d5760405162461bcd60e51b815260040161091890613eba565b6000826132f4575060006108b5565b8282028284828161330157fe5b0414610a805760405162461bcd60e51b815260040161091890613d13565b600082820183811015610a805760405162461bcd60e51b815260040161091890613c6e565b6000610a8083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506134d1565b600054613393908261331f565b60009081556001600160a01b0383168152600160205260409020546133b8908261331f565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e42908590613b92565b6000818484111561342b5760405162461bcd60e51b81526004016109189190613bed565b505050900390565b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190613462903090600401613ab1565b60206040518083038186803b15801561347a57600080fd5b505afa15801561348e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b291906138f2565b9050808211156134c0578091505b811561314c5761314c848484612e4e565b600081836134f25760405162461bcd60e51b81526004016109189190613bed565b5060008385816134fe57fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061354957805160ff1916838001178555613576565b82800160010185558215613576579182015b8281111561357657825182559160200191906001019061355b565b506135829291506135d3565b5090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b5b8082111561358257600081556001016135d4565b600082601f8301126135f8578081fd5b813567ffffffffffffffff81111561360e578182fd5b6136216020601f19601f84011601614062565b915080825283602082850101111561363857600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215613662578081fd5b61366c60a0614062565b9050813581526020820135602082015260408201356040820152606082013560608201526080820135608082015292915050565b6000602082840312156136b1578081fd5b8135610a80816140b5565b6000602082840312156136cd578081fd5b8151610a80816140b5565b600080604083850312156136ea578081fd5b82356136f5816140b5565b91506020830135613705816140b5565b809150509250929050565b60008060008060808587031215613725578182fd5b8435613730816140b5565b93506020850135613740816140b5565b9250604085013567ffffffffffffffff8082111561375c578384fd5b613768888389016135e8565b9350606087013591508082111561377d578283fd5b5061378a878288016135e8565b91505092959194509250565b6000806000606084860312156137aa578283fd5b83356137b5816140b5565b925060208401356137c5816140b5565b929592945050506040919091013590565b600080600080600080600060e0888a0312156137f0578283fd5b87356137fb816140b5565b9650602088013561380b816140b5565b95506040880135945060608801359350608088013560ff8116811461382e578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561385d578182fd5b8235613868816140b5565b946020939093013593505050565b60008060006060848603121561388a578283fd5b8335613895816140b5565b92506020840135915060408401356138ac816140b5565b809150509250925092565b6000602082840312156138c8578081fd5b81518015158114610a80578182fd5b600060a082840312156138e8578081fd5b610a808383613651565b600060208284031215613903578081fd5b5051919050565b60008060c0838503121561391c578182fd5b823591506111088460208501613651565b6000806040838503121561393f578182fd5b50508035926020909101359150565b600080600060e08486031215613962578081fd5b833592506020840135915061397a8560408601613651565b90509250925092565b6000806000806101008587031215613999578182fd5b8435935060208501359250604085013591506139b88660608701613651565b905092959194509250565b600080600080608085870312156139d8578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a08688031215613a0b578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b60008151808452613a4b816020860160208601614089565b601f01601f19169290920160200192915050565b60008251613a71818460208701614089565b9190910192915050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03929092168252602082015260400190565b60006001600160a01b038516825260ff84166020830152606060408301526123336060830184613a33565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610a806020830184613a33565b6020808252600d908201527f43506169723a204c4f434b454400000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4345524332303a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601c908201527f43506169723a20696e73756666696369656e7420616d6f756e74496e00000000604082015260600190565b60208082526011908201527f43506169723a20494e56414c49445f544f000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f43506169723a2077726f6e6720616d6f756e74496e206e656564656400000000604082015260600190565b6020808252600f908201527f4345524332303a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526015908201527f43506169723a2077726f6e67206f7574546f6b656e0000000000000000000000604082015260600190565b6020808252601d908201527f43506169723a2053484f52545f4c49515549444954595f4255524e4544000000604082015260600190565b6020808252601d908201527f43506169723a2053484f52545f4c49515549444954595f4d494e544544000000604082015260600190565b60208082526010908201527f43506169723a20464f5242494444454e00000000000000000000000000000000604082015260600190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f43506169723a205452414e534645525f4641494c454400000000000000000000604082015260600190565b6020808252600f908201527f43506169723a204f564552464c4f570000000000000000000000000000000000604082015260600190565b60208082526015908201527f43506169723a2077726f6e6720616d6f756e74496e0000000000000000000000604082015260600190565b6dffffffffffffffffffffffffffff92831681529116602082015260400190565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260600190565b600060e08201905085825260208581840152846040840152606083018460005b60048110156140475781518352918301919083019060010161402a565b5050505095945050505050565b60ff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561408157600080fd5b604052919050565b60005b838110156140a457818101518382015260200161408c565b8381111561314c5750506000910152565b6001600160a01b03811681146140ca57600080fd5b5056fea26469706673582212204d9c04fecc367b0b983af1eb4467f748ca149b973eebf1723301659a88c0b77264736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106102e05760003560e01c806395d89b4111610184578063bc25cf77116100d6578063d505accf1161008a578063e5eac39011610064578063e5eac39014610776578063eb77289914610796578063fff6cae9146107b6576102e7565b8063d505accf14610716578063dd2e0a3114610736578063dd62ed3e14610756576102e7565b8063bf36aac2116100bb578063bf36aac2146106cc578063c45a0155146106ec578063d21220a714610701576102e7565b8063bc25cf771461068c578063be5b32f8146106ac576102e7565b8063a661dbda11610138578063b2874f8711610112578063b2874f8714610637578063b72bda4a14610657578063ba9a7a5614610677576102e7565b8063a661dbda14610602578063a9059cbb14610617578063aaf07e9214610465576102e7565b80639c673c52116101695780639c673c52146105ac5780639f44296a146105cc578063a12db6cc146105ef576102e7565b806395d89b411461057757806399f45e481461058c576102e7565b8063313ce5671161023d5780634f6ec2dd116101f15780636a627842116101cb5780636a6278421461052457806370a08231146105375780637ecebe0014610557576102e7565b80634f6ec2dd146104cf5780635ad6bd30146104e4578063663eda1f14610504576102e7565b80633644e515116102225780633644e5151461047a57806339818b661461048f57806349a23da0146104af576102e7565b8063313ce567146104435780633298613114610465576102e7565b80632016a0d21161029457806324334be81161027957806324334be8146103ed57806327fc84a31461040d57806330adf81f1461042e576102e7565b80632016a0d2146103ab57806323b872dd146103cd576102e7565b8063095ea7b3116102c5578063095ea7b31461033a5780630dfe16811461036757806318160ddd14610389576102e7565b806306fdde03146102ec5780630902f1ac14610317576102e7565b366102e757005b600080fd5b3480156102f857600080fd5b506103016107cb565b60405161030e9190613bed565b60405180910390f35b34801561032357600080fd5b5061032c610877565b60405161030e929190613fbc565b34801561034657600080fd5b5061035a61035536600461384b565b6108a4565b60405161030e9190613b87565b34801561037357600080fd5b5061037c6108bb565b60405161030e9190613ab1565b34801561039557600080fd5b5061039e6108ca565b60405161030e9190613b92565b3480156103b757600080fd5b506103cb6103c6366004613710565b6108d0565b005b3480156103d957600080fd5b5061035a6103e8366004613796565b610997565b3480156103f957600080fd5b5061039e61040836600461392d565b610a49565b61042061041b3660046136d8565b610a87565b60405161030e929190613fdd565b34801561043a57600080fd5b5061039e610f2f565b34801561044f57600080fd5b50610458610f53565b60405161030e9190614054565b34801561047157600080fd5b5061039e610f58565b34801561048657600080fd5b5061039e610f60565b34801561049b57600080fd5b5061039e6104aa3660046138d7565b610f66565b3480156104bb57600080fd5b5061039e6104ca36600461394e565b610f98565b3480156104db57600080fd5b5061039e611061565b3480156104f057600080fd5b506104206104ff36600461390a565b61106d565b34801561051057600080fd5b5061039e61051f366004613983565b611112565b6104206105323660046136a0565b6111a0565b34801561054357600080fd5b5061039e6105523660046136a0565b6114a0565b34801561056357600080fd5b5061039e6105723660046136a0565b6114b2565b34801561058357600080fd5b506103016114c4565b34801561059857600080fd5b5061039e6105a73660046139c3565b61153d565b3480156105b857600080fd5b506104206105c736600461390a565b611593565b6105df6105da3660046136d8565b611627565b60405161030e949392919061400a565b6105df6105fd366004613876565b611c33565b34801561060e57600080fd5b506103016122d3565b34801561062357600080fd5b5061035a61063236600461384b565b61230c565b34801561064357600080fd5b5061039e61065236600461394e565b612319565b34801561066357600080fd5b5061039e61067236600461394e565b61233c565b34801561068357600080fd5b5061039e612372565b34801561069857600080fd5b506103cb6106a73660046136a0565b61237a565b3480156106b857600080fd5b5061039e6106c73660046138d7565b6124bc565b3480156106d857600080fd5b506104206106e736600461390a565b6124f2565b3480156106f857600080fd5b5061037c6125ac565b34801561070d57600080fd5b5061037c6125d0565b34801561072257600080fd5b506103cb6107313660046137d6565b6125df565b34801561074257600080fd5b5061042061075136600461390a565b61274e565b34801561076257600080fd5b5061039e6107713660046136d8565b612857565b34801561078257600080fd5b5061042061079136600461390a565b612874565b3480156107a257600080fd5b506104206107b136600461390a565b61293b565b3480156107c257600080fd5b506103cb6129fb565b6005805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b820191906000526020600020905b81548152906001019060200180831161085257829003601f168201915b505050505081565b6009546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000009092041690565b60006108b1338484612b30565b5060015b92915050565b6007546001600160a01b031681565b60005481565b336001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55016146109215760405162461bcd60e51b815260040161091890613e83565b60405180910390fd5b600780546001600160a01b038087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556008805492861692909116919091179055815161097c906005906020850190613508565b508051610990906006906020840190613508565b5050505050565b6001600160a01b03831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610a34576001600160a01b0384166000908152600260209081526040808320338452909152902054610a0f9083612b98565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b610a3f848484612bda565b5060019392505050565b600954600090610a80906dffffffffffffffffffffffffffff808216916e010000000000000000000000000000900416858561153d565b9392505050565b600080600a54600114610aac5760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546040516370a0823160e01b81526001600160a01b0392831693919092169183906370a0823190610aed903090600401613ab1565b60206040518083038186803b158015610b0557600080fd5b505afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d91906138f2565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b6d9190613ab1565b60206040518083038186803b158015610b8557600080fd5b505afa158015610b99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbd91906138f2565b30600090815260016020908152604080832054905193945092479291606091610bee9133918f918f91899101613ac5565b6040516020818303038152906040529050610c07613586565b610c1388600284612c7e565b608086015260408501526020840152825260608201526001600160a01b038d8116908a161415610c5157610c47858261293b565b909b509250610c8d565b876001600160a01b03168d6001600160a01b03161415610c7557610c47858261274e565b60405162461bcd60e51b815260040161091890613dde565b50610ca49050610c9d8347612b98565b3490612b98565b975060008911610cc65760405162461bcd60e51b815260040161091890613e15565b610cd03084612db8565b610cdb8b8b8b612e4e565b8015610db5576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55016906380feb39890610d46908990600401613ab1565b60206040518083038186803b158015610d5e57600080fd5b505afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9691906138b7565b15610daa57610da58782612fb9565b610db5565b610db5878783613073565b6040516370a0823160e01b81526001600160a01b038816906370a0823190610de1903090600401613ab1565b60206040518083038186803b158015610df957600080fd5b505afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3191906138f2565b6040516370a0823160e01b81529095506001600160a01b038716906370a0823190610e60903090600401613ab1565b60206040518083038186803b158015610e7857600080fd5b505afa158015610e8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb091906138f2565b9350610ebc8585613152565b8715610ecc57610ecc3389613258565b896001600160a01b0316336001600160a01b03167f3dd1df88dc92e2788892542d81f999d720a44b4c127065d45c128f4f59fdc3738d8c604051610f11929190613b43565b60405180910390a3505050505050506001600a819055509250929050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6305f5e10081565b60035481565b6009546000906108b5906dffffffffffffffffffffffffffff808216916e010000000000000000000000000000900416845b6000805480610fb157670de0b6b3a76400009150611059565b6000610fce84606001516305f5e100612b9890919063ffffffff16565b90506000610ff76305f5e100610ff18760000151896132e590919063ffffffff16565b906132e5565b9050600061101683610ff188602001518b6132e590919063ffffffff16565b90506110538361104d886020015161104d8861104d61103e888a61331f90919063ffffffff16565b670de0b6b3a7640000906132e5565b90613344565b94505050505b509392505050565b670de0b6b3a764000081565b6000806110db61108e84608001516305f5e100612b9890919063ffffffff16565b61104d6110ac86606001516305f5e100612b9890919063ffffffff16565b61104d876020015161104d6305f5e100610ff16305f5e100610ff18d600001518f6132e590919063ffffffff16565b9150826080015160001461110b576111086305f5e10061104d8560800151856132e590919063ffffffff16565b90505b9250929050565b60008061112b8461104d88670de0b6b3a76400006132e5565b9050600061115a6305f5e100610ff18660000151610ff1670de0b6b3a76400008b6132e590919063ffffffff16565b905061119561118e61117d86606001516305f5e10061331f90919063ffffffff16565b602087015161104d9081868b613344565b839061331f565b979650505050505050565b600080600a546001146111c55760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546001600160a01b0391821692911690806111ea610877565b915091506000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161121c9190613ab1565b60206040518083038186803b15801561123457600080fd5b505afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c91906138f2565b90506000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161129c9190613ab1565b60206040518083038186803b1580156112b457600080fd5b505afa1580156112c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ec91906138f2565b9050600061130a836dffffffffffffffffffffffffffff8716612b98565b90506000611328836dffffffffffffffffffffffffffff8716612b98565b905060004790506060338d85856040516020016113489493929190613b1a565b6040516020818303038152906040529050611361613586565b61136d8a600184612c7e565b6080860152604085015260208401528252606082015260006113a36dffffffffffffffffffffffffffff808c16908b1684610f98565b9050600054600014156113e0576113ca633b9aca006113c488888587611112565b90612b98565b9d506113db6000633b9aca00613386565b6113ef565b6113ec86868385611112565b9d505b506114019150610c9d90508247612b98565b995060008b116114235760405162461bcd60e51b815260040161091890613e4c565b61142d8c8c613386565b6114378585613152565b891561144757611447338b613258565b336001600160a01b03167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8484604051611482929190613fdd565b60405180910390a25050505050505050506001600a81905550915091565b60016020526000908152604090205481565b60046020526000908152604090205481565b6006805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b600080548061155657670de0b6b3a7640000915061158a565b600061156286866132e5565b9050600061157088866132e5565b90506115858561104d858161103e878761331f565b935050505b50949350505050565b6000806115fa6305f5e10061104d6305f5e10061104d876000015161104d6115cc8a608001516305f5e100612b9890919063ffffffff16565b610ff16115ea8c606001516305f5e100612b9890919063ffffffff16565b60208d0151610ff1908f906132e5565b9150826080015160001461110b576111086305f5e10061104d8560800151876132e590919063ffffffff16565b60008060006116346135b5565b600a546001146116565760405162461bcd60e51b815260040161091890613c00565b6000600a8190556007546008546040516370a0823160e01b81526001600160a01b0392831693919092169183906370a0823190611697903090600401613ab1565b60206040518083038186803b1580156116af57600080fd5b505afa1580156116c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e791906138f2565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016117179190613ab1565b60206040518083038186803b15801561172f57600080fd5b505afa158015611743573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176791906138f2565b905047600080611775610877565b91509150856001600160a01b03168d6001600160a01b031614156117b4576117ad856dffffffffffffffffffffffffffff8416612b98565b9a506117e8565b866001600160a01b03168d6001600160a01b03161415610c75576117ad846dffffffffffffffffffffffffffff8316612b98565b60008b116118085760405162461bcd60e51b815260040161091890613f85565b6060338e8e8e6040516020016118219493929190613ac5565b604051602081830303815290604052905061183a613586565b61184688600384612c7e565b608086015260408501526020840152825260608201526001600160a01b038f811690891614156118bc5761187a8d82611593565b8b526dffffffffffffffffffffffffffff8581166020808e01919091528301518351929e506118b292909161104d91908716906132e5565b60408b0152611927565b886001600160a01b03168f6001600160a01b03161415611927576118e08d82612874565b8b5260208201518251919d5061190b9161104d906dffffffffffffffffffffffffffff8716906132e5565b60208b01526dffffffffffffffffffffffffffff841660408b01525b611934610c9d8647612b98565b9a5061196a846dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff168360000151846020015161153d565b60608b015250505050506001600160a01b03848116908a16148015906119a25750826001600160a01b0316896001600160a01b031614155b6119be5760405162461bcd60e51b815260040161091890613cdc565b6119c98a8a89612e4e565b845115611ab9576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55016906380feb39890611a35908690600401613ab1565b60206040518083038186803b158015611a4d57600080fd5b505afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8591906138b7565b15611aa157611a9c848660005b6020020151612fb9565b611ab9565b611ab484848760005b6020020151613073565b600085525b6040516370a0823160e01b81526001600160a01b038516906370a0823190611ae5903090600401613ab1565b60206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3591906138f2565b6040516370a0823160e01b81529092506001600160a01b038416906370a0823190611b64903090600401613ab1565b60206040518083038186803b158015611b7c57600080fd5b505afa158015611b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb491906138f2565b9050611bc08282613152565b8515611bd057611bd03387613258565b886001600160a01b0316336001600160a01b03167f053d794b2310b8d186a24ae24a65ee066983a52a6efa6bd3df09a7601a3cb4f38a8a8e604051611c1793929190613feb565b60405180910390a350506001600a555093969295509093509150565b6000806000611c406135b5565b600a54600114611c625760405162461bcd60e51b815260040161091890613c00565b6000600a556007546008546001600160a01b039182169116611c82613586565b6040514790606090611c9e9033908e908e908e90602001613aef565b6040516020818303038152906040529050611cbb84600483612c7e565b60808801526040870152602086015284526060840152611cde610c9d8347612b98565b965050506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611d109190613ab1565b60206040518083038186803b158015611d2857600080fd5b505afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6091906138f2565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611d909190613ab1565b60206040518083038186803b158015611da857600080fd5b505afa158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de091906138f2565b9050600080611ded610877565b91509150856001600160a01b03168e6001600160a01b03161415611e6957611e25846dffffffffffffffffffffffffffff8416612b98565b6dffffffffffffffffffffffffffff8381166020808c01919091528701518751929d50611e5b92909161104d91908516906132e5565b8860025b6020020152611ee4565b866001600160a01b03168e6001600160a01b03161415610c7557611e9d836dffffffffffffffffffffffffffff8316612b98565b60208601518651919c50611ec69161104d906dffffffffffffffffffffffffffff8516906132e5565b60208901526dffffffffffffffffffffffffffff8216886002611e5f565b60008b11611f045760405162461bcd60e51b815260040161091890613f85565b611f38826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff168760000151886020015161153d565b60608901525060009250829150506001600160a01b03848116908d161415611f8a57611f648b8461106d565b87529150611f728983612b98565b90508015611f8557611f85858b83612e4e565b611fcf565b846001600160a01b03168c6001600160a01b03161415611fcf57611fae8b846124f2565b87529150611fbc8983612b98565b90508015611fcf57611fcf848b83612e4e565b88821115611fef5760405162461bcd60e51b815260040161091890613ca5565b6000821161200f5760405162461bcd60e51b815260040161091890613d70565b5050826001600160a01b0316886001600160a01b0316141580156120455750816001600160a01b0316886001600160a01b031614155b6120615760405162461bcd60e51b815260040161091890613cdc565b88955061206f8a8988612e4e565b835115612153576040517f80feb3980000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55016906380feb398906120db908590600401613ab1565b60206040518083038186803b1580156120f357600080fd5b505afa158015612107573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212b91906138b7565b156121415761213c83856000611a92565b612153565b61214e8383866000611aaa565b600084525b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190612182903090600401613ab1565b60206040518083038186803b15801561219a57600080fd5b505afa1580156121ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d291906138f2565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016122029190613ab1565b60206040518083038186803b15801561221a57600080fd5b505afa15801561222e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225291906138f2565b905061225e8282613152565b861561226e5761226e3388613258565b5050876001600160a01b0316336001600160a01b03167f053d794b2310b8d186a24ae24a65ee066983a52a6efa6bd3df09a7601a3cb4f389898e6040516122b793929190613feb565b60405180910390a35050506001600a8190555093509350935093565b6040518060400160405280601081526020017f436f46695820506f6f6c20546f6b656e0000000000000000000000000000000081525081565b60006108b1338484612bda565b60008061232583610f66565b905061233385858386611112565b95945050505050565b600080548061235557670de0b6b3a76400009150611059565b6000610fce84606001516305f5e10061331f90919063ffffffff16565b633b9aca0081565b600a5460011461239c5760405162461bcd60e51b815260040161091890613c00565b6000600a556007546008546009546040516370a0823160e01b81526001600160a01b039384169390921691612451918491869161244c916dffffffffffffffffffffffffffff9091169084906370a08231906123fc903090600401613ab1565b60206040518083038186803b15801561241457600080fd5b505afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c491906138f2565b612e4e565b6124b2818461244c6009600e9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16856001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016123fc9190613ab1565b50506001600a5550565b6009546000906108b5906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168461233c565b60008061254961251384608001516305f5e100612b9890919063ffffffff16565b61104d6305f5e10061104d876000015161104d6305f5e100610ff16115ea8c606001516305f5e10061331f90919063ffffffff16565b9150826080015160001461110b576111086305f5e10061104d61257d86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d8960800151610ff16305f5e100610ff18d600001518d6132e590919063ffffffff16565b7f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55081565b6008546001600160a01b031681565b428410156125ff5760405162461bcd60e51b815260040161091890613da7565b6003546001600160a01b03881660009081526004602090815260408083208054600181019091559051929392612660927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928d928d928d92918d9101613b9b565b60405160208183030381529060405280519060200120604051602001612687929190613a7b565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516126c49493929190613bcf565b6020604051602081039080840390855afa1580156126e6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061271c5750886001600160a01b0316816001600160a01b0316145b6127385760405162461bcd60e51b815260040161091890613c37565b612743898989612b30565b505050505050505050565b60095460009081908190612788906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168661233c565b905060006127d96127aa86608001516305f5e100612b9890919063ffffffff16565b610ff16127c888606001516305f5e100612b9890919063ffffffff16565b6020890151610ff190818c896132e5565b905061280e6305f5e10061104d6305f5e10061104d896000015161104d670de0b6b3a76400008861334490919063ffffffff16565b9350846080015160001461284e5761284b6305f5e10061104d670de0b6b3a764000061104d8960800151610ff1888d6132e590919063ffffffff16565b92505b50509250929050565b600260209081526000928352604080842090915290825290205481565b6000806128d86305f5e10061104d61289d86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d6128c38a608001516305f5e100612b9890919063ffffffff16565b8a51610ff1906305f5e1009082908f906132e5565b9150826080015160001461110b576111086305f5e10061104d61290c86606001516305f5e10061331f90919063ffffffff16565b61104d876020015161104d8960800151610ff16305f5e100610ff18d600001518f6132e590919063ffffffff16565b60095460009081908190612975906dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004168661233c565b90506129b36305f5e10061104d670de0b6b3a764000061104d6129a989608001516305f5e100612b9890919063ffffffff16565b610ff18b886132e5565b925083608001516000146129f3576129f06305f5e10061104d670de0b6b3a764000061104d8860800151610ff1878c6132e590919063ffffffff16565b91505b509250929050565b600a54600114612a1d5760405162461bcd60e51b815260040161091890613c00565b6000600a556007546040516370a0823160e01b8152612b29916001600160a01b0316906370a0823190612a54903090600401613ab1565b60206040518083038186803b158015612a6c57600080fd5b505afa158015612a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa491906138f2565b6008546040516370a0823160e01b81526001600160a01b03909116906370a0823190612ad4903090600401613ab1565b60206040518083038186803b158015612aec57600080fd5b505afa158015612b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2491906138f2565b613152565b6001600a55565b6001600160a01b0380841660008181526002602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612b8b908590613b92565b60405180910390a3505050565b6000610a8083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613407565b6001600160a01b038316600090815260016020526040902054612bfd9082612b98565b6001600160a01b038085166000908152600160205260408082209390935590841681522054612c2c908261331f565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612b8b908590613b92565b60008060008060007f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed5506001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612cdf57600080fd5b505afa158015612cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1791906136bc565b6001600160a01b0316638dba9329348a8a6004811115612d3357fe5b8a6040518563ffffffff1660e01b8152600401612d5293929190613b5c565b60a0604051808303818588803b158015612d6b57600080fd5b505af1158015612d7f573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612da491906139f4565b939c929b5090995097509095509350505050565b6001600160a01b038216600090815260016020526040902054612ddb9082612b98565b6001600160a01b03831660009081526001602052604081209190915554612e029082612b98565b60009081556040516001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e42908590613b92565b60405180910390a35050565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602090910152516000906060906001600160a01b038616907fa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b90612ec69087908790602401613b43565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051612f319190613a5f565b6000604051808303816000865af19150503d8060008114612f6e576040519150601f19603f3d011682016040523d82523d6000602084013e612f73565b606091505b5091509150818015612f9d575080511580612f9d575080806020019051810190612f9d91906138b7565b6109905760405162461bcd60e51b815260040161091890613f17565b60007f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed5506001600160a01b031663e8a353926040518163ffffffff1660e01b815260040160206040518083038186803b15801561301457600080fd5b505afa158015613028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304c91906136bc565b90506001600160a01b038116613062575061306f565b61306d838284613433565b505b5050565b6040517f72b8cbcc0000000000000000000000000000000000000000000000000000000081526000906001600160a01b037f00000000000000000000000066c64ecc3a6014733325a8f2ebee46b4ca3ed55016906372b8cbcc906130db908690600401613ab1565b60206040518083038186803b1580156130f357600080fd5b505afa158015613107573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312b91906136bc565b90506001600160a01b038116613141575061306d565b61314c848284613433565b50505050565b6dffffffffffffffffffffffffffff821180159061317e57506dffffffffffffffffffffffffffff8111155b61319a5760405162461bcd60e51b815260040161091890613f4e565b600980547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff848116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e010000000000000000000000000000848316810291909117928390556040517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad19361324c93818116939091041690613fbc565b60405180910390a15050565b604080516000808252602082019092526001600160a01b0384169083906040516132829190613a5f565b60006040518083038185875af1925050503d80600081146132bf576040519150601f19603f3d011682016040523d82523d6000602084013e6132c4565b606091505b505090508061306d5760405162461bcd60e51b815260040161091890613eba565b6000826132f4575060006108b5565b8282028284828161330157fe5b0414610a805760405162461bcd60e51b815260040161091890613d13565b600082820183811015610a805760405162461bcd60e51b815260040161091890613c6e565b6000610a8083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506134d1565b600054613393908261331f565b60009081556001600160a01b0383168152600160205260409020546133b8908261331f565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e42908590613b92565b6000818484111561342b5760405162461bcd60e51b81526004016109189190613bed565b505050900390565b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190613462903090600401613ab1565b60206040518083038186803b15801561347a57600080fd5b505afa15801561348e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b291906138f2565b9050808211156134c0578091505b811561314c5761314c848484612e4e565b600081836134f25760405162461bcd60e51b81526004016109189190613bed565b5060008385816134fe57fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061354957805160ff1916838001178555613576565b82800160010185558215613576579182015b8281111561357657825182559160200191906001019061355b565b506135829291506135d3565b5090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b5b8082111561358257600081556001016135d4565b600082601f8301126135f8578081fd5b813567ffffffffffffffff81111561360e578182fd5b6136216020601f19601f84011601614062565b915080825283602082850101111561363857600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215613662578081fd5b61366c60a0614062565b9050813581526020820135602082015260408201356040820152606082013560608201526080820135608082015292915050565b6000602082840312156136b1578081fd5b8135610a80816140b5565b6000602082840312156136cd578081fd5b8151610a80816140b5565b600080604083850312156136ea578081fd5b82356136f5816140b5565b91506020830135613705816140b5565b809150509250929050565b60008060008060808587031215613725578182fd5b8435613730816140b5565b93506020850135613740816140b5565b9250604085013567ffffffffffffffff8082111561375c578384fd5b613768888389016135e8565b9350606087013591508082111561377d578283fd5b5061378a878288016135e8565b91505092959194509250565b6000806000606084860312156137aa578283fd5b83356137b5816140b5565b925060208401356137c5816140b5565b929592945050506040919091013590565b600080600080600080600060e0888a0312156137f0578283fd5b87356137fb816140b5565b9650602088013561380b816140b5565b95506040880135945060608801359350608088013560ff8116811461382e578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561385d578182fd5b8235613868816140b5565b946020939093013593505050565b60008060006060848603121561388a578283fd5b8335613895816140b5565b92506020840135915060408401356138ac816140b5565b809150509250925092565b6000602082840312156138c8578081fd5b81518015158114610a80578182fd5b600060a082840312156138e8578081fd5b610a808383613651565b600060208284031215613903578081fd5b5051919050565b60008060c0838503121561391c578182fd5b823591506111088460208501613651565b6000806040838503121561393f578182fd5b50508035926020909101359150565b600080600060e08486031215613962578081fd5b833592506020840135915061397a8560408601613651565b90509250925092565b6000806000806101008587031215613999578182fd5b8435935060208501359250604085013591506139b88660608701613651565b905092959194509250565b600080600080608085870312156139d8578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a08688031215613a0b578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b60008151808452613a4b816020860160208601614089565b601f01601f19169290920160200192915050565b60008251613a71818460208701614089565b9190910192915050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03929092168252602082015260400190565b60006001600160a01b038516825260ff84166020830152606060408301526123336060830184613a33565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610a806020830184613a33565b6020808252600d908201527f43506169723a204c4f434b454400000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4345524332303a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601c908201527f43506169723a20696e73756666696369656e7420616d6f756e74496e00000000604082015260600190565b60208082526011908201527f43506169723a20494e56414c49445f544f000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f43506169723a2077726f6e6720616d6f756e74496e206e656564656400000000604082015260600190565b6020808252600f908201527f4345524332303a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526015908201527f43506169723a2077726f6e67206f7574546f6b656e0000000000000000000000604082015260600190565b6020808252601d908201527f43506169723a2053484f52545f4c49515549444954595f4255524e4544000000604082015260600190565b6020808252601d908201527f43506169723a2053484f52545f4c49515549444954595f4d494e544544000000604082015260600190565b60208082526010908201527f43506169723a20464f5242494444454e00000000000000000000000000000000604082015260600190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f43506169723a205452414e534645525f4641494c454400000000000000000000604082015260600190565b6020808252600f908201527f43506169723a204f564552464c4f570000000000000000000000000000000000604082015260600190565b60208082526015908201527f43506169723a2077726f6e6720616d6f756e74496e0000000000000000000000604082015260600190565b6dffffffffffffffffffffffffffff92831681529116602082015260400190565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260600190565b600060e08201905085825260208581840152846040840152606083018460005b60048110156140475781518352918301919083019060010161402a565b5050505095945050505050565b60ff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561408157600080fd5b604052919050565b60005b838110156140a457818101518382015260200161408c565b8381111561314c5750506000910152565b6001600160a01b03811681146140ca57600080fd5b5056fea26469706673582212204d9c04fecc367b0b983af1eb4467f748ca149b973eebf1723301659a88c0b77264736f6c634300060c0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.