ERC-20
Overview
Max Total Supply
1,080.24667640828329404 XT-1
Holders
229
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.000000006823160321 XT-1Value
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
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.