- Contract name:
- KaiDexFactory
- Optimization enabled
- true
- Compiler version
- v0.8.4+commit.c7e474f2
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-07-12T10:32:17.293534Z
Constructor Arguments
0000000000000000000000000f5c21435895bb2f7044d0700281c05cbd500dc9
Arg [0] (address) : 0x0f5c21435895bb2f7044d0700281c05cbd500dc9
Contract source code
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; interface IKaiDexFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint256); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; } // File contracts/exchange/interfaces/IKAIDexKRC20.sol pragma solidity ^0.8.0; interface IKAIDexKRC20 { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 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 (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 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 (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; } // File contracts/exchange/libraries/SafeMath.sol pragma solidity ^0.8.0; // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) library SafeMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x, "ds-math-add-overflow"); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x, "ds-math-sub-underflow"); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow"); } } // File contracts/exchange/KAIDexKRC20.sol pragma solidity ^0.8.0; contract KAIDexKRC20 is IKAIDexKRC20 { using SafeMath for uint256; string public constant override name = "KAIDEX LPs"; string public constant override symbol = "KDXLP"; uint8 public constant override decimals = 18; uint256 public override totalSupply; mapping(address => uint256) public override balanceOf; mapping(address => mapping(address => uint256)) public override allowance; bytes32 public override DOMAIN_SEPARATOR; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant override PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint256) public override nonces; constructor() public { uint256 id; assembly { id := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes("1")), id, address(this) ) ); } function _mint(address to, uint256 value) internal { totalSupply = totalSupply.add(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint256 value) internal { balanceOf[from] = balanceOf[from].sub(value); totalSupply = totalSupply.sub(value); emit Transfer(from, address(0), value); } function _approve( address owner, address spender, uint256 value ) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer( address from, address to, uint256 value ) private { balanceOf[from] = balanceOf[from].sub(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(from, to, value); } function approve(address spender, uint256 value) override external returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint256 value) override external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom( address from, address to, uint256 value ) override external returns (bool) { if (allowance[from][msg.sender] != type(uint256).max) { allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); } _transfer(from, to, value); return true; } function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) override external { require(deadline >= block.timestamp, "KAIDEX: 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, "KAIDEX: INVALID_SIGNATURE"); _approve(owner, spender, value); } } // File contracts/exchange/libraries/Math.sol pragma solidity ^0.8.0; // a library for performing various math operations library Math { function min(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } } // File contracts/exchange/libraries/UQ112x112.sol pragma solidity ^0.8.0; // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) // range: [0, 2**112 - 1] // resolution: 1 / 2**112 library UQ112x112 { uint224 constant Q112 = 2**112; // encode a uint112 as a UQ112x112 function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; // never overflows } // divide a UQ112x112 by a uint112, returning a UQ112x112 function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } } // File contracts/exchange/interfaces/IKRC20.sol pragma solidity ^0.8.0; interface IKRC20 { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); } // File contracts/exchange/interfaces/IKAIDexCallee.sol pragma solidity ^0.8.0; interface IKAIDexCallee { function KAIDexCall(address sender, uint amount0, uint amount1, bytes calldata data) external; } // File contracts/exchange/KaiDexPair.sol pragma solidity ^0.8.0; contract KaiDexPair is KAIDexKRC20 { using SafeMath for uint; using UQ112x112 for uint224; uint public constant MINIMUM_LIQUIDITY = 10**3; bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); address public factory; address public token0; address public token1; uint112 private reserve0; // uses single storage slot, accessible via getReserves uint112 private reserve1; // uses single storage slot, accessible via getReserves uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves uint public price0CumulativeLast; uint public price1CumulativeLast; uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event uint private unlocked = 1; modifier lock() { require(unlocked == 1, 'KAIDEX: LOCKED'); unlocked = 0; _; unlocked = 1; } function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } 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))), 'KAIDEX: TRANSFER_FAILED'); } event Sync(uint112 reserve0, uint112 reserve1); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); constructor() public { factory = msg.sender; } // called once by the factory at time of deployment function initialize(address _token0, address _token1) external { require(msg.sender == factory, 'KAIDEX: FORBIDDEN'); // sufficient check token0 = _token0; token1 = _token1; } // update reserves and, on the first call per block, price accumulators function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { require(balance0 <= type(uint112).max && balance1 <= type(uint112).max, 'KAIDEX: OVERFLOW'); uint32 blockTimestamp = uint32(block.timestamp % 2**32); uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { // * never overflows, and + overflow is desired price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; } reserve0 = uint112(balance0); reserve1 = uint112(balance1); blockTimestampLast = blockTimestamp; emit Sync(reserve0, reserve1); } // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k) function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) { address feeTo = IKaiDexFactory(factory).feeTo(); feeOn = feeTo != address(0); uint _kLast = kLast; // gas savings if (feeOn) { if (_kLast != 0) { uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); uint rootKLast = Math.sqrt(_kLast); if (rootK > rootKLast) { uint numerator = totalSupply.mul(rootK.sub(rootKLast)); uint denominator = rootK.mul(5).add(rootKLast); uint liquidity = numerator / denominator; if (liquidity > 0) _mint(feeTo, liquidity); } } } else if (_kLast != 0) { kLast = 0; } } // this low-level function should be called from a contract which performs important safety checks function mint(address to) external lock returns (uint liquidity) { (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings uint balance0 = IKRC20(token0).balanceOf(address(this)); uint balance1 = IKRC20(token1).balanceOf(address(this)); uint amount0 = balance0.sub(_reserve0); uint amount1 = balance1.sub(_reserve1); bool feeOn = _mintFee(_reserve0, _reserve1); uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee if (_totalSupply == 0) { liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens } else { liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); } require(liquidity > 0, 'KAIDEX: INSUFFICIENT_LIQUIDITY_MINTED'); _mint(to, liquidity); _update(balance0, balance1, _reserve0, _reserve1); if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date emit Mint(msg.sender, amount0, amount1); } // this low-level function should be called from a contract which performs important safety checks function burn(address to) external lock returns (uint amount0, uint amount1) { (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings address _token0 = token0; // gas savings address _token1 = token1; // gas savings uint balance0 = IKRC20(_token0).balanceOf(address(this)); uint balance1 = IKRC20(_token1).balanceOf(address(this)); uint liquidity = balanceOf[address(this)]; bool feeOn = _mintFee(_reserve0, _reserve1); uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution require(amount0 > 0 && amount1 > 0, 'KAIDEX: INSUFFICIENT_LIQUIDITY_BURNED'); _burn(address(this), liquidity); _safeTransfer(_token0, to, amount0); _safeTransfer(_token1, to, amount1); balance0 = IKRC20(_token0).balanceOf(address(this)); balance1 = IKRC20(_token1).balanceOf(address(this)); _update(balance0, balance1, _reserve0, _reserve1); if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date emit Burn(msg.sender, amount0, amount1, to); } // this low-level function should be called from a contract which performs important safety checks function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { require(amount0Out > 0 || amount1Out > 0, 'KAIDEX: INSUFFICIENT_OUTPUT_AMOUNT'); (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings require(amount0Out < _reserve0 && amount1Out < _reserve1, 'KAIDEX: INSUFFICIENT_LIQUIDITY'); uint balance0; uint balance1; { // scope for _token{0,1}, avoids stack too deep errors address _token0 = token0; address _token1 = token1; require(to != _token0 && to != _token1, 'KAIDEX: INVALID_TO'); if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens if (data.length > 0) IKAIDexCallee(to).KAIDexCall(msg.sender, amount0Out, amount1Out, data); balance0 = IKRC20(_token0).balanceOf(address(this)); balance1 = IKRC20(_token1).balanceOf(address(this)); } uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; require(amount0In > 0 || amount1In > 0, 'KAIDexCall: INSUFFICIENT_INPUT_AMOUNT'); { // scope for reserve{0,1}Adjusted, avoids stack too deep errors uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'KAIDexCall: K'); } _update(balance0, balance1, _reserve0, _reserve1); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); } // force balances to match reserves function skim(address to) external lock { address _token0 = token0; // gas savings address _token1 = token1; // gas savings _safeTransfer(_token0, to, IKRC20(_token0).balanceOf(address(this)).sub(reserve0)); _safeTransfer(_token1, to, IKRC20(_token1).balanceOf(address(this)).sub(reserve1)); } // force reserves to match balances function sync() external lock { _update(IKRC20(token0).balanceOf(address(this)), IKRC20(token1).balanceOf(address(this)), reserve0, reserve1); } } // File contracts/exchange/Factory.sol pragma solidity ^0.8.0; contract KaiDexFactory is IKaiDexFactory { bytes32 public constant INIT_CODE_PAIR_HASH = keccak256(abi.encodePacked(type(KaiDexPair).creationCode)); address public override feeTo; address public override feeToSetter; mapping(address => mapping(address => address)) public override getPair; address[] public override allPairs; constructor(address _feeToSetter) public { feeToSetter = _feeToSetter; } function allPairsLength() override external view returns (uint) { return allPairs.length; } function createPair(address tokenA, address tokenB) override external returns (address pair) { require(tokenA != tokenB, 'KAIDEX: IDENTICAL_ADDRESSES'); (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), 'KAIDEX: ZERO_ADDRESS'); require(getPair[token0][token1] == address(0), 'KAIDEX: PAIR_EXISTS'); // single check is sufficient bytes memory bytecode = type(KaiDexPair).creationCode; bytes32 salt = keccak256(abi.encodePacked(token0, token1)); assembly { pair := create2(0, add(bytecode, 32), mload(bytecode), salt) } KaiDexPair(pair).initialize(token0, token1); getPair[token0][token1] = pair; getPair[token1][token0] = pair; // populate mapping in the reverse direction allPairs.push(pair); emit PairCreated(token0, token1, pair, allPairs.length); } function setFeeTo(address _feeTo) override external { require(msg.sender == feeToSetter, 'KAIDEX: FORBIDDEN'); feeTo = _feeTo; } function setFeeToSetter(address _feeToSetter) override external { require(msg.sender == feeToSetter, 'KAIDEX: FORBIDDEN'); feeToSetter = _feeToSetter; } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_feeToSetter","internalType":"address"}]},{"type":"event","name":"PairCreated","inputs":[{"type":"address","name":"token0","internalType":"address","indexed":true},{"type":"address","name":"token1","internalType":"address","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":false},{"type":"uint256","name":"","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"INIT_CODE_PAIR_HASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"allPairs","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allPairsLength","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"pair","internalType":"address"}],"name":"createPair","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"feeTo","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"feeToSetter","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getPair","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeTo","inputs":[{"type":"address","name":"_feeTo","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeToSetter","inputs":[{"type":"address","name":"_feeToSetter","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50604051612b23380380612b2383398101604081905261002f91610054565b600180546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b612a92806100916000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80635855a25a116100665780635855a25a14610100578063a2e74af614610108578063c9c653961461011d578063e6a4390514610130578063f46901ed1461016457600080fd5b8063017e7e5814610098578063094b7415146100c85780631e3dd18b146100db578063574f2ba3146100ee575b600080fd5b6000546100ab906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6001546100ab906001600160a01b031681565b6100ab6100e936600461063f565b610177565b6003545b6040519081526020016100bf565b6100f26101a1565b61011b6101163660046105ec565b6101eb565b005b6100ab61012b36600461060d565b610260565b6100ab61013e36600461060d565b60026020908152600092835260408084209091529082529020546001600160a01b031681565b61011b6101723660046105ec565b610553565b6003818154811061018757600080fd5b6000918252602090912001546001600160a01b0316905081565b6040516101b0602082016105c3565b601f1982820381018352601f9091011660408190526101d29190602001610657565b6040516020818303038152906040528051906020012081565b6001546001600160a01b0316331461023e5760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b60448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000816001600160a01b0316836001600160a01b031614156102c45760405162461bcd60e51b815260206004820152601b60248201527f4b41494445583a204944454e544943414c5f41444452455353455300000000006044820152606401610235565b600080836001600160a01b0316856001600160a01b0316106102e75783856102ea565b84845b90925090506001600160a01b03821661033c5760405162461bcd60e51b81526020600482015260146024820152734b41494445583a205a45524f5f4144445245535360601b6044820152606401610235565b6001600160a01b038281166000908152600260209081526040808320858516845290915290205416156103a75760405162461bcd60e51b81526020600482015260136024820152724b41494445583a20504149525f45584953545360681b6044820152606401610235565b6000604051806020016103b9906105c3565b601f1982820381018352601f9091011660408190526bffffffffffffffffffffffff19606086811b8216602084015285901b166034820152909150600090604801604051602081830303815290604052805190602001209050808251602084016000f560405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529196509086169063485cc95590604401600060405180830381600087803b15801561046b57600080fd5b505af115801561047f573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526002602081815260408084208987168086529083528185208054978d166001600160a01b031998891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9095018054909716841790965592548351928352908201527f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9910160405180910390a35050505092915050565b6001546001600160a01b031633146105a15760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b6044820152606401610235565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6123cc8061069183390190565b80356001600160a01b03811681146105e757600080fd5b919050565b6000602082840312156105fd578081fd5b610606826105d0565b9392505050565b6000806040838503121561061f578081fd5b610628836105d0565b9150610636602084016105d0565b90509250929050565b600060208284031215610650578081fd5b5035919050565b60008251815b81811015610677576020818601810151858301520161065d565b818111156106855782828501525b50919091019291505056fe60806040526001600c5534801561001557600080fd5b50604080518082018252600a8152694b4149444558204c507360b01b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f513da3f0e0fd390af3688dee67345fb74c26bc0c21a4e1c7dbf0223516ff33f4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c09091019092528151910120600355600580546001600160a01b031916331790556122c4806101086000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a714610407578063d505accf1461041a578063dd62ed3e1461042d578063fff6cae91461045857600080fd5b8063ba9a7a56146103d8578063bc25cf77146103e1578063c45a0155146103f457600080fd5b80637ecebe00116100d35780637ecebe001461035957806389afcb441461037957806395d89b41146103a1578063a9059cbb146103c557600080fd5b80636a6278421461031d57806370a08231146103305780637464fc3d1461035057600080fd5b806323b872dd116101665780633644e515116101405780633644e515146102ef578063485cc955146102f85780635909c0d51461030b5780635a3d54931461031457600080fd5b806323b872dd1461029b57806330adf81f146102ae578063313ce567146102d557600080fd5b8063022c0d9f146101ae57806306fdde03146101c35780630902f1ac14610202578063095ea7b3146102365780630dfe16811461025957806318160ddd14610284575b600080fd5b6101c16101bc366004611fbb565b610460565b005b6101ec6040518060400160405280600a8152602001694b4149444558204c507360b01b81525081565b6040516101f991906120b4565b60405180910390f35b61020a610977565b604080516001600160701b03948516815293909216602084015263ffffffff16908201526060016101f9565b610249610244366004611f58565b6109a1565b60405190151581526020016101f9565b60065461026c906001600160a01b031681565b6040516001600160a01b0390911681526020016101f9565b61028d60005481565b6040519081526020016101f9565b6102496102a9366004611ea3565b6109b8565b61028d7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102dd601281565b60405160ff90911681526020016101f9565b61028d60035481565b6101c1610306366004611e6b565b610a4c565b61028d60095481565b61028d600a5481565b61028d61032b366004611e33565b610ac8565b61028d61033e366004611e33565b60016020526000908152604090205481565b61028d600b5481565b61028d610367366004611e33565b60046020526000908152604090205481565b61038c610387366004611e33565b610da8565b604080519283526020830191909152016101f9565b6101ec6040518060400160405280600581526020016404b44584c560dc1b81525081565b6102496103d3366004611f58565b611147565b61028d6103e881565b6101c16103ef366004611e33565b611154565b60055461026c906001600160a01b031681565b60075461026c906001600160a01b031681565b6101c1610428366004611ee3565b611277565b61028d61043b366004611e6b565b600260209081526000928352604080842090915290825290205481565b6101c1611488565b600c5460011461048b5760405162461bcd60e51b8152600401610482906120e7565b60405180910390fd5b6000600c558415158061049e5750600084115b6104f55760405162461bcd60e51b815260206004820152602260248201527f4b41494445583a20494e53554646494349454e545f4f55545055545f414d4f55604482015261139560f21b6064820152608401610482565b600080610500610977565b5091509150816001600160701b0316871080156105255750806001600160701b031686105b6105715760405162461bcd60e51b815260206004820152601e60248201527f4b41494445583a20494e53554646494349454e545f4c495155494449545900006044820152606401610482565b60065460075460009182916001600160a01b039182169190811690891682148015906105af5750806001600160a01b0316896001600160a01b031614155b6105f05760405162461bcd60e51b81526020600482015260126024820152714b41494445583a20494e56414c49445f544f60701b6044820152606401610482565b8a1561060157610601828a8d6115ca565b891561061257610612818a8c6115ca565b861561067f576040516303468d3b60e51b81526001600160a01b038a16906368d1a7609061064c9033908f908f908e908e90600401612068565b600060405180830381600087803b15801561066657600080fd5b505af115801561067a573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b1580156106be57600080fd5b505afa1580156106d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f69190611fa3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b15801561073857600080fd5b505afa15801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190611fa3565b92505050600089856001600160701b031661078b91906121af565b83116107985760006107b5565b6107ab8a6001600160701b0387166121af565b6107b590846121af565b905060006107cc8a6001600160701b0387166121af565b83116107d95760006107f6565b6107ec8a6001600160701b0387166121af565b6107f690846121af565b905060008211806108075750600081115b6108615760405162461bcd60e51b815260206004820152602560248201527f4b414944657843616c6c3a20494e53554646494349454e545f494e5055545f416044820152641353d5539560da1b6064820152608401610482565b6000610883610871846003611715565b61087d876103e8611715565b9061177c565b90506000610895610871846003611715565b90506108ba620f42406108b46001600160701b038b8116908b16611715565b90611715565b6108c48383611715565b10156109025760405162461bcd60e51b815260206004820152600d60248201526c4b414944657843616c6c3a204b60981b6044820152606401610482565b5050610910848488886117d2565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001600c55505050505050505050565b6008546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b60006109ae3384846119bb565b5060015b92915050565b6001600160a01b038316600090815260026020908152604080832033845290915281205460001914610a37576001600160a01b0384166000908152600260209081526040808320338452909152902054610a12908361177c565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b610a42848484611a1d565b5060019392505050565b6005546001600160a01b03163314610a9a5760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b6044820152606401610482565b600680546001600160a01b039384166001600160a01b03199182161790915560078054929093169116179055565b6000600c54600114610aec5760405162461bcd60e51b8152600401610482906120e7565b6000600c81905580610afc610977565b506006546040516370a0823160e01b81523060048201529294509092506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015610b4957600080fd5b505afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b819190611fa3565b6007546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c029190611fa3565b90506000610c19836001600160701b03871661177c565b90506000610c30836001600160701b03871661177c565b90506000610c3e8787611ac3565b60005490915080610c7557610c616103e861087d610c5c8787611715565b611c0f565b9850610c7060006103e8611c7f565b610cbc565b610cb96001600160701b038916610c8c8684611715565b610c96919061214d565b6001600160701b038916610caa8685611715565b610cb4919061214d565b611d0e565b98505b60008911610d1a5760405162461bcd60e51b815260206004820152602560248201527f4b41494445583a20494e53554646494349454e545f4c49515549444954595f4d604482015264125395115160da1b6064820152608401610482565b610d248a8a611c7f565b610d3086868a8a6117d2565b8115610d5a57600854610d56906001600160701b0380821691600160701b900416611715565b600b555b604080518581526020810185905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001600c5550949695505050505050565b600080600c54600114610dcd5760405162461bcd60e51b8152600401610482906120e7565b6000600c81905580610ddd610977565b506006546007546040516370a0823160e01b81523060048201529395509193506001600160a01b039081169291169060009083906370a082319060240160206040518083038186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6a9190611fa3565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015610eaf57600080fd5b505afa158015610ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee79190611fa3565b30600090815260016020526040812054919250610f048888611ac3565b60005490915080610f158487611715565b610f1f919061214d565b9a5080610f2c8486611715565b610f36919061214d565b995060008b118015610f48575060008a115b610fa25760405162461bcd60e51b815260206004820152602560248201527f4b41494445583a20494e53554646494349454e545f4c49515549444954595f42604482015264155493915160da1b6064820152608401610482565b610fac3084611d26565b610fb7878d8d6115ca565b610fc2868d8c6115ca565b6040516370a0823160e01b81523060048201526001600160a01b038816906370a082319060240160206040518083038186803b15801561100157600080fd5b505afa158015611015573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110399190611fa3565b6040516370a0823160e01b81523060048201529095506001600160a01b038716906370a082319060240160206040518083038186803b15801561107b57600080fd5b505afa15801561108f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b39190611fa3565b93506110c185858b8b6117d2565b81156110eb576008546110e7906001600160701b0380821691600160701b900416611715565b600b555b604080518c8152602081018c90526001600160a01b038e169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050505050505050506001600c81905550915091565b60006109ae338484611a1d565b600c546001146111765760405162461bcd60e51b8152600401610482906120e7565b6000600c556006546007546008546040516370a0823160e01b81523060048201526001600160a01b039384169390921691611220918491869161121b916001600160701b039091169084906370a08231906024015b60206040518083038186803b1580156111e357600080fd5b505afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087d9190611fa3565b6115ca565b6008546040516370a0823160e01b815230600482015261126d918391869161121b91600160701b9091046001600160701b0316906001600160a01b038516906370a08231906024016111cb565b50506001600c5550565b428410156112b95760405162461bcd60e51b815260206004820152600f60248201526e12d0525111560e8811561412549151608a1b6044820152606401610482565b6003546001600160a01b038816600090815260046020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761130c8361221b565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161138592919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156113f0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906114265750886001600160a01b0316816001600160a01b0316145b6114725760405162461bcd60e51b815260206004820152601960248201527f4b41494445583a20494e56414c49445f5349474e4154555245000000000000006044820152606401610482565b61147d8989896119bb565b505050505050505050565b600c546001146114aa5760405162461bcd60e51b8152600401610482906120e7565b6000600c556006546040516370a0823160e01b81523060048201526115c3916001600160a01b0316906370a082319060240160206040518083038186803b1580156114f457600080fd5b505afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c9190611fa3565b6007546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561156f57600080fd5b505afa158015611583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a79190611fa3565b6008546001600160701b0380821691600160701b9004166117d2565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291516000928392871691611656919061204c565b6000604051808303816000865af19150503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b50915091508180156116c25750805115806116c25750808060200190518101906116c29190611f83565b61170e5760405162461bcd60e51b815260206004820152601760248201527f4b41494445583a205452414e534645525f4641494c45440000000000000000006044820152606401610482565b5050505050565b60008115806117395750828261172b8183612190565b9250611737908361214d565b145b6109b25760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b6044820152606401610482565b60008261178983826121af565b91508111156109b25760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b6044820152606401610482565b6001600160701b0384118015906117f057506001600160701b038311155b61182f5760405162461bcd60e51b815260206004820152601060248201526f4b41494445583a204f564552464c4f5760801b6044820152606401610482565b600061184064010000000042612236565b60085490915060009061186090600160e01b900463ffffffff16836121c6565b905060008163ffffffff1611801561188057506001600160701b03841615155b801561189457506001600160701b03831615155b15611923578063ffffffff166118bc856118ad86611db0565b6001600160e01b031690611dc9565b6001600160e01b03166118cf9190612190565b600960008282546118e0919061210f565b909155505063ffffffff81166118f9846118ad87611db0565b6001600160e01b031661190c9190612190565b600a600082825461191d919061210f565b90915550505b6008805463ffffffff8416600160e01b026001600160e01b036001600160701b03898116600160701b9081026001600160e01b03199095168c83161794909417918216831794859055604080519382169282169290921783529290930490911660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a1505050505050565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316600090815260016020526040902054611a40908261177c565b6001600160a01b038085166000908152600160205260408082209390935590841681522054611a6f9082611dde565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a109085815260200190565b600080600560009054906101000a90046001600160a01b03166001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b158015611b1457600080fd5b505afa158015611b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4c9190611e4f565b600b546001600160a01b038216158015945091925090611bfb578015611bf6576000611b87610c5c6001600160701b03888116908816611715565b90506000611b9483611c0f565b905080821115611bf3576000611bb6611bad848461177c565b60005490611715565b90506000611bcf83611bc9866005611715565b90611dde565b90506000611bdd828461214d565b90508015611bef57611bef8782611c7f565b5050505b50505b611c07565b8015611c07576000600b555b505092915050565b60006003821115611c705750806000611c2960028361214d565b611c3490600161210f565b90505b81811015611c6a57905080600281611c4f818661214d565b611c59919061210f565b611c63919061214d565b9050611c37565b50919050565b8115611c7a575060015b919050565b600054611c8c9082611dde565b60009081556001600160a01b038316815260016020526040902054611cb19082611dde565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d029085815260200190565b60405180910390a35050565b6000818310611d1d5781611d1f565b825b9392505050565b6001600160a01b038216600090815260016020526040902054611d49908261177c565b6001600160a01b03831660009081526001602052604081209190915554611d70908261177c565b60009081556040518281526001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611d02565b60006109b2600160701b6001600160701b038416612161565b6000611d1f6001600160701b03831684612127565b600082611deb838261210f565b91508110156109b25760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b6044820152606401610482565b600060208284031215611e44578081fd5b8135611d1f81612276565b600060208284031215611e60578081fd5b8151611d1f81612276565b60008060408385031215611e7d578081fd5b8235611e8881612276565b91506020830135611e9881612276565b809150509250929050565b600080600060608486031215611eb7578081fd5b8335611ec281612276565b92506020840135611ed281612276565b929592945050506040919091013590565b600080600080600080600060e0888a031215611efd578283fd5b8735611f0881612276565b96506020880135611f1881612276565b95506040880135945060608801359350608088013560ff81168114611f3b578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611f6a578182fd5b8235611f7581612276565b946020939093013593505050565b600060208284031215611f94578081fd5b81518015158114611d1f578182fd5b600060208284031215611fb4578081fd5b5051919050565b600080600080600060808688031215611fd2578081fd5b85359450602086013593506040860135611feb81612276565b9250606086013567ffffffffffffffff80821115612007578283fd5b818801915088601f83011261201a578283fd5b813581811115612028578384fd5b896020828501011115612039578384fd5b9699959850939650602001949392505050565b6000825161205e8184602087016121eb565b9190910192915050565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60208152600082518060208401526120d38160408501602087016121eb565b601f01601f19169190910160400192915050565b6020808252600e908201526d12d0525111560e881313d0d2d15160921b604082015260600190565b600082198211156121225761212261224a565b500190565b60006001600160e01b038381168061214157612141612260565b92169190910492915050565b60008261215c5761215c612260565b500490565b60006001600160e01b03828116848216811515828404821116156121875761218761224a565b02949350505050565b60008160001904831182151516156121aa576121aa61224a565b500290565b6000828210156121c1576121c161224a565b500390565b600063ffffffff838116908316818110156121e3576121e361224a565b039392505050565b60005b838110156122065781810151838201526020016121ee565b83811115612215576000848401525b50505050565b600060001982141561222f5761222f61224a565b5060010190565b60008261224557612245612260565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811461228b57600080fd5b5056fea264697066735822122002402f46a09feed7c0fcabe7f48a37e50b8ac31b1b916da406fbf1c1c05368c864736f6c63430008040033a264697066735822122073cc7aeae6505ce767fa22a6a210e910b16f2da2c73afb489e7c40b6a82d738664736f6c634300080400330000000000000000000000000f5c21435895bb2f7044d0700281c05cbd500dc9
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c80635855a25a116100665780635855a25a14610100578063a2e74af614610108578063c9c653961461011d578063e6a4390514610130578063f46901ed1461016457600080fd5b8063017e7e5814610098578063094b7415146100c85780631e3dd18b146100db578063574f2ba3146100ee575b600080fd5b6000546100ab906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6001546100ab906001600160a01b031681565b6100ab6100e936600461063f565b610177565b6003545b6040519081526020016100bf565b6100f26101a1565b61011b6101163660046105ec565b6101eb565b005b6100ab61012b36600461060d565b610260565b6100ab61013e36600461060d565b60026020908152600092835260408084209091529082529020546001600160a01b031681565b61011b6101723660046105ec565b610553565b6003818154811061018757600080fd5b6000918252602090912001546001600160a01b0316905081565b6040516101b0602082016105c3565b601f1982820381018352601f9091011660408190526101d29190602001610657565b6040516020818303038152906040528051906020012081565b6001546001600160a01b0316331461023e5760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b60448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000816001600160a01b0316836001600160a01b031614156102c45760405162461bcd60e51b815260206004820152601b60248201527f4b41494445583a204944454e544943414c5f41444452455353455300000000006044820152606401610235565b600080836001600160a01b0316856001600160a01b0316106102e75783856102ea565b84845b90925090506001600160a01b03821661033c5760405162461bcd60e51b81526020600482015260146024820152734b41494445583a205a45524f5f4144445245535360601b6044820152606401610235565b6001600160a01b038281166000908152600260209081526040808320858516845290915290205416156103a75760405162461bcd60e51b81526020600482015260136024820152724b41494445583a20504149525f45584953545360681b6044820152606401610235565b6000604051806020016103b9906105c3565b601f1982820381018352601f9091011660408190526bffffffffffffffffffffffff19606086811b8216602084015285901b166034820152909150600090604801604051602081830303815290604052805190602001209050808251602084016000f560405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529196509086169063485cc95590604401600060405180830381600087803b15801561046b57600080fd5b505af115801561047f573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526002602081815260408084208987168086529083528185208054978d166001600160a01b031998891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9095018054909716841790965592548351928352908201527f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9910160405180910390a35050505092915050565b6001546001600160a01b031633146105a15760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b6044820152606401610235565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6123cc8061069183390190565b80356001600160a01b03811681146105e757600080fd5b919050565b6000602082840312156105fd578081fd5b610606826105d0565b9392505050565b6000806040838503121561061f578081fd5b610628836105d0565b9150610636602084016105d0565b90509250929050565b600060208284031215610650578081fd5b5035919050565b60008251815b81811015610677576020818601810151858301520161065d565b818111156106855782828501525b50919091019291505056fe60806040526001600c5534801561001557600080fd5b50604080518082018252600a8152694b4149444558204c507360b01b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f513da3f0e0fd390af3688dee67345fb74c26bc0c21a4e1c7dbf0223516ff33f4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c09091019092528151910120600355600580546001600160a01b031916331790556122c4806101086000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a714610407578063d505accf1461041a578063dd62ed3e1461042d578063fff6cae91461045857600080fd5b8063ba9a7a56146103d8578063bc25cf77146103e1578063c45a0155146103f457600080fd5b80637ecebe00116100d35780637ecebe001461035957806389afcb441461037957806395d89b41146103a1578063a9059cbb146103c557600080fd5b80636a6278421461031d57806370a08231146103305780637464fc3d1461035057600080fd5b806323b872dd116101665780633644e515116101405780633644e515146102ef578063485cc955146102f85780635909c0d51461030b5780635a3d54931461031457600080fd5b806323b872dd1461029b57806330adf81f146102ae578063313ce567146102d557600080fd5b8063022c0d9f146101ae57806306fdde03146101c35780630902f1ac14610202578063095ea7b3146102365780630dfe16811461025957806318160ddd14610284575b600080fd5b6101c16101bc366004611fbb565b610460565b005b6101ec6040518060400160405280600a8152602001694b4149444558204c507360b01b81525081565b6040516101f991906120b4565b60405180910390f35b61020a610977565b604080516001600160701b03948516815293909216602084015263ffffffff16908201526060016101f9565b610249610244366004611f58565b6109a1565b60405190151581526020016101f9565b60065461026c906001600160a01b031681565b6040516001600160a01b0390911681526020016101f9565b61028d60005481565b6040519081526020016101f9565b6102496102a9366004611ea3565b6109b8565b61028d7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102dd601281565b60405160ff90911681526020016101f9565b61028d60035481565b6101c1610306366004611e6b565b610a4c565b61028d60095481565b61028d600a5481565b61028d61032b366004611e33565b610ac8565b61028d61033e366004611e33565b60016020526000908152604090205481565b61028d600b5481565b61028d610367366004611e33565b60046020526000908152604090205481565b61038c610387366004611e33565b610da8565b604080519283526020830191909152016101f9565b6101ec6040518060400160405280600581526020016404b44584c560dc1b81525081565b6102496103d3366004611f58565b611147565b61028d6103e881565b6101c16103ef366004611e33565b611154565b60055461026c906001600160a01b031681565b60075461026c906001600160a01b031681565b6101c1610428366004611ee3565b611277565b61028d61043b366004611e6b565b600260209081526000928352604080842090915290825290205481565b6101c1611488565b600c5460011461048b5760405162461bcd60e51b8152600401610482906120e7565b60405180910390fd5b6000600c558415158061049e5750600084115b6104f55760405162461bcd60e51b815260206004820152602260248201527f4b41494445583a20494e53554646494349454e545f4f55545055545f414d4f55604482015261139560f21b6064820152608401610482565b600080610500610977565b5091509150816001600160701b0316871080156105255750806001600160701b031686105b6105715760405162461bcd60e51b815260206004820152601e60248201527f4b41494445583a20494e53554646494349454e545f4c495155494449545900006044820152606401610482565b60065460075460009182916001600160a01b039182169190811690891682148015906105af5750806001600160a01b0316896001600160a01b031614155b6105f05760405162461bcd60e51b81526020600482015260126024820152714b41494445583a20494e56414c49445f544f60701b6044820152606401610482565b8a1561060157610601828a8d6115ca565b891561061257610612818a8c6115ca565b861561067f576040516303468d3b60e51b81526001600160a01b038a16906368d1a7609061064c9033908f908f908e908e90600401612068565b600060405180830381600087803b15801561066657600080fd5b505af115801561067a573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b1580156106be57600080fd5b505afa1580156106d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f69190611fa3565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b15801561073857600080fd5b505afa15801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190611fa3565b92505050600089856001600160701b031661078b91906121af565b83116107985760006107b5565b6107ab8a6001600160701b0387166121af565b6107b590846121af565b905060006107cc8a6001600160701b0387166121af565b83116107d95760006107f6565b6107ec8a6001600160701b0387166121af565b6107f690846121af565b905060008211806108075750600081115b6108615760405162461bcd60e51b815260206004820152602560248201527f4b414944657843616c6c3a20494e53554646494349454e545f494e5055545f416044820152641353d5539560da1b6064820152608401610482565b6000610883610871846003611715565b61087d876103e8611715565b9061177c565b90506000610895610871846003611715565b90506108ba620f42406108b46001600160701b038b8116908b16611715565b90611715565b6108c48383611715565b10156109025760405162461bcd60e51b815260206004820152600d60248201526c4b414944657843616c6c3a204b60981b6044820152606401610482565b5050610910848488886117d2565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001600c55505050505050505050565b6008546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b60006109ae3384846119bb565b5060015b92915050565b6001600160a01b038316600090815260026020908152604080832033845290915281205460001914610a37576001600160a01b0384166000908152600260209081526040808320338452909152902054610a12908361177c565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b610a42848484611a1d565b5060019392505050565b6005546001600160a01b03163314610a9a5760405162461bcd60e51b815260206004820152601160248201527025a0a4a222ac1d102327a92124a22222a760791b6044820152606401610482565b600680546001600160a01b039384166001600160a01b03199182161790915560078054929093169116179055565b6000600c54600114610aec5760405162461bcd60e51b8152600401610482906120e7565b6000600c81905580610afc610977565b506006546040516370a0823160e01b81523060048201529294509092506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015610b4957600080fd5b505afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b819190611fa3565b6007546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c029190611fa3565b90506000610c19836001600160701b03871661177c565b90506000610c30836001600160701b03871661177c565b90506000610c3e8787611ac3565b60005490915080610c7557610c616103e861087d610c5c8787611715565b611c0f565b9850610c7060006103e8611c7f565b610cbc565b610cb96001600160701b038916610c8c8684611715565b610c96919061214d565b6001600160701b038916610caa8685611715565b610cb4919061214d565b611d0e565b98505b60008911610d1a5760405162461bcd60e51b815260206004820152602560248201527f4b41494445583a20494e53554646494349454e545f4c49515549444954595f4d604482015264125395115160da1b6064820152608401610482565b610d248a8a611c7f565b610d3086868a8a6117d2565b8115610d5a57600854610d56906001600160701b0380821691600160701b900416611715565b600b555b604080518581526020810185905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001600c5550949695505050505050565b600080600c54600114610dcd5760405162461bcd60e51b8152600401610482906120e7565b6000600c81905580610ddd610977565b506006546007546040516370a0823160e01b81523060048201529395509193506001600160a01b039081169291169060009083906370a082319060240160206040518083038186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6a9190611fa3565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015610eaf57600080fd5b505afa158015610ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee79190611fa3565b30600090815260016020526040812054919250610f048888611ac3565b60005490915080610f158487611715565b610f1f919061214d565b9a5080610f2c8486611715565b610f36919061214d565b995060008b118015610f48575060008a115b610fa25760405162461bcd60e51b815260206004820152602560248201527f4b41494445583a20494e53554646494349454e545f4c49515549444954595f42604482015264155493915160da1b6064820152608401610482565b610fac3084611d26565b610fb7878d8d6115ca565b610fc2868d8c6115ca565b6040516370a0823160e01b81523060048201526001600160a01b038816906370a082319060240160206040518083038186803b15801561100157600080fd5b505afa158015611015573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110399190611fa3565b6040516370a0823160e01b81523060048201529095506001600160a01b038716906370a082319060240160206040518083038186803b15801561107b57600080fd5b505afa15801561108f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b39190611fa3565b93506110c185858b8b6117d2565b81156110eb576008546110e7906001600160701b0380821691600160701b900416611715565b600b555b604080518c8152602081018c90526001600160a01b038e169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050505050505050506001600c81905550915091565b60006109ae338484611a1d565b600c546001146111765760405162461bcd60e51b8152600401610482906120e7565b6000600c556006546007546008546040516370a0823160e01b81523060048201526001600160a01b039384169390921691611220918491869161121b916001600160701b039091169084906370a08231906024015b60206040518083038186803b1580156111e357600080fd5b505afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087d9190611fa3565b6115ca565b6008546040516370a0823160e01b815230600482015261126d918391869161121b91600160701b9091046001600160701b0316906001600160a01b038516906370a08231906024016111cb565b50506001600c5550565b428410156112b95760405162461bcd60e51b815260206004820152600f60248201526e12d0525111560e8811561412549151608a1b6044820152606401610482565b6003546001600160a01b038816600090815260046020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761130c8361221b565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161138592919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156113f0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906114265750886001600160a01b0316816001600160a01b0316145b6114725760405162461bcd60e51b815260206004820152601960248201527f4b41494445583a20494e56414c49445f5349474e4154555245000000000000006044820152606401610482565b61147d8989896119bb565b505050505050505050565b600c546001146114aa5760405162461bcd60e51b8152600401610482906120e7565b6000600c556006546040516370a0823160e01b81523060048201526115c3916001600160a01b0316906370a082319060240160206040518083038186803b1580156114f457600080fd5b505afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c9190611fa3565b6007546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561156f57600080fd5b505afa158015611583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a79190611fa3565b6008546001600160701b0380821691600160701b9004166117d2565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291516000928392871691611656919061204c565b6000604051808303816000865af19150503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b50915091508180156116c25750805115806116c25750808060200190518101906116c29190611f83565b61170e5760405162461bcd60e51b815260206004820152601760248201527f4b41494445583a205452414e534645525f4641494c45440000000000000000006044820152606401610482565b5050505050565b60008115806117395750828261172b8183612190565b9250611737908361214d565b145b6109b25760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b6044820152606401610482565b60008261178983826121af565b91508111156109b25760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b6044820152606401610482565b6001600160701b0384118015906117f057506001600160701b038311155b61182f5760405162461bcd60e51b815260206004820152601060248201526f4b41494445583a204f564552464c4f5760801b6044820152606401610482565b600061184064010000000042612236565b60085490915060009061186090600160e01b900463ffffffff16836121c6565b905060008163ffffffff1611801561188057506001600160701b03841615155b801561189457506001600160701b03831615155b15611923578063ffffffff166118bc856118ad86611db0565b6001600160e01b031690611dc9565b6001600160e01b03166118cf9190612190565b600960008282546118e0919061210f565b909155505063ffffffff81166118f9846118ad87611db0565b6001600160e01b031661190c9190612190565b600a600082825461191d919061210f565b90915550505b6008805463ffffffff8416600160e01b026001600160e01b036001600160701b03898116600160701b9081026001600160e01b03199095168c83161794909417918216831794859055604080519382169282169290921783529290930490911660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a1505050505050565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316600090815260016020526040902054611a40908261177c565b6001600160a01b038085166000908152600160205260408082209390935590841681522054611a6f9082611dde565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611a109085815260200190565b600080600560009054906101000a90046001600160a01b03166001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b158015611b1457600080fd5b505afa158015611b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4c9190611e4f565b600b546001600160a01b038216158015945091925090611bfb578015611bf6576000611b87610c5c6001600160701b03888116908816611715565b90506000611b9483611c0f565b905080821115611bf3576000611bb6611bad848461177c565b60005490611715565b90506000611bcf83611bc9866005611715565b90611dde565b90506000611bdd828461214d565b90508015611bef57611bef8782611c7f565b5050505b50505b611c07565b8015611c07576000600b555b505092915050565b60006003821115611c705750806000611c2960028361214d565b611c3490600161210f565b90505b81811015611c6a57905080600281611c4f818661214d565b611c59919061210f565b611c63919061214d565b9050611c37565b50919050565b8115611c7a575060015b919050565b600054611c8c9082611dde565b60009081556001600160a01b038316815260016020526040902054611cb19082611dde565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d029085815260200190565b60405180910390a35050565b6000818310611d1d5781611d1f565b825b9392505050565b6001600160a01b038216600090815260016020526040902054611d49908261177c565b6001600160a01b03831660009081526001602052604081209190915554611d70908261177c565b60009081556040518281526001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611d02565b60006109b2600160701b6001600160701b038416612161565b6000611d1f6001600160701b03831684612127565b600082611deb838261210f565b91508110156109b25760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b6044820152606401610482565b600060208284031215611e44578081fd5b8135611d1f81612276565b600060208284031215611e60578081fd5b8151611d1f81612276565b60008060408385031215611e7d578081fd5b8235611e8881612276565b91506020830135611e9881612276565b809150509250929050565b600080600060608486031215611eb7578081fd5b8335611ec281612276565b92506020840135611ed281612276565b929592945050506040919091013590565b600080600080600080600060e0888a031215611efd578283fd5b8735611f0881612276565b96506020880135611f1881612276565b95506040880135945060608801359350608088013560ff81168114611f3b578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611f6a578182fd5b8235611f7581612276565b946020939093013593505050565b600060208284031215611f94578081fd5b81518015158114611d1f578182fd5b600060208284031215611fb4578081fd5b5051919050565b600080600080600060808688031215611fd2578081fd5b85359450602086013593506040860135611feb81612276565b9250606086013567ffffffffffffffff80821115612007578283fd5b818801915088601f83011261201a578283fd5b813581811115612028578384fd5b896020828501011115612039578384fd5b9699959850939650602001949392505050565b6000825161205e8184602087016121eb565b9190910192915050565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60208152600082518060208401526120d38160408501602087016121eb565b601f01601f19169190910160400192915050565b6020808252600e908201526d12d0525111560e881313d0d2d15160921b604082015260600190565b600082198211156121225761212261224a565b500190565b60006001600160e01b038381168061214157612141612260565b92169190910492915050565b60008261215c5761215c612260565b500490565b60006001600160e01b03828116848216811515828404821116156121875761218761224a565b02949350505050565b60008160001904831182151516156121aa576121aa61224a565b500290565b6000828210156121c1576121c161224a565b500390565b600063ffffffff838116908316818110156121e3576121e361224a565b039392505050565b60005b838110156122065781810151838201526020016121ee565b83811115612215576000848401525b50505050565b600060001982141561222f5761222f61224a565b5060010190565b60008261224557612245612260565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811461228b57600080fd5b5056fea264697066735822122002402f46a09feed7c0fcabe7f48a37e50b8ac31b1b916da406fbf1c1c05368c864736f6c63430008040033a264697066735822122073cc7aeae6505ce767fa22a6a210e910b16f2da2c73afb489e7c40b6a82d738664736f6c63430008040033