Source Code
Latest 25 from a total of 21,692 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Add Order With E... | 82100783 | 1 hr ago | IN | 130 POL | 0.01548201 | ||||
| Add Order With E... | 82100683 | 2 hrs ago | IN | 120 POL | 0.01553287 | ||||
| Add Order With E... | 82100604 | 2 hrs ago | IN | 120 POL | 0.0157327 | ||||
| Add Order With E... | 82100483 | 2 hrs ago | IN | 120 POL | 0.01591026 | ||||
| Add Order With E... | 82100393 | 2 hrs ago | IN | 110 POL | 0.01606868 | ||||
| Add Order With E... | 82100325 | 2 hrs ago | IN | 100 POL | 0.01700973 | ||||
| Add Order With E... | 82100206 | 2 hrs ago | IN | 85 POL | 0.01892025 | ||||
| Add Order With E... | 82099962 | 2 hrs ago | IN | 75 POL | 0.01905844 | ||||
| Add Order With E... | 82097810 | 3 hrs ago | IN | 65 POL | 0.03870542 | ||||
| Add Order With E... | 82097745 | 3 hrs ago | IN | 57 POL | 0.03606965 | ||||
| Add Order With E... | 82097664 | 3 hrs ago | IN | 47 POL | 0.03094131 | ||||
| Add Order With E... | 82096825 | 4 hrs ago | IN | 39 POL | 0.03031794 | ||||
| Add Order With E... | 82096269 | 4 hrs ago | IN | 32 POL | 0.04938424 | ||||
| Add Order With E... | 82096049 | 4 hrs ago | IN | 25 POL | 0.07182032 | ||||
| Add Order With E... | 82095805 | 4 hrs ago | IN | 21 POL | 0.04420001 | ||||
| Add Order With E... | 82095471 | 4 hrs ago | IN | 8 POL | 0.05634541 | ||||
| Add Order With E... | 82095400 | 4 hrs ago | IN | 3 POL | 0.05481689 | ||||
| Add Order With E... | 82095258 | 5 hrs ago | IN | 43 POL | 0.04775528 | ||||
| Add Order With E... | 82095038 | 5 hrs ago | IN | 67 POL | 0.05129498 | ||||
| Add Order With E... | 82094945 | 5 hrs ago | IN | 51 POL | 0.04455466 | ||||
| Add Order With E... | 82094765 | 5 hrs ago | IN | 39 POL | 0.04090607 | ||||
| Add Order With E... | 82091254 | 7 hrs ago | IN | 0.1 POL | 0.05377337 | ||||
| Add Order For ET... | 82025347 | 43 hrs ago | IN | 0 POL | 0.1312788 | ||||
| Add Order For ET... | 81988312 | 2 days ago | IN | 0 POL | 0.2298418 | ||||
| Add Order With E... | 81983814 | 2 days ago | IN | 67 POL | 0.3039072 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 82100783 | 1 hr ago | 130 POL | ||||
| 82100683 | 2 hrs ago | 120 POL | ||||
| 82100604 | 2 hrs ago | 120 POL | ||||
| 82100483 | 2 hrs ago | 120 POL | ||||
| 82100393 | 2 hrs ago | 110 POL | ||||
| 82100325 | 2 hrs ago | 100 POL | ||||
| 82100206 | 2 hrs ago | 85 POL | ||||
| 82099962 | 2 hrs ago | 75 POL | ||||
| 82097810 | 3 hrs ago | 65 POL | ||||
| 82097745 | 3 hrs ago | 57 POL | ||||
| 82097664 | 3 hrs ago | 47 POL | ||||
| 82096825 | 4 hrs ago | 39 POL | ||||
| 82096269 | 4 hrs ago | 32 POL | ||||
| 82096049 | 4 hrs ago | 25 POL | ||||
| 82095805 | 4 hrs ago | 21 POL | ||||
| 82095471 | 4 hrs ago | 8 POL | ||||
| 82095400 | 4 hrs ago | 3 POL | ||||
| 82095258 | 5 hrs ago | 43 POL | ||||
| 82095038 | 5 hrs ago | 67 POL | ||||
| 82094945 | 5 hrs ago | 51 POL | ||||
| 82094765 | 5 hrs ago | 39 POL | ||||
| 82091254 | 7 hrs ago | 0.1 POL | ||||
| 82025347 | 43 hrs ago | 57.92932371 POL | ||||
| 82025347 | 43 hrs ago | 57.92932371 POL | ||||
| 81988312 | 2 days ago | 9.45472757 POL |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MyTradeOrderBook
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.8.0;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error.
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on 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-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b,"mul");
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0,"div");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a,"sub");
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a,"add");
return c;
}
}
/**
* @title ERC20 interface
* @dev see https://eips.ethereum.org/EIPS/eip-20
*/
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function balanceOf(address who) external view returns (uint256);
}
interface IUniswapV2Factory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IUniswapV2Pair {
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor () {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(),"onlyOwner");
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
* @notice Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0),"incorrect address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
// 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: MyTradeOrderBook 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: MyTradeOrderBook 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: MyTradeOrderBook TRANSFER_FROM_FAILED');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: MyTradeOrderBook ETH_TRANSFER_FAILED');
}
}
interface IMyTradeOrderBookExt{
function liquidityPrice(
address _fromTokenAddr,
address _toTokenAddr,
address _pairAddr,
uint _reserve0,
uint _reserve1
)external;
function cancelOrderWithNum(//按数量取消订单
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
uint256 _num
)external;
function addOrder(
address _maker,
address _fromTokenAddr,
address _toTokenAddr,
uint256 _fromTokenNumber,
uint256 _toTokenNumber,
uint256 _orderIndex
)external;
function updateOrderInfo(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _orderIndex,
uint256 _outNum,
uint256 _inNum
)external;
function getOrderIndexsForMaker(
address _fromTokenAddr,
address _toTokenAddr,
address _maker
)external view returns(uint256[] memory cindexs);
function getOrderInfo(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _orderIndex
)external view returns(uint256 _orderTime,uint256 _toTokenSum);
}
interface IMyTradeOrderMining{
function updateOrderMiningNumByOuter() external returns (bool);
}
interface ISwapMining {
function swap(address account, address input, address output, uint256 amount) external returns (bool);
}
library OrderBookHelper{
using SafeMath for uint;
// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
// 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;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
function getInAmount(
uint256 fromNum,
uint256 toNum,
uint256 reserveA,
uint256 reserveB
) internal pure returns(uint256 z){
uint256 p=reserveA.mul(reserveB).mul(fromNum).mul(1000)/997/toNum;
uint256 q=reserveA.mul(reserveA).mul(8973)/3964107892;
uint256 x=sqrt(p.add(q));
uint256 y=reserveA.mul(1997)/1994;
if(x>y){
z=x.sub(y).add(1);
}else{
z=0;
}
}
function joinNumber(
uint256 _number,
uint256[] memory narray
)internal pure returns(uint256[] memory){
if(_number==0){
return narray;
}
uint256 nl=narray.length;
uint256[] memory narray1=new uint256[](nl+1);
for(uint256 i=0;i<nl;i++){
narray1[i]=narray[i];
}
narray1[nl]=_number;
return narray1;
}
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
}
}
contract MyTradeOrderBook is Ownable,ReentrancyGuard{
using SafeMath for uint;
IUniswapV2Factory immutable public uniswapV2Factory;
address immutable public WETH;
address public feeAddr;
uint256 constant UINT256_MAX = ~uint256(0);
IMyTradeOrderBookExt myTradeOrderBookExt;
address public myTradeOrderMining;
address public swapMining;
function setMyTradeOrderMining(address _myTradeOrderMining) public onlyOwner {
myTradeOrderMining = _myTradeOrderMining;
}
address public forPreDiposit;
function setForPreDiposit(address _forPreDiposit) public onlyOwner {
forPreDiposit = _forPreDiposit;
}
function setSwapMining(address _swapMininng) public onlyOwner {
swapMining = _swapMininng;
}
//最小数量限额:0.1,可外部设置
mapping (address => uint) minLimitMap;
/**
*设置最小允许的数
*/
function setMinLimit(
address _tokenAddr,
uint _minLimit
) onlyOwner public returns(bool) {
minLimitMap[_tokenAddr] = _minLimit;
return true;
}
struct Order{
address maker;
address fromTokenAddr;
address toTokenAddr;
uint256 remainNumber;
uint256 fromTokenNumber;// 代币挂单金额
uint256 toTokenNumber;// 意向代币目标金额
}
struct TokenPair{
uint256 orderMaxIndex;
mapping(address=> uint256) lastIndex;
mapping(uint256=> Order) orderMap;// orderIndex=》Order
mapping(uint256=> uint256) orderNextSequence;// 价格低的orderIndex=》价格高的orderIndex
mapping(uint256=> uint256) orderPreSequence;// 价格高的orderIndex=》价格低的orderIndex
}
mapping (address=> mapping (uint => uint8)) isForEth;
TokenPair[] tokenPairArray;// tokenPair数组
mapping (address => uint256) tokenPairIndexMap;// tokenPairAddr=>tokenPair数组下标
address immutable public flashLoan;
constructor(
address _WETH,
address _uniswapV2Factory
) payable {
WETH=_WETH;
feeAddr=msg.sender;
tokenPairArray.push();
uniswapV2Factory=IUniswapV2Factory(_uniswapV2Factory);
flashLoan=address(new FlashLoan(msg.sender));
}
function safeApproveFlashLoan(
address tokenA
)public{
TransferHelper.safeApprove(
tokenA,
flashLoan,
UINT256_MAX
);
}
function setMyTradeOrderBookExtAddr(
address _myTradeOrderBookExtAddr
) onlyOwner public returns(bool) {
myTradeOrderBookExt=IMyTradeOrderBookExt(_myTradeOrderBookExtAddr);
return true;
}
receive() external payable {
if(msg.value>0&&msg.sender!=WETH){
IWETH(WETH).deposit{value : msg.value}();
}
}
fallback(bytes calldata _input) external payable returns (bytes memory _output){
}
function setFeeAddr(address _feeAddr)public onlyOwner {
feeAddr=_feeAddr;
}
mapping (address => uint256) public allUserDiposit;//所有用户存款代币数量
mapping (address => mapping (address => uint256)) public userDiposit;
function deposit(address _token,uint _num) public {
TransferHelper.safeTransferFrom(
_token,
msg.sender,
address(this),
_num
);
userDiposit[msg.sender][_token] = userDiposit[msg.sender][_token].add(_num);
allUserDiposit[_token]=allUserDiposit[_token].add(_num);
}
function withdraw(address _token,uint _num) public {
require(userDiposit[msg.sender][_token]>=_num,"Insufficient Number");
TransferHelper.safeTransfer(
_token,
msg.sender,
_num
);
userDiposit[msg.sender][_token] = userDiposit[msg.sender][_token].sub(_num);
allUserDiposit[_token]=allUserDiposit[_token].sub(_num);
}
function addOrderWithPreDiposit(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _targetOrderIndex,
uint256 _fromTokenNumber,
uint256 _toTokenNumber
)public nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
require(msg.sender==forPreDiposit);
require(userDiposit[msg.sender][_fromTokenAddr]>=_fromTokenNumber,"Insufficient Balance");
require(_fromTokenNumber>=minLimitMap[_fromTokenAddr],"min limit");
userDiposit[msg.sender][_fromTokenAddr] = userDiposit[msg.sender][_fromTokenAddr].sub(_fromTokenNumber);
(reserveNum,orderIndex)=_addOrder(
msg.sender,
_fromTokenAddr,
_toTokenAddr,
_targetOrderIndex,
_fromTokenNumber,
_toTokenNumber
);
}
function cancelOrderForNumWithPreDiposit(//按数量取消订单
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
uint256 _num
)public nonReentrant returns(bool) {
_cancelOrderForNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
userDiposit[msg.sender][_fromTokenAddr] = userDiposit[msg.sender][_fromTokenAddr].add(_num);
return true;
}
function cancelOrderForNum(//按数量取消订单
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
uint256 _num
)public nonReentrant returns(bool) {
_cancelOrderForNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
allUserDiposit[_fromTokenAddr]=allUserDiposit[_fromTokenAddr].sub(_num);
if(_fromTokenAddr==WETH){
IWETH(WETH).withdraw(_num);
TransferHelper.safeTransferETH(
msg.sender,
_num
);
}else{
TransferHelper.safeTransfer(
_fromTokenAddr,
msg.sender,
_num
);
}
if(myTradeOrderMining!=address(0)){
IMyTradeOrderMining(myTradeOrderMining).updateOrderMiningNumByOuter();
}
return true;
}
function _cancelOrderForNum(//按数量取消订单
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
uint256 _num
)internal{
address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,_toTokenAddr);
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
require(tokenPairIndex!=0,"tokenPair not exist");
TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
require(_tokenPair.orderMap[_orderIndex].maker==msg.sender,"invalid maker");
require(_orderIndex!=0,"order not exist");
uint256 remainNumber=_tokenPair.orderMap[_orderIndex].remainNumber;
require(remainNumber>=_num,"Insufficient RemainNumber");
if(remainNumber==_num){
if(_tokenPair.lastIndex[_fromTokenAddr]==_orderIndex){
_tokenPair.lastIndex[_fromTokenAddr]=_tokenPair.orderNextSequence[_orderIndex];
_tokenPair.orderPreSequence[_tokenPair.lastIndex[_fromTokenAddr]]=0;
_tokenPair.orderNextSequence[_orderIndex]=0;
}else{
uint256 orderPreIndex=_tokenPair.orderPreSequence[_orderIndex];
require(orderPreIndex!=0,"no preIndex");
require(_tokenPair.orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr,"invalid fromTokenAddr");
uint256 orderNextIndex=_tokenPair.orderNextSequence[_orderIndex];
_tokenPair.orderNextSequence[orderPreIndex]=orderNextIndex;
if(orderNextIndex!=0){
_tokenPair.orderPreSequence[orderNextIndex]=orderPreIndex;
}
_tokenPair.orderPreSequence[_orderIndex]=0;
_tokenPair.orderNextSequence[_orderIndex]=0;
}
}else{
_tokenPair.orderMap[_orderIndex].remainNumber=remainNumber.sub(_num);
}
(uint256 reserveA,uint256 reserveB)=getReserves(_fromTokenAddr, _toTokenAddr);
myTradeOrderBookExt.liquidityPrice(_fromTokenAddr,_toTokenAddr,pairAddr,reserveA,reserveB);
myTradeOrderBookExt.cancelOrderWithNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
}
function _orderIndexSequence(
uint256 _targetOrderIndex,
uint256 _orderIndex,
TokenPair storage _tokenPair,
uint256 _fromTokenNumber,
uint256 _toTokenNumber
)internal{
if(_fromTokenNumber.mul(_tokenPair.orderMap[_targetOrderIndex].toTokenNumber)<=
_tokenPair.orderMap[_targetOrderIndex].fromTokenNumber.mul(_toTokenNumber)){
uint256 orderNextSequence=_tokenPair.orderNextSequence[_targetOrderIndex];
if(orderNextSequence==0){
_tokenPair.orderNextSequence[_targetOrderIndex]=_orderIndex;
_tokenPair.orderPreSequence[_orderIndex]=_targetOrderIndex;
}else{
if(_fromTokenNumber.mul(_tokenPair.orderMap[orderNextSequence].toTokenNumber)<=
_tokenPair.orderMap[orderNextSequence].fromTokenNumber.mul(_toTokenNumber)){
_orderIndexSequence(orderNextSequence,
_orderIndex,_tokenPair,_fromTokenNumber,_toTokenNumber);
}else{
_tokenPair.orderPreSequence[_orderIndex]=_targetOrderIndex;
_tokenPair.orderNextSequence[_targetOrderIndex]=_orderIndex;
_tokenPair.orderPreSequence[orderNextSequence]=_orderIndex;
_tokenPair.orderNextSequence[_orderIndex]=orderNextSequence;
}
}
}else{
uint256 orderPreIndex=_tokenPair.orderPreSequence[_targetOrderIndex];
if(orderPreIndex==0){
_tokenPair.orderPreSequence[_targetOrderIndex]=_orderIndex;
_tokenPair.orderNextSequence[_orderIndex]=_targetOrderIndex;
}else{
if(_fromTokenNumber.mul(_tokenPair.orderMap[orderPreIndex].toTokenNumber)>=
_tokenPair.orderMap[orderPreIndex].fromTokenNumber.mul(_toTokenNumber)){
_orderIndexSequence(orderPreIndex,
_orderIndex,_tokenPair,_fromTokenNumber,_toTokenNumber);
}else{
_tokenPair.orderNextSequence[_orderIndex]=_targetOrderIndex;
_tokenPair.orderPreSequence[_targetOrderIndex]=_orderIndex;
_tokenPair.orderNextSequence[orderPreIndex]=_orderIndex;
_tokenPair.orderPreSequence[_orderIndex]=orderPreIndex;
}
}
}
}
function addOrderWithETH(
address _maker,
address _toTokenAddr,
uint256 _targetOrderIndex,
uint256 _toTokenNumber
)public payable nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
require(msg.value>minLimitMap[WETH],"min limit");
IWETH(WETH).deposit{value : msg.value}();
(reserveNum,orderIndex)=_addOrder(_maker,WETH,_toTokenAddr,_targetOrderIndex,msg.value,_toTokenNumber);
}
function addOrderForETH(
address _maker,
address _fromTokenAddr,
uint256 _targetOrderIndex,
uint256 _fromTokenNumber,
uint256 _toTokenNumber
)public returns(uint256 reserveNum,uint256 orderIndex) {
address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,WETH);
require(pairAddr!=address(0),"pairAddr not exist");
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex== 0){//如果交易对不存在就新增一个
tokenPairIndex=tokenPairArray.length;
tokenPairArray.push();
tokenPairIndexMap[pairAddr]=tokenPairIndex;
}
isForEth[_fromTokenAddr][tokenPairArray[tokenPairIndex].orderMaxIndex.add(1)]=2;
(reserveNum,orderIndex)=addOrder(
_maker,
_fromTokenAddr,
WETH,
_targetOrderIndex,
_fromTokenNumber,
_toTokenNumber
);
}
function addOrder(
address _maker,
address _fromTokenAddr,
address _toTokenAddr,
uint256 _targetOrderIndex,
uint256 _fromTokenNumber,
uint256 _toTokenNumber
)public nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
require(_fromTokenNumber>minLimitMap[_fromTokenAddr],"min limit");
TransferHelper.safeTransferFrom(
_fromTokenAddr,
msg.sender,
address(this),
_fromTokenNumber
);
(reserveNum,orderIndex)=_addOrder(_maker,_fromTokenAddr,
_toTokenAddr,_targetOrderIndex,_fromTokenNumber,_toTokenNumber
);
}
function _addOrder(
address _maker,
address _fromTokenAddr,
address _toTokenAddr,
uint256 _targetOrderIndex,
uint256 _fromTokenNumber,
uint256 _toTokenNumber
)internal returns(
uint256 reserveNum,
uint256 orderIndex
) {
address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,_toTokenAddr);
require(pairAddr!=address(0),"pairAddr not exist");
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex== 0){//如果交易对不存在就新增一个
tokenPairIndex=tokenPairArray.length;
tokenPairArray.push();
tokenPairIndexMap[pairAddr]=tokenPairIndex;
}
TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
orderIndex=_tokenPair.orderMaxIndex.add(1);
_tokenPair.orderMaxIndex=orderIndex;
uint256 lastIndex=_tokenPair.lastIndex[_fromTokenAddr];
if(lastIndex!=0){
if(_targetOrderIndex==0){
_targetOrderIndex=lastIndex;
}else if(
_tokenPair.orderNextSequence[_targetOrderIndex]==0&&
_tokenPair.orderPreSequence[_targetOrderIndex]==0
){
_targetOrderIndex=lastIndex;
}else if(_tokenPair.orderMap[_targetOrderIndex].fromTokenAddr!=_fromTokenAddr){
_targetOrderIndex=lastIndex;
}
_orderIndexSequence(_targetOrderIndex,orderIndex,_tokenPair,
_fromTokenNumber,_toTokenNumber
);
}
myTradeOrderBookExt.addOrder(
_maker,
_fromTokenAddr,
_toTokenAddr,
_fromTokenNumber,
_toTokenNumber,
orderIndex);
Order memory order=Order(_maker,_fromTokenAddr,_toTokenAddr,
_fromTokenNumber,_fromTokenNumber,_toTokenNumber);
_tokenPair.orderMap[orderIndex]=order;
(uint256 reserveA,uint256 reserveB)=getReserves(_fromTokenAddr, _toTokenAddr);
if(_tokenPair.orderPreSequence[orderIndex]==0){
_tokenPair.lastIndex[order.fromTokenAddr]=orderIndex;
checkTrade(_tokenPair,orderIndex,order,reserveA,reserveB);
reserveNum=_tokenPair.orderMap[orderIndex].remainNumber;
if(reserveNum==0){
uint _nextIndex=_tokenPair.orderNextSequence[orderIndex];
_tokenPair.lastIndex[order.fromTokenAddr]=_nextIndex;
if(_nextIndex!=0){
_tokenPair.orderNextSequence[orderIndex]=0;
_tokenPair.orderPreSequence[_nextIndex]=0;
}
}else{
allUserDiposit[order.fromTokenAddr]=allUserDiposit[order.fromTokenAddr].add(reserveNum);
}
uint remainBal=IERC20(_fromTokenAddr).balanceOf(address(this));
if(remainBal>allUserDiposit[order.fromTokenAddr]){//剩余的是手续费
TransferHelper.safeTransfer(
order.fromTokenAddr,
feeAddr,
remainBal.sub(allUserDiposit[order.fromTokenAddr])
);
}
}else{
reserveNum=_fromTokenNumber;
allUserDiposit[order.fromTokenAddr]=allUserDiposit[order.fromTokenAddr].add(reserveNum);
}
myTradeOrderBookExt.liquidityPrice(order.fromTokenAddr,order.toTokenAddr,pairAddr,reserveA,reserveB);
if(myTradeOrderMining!=address(0)){
IMyTradeOrderMining(myTradeOrderMining).updateOrderMiningNumByOuter();
}
}
function checkTrade(
TokenPair storage _tokenPair,
uint256 orderIndex,
Order memory o,
uint256 reserveA,
uint256 reserveB
) internal {
if(o.fromTokenNumber.mul(reserveB)>o.toTokenNumber.mul(reserveA)){//如果流动池价格低于当前价格
uint256 cInAmount=OrderBookHelper.getInAmount(
o.fromTokenNumber,o.toTokenNumber,reserveA,reserveB
);//计算达到当前订单价格需要付出的币数量
if(cInAmount>o.fromTokenNumber){
cInAmount=o.fromTokenNumber;
}
uint[3] memory numArray=[0,0,_tokenPair.lastIndex[o.toTokenAddr]];
if(numArray[2]!=0){//如果存在挂单
Order storage bom=_tokenPair.orderMap[numArray[2]];
Order memory bo=bom;
if(o.fromTokenNumber.mul(bo.fromTokenNumber)>=o.toTokenNumber.mul(bo.toTokenNumber)){//当前订单价格超过挂单的价格
uint256 newInAmount;
if(o.fromTokenNumber.mul(bo.fromTokenNumber)==o.toTokenNumber.mul(bo.toTokenNumber)){
newInAmount=cInAmount;
}else{
newInAmount=OrderBookHelper.getInAmount(//计算对手订单价格需要付出的币数量
bo.toTokenNumber,bo.fromTokenNumber,reserveA,reserveB);
}
if(cInAmount>=newInAmount){//全部成交超过对手订单价格
uint256 tokenANum=o.fromTokenNumber.sub(newInAmount);
while(numArray[2]>0&&tokenANum>0){
uint tonum=getToNum(bo);
uint tonumsFee=tonum.mul(997).div(1000);
if(tokenANum>=tonum){//如果全部成交也不够
if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
IWETH(WETH).withdraw(tonumsFee);
TransferHelper.safeTransferETH(
bo.maker,
tonumsFee
);
}else{
TransferHelper.safeTransfer(
bo.toTokenAddr,
bo.maker,
tonumsFee
);
}
numArray[0]=numArray[0].add(tonum);//付出的
numArray[1]=numArray[1].add(bo.remainNumber);//得到的
bom.remainNumber=0;
myTradeOrderBookExt.updateOrderInfo(
bo.fromTokenAddr,
bo.toTokenAddr,
numArray[2],
tonumsFee,//成交数量
bo.remainNumber
);
uint newBIndex=_tokenPair.orderNextSequence[numArray[2]];//继续向上一单推进
_tokenPair.orderNextSequence[numArray[2]]=0;
numArray[2]=newBIndex;
_tokenPair.lastIndex[o.toTokenAddr]=numArray[2];
if(numArray[2]!=0){
_tokenPair.orderPreSequence[numArray[2]]=0;
bom=_tokenPair.orderMap[numArray[2]];
bo=bom;
if(o.fromTokenNumber.mul(bo.fromTokenNumber)>=o.toTokenNumber.mul(bo.toTokenNumber)){
newInAmount=OrderBookHelper.getInAmount(
bo.toTokenNumber,bo.fromTokenNumber,reserveA,reserveB);//计算对手订单价格需要付出的币数量
uint atemp=newInAmount.add(numArray[0]);
if(cInAmount>=newInAmount&&o.fromTokenNumber>atemp){//继续向上一条订单价格推进
tokenANum=o.fromTokenNumber.sub(atemp);
}else{
tokenANum=0;//停止向上遍列
}
}else{
tokenANum=0;//停止向上遍列
}
}
}else{
//如果最后一条订单簿能成交够,部分成交订单簿
uint256 atoNum=tokenANum.mul(997).div(1000);
if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
IWETH(WETH).withdraw(atoNum);
TransferHelper.safeTransferETH(
bo.maker,
atoNum
);
}else{
TransferHelper.safeTransfer(
bo.toTokenAddr,
bo.maker,
atoNum
);
}
numArray[0]=numArray[0].add(tokenANum);
uint256 tokenBNum=atoNum.mul(bo.fromTokenNumber) / bo.toTokenNumber;
numArray[1]=numArray[1].add(tokenBNum);
bom.remainNumber=bo.remainNumber.sub(tokenBNum);
myTradeOrderBookExt.updateOrderInfo(
bo.fromTokenAddr,
bo.toTokenAddr,
numArray[2],
atoNum,//成交数量
tokenBNum
);
tokenANum=0;//停止向上遍列
}
}
}
}
}
uint256 inAmountToliq=o.fromTokenNumber.sub(numArray[0]);
if(cInAmount<inAmountToliq){
inAmountToliq=cInAmount;
}
if(inAmountToliq>0){
numArray[0]=numArray[0].add(inAmountToliq);
{
address _fromTokenAddr=o.fromTokenAddr;
address _toTokenAddr=o.toTokenAddr;
uint _reserveA=reserveA;
uint _reserveB=reserveB;
uint256 numerator = _reserveA.mul(1000);
uint256 denominator =_reserveB.sub(1).mul(997);
uint256 amountIn = (numerator / denominator).add(2);
if(inAmountToliq>=amountIn){
uint256 amountOut=OrderBookHelper.getAmountOut(inAmountToliq,_reserveA,_reserveB);
numArray[1]=numArray[1].add(amountOut);
address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
TransferHelper.safeTransfer(
_fromTokenAddr,
pairAddr,
inAmountToliq
);
(address token0,) =OrderBookHelper.sortTokens(_fromTokenAddr, _toTokenAddr);
if(_fromTokenAddr == token0){
IUniswapV2Pair(pairAddr).swap(
0, amountOut, address(this), new bytes(0)
);
}else{
IUniswapV2Pair(pairAddr).swap(
amountOut, 0, address(this), new bytes(0)
);
}
allUserDiposit[_toTokenAddr]=allUserDiposit[_toTokenAddr].add(amountOut);
}
}
}
if(numArray[0]>0){
if(numArray[1]>0){
if(o.toTokenAddr==WETH&&isForEth[o.fromTokenAddr][orderIndex]==2){
IWETH(WETH).withdraw(numArray[1]);
TransferHelper.safeTransferETH(
o.maker,
numArray[1]
);
}else{
TransferHelper.safeTransfer(
o.toTokenAddr,
o.maker,
numArray[1]
);
}
if (swapMining != address(0)) {
ISwapMining(swapMining).swap(o.maker, o.fromTokenAddr, o.toTokenAddr, numArray[1]);
}
allUserDiposit[o.toTokenAddr]=allUserDiposit[o.toTokenAddr].sub(numArray[1]);
}
myTradeOrderBookExt.updateOrderInfo(
_tokenPair.orderMap[orderIndex].fromTokenAddr,
_tokenPair.orderMap[orderIndex].toTokenAddr,
orderIndex,
numArray[1],//成交数量
numArray[0]
);
_tokenPair.orderMap[orderIndex].remainNumber=
o.fromTokenNumber.sub(numArray[0]);
}
}else {
uint[3] memory numArray=[0,0,_tokenPair.lastIndex[o.toTokenAddr]];
uint256 tokenANum=o.fromTokenNumber;
while(numArray[2]!=0&&tokenANum!=0){
Order storage bo=_tokenPair.orderMap[numArray[2]];
if(o.fromTokenNumber.mul(bo.fromTokenNumber)==o.toTokenNumber.mul(bo.toTokenNumber)){
tokenANum=o.fromTokenNumber.sub(numArray[0]);
uint256 toNum=getToNum(bo);
if(tokenANum>=toNum){
uint256 atoNum=toNum.mul(997).div(1000);
if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
IWETH(WETH).withdraw(atoNum);
TransferHelper.safeTransferETH(
bo.maker,
atoNum
);
}else{
TransferHelper.safeTransfer(
bo.toTokenAddr,
bo.maker,
atoNum
);
}
numArray[0]=numArray[0].add(toNum);
numArray[1]=numArray[1].add(bo.remainNumber);
myTradeOrderBookExt.updateOrderInfo(
_tokenPair.orderMap[numArray[2]].fromTokenAddr,
_tokenPair.orderMap[numArray[2]].toTokenAddr,
numArray[2],
atoNum,//成交数量
bo.remainNumber
);
uint newBIndex=_tokenPair.orderNextSequence[numArray[2]];
_tokenPair.lastIndex[o.toTokenAddr]=newBIndex;
if(newBIndex!=0){
_tokenPair.orderNextSequence[numArray[2]]=0;
_tokenPair.orderPreSequence[newBIndex]=0;
}
_tokenPair.orderMap[numArray[2]].remainNumber=0;
numArray[2]=newBIndex;
}else{
uint256 atoNum=tokenANum.mul(997).div(1000);
if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
IWETH(WETH).withdraw(atoNum);
TransferHelper.safeTransferETH(
bo.maker,
atoNum
);
}else{
TransferHelper.safeTransfer(
bo.toTokenAddr,
bo.maker,
atoNum
);
}
numArray[0]=o.fromTokenNumber;
uint256 tokenBNum=atoNum.mul(bo.fromTokenNumber) / bo.toTokenNumber;
numArray[1]=numArray[1].add(tokenBNum);
_tokenPair.orderMap[numArray[2]].remainNumber=
bo.remainNumber.sub(tokenBNum);
myTradeOrderBookExt.updateOrderInfo(
_tokenPair.orderMap[numArray[2]].fromTokenAddr,
_tokenPair.orderMap[numArray[2]].toTokenAddr,
numArray[2],
atoNum,//成交数量
tokenBNum
);
break;
}
}else{
break;
}
}
if(numArray[0]>0){
if(o.toTokenAddr==WETH&&isForEth[o.fromTokenAddr][orderIndex]==2){
IWETH(WETH).withdraw(numArray[1]);
TransferHelper.safeTransferETH(
o.maker,
numArray[1]
);
}else{
TransferHelper.safeTransfer(
o.toTokenAddr,
o.maker,
numArray[1]
);
}
if (swapMining != address(0)) {
ISwapMining(swapMining).swap(o.maker, o.fromTokenAddr, o.toTokenAddr, numArray[1]);
}
allUserDiposit[o.toTokenAddr]=allUserDiposit[o.toTokenAddr].sub(numArray[1]);
myTradeOrderBookExt.updateOrderInfo(
_tokenPair.orderMap[orderIndex].fromTokenAddr,
_tokenPair.orderMap[orderIndex].toTokenAddr,
orderIndex,
numArray[1],//成交数量
numArray[0]
);
_tokenPair.orderMap[orderIndex].remainNumber=
o.fromTokenNumber.sub(numArray[0]);
}
}
}
function getOrderByIndexBatch(
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256[] memory _orderIndexs//必须是已存在的orderIndex,否则会得不到正确结果
)public view returns(
address[] memory makers,//挂单者
address[] memory fromTokenAddrs,// 代币地址
uint256[] memory fromTokenNumbers,//初始挂单量
uint256[] memory timestamps,//初始挂单时间
uint256[] memory remainNumbers,//当前挂单存量
uint256[] memory toTokenNumbers,//初始意向代币目标金额
uint256[] memory toTokenSums//已经获取的金额
){
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
if(pairAddr!=address(0)){
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
TokenPair storage tokenPair=tokenPairArray[tokenPairIndex];
uint256 l=_orderIndexs.length;
makers=new address[](l);
fromTokenAddrs=new address[](l);
fromTokenNumbers=new uint256[](l);
remainNumbers=new uint256[](l);
toTokenNumbers=new uint256[](l);
timestamps=new uint256[](l);
toTokenSums=new uint256[](l);
for(uint256 i=0;i<l;i++){
{
uint256 _orderIndex=_orderIndexs[i];
Order memory o=tokenPair.orderMap[_orderIndex];
makers[i]=o.maker;
fromTokenAddrs[i]=o.fromTokenAddr;
toTokenNumbers[i]=o.toTokenNumber;
fromTokenNumbers[i]=o.fromTokenNumber;
remainNumbers[i]=o.remainNumber;
(timestamps[i],toTokenSums[i])=myTradeOrderBookExt.getOrderInfo(o.fromTokenAddr,o.toTokenAddr,_orderIndex);
}
}
}
}
}
function getPageOrders(// 分页获取所有订单号
address _fromTokenAddr,// 卖出token地址
address _toTokenAddr,// 买入token地址
uint256 _orderStartIndex,// 订单序号点
uint256 _records// 每次获取的个数
)public view returns(uint256[] memory orderIndexs){
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
if(pairAddr!=address(0)){
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
TokenPair storage tokenPair=tokenPairArray[tokenPairIndex];
if(tokenPair.orderNextSequence[_orderStartIndex]==0){
uint256 ordersLastIndex=tokenPair.lastIndex[_fromTokenAddr];
if(tokenPair.orderPreSequence[_orderStartIndex]!=0||
_orderStartIndex==ordersLastIndex){
orderIndexs=new uint256[](1);
orderIndexs[0]=_orderStartIndex;
}
}else{
orderIndexs=new uint256[](1);
orderIndexs[0]=_orderStartIndex;
if(_records!=1){
uint256[] memory newOrderIndexs=OrderBookHelper.joinNumber(
tokenPair.orderNextSequence[orderIndexs[0]],orderIndexs);
uint256 ll=newOrderIndexs.length;//新数组长度
uint256 orderNextSequence=tokenPair.orderNextSequence[newOrderIndexs[ll-1]];
while(orderNextSequence>0&&ll<_records){
newOrderIndexs=OrderBookHelper.joinNumber(orderNextSequence,newOrderIndexs);
if(ll==newOrderIndexs.length){//新数组长度没变停止
break;
}
ll=newOrderIndexs.length;//更新新数组长度
orderNextSequence=tokenPair.orderNextSequence[newOrderIndexs[ll-1]];
}
orderIndexs=newOrderIndexs;
}
}
}
}
}
function getClosestOrderIndex(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _targetOrderIndex,
uint256 _fromTokenNumber,
uint256 _toTokenNumber,
uint256 _depth
)public view returns (uint256 closestOrderIndex,uint8 isEnd){
if(_depth==0){
return (_targetOrderIndex,0);
}
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
if(pairAddr!=address(0)){
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
if(_tokenPair.orderNextSequence[_targetOrderIndex]==0
&&_tokenPair.orderPreSequence[_targetOrderIndex]==0){
_targetOrderIndex=_tokenPair.lastIndex[_fromTokenAddr];
}
if(_targetOrderIndex!=0){
Order memory o=_tokenPair.orderMap[_targetOrderIndex];
if(o.fromTokenAddr!=_fromTokenAddr){
_targetOrderIndex=_tokenPair.lastIndex[_fromTokenAddr];
}
if(_targetOrderIndex!=0){
if(_fromTokenNumber.mul(_tokenPair.orderMap[_targetOrderIndex].toTokenNumber)<=
_tokenPair.orderMap[_targetOrderIndex].fromTokenNumber.mul(_toTokenNumber)){
uint256 orderNextSequence=_tokenPair.orderNextSequence[_targetOrderIndex];
if(orderNextSequence==0){
return (_targetOrderIndex,1);
}else{
if(_fromTokenNumber.mul(_tokenPair.orderMap[orderNextSequence].toTokenNumber)<=
_tokenPair.orderMap[orderNextSequence].fromTokenNumber.mul(_toTokenNumber)){
return getClosestOrderIndex(
_fromTokenAddr,
_toTokenAddr,
orderNextSequence,
_fromTokenNumber,
_toTokenNumber,
_depth.sub(1)
);
}else{
return (_targetOrderIndex,1);
}
}
}else{
uint256 orderPreIndex=_tokenPair.orderPreSequence[_targetOrderIndex];
if(orderPreIndex==0){
return (_targetOrderIndex,1);
}else{
if(_fromTokenNumber.mul(_tokenPair.orderMap[orderPreIndex].toTokenNumber)>=
_tokenPair.orderMap[orderPreIndex].fromTokenNumber.mul(_toTokenNumber)){
return getClosestOrderIndex(
_fromTokenAddr,
_toTokenAddr,
orderPreIndex,
_fromTokenNumber,
_toTokenNumber,
_depth.sub(1)
);
}else{
return (_targetOrderIndex,1);
}
}
}
}
}
}
}
}
function getLastOrderIndex(
address _fromTokenAddr,
address _toTokenAddr
)public view returns (uint256 lastOrderIndex){
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
if(pairAddr!=address(0)){
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
lastOrderIndex=tokenPairArray[tokenPairIndex].lastIndex[_fromTokenAddr];
}
}
}
function getNextOrderIndex(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _orderIndex
)public view returns (uint256 nextOrderIndex){
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
if(pairAddr!=address(0)){
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
if(tokenPairArray[tokenPairIndex].orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr){
nextOrderIndex=tokenPairArray[tokenPairIndex].orderNextSequence[_orderIndex];
}
}
}
}
function getPreOrderIndex(
address _fromTokenAddr,
address _toTokenAddr,
uint256 _orderIndex
)public view returns (uint256 preOrderIndex){
address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
if(tokenPairIndex!=0){
if(tokenPairArray[tokenPairIndex].orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr){
preOrderIndex=tokenPairArray[tokenPairIndex].orderPreSequence[_orderIndex];
}
}
}
function getToNum(Order memory bo) internal pure returns (uint256 _to){
_to=bo.toTokenNumber.mul(
bo.remainNumber
).div(bo.fromTokenNumber).mul(1000).div(997);
}
// fetches and sorts the reserves for a pair
function getReserves(address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
(address token0,) = OrderBookHelper.sortTokens(tokenA, tokenB);
(uint reserve0, uint reserve1,) = IUniswapV2Pair(uniswapV2Factory.getPair(tokenA, tokenB)).getReserves();
(reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
}
}
interface IFlashLoanService {
function check(address from, uint256 value) external returns (bool);
}
contract FlashLoan is ReentrancyGuard,Ownable{
address public loanServiceAddr;
constructor(
address _owner
){
_transferOwnership(_owner);
}
function setLoanServiceAddr(address _loanServiceAddr)public onlyOwner {
loanServiceAddr=_loanServiceAddr;
}
function loan(
address from,
address token,
uint value,
address contractAddr,
bytes memory msgdata
) public nonReentrant returns(bool){
uint fromBal=IERC20(token).balanceOf(from);
require(fromBal>=value,"insufficient balance");
TransferHelper.safeTransferFrom(token,from,contractAddr,value);
(bool success, bytes memory data) =contractAddr.call(msgdata);
require(success && (data.length == 0 || abi.decode(data, (bool))), 'loan failed');
require(IFlashLoanService(loanServiceAddr).check(from,fromBal));
require(IERC20(token).balanceOf(from)>=fromBal,"error balance:loan failed");
return true;
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_uniswapV2Factory","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrder","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderForETH","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderWithETH","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderWithPreDiposit","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allUserDiposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"cancelOrderForNum","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"cancelOrderForNumWithPreDiposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashLoan","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"forPreDiposit","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_depth","type":"uint256"}],"name":"getClosestOrderIndex","outputs":[{"internalType":"uint256","name":"closestOrderIndex","type":"uint256"},{"internalType":"uint8","name":"isEnd","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"}],"name":"getLastOrderIndex","outputs":[{"internalType":"uint256","name":"lastOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getNextOrderIndex","outputs":[{"internalType":"uint256","name":"nextOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256[]","name":"_orderIndexs","type":"uint256[]"}],"name":"getOrderByIndexBatch","outputs":[{"internalType":"address[]","name":"makers","type":"address[]"},{"internalType":"address[]","name":"fromTokenAddrs","type":"address[]"},{"internalType":"uint256[]","name":"fromTokenNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"timestamps","type":"uint256[]"},{"internalType":"uint256[]","name":"remainNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"toTokenNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"toTokenSums","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderStartIndex","type":"uint256"},{"internalType":"uint256","name":"_records","type":"uint256"}],"name":"getPageOrders","outputs":[{"internalType":"uint256[]","name":"orderIndexs","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getPreOrderIndex","outputs":[{"internalType":"uint256","name":"preOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"myTradeOrderMining","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"}],"name":"safeApproveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"setFeeAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forPreDiposit","type":"address"}],"name":"setForPreDiposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddr","type":"address"},{"internalType":"uint256","name":"_minLimit","type":"uint256"}],"name":"setMinLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_myTradeOrderBookExtAddr","type":"address"}],"name":"setMyTradeOrderBookExtAddr","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_myTradeOrderMining","type":"address"}],"name":"setMyTradeOrderMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapMininng","type":"address"}],"name":"setSwapMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapMining","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Factory","outputs":[{"internalType":"contract IUniswapV2Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userDiposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60e06040526040516200694838038062006948833981810160405260408110156200002957600080fd5b508051602090910151600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360018080556001600160601b0319606084811b821660a052600280546001600160a01b0319163390811790915560098054909401845560009390935283901b16608052604051620000cc9062000114565b6001600160a01b03909116815260405190819003602001906000f080158015620000fa573d6000803e3d6000fd5b5060601b6001600160601b03191660c05250620001229050565b610ad18062005e7783390190565b60805160601c60a05160601c60c05160601c615c7a620001fd60003980610cb55280611daf52508061021852806102425280610d7a5280610da252806116c452806118735280611902528061197252806119ea5280611de552806142fb528061436f52806146d9528061474d5280614c9d5280614d1652806150c8528061513552806153b0528061541d528061567952806156f25250806110ca52806115cd52806116945280611a3a5280611edf528061219b52806123d152806127eb5280612ba552806134d25280613dba52806149cb5250615c7a6000f3fe6080604052600436106101fd5760003560e01c80638f32d59b1161010d578063d40ea4f4116100a0578063e91b3f321161006f578063e91b3f3214610b94578063ed57fb2814610bcd578063f2fde38b14610c08578063f3fef3a314610c3b578063f55f918d14610c74576102b7565b8063d40ea4f414610a64578063d58960cf14610ab9578063e0ada45e14610afc578063e2a9bed114610b45576102b7565b8063b2855b4f116100dc578063b2855b4f14610922578063bf653f9314610955578063c2ffcaad14610988578063c621c9e114610a21576102b7565b80638f32d59b1461089e5780639ad5981e146108b3578063a8f9cb0e146108c8578063ad5c46481461090d576102b7565b80634f88718311610190578063715018a61161015f578063715018a6146107605780637170cba51461077557806371e43506146107dd5780638cd0cb10146108195780638da5cb5b14610889576102b7565b80634f8871831461044857806350c84f6b1461047b57806359d0f713146107365780636c37a7591461074b576102b7565b806339e7fddc116101cc57806339e7fddc146103b2578063441e24b9146103c757806347e7ef24146103fa5780634e5eda1114610433576102b7565b8063021be644146102be5780630f825ee2146102f15780631108749d1461034e57806317c1116a1461037f576102b7565b366102b75760003411801561023b5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b156102b5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561029b57600080fd5b505af11580156102af573d6000803e3d6000fd5b50505050505b005b6060516080f35b3480156102ca57600080fd5b506102b5600480360360208110156102e157600080fd5b50356001600160a01b0316610caf565b3480156102fd57600080fd5b5061033a6004803603608081101561031457600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610cdf565b604080519115158252519081900360200190f35b34801561035a57600080fd5b50610363610ec8565b604080516001600160a01b039092168252519081900360200190f35b34801561038b57600080fd5b506102b5600480360360208110156103a257600080fd5b50356001600160a01b0316610ed7565b3480156103be57600080fd5b50610363610f3e565b3480156103d357600080fd5b506102b5600480360360208110156103ea57600080fd5b50356001600160a01b0316610f4d565b34801561040657600080fd5b506102b56004803603604081101561041d57600080fd5b506001600160a01b038135169060200135610fb4565b34801561043f57600080fd5b50610363611045565b34801561045457600080fd5b506102b56004803603602081101561046b57600080fd5b50356001600160a01b0316611054565b34801561048757600080fd5b506105446004803603606081101561049e57600080fd5b6001600160a01b0382358116926020810135909116918101906060810160408201356401000000008111156104d257600080fd5b8201836020820111156104e457600080fd5b8035906020019184602083028401116401000000008311171561050657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506110bb945050505050565b604051808060200180602001806020018060200180602001806020018060200188810388528f818151815260200191508051906020019060200280838360005b8381101561059c578181015183820152602001610584565b5050505090500188810387528e818151815260200191508051906020019060200280838360005b838110156105db5781810151838201526020016105c3565b5050505090500188810386528d818151815260200191508051906020019060200280838360005b8381101561061a578181015183820152602001610602565b5050505090500188810385528c818151815260200191508051906020019060200280838360005b83811015610659578181015183820152602001610641565b5050505090500188810384528b818151815260200191508051906020019060200280838360005b83811015610698578181015183820152602001610680565b5050505090500188810383528a818151815260200191508051906020019060200280838360005b838110156106d75781810151838201526020016106bf565b50505050905001888103825289818151815260200191508051906020019060200280838360005b838110156107165781810151838201526020016106fe565b505050509050019e50505050505050505050505050505060405180910390f35b34801561074257600080fd5b506103636115cb565b34801561075757600080fd5b506103636115ef565b34801561076c57600080fd5b506102b56115fe565b34801561078157600080fd5b506107c4600480360360a081101561079857600080fd5b506001600160a01b0381358116916020810135909116906040810135906060810135906080013561168d565b6040805192835260208301919091528051918290030190f35b6107c4600480360360808110156107f357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356118aa565b34801561082557600080fd5b5061086e600480360360c081101561083c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135611a23565b6040805192835260ff90911660208301528051918290030190f35b34801561089557600080fd5b50610363611d8d565b3480156108aa57600080fd5b5061033a611d9c565b3480156108bf57600080fd5b50610363611dad565b3480156108d457600080fd5b506108fb600480360360208110156108eb57600080fd5b50356001600160a01b0316611dd1565b60408051918252519081900360200190f35b34801561091957600080fd5b50610363611de3565b34801561092e57600080fd5b506102b56004803603602081101561094557600080fd5b50356001600160a01b0316611e07565b34801561096157600080fd5b5061033a6004803603602081101561097857600080fd5b50356001600160a01b0316611e6e565b34801561099457600080fd5b506109d1600480360360808110156109ab57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611ed9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610a0d5781810151838201526020016109f5565b505050509050019250505060405180910390f35b348015610a2d57600080fd5b506108fb60048036036060811015610a4457600080fd5b506001600160a01b03813581169160208101359091169060400135612196565b348015610a7057600080fd5b506107c4600480360360c0811015610a8757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a001356122f9565b348015610ac557600080fd5b506108fb60048036036060811015610adc57600080fd5b506001600160a01b038135811691602081013590911690604001356123cc565b348015610b0857600080fd5b5061033a60048036036080811015610b1f57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561251f565b348015610b5157600080fd5b506107c4600480360360a0811015610b6857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356125d8565b348015610ba057600080fd5b5061033a60048036036040811015610bb757600080fd5b506001600160a01b03813516906020013561277a565b348015610bd957600080fd5b506108fb60048036036040811015610bf057600080fd5b506001600160a01b03813581169160200135166127e6565b348015610c1457600080fd5b506102b560048036036020811015610c2b57600080fd5b50356001600160a01b0316612905565b348015610c4757600080fd5b506102b560048036036040811015610c5e57600080fd5b506001600160a01b038135169060200135612953565b348015610c8057600080fd5b506108fb60048036036040811015610c9757600080fd5b506001600160a01b0381358116916020013516612a31565b610cdc817f0000000000000000000000000000000000000000000000000000000000000000600019612a4e565b50565b600060026001541415610d27576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b6002600155610d3885858585612ba1565b6001600160a01b0385166000908152600b6020526040902054610d5b90836130a1565b6001600160a01b038087166000818152600b60205260409020929092557f0000000000000000000000000000000000000000000000000000000000000000161415610e2d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610e0657600080fd5b505af1158015610e1a573d6000803e3d6000fd5b50505050610e2833836130e4565b610e38565b610e388533846131dc565b6004546001600160a01b031615610eba576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505050506040513d6020811015610eb757600080fd5b50505b506001808055949350505050565b6004546001600160a01b031681565b610edf611d9c565b610f1c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f55611d9c565b610f92576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b610fc082333084613328565b336000908152600c602090815260408083206001600160a01b0386168452909152902054610fee9082613484565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b905220546110259082613484565b6001600160a01b039092166000908152600b602052604090209190915550565b6005546001600160a01b031681565b61105c611d9c565b611099576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b606080606080606080606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058c8c6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d602081101561117057600080fd5b505190506001600160a01b038116156115bd576001600160a01b0381166000908152600a602052604090205480156115bb576000600982815481106111b157fe5b9060005260206000209060050201905060008b5190508067ffffffffffffffff811180156111de57600080fd5b50604051908082528060200260200182016040528015611208578160200160208202803683370190505b509a508067ffffffffffffffff8111801561122257600080fd5b5060405190808252806020026020018201604052801561124c578160200160208202803683370190505b5099508067ffffffffffffffff8111801561126657600080fd5b50604051908082528060200260200182016040528015611290578160200160208202803683370190505b5098508067ffffffffffffffff811180156112aa57600080fd5b506040519080825280602002602001820160405280156112d4578160200160208202803683370190505b5096508067ffffffffffffffff811180156112ee57600080fd5b50604051908082528060200260200182016040528015611318578160200160208202803683370190505b5095508067ffffffffffffffff8111801561133257600080fd5b5060405190808252806020026020018201604052801561135c578160200160208202803683370190505b5097508067ffffffffffffffff8111801561137657600080fd5b506040519080825280602002602001820160405280156113a0578160200160208202803683370190505b50945060005b818110156115b75760008d82815181106113bc57fe5b602090810291909101810151600081815260028088018452604091829020825160c08101845281546001600160a01b0390811680835260018401548216978301979097529282015490921692820192909252600382015460608201526004820154608082015260059091015460a08201528f5191935091908f908590811061144057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505080602001518d848151811061147157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508060a001518984815181106114a257fe5b60200260200101818152505080608001518c84815181106114bf57fe5b60200260200101818152505080606001518a84815181106114dc57fe5b602090810291909101810191909152600354908201516040808401518151625d2d6f60e21b81526001600160a01b03938416600482015290831660248201526044810186905281519290931692630174b5bc9260648083019392829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d604081101561157457600080fd5b5080516020909101518c518d908690811061158b57fe5b602002602001018a868151811061159e57fe5b60209081029190910101919091525250506001016113a6565b5050505b505b509397509397509397909450565b7f000000000000000000000000000000000000000000000000000000000000000081565b6006546001600160a01b031681565b611606611d9c565b611643576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a43905887f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b505190506001600160a01b0381166117ae576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a6020526040902054806117f4575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b6002600860008a6001600160a01b03166001600160a01b03168152602001908152602001600020600061184660016009868154811061182f57fe5b600091825260209091206005909102015490613484565b815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061189a89897f00000000000000000000000000000000000000000000000000000000000000008a8a8a6122f9565b909a909950975050505050505050565b600080600260015414156118f3576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166000908152600760205260409020543411611970576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119cb57600080fd5b505af11580156119df573d6000803e3d6000fd5b5050505050611a12867f0000000000000000000000000000000000000000000000000000000000000000878734886134cb565b600180559097909650945050505050565b60008082611a3657508490506000611d82565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505190506001600160a01b03811615611d80576001600160a01b0381166000908152600a60205260409020548015611d7e57600060098281548110611b2157fe5b906000526020600020906005020190508060030160008a8152602001908152602001600020546000148015611b6457506000898152600482016020526040902054155b15611b87576001600160a01b038b16600090815260018201602052604090205498505b8815611d7c57600089815260028083016020908152604092839020835160c08101855281546001600160a01b039081168252600183015481169382018490529382015484169481019490945260038101546060850152600481015460808501526005015460a0840152908d1614611c16576001600160a01b038c16600090815260018301602052604090205499505b8915611d7a5760008a8152600283016020526040902060040154611c3a9089613bec565b60008b8152600284016020526040902060050154611c59908b90613bec565b11611cfe5760008a815260038301602052604090205480611c85578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611ca3908a613bec565b6000828152600285016020526040902060050154611cc2908c90613bec565b11611ced57611cdf8d8d838d8d611cda8e60016130a1565b611a23565b965096505050505050611d82565b8a6001965096505050505050611d82565b60008a815260048301602052604090205480611d25578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611d43908a613bec565b6000828152600285016020526040902060050154611d62908c90613bec565b10611ced57611cdf8d8d838d8d611cda8e60016130a1565b505b505b505b505b965096945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b7f000000000000000000000000000000000000000000000000000000000000000081565b600b6020526000908152604090205481565b7f000000000000000000000000000000000000000000000000000000000000000081565b611e0f611d9c565b611e4c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611e78611d9c565b611eb5576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b50600380546001600160a01b0319166001600160a01b03831617905560015b919050565b606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611f5b57600080fd5b505afa158015611f6f573d6000803e3d6000fd5b505050506040513d6020811015611f8557600080fd5b505190506001600160a01b0381161561218d576001600160a01b0381166000908152600a6020526040902054801561218b57600060098281548110611fc657fe5b906000526020600020906005020190508060030160008781526020019081526020016000205460001415612072576001600160a01b0388166000908152600182016020908152604080832054898452600485019092529091205415158061202c57508087145b1561206c576040805160018082528183019092529060208083019080368337019050509450868560008151811061205f57fe5b6020026020010181815250505b50612189565b604080516001808252818301909252906020808301908036833701905050935085846000815181106120a057fe5b602002602001018181525050846001146121895760006120e9826003016000876000815181106120cc57fe5b602002602001015181526020019081526020016000205486613c41565b80519091506000600384018184600019850185811061210457fe5b602002602001015181526020019081526020016000205490505b60008111801561212d57508782105b156121835761213c8184613c41565b9250825182141561214c57612183565b8251915060038401600084600019850185811061216557fe5b6020026020010151815260200190815260200160002054905061211e565b50909450505b505b505b50949350505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561221757600080fd5b505afa15801561222b573d6000803e3d6000fd5b505050506040513d602081101561224157600080fd5b505190506001600160a01b038116156122f1576001600160a01b0381166000908152600a602052604090205480156122ef57856001600160a01b03166009828154811061228a57fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106122c957fe5b906000526020600020906005020160030160008581526020019081526020016000205492505b505b509392505050565b60008060026001541415612342576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b038716600090815260076020526040902054841161239f576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b6123ab87333087613328565b6123b98888888888886134cb565b6001805590999098509650505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561244d57600080fd5b505afa158015612461573d6000803e3d6000fd5b505050506040513d602081101561247757600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080156122ef57856001600160a01b0316600982815481106124b257fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106124f157fe5b9060005260206000209060050201600401600085815260200190815260200160002054925050509392505050565b600060026001541415612567576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b600260015561257885858585612ba1565b336000908152600c602090815260408083206001600160a01b03891684529091529020546125a69083613484565b336000908152600c602090815260408083206001600160a01b038a168452909152902055506001808055949350505050565b60008060026001541415612621576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556006546001600160a01b0316331461263d57600080fd5b336000908152600c602090815260408083206001600160a01b038b1684529091529020548411156126ac576040805162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742042616c616e636560601b604482015290519081900360640190fd5b6001600160a01b038716600090815260076020526040902054841015612705576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b038b16845290915290205461273390856130a1565b336000818152600c602090815260408083206001600160a01b038d1684529091529020919091556127689088888888886134cb565b60018055909890975095505050505050565b6000612784611d9c565b6127c1576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b506001600160a01b038216600090815260076020526040902081905560015b92915050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561286757600080fd5b505afa15801561287b573d6000803e3d6000fd5b505050506040513d602081101561289157600080fd5b505190506001600160a01b038116156128fe576001600160a01b0381166000908152600a602052604090205480156128fc57600981815481106128d057fe5b600091825260208083206001600160a01b03891684526001600590930201919091019052604090205492505b505b5092915050565b61290d611d9c565b61294a576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b610cdc81613cf9565b336000908152600c602090815260408083206001600160a01b03861684529091529020548111156129c1576040805162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10273ab6b132b960691b604482015290519081900360640190fd5b6129cc8233836131dc565b336000908152600c602090815260408083206001600160a01b03861684529091529020546129fa90826130a1565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b9052205461102590826130a1565b600c60209081526000928352604080842090915290825290205481565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1781529251825160009485949389169392918291908083835b60208310612aca5780518252601f199092019160209182019101612aab565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612b2c576040519150601f19603f3d011682016040523d82523d6000602084013e612b31565b606091505b5091509150818015612b5f575080511580612b5f5750808060200190516020811015612b5c57600080fd5b50515b612b9a5760405162461bcd60e51b815260040180806020018281038252602f815260200180615b5d602f913960400191505060405180910390fd5b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080612cb1576040805162461bcd60e51b81526020600482015260136024820152721d1bdad95b94185a5c881b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060098281548110612cc057fe5b60009182526020808320888452600260059093020191820190526040909120549091506001600160a01b03163314612d2f576040805162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21036b0b5b2b960991b604482015290519081900360640190fd5b84612d73576040805162461bcd60e51b815260206004820152600f60248201526e1bdc99195c881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b600085815260028201602052604090206003015484811015612ddc576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e742052656d61696e4e756d62657200000000000000604482015290519081900360640190fd5b84811415612f65576001600160a01b0388166000908152600183016020526040902054861415612e4d576000868152600383016020818152604080842080546001600160a01b038e168652600188018452828620819055855260048701835290842084905589845291905255612f60565b600086815260048301602052604090205480612e9e576040805162461bcd60e51b815260206004820152600b60248201526a0dcde40e0e4ca92dcc8caf60ab1b604482015290519081900360640190fd5b60008781526002840160205260409020600101546001600160a01b038a8116911614612f09576040805162461bcd60e51b815260206004820152601560248201527434b73b30b634b210333937b6aa37b5b2b720b2323960591b604482015290519081900360640190fd5b60008781526003840160205260408082205483835291208190558015612f3d57600081815260048501602052604090208290555b505060008681526004830160209081526040808320839055600385019091528120555b612f84565b612f6f81866130a1565b60008781526002840160205260409020600301555b600080612f918a8a613da3565b60035460408051636128bde760e01b81526001600160a01b038f811660048301528e811660248301528b81166044830152606482018690526084820185905291519496509294501691636128bde79160a48082019260009290919082900301818387803b15801561300157600080fd5b505af1158015613015573d6000803e3d6000fd5b505060035460408051636430f85b60e11b81526001600160a01b038f811660048301528e81166024830152604482018e9052606482018d9052915191909216935063c861f0b69250608480830192600092919082900301818387803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050505050505050505050505050565b6000828211156130de576040805162461bcd60e51b815260206004820152600360248201526239bab160e91b604482015290519081900360640190fd5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106131305780518252601f199092019160209182019101613111565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613192576040519150601f19603f3d011682016040523d82523d6000602084013e613197565b606091505b50509050806131d75760405162461bcd60e51b8152600401808060200182810382526034815260200180615bac6034913960400191505060405180910390fd5b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b602083106132585780518252601f199092019160209182019101613239565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132ba576040519150601f19603f3d011682016040523d82523d6000602084013e6132bf565b606091505b50915091508180156132ed5750805115806132ed57508080602001905160208110156132ea57600080fd5b50515b612b9a5760405162461bcd60e51b8152600401808060200182810382526030815260200180615be06030913960400191505060405180910390fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106133ac5780518252601f19909201916020918201910161338d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461340e576040519150601f19603f3d011682016040523d82523d6000602084013e613413565b606091505b5091509150818015613441575080511580613441575080806020019051602081101561343e57600080fd5b50515b61347c5760405162461bcd60e51b8152600401808060200182810382526035815260200180615c106035913960400191505060405180910390fd5b505050505050565b6000828201838110156134c4576040805162461bcd60e51b815260206004820152600360248201526218591960ea1b604482015290519081900360640190fd5b9392505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390589896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b505190506001600160a01b0381166135cc576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a602052604090205480613612575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b60006009828154811061362157fe5b906000526020600020906005020190506136496001826000015461348490919063ffffffff16565b8082556001600160a01b038b16600090815260018301602052604090205490945080156136ed578861367d578098506136e0565b60008981526003830160205260409020541580156136a957506000898152600483016020526040902054155b156136b6578098506136e0565b60008981526002830160205260409020600101546001600160a01b038c81169116146136e0578098505b6136ed8986848b8b613f19565b60035460408051633503a93d60e21b81526001600160a01b038f811660048301528e811660248301528d81166044830152606482018c9052608482018b905260a482018990529151919092169163d40ea4f49160c480830192600092919082900301818387803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b5050505060006040518060c001604052808e6001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018a81526020018a81526020018981525090508083600201600088815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015590505060008061388f8e8e613da3565b60008a81526004880160205260409020549193509150613a7f576020808401516001600160a01b0316600090815260018701909152604090208890556138d88589858585614109565b6000888152600286016020526040902060030154985088613953576000888152600386016020908152604080832054868301516001600160a01b0316845260018901909252909120819055801561394d5760008981526003870160209081526040808320839055838352600489019091528120555b5061399a565b6020808401516001600160a01b03166000908152600b909152604090205461397b908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60008e6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d6020811015613a1357600080fd5b50516020858101516001600160a01b03166000908152600b9091526040902054909150811115613a79576020808501516002546001600160a01b038083166000908152600b909452604090932054613a799390911690613a749085906130a1565b6131dc565b50613ac9565b6020808401516001600160a01b03166000908152600b90915260409020548b9950613aaa908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60035460208401516040808601518151636128bde760e01b81526001600160a01b03938416600482015290831660248201528a83166044820152606481018690526084810185905290519190921691636128bde79160a480830192600092919082900301818387803b158015613b3e57600080fd5b505af1158015613b52573d6000803e3d6000fd5b50506004546001600160a01b0316159150613bda9050576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015613bad57600080fd5b505af1158015613bc1573d6000803e3d6000fd5b505050506040513d6020811015613bd757600080fd5b50505b50505050505050965096945050505050565b600082613bfb575060006127e0565b82820282848281613c0857fe5b04146134c4576040805162461bcd60e51b81526020600482015260036024820152621b5d5b60ea1b604482015290519081900360640190fd5b606082613c4f5750806127e0565b815160006001820167ffffffffffffffff81118015613c6d57600080fd5b50604051908082528060200260200182016040528015613c97578160200160208202803683370190505b50905060005b82811015613cd857848181518110613cb157fe5b6020026020010151828281518110613cc557fe5b6020908102919091010152600101613c9d565b5084818381518110613ce657fe5b6020908102919091010152949350505050565b6001600160a01b038116613d48576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000613db2858561595f565b5090506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390588886040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015613e3657600080fd5b505afa158015613e4a573d6000803e3d6000fd5b505050506040513d6020811015613e6057600080fd5b505160408051630240bc6b60e21b815290516001600160a01b0390921691630902f1ac91600480820192606092909190829003018186803b158015613ea457600080fd5b505afa158015613eb8573d6000803e3d6000fd5b505050506040513d6060811015613ece57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b0387811690841614613f08578082613f0b565b81815b909890975095505050505050565b6000858152600284016020526040902060040154613f379082613bec565b6000868152600285016020526040902060050154613f56908490613bec565b1161403357600085815260038401602052604090205480613f9b576000868152600385016020908152604080832088905587835260048701909152902086905561402d565b6000818152600285016020526040902060040154613fb99083613bec565b6000828152600286016020526040902060050154613fd8908590613bec565b11613fef57613fea8186868686613f19565b61402d565b600085815260048501602081815260408084208a9055898452600388018083528185208a905585855292825280842089905588845291905290208190555b50612b9a565b600085815260048401602052604090205480614073576000868152600485016020908152604080832088905587835260038701909152902086905561347c565b60008181526002850160205260409020600401546140919083613bec565b60008281526002860160205260409020600501546140b0908590613bec565b106140c7576140c28186868686613f19565b61347c565b600085815260038501602081815260408084208a9055988352600490960180875288832088905583835290865287822087905595815294909352505091902055565b60a08301516141189083613bec565b60808401516141279083613bec565b1115614f8557600061414384608001518560a001518585615990565b90508360800151811115614158575060808301515b6040805160608101825260008082526020808301829052878401516001600160a01b0316825260018a0190528290205491810182905290156148ea576000876002016000836002600381106141a957fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528901519193506142299190613bec565b6080808301519089015161423c91613bec565b106148e757600061425e8260a001518960a00151613bec90919063ffffffff16565b608080840151908a015161427191613bec565b141561427e575083614295565b6142928260a0015183608001518989615990565b90505b8085106148e55760808801516000906142ae90836130a1565b90505b6040850151158015906142c45750600081115b156148e35760006142d484615a42565b905060006142f06103e86142ea846103e5613bec565b90615a73565b90508183106146c1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685604001516001600160a01b031614801561436857506020858101516001600160a01b031660009081526008825260408082208a8201518352909252205460ff166002145b156143fe577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505050506143f98560000151826130e4565b614411565b61441185604001518660000151836131dc565b614424828860005b602002015190613484565b8752606085015161443790886001614419565b602080890191909152600060038881018290555491870151604080890151818c015160608b015183516342dc858d60e01b81526001600160a01b03958616600482015292851660248401526044830191909152606482018790526084820152905191909316926342dc858d9260a480830193919282900301818387803b1580156144c057600080fd5b505af11580156144d4573d6000803e3d6000fd5b5060009250505060038e01818960026020020151815260200190815260200160002054905060008e60030160008a60026003811061450e57fe5b6020020151815260200190815260200160002081905550808860026003811061453357fe5b602002015287600260200201518e60010160008e604001516001600160a01b03166001600160a01b03168152602001908152602001600020819055508760026003811061457c57fe5b6020020151156146bb57600060048f01818a600260200201518152602001908152602001600020819055508d6002016000896002600381106145ba57fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528f015191995091975061463c91613bec565b608080880151908e015161464f91613bec565b106146b6576146688660a0015187608001518d8d615990565b885190955060009061467b908790613484565b9050858a101580156146905750808d60800151115b156146ab5760808d01516146a490826130a1565b94506146b0565b600094505b506146bb565b600093505b506148dc565b60006146d56103e86142ea866103e5613bec565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686604001516001600160a01b031614801561474657506020868101516001600160a01b031660009081526008825260408082208b8201518352909252205460ff166002145b156147dc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147b157600080fd5b505af11580156147c5573d6000803e3d6000fd5b505050506147d78660000151826130e4565b6147ef565b6147ef86604001518760000151836131dc565b6147fb84896000614419565b885260a0860151608087015160009190614816908490613bec565b8161481d57fe5b04905061482c818a6001614419565b60208a0152606087015161484090826130a1565b6003898101919091555460208801516040808a01518c82015182516342dc858d60e01b81526001600160a01b039485166004820152918416602483015260448201526064810186905260848101859052905191909216916342dc858d9160a480830192600092919082900301818387803b1580156148bd57600080fd5b505af11580156148d1573d6000803e3d6000fd5b505050506000945050505b50506142b1565b505b505b50505b600061490282825b60200201516080880151906130a1565b90508083101561490f5750815b8015614c8a5761492181836000614419565b8252602086015160408701518686600061493d836103e8613bec565b905060006149586103e56149528560016130a1565b90613bec565b90506000614971600283858161496a57fe5b0490613484565b9050808810614c82576000614987898787615ac3565b9050614995818b6001614419565b60208b8101919091526040805163e6a4390560e01b81526001600160a01b038b811660048301528a8116602483015291516000937f00000000000000000000000000000000000000000000000000000000000000009093169263e6a439059260448082019391829003018186803b158015614a0f57600080fd5b505afa158015614a23573d6000803e3d6000fd5b505050506040513d6020811015614a3957600080fd5b50519050614a4889828c6131dc565b6000614a548a8a61595f565b509050806001600160a01b03168a6001600160a01b03161415614b5b57604080516000808252602082019283905263022c0d9f60e01b835260248201818152604483018790523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b9590939092909160c48501918083838b5b83811015614aef578181015183820152602001614ad7565b50505050905090810190601f168015614b1c5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614b3e57600080fd5b505af1158015614b52573d6000803e3d6000fd5b50505050614c42565b604080516000808252602082019283905263022c0d9f60e01b835260248201868152604483018290523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b969590939092909160c48501918083838a5b83811015614bda578181015183820152602001614bc2565b50505050905090810190601f168015614c075780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b6001600160a01b0389166000908152600b6020526040902054614c659084613484565b6001600160a01b038a166000908152600b60205260409020555050505b505050505050505b815115614f7d57602082015115614eba577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686604001516001600160a01b0316148015614d0757506020868101516001600160a01b031660009081526008825260408082208a8352909252205460ff166002145b15614dab576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015614d7957600080fd5b505af1158015614d8d573d6000803e3d6000fd5b50508751614da6925090508360015b60200201516130e4565b614dc5565b60408601518651614dc591908460015b60200201516131dc565b6005546001600160a01b031615614e725760055486516020808901516040808b015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b158015614e4557600080fd5b505af1158015614e59573d6000803e3d6000fd5b505050506040513d6020811015614e6f57600080fd5b50505b6020808301516040808901516001600160a01b03166000908152600b90935290912054614e9e916130a1565b6040808801516001600160a01b03166000908152600b60205220555b600354600088815260028a810160209081526040808420600181015493015491870151875182516342dc858d60e01b81526001600160a01b0395861660048201529385166024850152604484018e9052606484019190915260848301525191909316926342dc858d9260a480830193919282900301818387803b158015614f4057600080fd5b505af1158015614f54573d6000803e3d6000fd5b50505050614f68826000600381106148f257fe5b600088815260028a0160205260409020600301555b505050612b9a565b6040805160608101825260008082526020808301829052868401516001600160a01b03168252600189019052829020549181019190915260808401515b604082015115801590614fd457508015155b1561567057600087600201600084600260038110614fee57fe5b60200201518152602001908152602001600020905061501e81600501548760a00151613bec90919063ffffffff16565b6004820154608088015161503191613bec565b1415615664576150428360006148f2565b6040805160c08101825283546001600160a01b039081168252600185015481166020830152600285015416918101919091526003830154606082015260048301546080820152600583015460a08201529092506000906150a190615a42565b90508083106153925760006150be6103e86142ea846103e5613bec565b60028401549091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116911614801561512e575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156151cc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561519957600080fd5b505af11580156151ad573d6000803e3d6000fd5b505084546151c792506001600160a01b03169050826130e4565b6151ea565b600283015483546151ea916001600160a01b039081169116836131dc565b6151f682866000614419565b8552600383015461520990866001614419565b602086810191909152600354604080880151600090815260028e810194859052918120600101546001600160a01b03938416946342dc858d94909116929091908a9060209081029190910151825281019190915260409081016000908120600201548a83015160038a015484516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590921660248601526044850152606484018790526084840152905160a48084019382900301818387803b1580156152ce57600080fd5b505af11580156152e2573d6000803e3d6000fd5b50505050604085810151600090815260038c016020908152828220548b8401516001600160a01b0316835260018e01909152919020819055801561534857604080870151600090815260038d01602090815282822082905583825260048e019052908120555b60008b60020160008860026003811061535d57fe5b6020020151815260200190815260200160002060030181905550808660026003811061538557fe5b60200201525061565e9050565b60006153a66103e86142ea866103e5613bec565b60028401549091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015615416575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156154b4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561548157600080fd5b505af1158015615495573d6000803e3d6000fd5b505084546154af92506001600160a01b03169050826130e4565b6154d2565b600283015483546154d2916001600160a01b039081169116836131dc565b6080880151855260058301546004840154600091906154f2908490613bec565b816154f957fe5b04905061550881876001614419565b6020870152600384015461551c90826130a1565b8b60020160008860026003811061552f57fe5b6020020151815260200190815260200160002060030181905550600360009054906101000a90046001600160a01b03166001600160a01b03166342dc858d8c60020160008960026003811061558057fe5b6020020151815260200190815260200160002060010160009054906101000a90046001600160a01b03168d60020160008a6002600381106155bd57fe5b60209081029190910151825281019190915260409081016000908120600201548b83015183516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909116602485015260448401526064830187905260848301869052905160a48084019382900301818387803b15801561563d57600080fd5b505af1158015615651573d6000803e3d6000fd5b5050505050505050615670565b5061566a565b50615670565b50614fc2565b815115615956577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685604001516001600160a01b03161480156156e357506020858101516001600160a01b03166000908152600882526040808220898352909252205460ff166002145b15615781576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561575557600080fd5b505af1158015615769573d6000803e3d6000fd5b5050865161577c92509050836001614d9c565b615795565b604085015185516157959190846001614dbb565b6005546001600160a01b0316156158425760055485516020808801516040808a015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b15801561581557600080fd5b505af1158015615829573d6000803e3d6000fd5b505050506040513d602081101561583f57600080fd5b50505b6020808301516040808801516001600160a01b03166000908152600b9093529091205461586e916130a1565b6040868101516001600160a01b039081166000908152600b6020908152838220949094556003548a825260028c81018652848320600181015491015495880151885186516342dc858d60e01b815292861660048401529685166024830152604482018d905260648201526084810195909552925192909116926342dc858d9260a4808301939282900301818387803b15801561590957600080fd5b505af115801561591d573d6000803e3d6000fd5b505050506159418260006003811061593157fe5b60200201516080870151906130a1565b60008781526002890160205260409020600301555b50505050505050565b600080826001600160a01b0316846001600160a01b031610615982578284615985565b83835b909590945092505050565b600080846103e56159a96103e86149528a818a8a613bec565b816159b057fe5b04816159b857fe5b049050600063ec477c746159d261230d6149528880613bec565b816159d957fe5b04905060006159f06159eb8484613484565b615b0b565b905060006107ca615a03886107cd613bec565b81615a0a57fe5b04905080821115615a3157615a2a6001615a2484846130a1565b90613484565b9450615a36565b600094505b50505050949350505050565b60006127e06103e56142ea6103e861495286608001516142ea88606001518960a00151613bec90919063ffffffff16565b6000808211615aaf576040805162461bcd60e51b81526020600482015260036024820152623234bb60e91b604482015290519081900360640190fd5b6000828481615aba57fe5b04949350505050565b600080615ad2856103e5613bec565b90506000615ae08285613bec565b90506000615af483615a24886103e8613bec565b9050808281615aff57fe5b04979650505050505050565b60006003821115615b4e575080600160028204015b81811015615b4857809150600281828581615b3757fe5b040181615b4057fe5b049050615b20565b50611ed4565b8115611ed45750600191905056fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b20415050524f56455f4641494c45445265656e7472616e637947756172643a207265656e7472616e742063616c6c005472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220897532e588292b1fee078ed1f909ed34dfe9d24c1a3fbf6b86c72e1045574e7064736f6c63430007060033608060405234801561001057600080fd5b50604051610ad1380380610ad18339818101604052602081101561003357600080fd5b50516001600081815581546001600160a01b0319163317918290556040516001600160a01b039290921691600080516020610ab1833981519152908290a361007a81610080565b50610119565b6001600160a01b0381166100cf576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b6001546040516001600160a01b03808416921690600080516020610ab183398151915290600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b610989806101286000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638f32d59b1161005b5780638f32d59b14610190578063a96d222714610198578063cb7cce16146101a0578063f2fde38b146101c65761007d565b80635e86973014610082578063715018a6146101625780638da5cb5b1461016c575b600080fd5b61014e600480360360a081101561009857600080fd5b6001600160a01b0382358116926020810135821692604082013592606083013516919081019060a0810160808201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506101ec945050505050565b604080519115158252519081900360200190f35b61016a6105a1565b005b610174610630565b604080516001600160a01b039092168252519081900360200190f35b61014e61063f565b610174610650565b61016a600480360360208110156101b657600080fd5b50356001600160a01b031661065f565b61016a600480360360208110156101dc57600080fd5b50356001600160a01b03166106c6565b600060026000541415610246576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000819055506000856001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561029d57600080fd5b505afa1580156102b1573d6000803e3d6000fd5b505050506040513d60208110156102c757600080fd5b5051905084811015610317576040805162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015290519081900360640190fd5b61032386888688610717565b600080856001600160a01b0316856040518082805190602001908083835b602083106103605780518252601f199092019160209182019101610341565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103c2576040519150601f19603f3d011682016040523d82523d6000602084013e6103c7565b606091505b50915091508180156103f55750805115806103f557508080602001905160208110156103f257600080fd5b50515b610434576040805162461bcd60e51b815260206004820152600b60248201526a1b1bd85b8819985a5b195960aa1b604482015290519081900360640190fd5b600254604080516396fb721760e01b81526001600160a01b038c8116600483015260248201879052915191909216916396fb72179160448083019260209291908290030181600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050506040513d60208110156104b457600080fd5b50516104bf57600080fd5b82886001600160a01b03166370a082318b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561050d57600080fd5b505afa158015610521573d6000803e3d6000fd5b505050506040513d602081101561053757600080fd5b5051101561058c576040805162461bcd60e51b815260206004820152601960248201527f6572726f722062616c616e63653a6c6f616e206661696c656400000000000000604482015290519081900360640190fd5b60019350505050600160005595945050505050565b6105a961063f565b6105e6576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6001546001600160a01b031690565b6001546001600160a01b0316331490565b6002546001600160a01b031681565b61066761063f565b6106a4576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6106ce61063f565b61070b576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b61071481610873565b50565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b6020831061079b5780518252601f19909201916020918201910161077c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146107fd576040519150601f19603f3d011682016040523d82523d6000602084013e610802565b606091505b5091509150818015610830575080511580610830575080806020019051602081101561082d57600080fd5b50515b61086b5760405162461bcd60e51b815260040180806020018281038252603581526020018061091f6035913960400191505060405180910390fd5b505050505050565b6001600160a01b0381166108c2576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b039290921691909117905556fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220f34f03197cd6cdbdac3da9f2bf4749659ea5baee38066392730d9a572c198e3764736f6c634300070600338be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e00000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2
Deployed Bytecode
0x6080604052600436106101fd5760003560e01c80638f32d59b1161010d578063d40ea4f4116100a0578063e91b3f321161006f578063e91b3f3214610b94578063ed57fb2814610bcd578063f2fde38b14610c08578063f3fef3a314610c3b578063f55f918d14610c74576102b7565b8063d40ea4f414610a64578063d58960cf14610ab9578063e0ada45e14610afc578063e2a9bed114610b45576102b7565b8063b2855b4f116100dc578063b2855b4f14610922578063bf653f9314610955578063c2ffcaad14610988578063c621c9e114610a21576102b7565b80638f32d59b1461089e5780639ad5981e146108b3578063a8f9cb0e146108c8578063ad5c46481461090d576102b7565b80634f88718311610190578063715018a61161015f578063715018a6146107605780637170cba51461077557806371e43506146107dd5780638cd0cb10146108195780638da5cb5b14610889576102b7565b80634f8871831461044857806350c84f6b1461047b57806359d0f713146107365780636c37a7591461074b576102b7565b806339e7fddc116101cc57806339e7fddc146103b2578063441e24b9146103c757806347e7ef24146103fa5780634e5eda1114610433576102b7565b8063021be644146102be5780630f825ee2146102f15780631108749d1461034e57806317c1116a1461037f576102b7565b366102b75760003411801561023b5750336001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12701614155b156102b5577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561029b57600080fd5b505af11580156102af573d6000803e3d6000fd5b50505050505b005b6060516080f35b3480156102ca57600080fd5b506102b5600480360360208110156102e157600080fd5b50356001600160a01b0316610caf565b3480156102fd57600080fd5b5061033a6004803603608081101561031457600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610cdf565b604080519115158252519081900360200190f35b34801561035a57600080fd5b50610363610ec8565b604080516001600160a01b039092168252519081900360200190f35b34801561038b57600080fd5b506102b5600480360360208110156103a257600080fd5b50356001600160a01b0316610ed7565b3480156103be57600080fd5b50610363610f3e565b3480156103d357600080fd5b506102b5600480360360208110156103ea57600080fd5b50356001600160a01b0316610f4d565b34801561040657600080fd5b506102b56004803603604081101561041d57600080fd5b506001600160a01b038135169060200135610fb4565b34801561043f57600080fd5b50610363611045565b34801561045457600080fd5b506102b56004803603602081101561046b57600080fd5b50356001600160a01b0316611054565b34801561048757600080fd5b506105446004803603606081101561049e57600080fd5b6001600160a01b0382358116926020810135909116918101906060810160408201356401000000008111156104d257600080fd5b8201836020820111156104e457600080fd5b8035906020019184602083028401116401000000008311171561050657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506110bb945050505050565b604051808060200180602001806020018060200180602001806020018060200188810388528f818151815260200191508051906020019060200280838360005b8381101561059c578181015183820152602001610584565b5050505090500188810387528e818151815260200191508051906020019060200280838360005b838110156105db5781810151838201526020016105c3565b5050505090500188810386528d818151815260200191508051906020019060200280838360005b8381101561061a578181015183820152602001610602565b5050505090500188810385528c818151815260200191508051906020019060200280838360005b83811015610659578181015183820152602001610641565b5050505090500188810384528b818151815260200191508051906020019060200280838360005b83811015610698578181015183820152602001610680565b5050505090500188810383528a818151815260200191508051906020019060200280838360005b838110156106d75781810151838201526020016106bf565b50505050905001888103825289818151815260200191508051906020019060200280838360005b838110156107165781810151838201526020016106fe565b505050509050019e50505050505050505050505050505060405180910390f35b34801561074257600080fd5b506103636115cb565b34801561075757600080fd5b506103636115ef565b34801561076c57600080fd5b506102b56115fe565b34801561078157600080fd5b506107c4600480360360a081101561079857600080fd5b506001600160a01b0381358116916020810135909116906040810135906060810135906080013561168d565b6040805192835260208301919091528051918290030190f35b6107c4600480360360808110156107f357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356118aa565b34801561082557600080fd5b5061086e600480360360c081101561083c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135611a23565b6040805192835260ff90911660208301528051918290030190f35b34801561089557600080fd5b50610363611d8d565b3480156108aa57600080fd5b5061033a611d9c565b3480156108bf57600080fd5b50610363611dad565b3480156108d457600080fd5b506108fb600480360360208110156108eb57600080fd5b50356001600160a01b0316611dd1565b60408051918252519081900360200190f35b34801561091957600080fd5b50610363611de3565b34801561092e57600080fd5b506102b56004803603602081101561094557600080fd5b50356001600160a01b0316611e07565b34801561096157600080fd5b5061033a6004803603602081101561097857600080fd5b50356001600160a01b0316611e6e565b34801561099457600080fd5b506109d1600480360360808110156109ab57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611ed9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610a0d5781810151838201526020016109f5565b505050509050019250505060405180910390f35b348015610a2d57600080fd5b506108fb60048036036060811015610a4457600080fd5b506001600160a01b03813581169160208101359091169060400135612196565b348015610a7057600080fd5b506107c4600480360360c0811015610a8757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a001356122f9565b348015610ac557600080fd5b506108fb60048036036060811015610adc57600080fd5b506001600160a01b038135811691602081013590911690604001356123cc565b348015610b0857600080fd5b5061033a60048036036080811015610b1f57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561251f565b348015610b5157600080fd5b506107c4600480360360a0811015610b6857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356125d8565b348015610ba057600080fd5b5061033a60048036036040811015610bb757600080fd5b506001600160a01b03813516906020013561277a565b348015610bd957600080fd5b506108fb60048036036040811015610bf057600080fd5b506001600160a01b03813581169160200135166127e6565b348015610c1457600080fd5b506102b560048036036020811015610c2b57600080fd5b50356001600160a01b0316612905565b348015610c4757600080fd5b506102b560048036036040811015610c5e57600080fd5b506001600160a01b038135169060200135612953565b348015610c8057600080fd5b506108fb60048036036040811015610c9757600080fd5b506001600160a01b0381358116916020013516612a31565b610cdc817f0000000000000000000000000c41fd2585a0c158b9d760a8e400c55db56971e4600019612a4e565b50565b600060026001541415610d27576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b6002600155610d3885858585612ba1565b6001600160a01b0385166000908152600b6020526040902054610d5b90836130a1565b6001600160a01b038087166000818152600b60205260409020929092557f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270161415610e2d577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610e0657600080fd5b505af1158015610e1a573d6000803e3d6000fd5b50505050610e2833836130e4565b610e38565b610e388533846131dc565b6004546001600160a01b031615610eba576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505050506040513d6020811015610eb757600080fd5b50505b506001808055949350505050565b6004546001600160a01b031681565b610edf611d9c565b610f1c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f55611d9c565b610f92576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b610fc082333084613328565b336000908152600c602090815260408083206001600160a01b0386168452909152902054610fee9082613484565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b905220546110259082613484565b6001600160a01b039092166000908152600b602052604090209190915550565b6005546001600160a01b031681565b61105c611d9c565b611099576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b606080606080606080606060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a439058c8c6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d602081101561117057600080fd5b505190506001600160a01b038116156115bd576001600160a01b0381166000908152600a602052604090205480156115bb576000600982815481106111b157fe5b9060005260206000209060050201905060008b5190508067ffffffffffffffff811180156111de57600080fd5b50604051908082528060200260200182016040528015611208578160200160208202803683370190505b509a508067ffffffffffffffff8111801561122257600080fd5b5060405190808252806020026020018201604052801561124c578160200160208202803683370190505b5099508067ffffffffffffffff8111801561126657600080fd5b50604051908082528060200260200182016040528015611290578160200160208202803683370190505b5098508067ffffffffffffffff811180156112aa57600080fd5b506040519080825280602002602001820160405280156112d4578160200160208202803683370190505b5096508067ffffffffffffffff811180156112ee57600080fd5b50604051908082528060200260200182016040528015611318578160200160208202803683370190505b5095508067ffffffffffffffff8111801561133257600080fd5b5060405190808252806020026020018201604052801561135c578160200160208202803683370190505b5097508067ffffffffffffffff8111801561137657600080fd5b506040519080825280602002602001820160405280156113a0578160200160208202803683370190505b50945060005b818110156115b75760008d82815181106113bc57fe5b602090810291909101810151600081815260028088018452604091829020825160c08101845281546001600160a01b0390811680835260018401548216978301979097529282015490921692820192909252600382015460608201526004820154608082015260059091015460a08201528f5191935091908f908590811061144057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505080602001518d848151811061147157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508060a001518984815181106114a257fe5b60200260200101818152505080608001518c84815181106114bf57fe5b60200260200101818152505080606001518a84815181106114dc57fe5b602090810291909101810191909152600354908201516040808401518151625d2d6f60e21b81526001600160a01b03938416600482015290831660248201526044810186905281519290931692630174b5bc9260648083019392829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d604081101561157457600080fd5b5080516020909101518c518d908690811061158b57fe5b602002602001018a868151811061159e57fe5b60209081029190910101919091525250506001016113a6565b5050505b505b509397509397509397909450565b7f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b281565b6006546001600160a01b031681565b611606611d9c565b611643576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a43905887f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b505190506001600160a01b0381166117ae576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a6020526040902054806117f4575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b6002600860008a6001600160a01b03166001600160a01b03168152602001908152602001600020600061184660016009868154811061182f57fe5b600091825260209091206005909102015490613484565b815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061189a89897f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12708a8a8a6122f9565b909a909950975050505050505050565b600080600260015414156118f3576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270166000908152600760205260409020543411611970576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119cb57600080fd5b505af11580156119df573d6000803e3d6000fd5b5050505050611a12867f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270878734886134cb565b600180559097909650945050505050565b60008082611a3657508490506000611d82565b60007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505190506001600160a01b03811615611d80576001600160a01b0381166000908152600a60205260409020548015611d7e57600060098281548110611b2157fe5b906000526020600020906005020190508060030160008a8152602001908152602001600020546000148015611b6457506000898152600482016020526040902054155b15611b87576001600160a01b038b16600090815260018201602052604090205498505b8815611d7c57600089815260028083016020908152604092839020835160c08101855281546001600160a01b039081168252600183015481169382018490529382015484169481019490945260038101546060850152600481015460808501526005015460a0840152908d1614611c16576001600160a01b038c16600090815260018301602052604090205499505b8915611d7a5760008a8152600283016020526040902060040154611c3a9089613bec565b60008b8152600284016020526040902060050154611c59908b90613bec565b11611cfe5760008a815260038301602052604090205480611c85578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611ca3908a613bec565b6000828152600285016020526040902060050154611cc2908c90613bec565b11611ced57611cdf8d8d838d8d611cda8e60016130a1565b611a23565b965096505050505050611d82565b8a6001965096505050505050611d82565b60008a815260048301602052604090205480611d25578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611d43908a613bec565b6000828152600285016020526040902060050154611d62908c90613bec565b10611ced57611cdf8d8d838d8d611cda8e60016130a1565b505b505b505b505b965096945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b7f0000000000000000000000000c41fd2585a0c158b9d760a8e400c55db56971e481565b600b6020526000908152604090205481565b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127081565b611e0f611d9c565b611e4c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611e78611d9c565b611eb5576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b50600380546001600160a01b0319166001600160a01b03831617905560015b919050565b606060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611f5b57600080fd5b505afa158015611f6f573d6000803e3d6000fd5b505050506040513d6020811015611f8557600080fd5b505190506001600160a01b0381161561218d576001600160a01b0381166000908152600a6020526040902054801561218b57600060098281548110611fc657fe5b906000526020600020906005020190508060030160008781526020019081526020016000205460001415612072576001600160a01b0388166000908152600182016020908152604080832054898452600485019092529091205415158061202c57508087145b1561206c576040805160018082528183019092529060208083019080368337019050509450868560008151811061205f57fe5b6020026020010181815250505b50612189565b604080516001808252818301909252906020808301908036833701905050935085846000815181106120a057fe5b602002602001018181525050846001146121895760006120e9826003016000876000815181106120cc57fe5b602002602001015181526020019081526020016000205486613c41565b80519091506000600384018184600019850185811061210457fe5b602002602001015181526020019081526020016000205490505b60008111801561212d57508782105b156121835761213c8184613c41565b9250825182141561214c57612183565b8251915060038401600084600019850185811061216557fe5b6020026020010151815260200190815260200160002054905061211e565b50909450505b505b505b50949350505050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561221757600080fd5b505afa15801561222b573d6000803e3d6000fd5b505050506040513d602081101561224157600080fd5b505190506001600160a01b038116156122f1576001600160a01b0381166000908152600a602052604090205480156122ef57856001600160a01b03166009828154811061228a57fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106122c957fe5b906000526020600020906005020160030160008581526020019081526020016000205492505b505b509392505050565b60008060026001541415612342576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b038716600090815260076020526040902054841161239f576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b6123ab87333087613328565b6123b98888888888886134cb565b6001805590999098509650505050505050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561244d57600080fd5b505afa158015612461573d6000803e3d6000fd5b505050506040513d602081101561247757600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080156122ef57856001600160a01b0316600982815481106124b257fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106124f157fe5b9060005260206000209060050201600401600085815260200190815260200160002054925050509392505050565b600060026001541415612567576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b600260015561257885858585612ba1565b336000908152600c602090815260408083206001600160a01b03891684529091529020546125a69083613484565b336000908152600c602090815260408083206001600160a01b038a168452909152902055506001808055949350505050565b60008060026001541415612621576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556006546001600160a01b0316331461263d57600080fd5b336000908152600c602090815260408083206001600160a01b038b1684529091529020548411156126ac576040805162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742042616c616e636560601b604482015290519081900360640190fd5b6001600160a01b038716600090815260076020526040902054841015612705576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b038b16845290915290205461273390856130a1565b336000818152600c602090815260408083206001600160a01b038d1684529091529020919091556127689088888888886134cb565b60018055909890975095505050505050565b6000612784611d9c565b6127c1576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b506001600160a01b038216600090815260076020526040902081905560015b92915050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561286757600080fd5b505afa15801561287b573d6000803e3d6000fd5b505050506040513d602081101561289157600080fd5b505190506001600160a01b038116156128fe576001600160a01b0381166000908152600a602052604090205480156128fc57600981815481106128d057fe5b600091825260208083206001600160a01b03891684526001600590930201919091019052604090205492505b505b5092915050565b61290d611d9c565b61294a576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b610cdc81613cf9565b336000908152600c602090815260408083206001600160a01b03861684529091529020548111156129c1576040805162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10273ab6b132b960691b604482015290519081900360640190fd5b6129cc8233836131dc565b336000908152600c602090815260408083206001600160a01b03861684529091529020546129fa90826130a1565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b9052205461102590826130a1565b600c60209081526000928352604080842090915290825290205481565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1781529251825160009485949389169392918291908083835b60208310612aca5780518252601f199092019160209182019101612aab565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612b2c576040519150601f19603f3d011682016040523d82523d6000602084013e612b31565b606091505b5091509150818015612b5f575080511580612b5f5750808060200190516020811015612b5c57600080fd5b50515b612b9a5760405162461bcd60e51b815260040180806020018281038252602f815260200180615b5d602f913960400191505060405180910390fd5b5050505050565b60007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080612cb1576040805162461bcd60e51b81526020600482015260136024820152721d1bdad95b94185a5c881b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060098281548110612cc057fe5b60009182526020808320888452600260059093020191820190526040909120549091506001600160a01b03163314612d2f576040805162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21036b0b5b2b960991b604482015290519081900360640190fd5b84612d73576040805162461bcd60e51b815260206004820152600f60248201526e1bdc99195c881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b600085815260028201602052604090206003015484811015612ddc576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e742052656d61696e4e756d62657200000000000000604482015290519081900360640190fd5b84811415612f65576001600160a01b0388166000908152600183016020526040902054861415612e4d576000868152600383016020818152604080842080546001600160a01b038e168652600188018452828620819055855260048701835290842084905589845291905255612f60565b600086815260048301602052604090205480612e9e576040805162461bcd60e51b815260206004820152600b60248201526a0dcde40e0e4ca92dcc8caf60ab1b604482015290519081900360640190fd5b60008781526002840160205260409020600101546001600160a01b038a8116911614612f09576040805162461bcd60e51b815260206004820152601560248201527434b73b30b634b210333937b6aa37b5b2b720b2323960591b604482015290519081900360640190fd5b60008781526003840160205260408082205483835291208190558015612f3d57600081815260048501602052604090208290555b505060008681526004830160209081526040808320839055600385019091528120555b612f84565b612f6f81866130a1565b60008781526002840160205260409020600301555b600080612f918a8a613da3565b60035460408051636128bde760e01b81526001600160a01b038f811660048301528e811660248301528b81166044830152606482018690526084820185905291519496509294501691636128bde79160a48082019260009290919082900301818387803b15801561300157600080fd5b505af1158015613015573d6000803e3d6000fd5b505060035460408051636430f85b60e11b81526001600160a01b038f811660048301528e81166024830152604482018e9052606482018d9052915191909216935063c861f0b69250608480830192600092919082900301818387803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050505050505050505050505050565b6000828211156130de576040805162461bcd60e51b815260206004820152600360248201526239bab160e91b604482015290519081900360640190fd5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106131305780518252601f199092019160209182019101613111565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613192576040519150601f19603f3d011682016040523d82523d6000602084013e613197565b606091505b50509050806131d75760405162461bcd60e51b8152600401808060200182810382526034815260200180615bac6034913960400191505060405180910390fd5b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b602083106132585780518252601f199092019160209182019101613239565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132ba576040519150601f19603f3d011682016040523d82523d6000602084013e6132bf565b606091505b50915091508180156132ed5750805115806132ed57508080602001905160208110156132ea57600080fd5b50515b612b9a5760405162461bcd60e51b8152600401808060200182810382526030815260200180615be06030913960400191505060405180910390fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106133ac5780518252601f19909201916020918201910161338d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461340e576040519150601f19603f3d011682016040523d82523d6000602084013e613413565b606091505b5091509150818015613441575080511580613441575080806020019051602081101561343e57600080fd5b50515b61347c5760405162461bcd60e51b8152600401808060200182810382526035815260200180615c106035913960400191505060405180910390fd5b505050505050565b6000828201838110156134c4576040805162461bcd60e51b815260206004820152600360248201526218591960ea1b604482015290519081900360640190fd5b9392505050565b60008060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390589896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b505190506001600160a01b0381166135cc576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a602052604090205480613612575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b60006009828154811061362157fe5b906000526020600020906005020190506136496001826000015461348490919063ffffffff16565b8082556001600160a01b038b16600090815260018301602052604090205490945080156136ed578861367d578098506136e0565b60008981526003830160205260409020541580156136a957506000898152600483016020526040902054155b156136b6578098506136e0565b60008981526002830160205260409020600101546001600160a01b038c81169116146136e0578098505b6136ed8986848b8b613f19565b60035460408051633503a93d60e21b81526001600160a01b038f811660048301528e811660248301528d81166044830152606482018c9052608482018b905260a482018990529151919092169163d40ea4f49160c480830192600092919082900301818387803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b5050505060006040518060c001604052808e6001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018a81526020018a81526020018981525090508083600201600088815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015590505060008061388f8e8e613da3565b60008a81526004880160205260409020549193509150613a7f576020808401516001600160a01b0316600090815260018701909152604090208890556138d88589858585614109565b6000888152600286016020526040902060030154985088613953576000888152600386016020908152604080832054868301516001600160a01b0316845260018901909252909120819055801561394d5760008981526003870160209081526040808320839055838352600489019091528120555b5061399a565b6020808401516001600160a01b03166000908152600b909152604090205461397b908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60008e6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d6020811015613a1357600080fd5b50516020858101516001600160a01b03166000908152600b9091526040902054909150811115613a79576020808501516002546001600160a01b038083166000908152600b909452604090932054613a799390911690613a749085906130a1565b6131dc565b50613ac9565b6020808401516001600160a01b03166000908152600b90915260409020548b9950613aaa908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60035460208401516040808601518151636128bde760e01b81526001600160a01b03938416600482015290831660248201528a83166044820152606481018690526084810185905290519190921691636128bde79160a480830192600092919082900301818387803b158015613b3e57600080fd5b505af1158015613b52573d6000803e3d6000fd5b50506004546001600160a01b0316159150613bda9050576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015613bad57600080fd5b505af1158015613bc1573d6000803e3d6000fd5b505050506040513d6020811015613bd757600080fd5b50505b50505050505050965096945050505050565b600082613bfb575060006127e0565b82820282848281613c0857fe5b04146134c4576040805162461bcd60e51b81526020600482015260036024820152621b5d5b60ea1b604482015290519081900360640190fd5b606082613c4f5750806127e0565b815160006001820167ffffffffffffffff81118015613c6d57600080fd5b50604051908082528060200260200182016040528015613c97578160200160208202803683370190505b50905060005b82811015613cd857848181518110613cb157fe5b6020026020010151828281518110613cc557fe5b6020908102919091010152600101613c9d565b5084818381518110613ce657fe5b6020908102919091010152949350505050565b6001600160a01b038116613d48576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000613db2858561595f565b5090506000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390588886040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015613e3657600080fd5b505afa158015613e4a573d6000803e3d6000fd5b505050506040513d6020811015613e6057600080fd5b505160408051630240bc6b60e21b815290516001600160a01b0390921691630902f1ac91600480820192606092909190829003018186803b158015613ea457600080fd5b505afa158015613eb8573d6000803e3d6000fd5b505050506040513d6060811015613ece57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b0387811690841614613f08578082613f0b565b81815b909890975095505050505050565b6000858152600284016020526040902060040154613f379082613bec565b6000868152600285016020526040902060050154613f56908490613bec565b1161403357600085815260038401602052604090205480613f9b576000868152600385016020908152604080832088905587835260048701909152902086905561402d565b6000818152600285016020526040902060040154613fb99083613bec565b6000828152600286016020526040902060050154613fd8908590613bec565b11613fef57613fea8186868686613f19565b61402d565b600085815260048501602081815260408084208a9055898452600388018083528185208a905585855292825280842089905588845291905290208190555b50612b9a565b600085815260048401602052604090205480614073576000868152600485016020908152604080832088905587835260038701909152902086905561347c565b60008181526002850160205260409020600401546140919083613bec565b60008281526002860160205260409020600501546140b0908590613bec565b106140c7576140c28186868686613f19565b61347c565b600085815260038501602081815260408084208a9055988352600490960180875288832088905583835290865287822087905595815294909352505091902055565b60a08301516141189083613bec565b60808401516141279083613bec565b1115614f8557600061414384608001518560a001518585615990565b90508360800151811115614158575060808301515b6040805160608101825260008082526020808301829052878401516001600160a01b0316825260018a0190528290205491810182905290156148ea576000876002016000836002600381106141a957fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528901519193506142299190613bec565b6080808301519089015161423c91613bec565b106148e757600061425e8260a001518960a00151613bec90919063ffffffff16565b608080840151908a015161427191613bec565b141561427e575083614295565b6142928260a0015183608001518989615990565b90505b8085106148e55760808801516000906142ae90836130a1565b90505b6040850151158015906142c45750600081115b156148e35760006142d484615a42565b905060006142f06103e86142ea846103e5613bec565b90615a73565b90508183106146c1577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031685604001516001600160a01b031614801561436857506020858101516001600160a01b031660009081526008825260408082208a8201518352909252205460ff166002145b156143fe577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505050506143f98560000151826130e4565b614411565b61441185604001518660000151836131dc565b614424828860005b602002015190613484565b8752606085015161443790886001614419565b602080890191909152600060038881018290555491870151604080890151818c015160608b015183516342dc858d60e01b81526001600160a01b03958616600482015292851660248401526044830191909152606482018790526084820152905191909316926342dc858d9260a480830193919282900301818387803b1580156144c057600080fd5b505af11580156144d4573d6000803e3d6000fd5b5060009250505060038e01818960026020020151815260200190815260200160002054905060008e60030160008a60026003811061450e57fe5b6020020151815260200190815260200160002081905550808860026003811061453357fe5b602002015287600260200201518e60010160008e604001516001600160a01b03166001600160a01b03168152602001908152602001600020819055508760026003811061457c57fe5b6020020151156146bb57600060048f01818a600260200201518152602001908152602001600020819055508d6002016000896002600381106145ba57fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528f015191995091975061463c91613bec565b608080880151908e015161464f91613bec565b106146b6576146688660a0015187608001518d8d615990565b885190955060009061467b908790613484565b9050858a101580156146905750808d60800151115b156146ab5760808d01516146a490826130a1565b94506146b0565b600094505b506146bb565b600093505b506148dc565b60006146d56103e86142ea866103e5613bec565b90507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031686604001516001600160a01b031614801561474657506020868101516001600160a01b031660009081526008825260408082208b8201518352909252205460ff166002145b156147dc577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147b157600080fd5b505af11580156147c5573d6000803e3d6000fd5b505050506147d78660000151826130e4565b6147ef565b6147ef86604001518760000151836131dc565b6147fb84896000614419565b885260a0860151608087015160009190614816908490613bec565b8161481d57fe5b04905061482c818a6001614419565b60208a0152606087015161484090826130a1565b6003898101919091555460208801516040808a01518c82015182516342dc858d60e01b81526001600160a01b039485166004820152918416602483015260448201526064810186905260848101859052905191909216916342dc858d9160a480830192600092919082900301818387803b1580156148bd57600080fd5b505af11580156148d1573d6000803e3d6000fd5b505050506000945050505b50506142b1565b505b505b50505b600061490282825b60200201516080880151906130a1565b90508083101561490f5750815b8015614c8a5761492181836000614419565b8252602086015160408701518686600061493d836103e8613bec565b905060006149586103e56149528560016130a1565b90613bec565b90506000614971600283858161496a57fe5b0490613484565b9050808810614c82576000614987898787615ac3565b9050614995818b6001614419565b60208b8101919091526040805163e6a4390560e01b81526001600160a01b038b811660048301528a8116602483015291516000937f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b29093169263e6a439059260448082019391829003018186803b158015614a0f57600080fd5b505afa158015614a23573d6000803e3d6000fd5b505050506040513d6020811015614a3957600080fd5b50519050614a4889828c6131dc565b6000614a548a8a61595f565b509050806001600160a01b03168a6001600160a01b03161415614b5b57604080516000808252602082019283905263022c0d9f60e01b835260248201818152604483018790523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b9590939092909160c48501918083838b5b83811015614aef578181015183820152602001614ad7565b50505050905090810190601f168015614b1c5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614b3e57600080fd5b505af1158015614b52573d6000803e3d6000fd5b50505050614c42565b604080516000808252602082019283905263022c0d9f60e01b835260248201868152604483018290523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b969590939092909160c48501918083838a5b83811015614bda578181015183820152602001614bc2565b50505050905090810190601f168015614c075780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b6001600160a01b0389166000908152600b6020526040902054614c659084613484565b6001600160a01b038a166000908152600b60205260409020555050505b505050505050505b815115614f7d57602082015115614eba577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031686604001516001600160a01b0316148015614d0757506020868101516001600160a01b031660009081526008825260408082208a8352909252205460ff166002145b15614dab576001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015614d7957600080fd5b505af1158015614d8d573d6000803e3d6000fd5b50508751614da6925090508360015b60200201516130e4565b614dc5565b60408601518651614dc591908460015b60200201516131dc565b6005546001600160a01b031615614e725760055486516020808901516040808b015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b158015614e4557600080fd5b505af1158015614e59573d6000803e3d6000fd5b505050506040513d6020811015614e6f57600080fd5b50505b6020808301516040808901516001600160a01b03166000908152600b90935290912054614e9e916130a1565b6040808801516001600160a01b03166000908152600b60205220555b600354600088815260028a810160209081526040808420600181015493015491870151875182516342dc858d60e01b81526001600160a01b0395861660048201529385166024850152604484018e9052606484019190915260848301525191909316926342dc858d9260a480830193919282900301818387803b158015614f4057600080fd5b505af1158015614f54573d6000803e3d6000fd5b50505050614f68826000600381106148f257fe5b600088815260028a0160205260409020600301555b505050612b9a565b6040805160608101825260008082526020808301829052868401516001600160a01b03168252600189019052829020549181019190915260808401515b604082015115801590614fd457508015155b1561567057600087600201600084600260038110614fee57fe5b60200201518152602001908152602001600020905061501e81600501548760a00151613bec90919063ffffffff16565b6004820154608088015161503191613bec565b1415615664576150428360006148f2565b6040805160c08101825283546001600160a01b039081168252600185015481166020830152600285015416918101919091526003830154606082015260048301546080820152600583015460a08201529092506000906150a190615a42565b90508083106153925760006150be6103e86142ea846103e5613bec565b60028401549091507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b03908116911614801561512e575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156151cc577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561519957600080fd5b505af11580156151ad573d6000803e3d6000fd5b505084546151c792506001600160a01b03169050826130e4565b6151ea565b600283015483546151ea916001600160a01b039081169116836131dc565b6151f682866000614419565b8552600383015461520990866001614419565b602086810191909152600354604080880151600090815260028e810194859052918120600101546001600160a01b03938416946342dc858d94909116929091908a9060209081029190910151825281019190915260409081016000908120600201548a83015160038a015484516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590921660248601526044850152606484018790526084840152905160a48084019382900301818387803b1580156152ce57600080fd5b505af11580156152e2573d6000803e3d6000fd5b50505050604085810151600090815260038c016020908152828220548b8401516001600160a01b0316835260018e01909152919020819055801561534857604080870151600090815260038d01602090815282822082905583825260048e019052908120555b60008b60020160008860026003811061535d57fe5b6020020151815260200190815260200160002060030181905550808660026003811061538557fe5b60200201525061565e9050565b60006153a66103e86142ea866103e5613bec565b60028401549091507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b039081169116148015615416575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156154b4577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561548157600080fd5b505af1158015615495573d6000803e3d6000fd5b505084546154af92506001600160a01b03169050826130e4565b6154d2565b600283015483546154d2916001600160a01b039081169116836131dc565b6080880151855260058301546004840154600091906154f2908490613bec565b816154f957fe5b04905061550881876001614419565b6020870152600384015461551c90826130a1565b8b60020160008860026003811061552f57fe5b6020020151815260200190815260200160002060030181905550600360009054906101000a90046001600160a01b03166001600160a01b03166342dc858d8c60020160008960026003811061558057fe5b6020020151815260200190815260200160002060010160009054906101000a90046001600160a01b03168d60020160008a6002600381106155bd57fe5b60209081029190910151825281019190915260409081016000908120600201548b83015183516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909116602485015260448401526064830187905260848301869052905160a48084019382900301818387803b15801561563d57600080fd5b505af1158015615651573d6000803e3d6000fd5b5050505050505050615670565b5061566a565b50615670565b50614fc2565b815115615956577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031685604001516001600160a01b03161480156156e357506020858101516001600160a01b03166000908152600882526040808220898352909252205460ff166002145b15615781576001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561575557600080fd5b505af1158015615769573d6000803e3d6000fd5b5050865161577c92509050836001614d9c565b615795565b604085015185516157959190846001614dbb565b6005546001600160a01b0316156158425760055485516020808801516040808a015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b15801561581557600080fd5b505af1158015615829573d6000803e3d6000fd5b505050506040513d602081101561583f57600080fd5b50505b6020808301516040808801516001600160a01b03166000908152600b9093529091205461586e916130a1565b6040868101516001600160a01b039081166000908152600b6020908152838220949094556003548a825260028c81018652848320600181015491015495880151885186516342dc858d60e01b815292861660048401529685166024830152604482018d905260648201526084810195909552925192909116926342dc858d9260a4808301939282900301818387803b15801561590957600080fd5b505af115801561591d573d6000803e3d6000fd5b505050506159418260006003811061593157fe5b60200201516080870151906130a1565b60008781526002890160205260409020600301555b50505050505050565b600080826001600160a01b0316846001600160a01b031610615982578284615985565b83835b909590945092505050565b600080846103e56159a96103e86149528a818a8a613bec565b816159b057fe5b04816159b857fe5b049050600063ec477c746159d261230d6149528880613bec565b816159d957fe5b04905060006159f06159eb8484613484565b615b0b565b905060006107ca615a03886107cd613bec565b81615a0a57fe5b04905080821115615a3157615a2a6001615a2484846130a1565b90613484565b9450615a36565b600094505b50505050949350505050565b60006127e06103e56142ea6103e861495286608001516142ea88606001518960a00151613bec90919063ffffffff16565b6000808211615aaf576040805162461bcd60e51b81526020600482015260036024820152623234bb60e91b604482015290519081900360640190fd5b6000828481615aba57fe5b04949350505050565b600080615ad2856103e5613bec565b90506000615ae08285613bec565b90506000615af483615a24886103e8613bec565b9050808281615aff57fe5b04979650505050505050565b60006003821115615b4e575080600160028204015b81811015615b4857809150600281828581615b3757fe5b040181615b4057fe5b049050615b20565b50611ed4565b8115611ed45750600191905056fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b20415050524f56455f4641494c45445265656e7472616e637947756172643a207265656e7472616e742063616c6c005472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220897532e588292b1fee078ed1f909ed34dfe9d24c1a3fbf6b86c72e1045574e7064736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2
-----Decoded View---------------
Arg [0] : _WETH (address): 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270
Arg [1] : _uniswapV2Factory (address): 0x3EE4154c7F42D94e1092ad8cE5debb4B743ed0B2
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270
Arg [1] : 0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$382.96
Net Worth in POL
Token Allocations
USDC.E
83.14%
WPOL
16.72%
DUCKIES
0.06%
Others
0.08%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.