Overview
ETH Balance
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 134 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Dodo Swap V2Toke... | 14937633 | 12 mins ago | IN | 0 ETH | 0.00002131 | ||||
Dodo Swap V2Toke... | 14937462 | 33 mins ago | IN | 0 ETH | 0.00002241 | ||||
Dodo Swap V2Toke... | 14937458 | 34 mins ago | IN | 0 ETH | 0.00002035 | ||||
Dodo Swap V2Toke... | 14937396 | 41 mins ago | IN | 0 ETH | 0.0000195 | ||||
Dodo Swap V2Toke... | 14937391 | 42 mins ago | IN | 0 ETH | 0.00002098 | ||||
Dodo Swap V2Toke... | 14937370 | 45 mins ago | IN | 0 ETH | 0.00001925 | ||||
Dodo Swap V2Toke... | 14936817 | 1 hr ago | IN | 0 ETH | 0.00002655 | ||||
Dodo Swap V2Toke... | 14936801 | 1 hr ago | IN | 0 ETH | 0.00003092 | ||||
Dodo Swap V2Toke... | 14936635 | 2 hrs ago | IN | 0 ETH | 0.00002163 | ||||
Dodo Swap V2Toke... | 14936034 | 3 hrs ago | IN | 0 ETH | 0.00001945 | ||||
Dodo Swap V2ETH ... | 14933077 | 8 hrs ago | IN | 0.02 ETH | 0.00001282 | ||||
Dodo Swap V2Toke... | 14927478 | 13 hrs ago | IN | 0 ETH | 0.00001549 | ||||
Dodo Swap V2Toke... | 14927466 | 13 hrs ago | IN | 0 ETH | 0.00001471 | ||||
Dodo Swap V2Toke... | 14927423 | 13 hrs ago | IN | 0 ETH | 0.00001486 | ||||
Dodo Swap V2Toke... | 14927402 | 13 hrs ago | IN | 0 ETH | 0.00001478 | ||||
Dodo Swap V2Toke... | 14927393 | 13 hrs ago | IN | 0 ETH | 0.00001536 | ||||
Dodo Swap V2Toke... | 14927041 | 13 hrs ago | IN | 0 ETH | 0.00001583 | ||||
Dodo Swap V2Toke... | 14926992 | 13 hrs ago | IN | 0 ETH | 0.00001477 | ||||
Dodo Swap V2Toke... | 14926948 | 13 hrs ago | IN | 0 ETH | 0.00001431 | ||||
Dodo Swap V2Toke... | 14926548 | 14 hrs ago | IN | 0 ETH | 0.00001739 | ||||
Dodo Swap V2Toke... | 14923089 | 18 hrs ago | IN | 0 ETH | 0.00001745 | ||||
Dodo Swap V2Toke... | 14923085 | 18 hrs ago | IN | 0 ETH | 0.00001691 | ||||
Dodo Swap V2Toke... | 14923081 | 18 hrs ago | IN | 0 ETH | 0.00001615 | ||||
Dodo Swap V2ETH ... | 14919766 | 21 hrs ago | IN | 0.02 ETH | 0.00001323 | ||||
Dodo Swap V2ETH ... | 14919755 | 21 hrs ago | IN | 0.02 ETH | 0.00001285 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
14937633 | 12 mins ago | 0.01784133 ETH | ||||
14937633 | 12 mins ago | 0.01784133 ETH | ||||
14937462 | 33 mins ago | 0.01787275 ETH | ||||
14937462 | 33 mins ago | 0.01787275 ETH | ||||
14937458 | 34 mins ago | 0.01790425 ETH | ||||
14937458 | 34 mins ago | 0.01790425 ETH | ||||
14937396 | 41 mins ago | 0.01793584 ETH | ||||
14937396 | 41 mins ago | 0.01793584 ETH | ||||
14937391 | 42 mins ago | 0.0179675 ETH | ||||
14937391 | 42 mins ago | 0.0179675 ETH | ||||
14937370 | 45 mins ago | 0.01799926 ETH | ||||
14937370 | 45 mins ago | 0.01799926 ETH | ||||
14936817 | 1 hr ago | 0.01803109 ETH | ||||
14936817 | 1 hr ago | 0.01803109 ETH | ||||
14936801 | 1 hr ago | 0.01806302 ETH | ||||
14936801 | 1 hr ago | 0.01806302 ETH | ||||
14936635 | 2 hrs ago | 0.01809502 ETH | ||||
14936635 | 2 hrs ago | 0.01809502 ETH | ||||
14936034 | 3 hrs ago | 0.01812711 ETH | ||||
14936034 | 3 hrs ago | 0.01812711 ETH | ||||
14933077 | 8 hrs ago | 0.02 ETH | ||||
14927478 | 13 hrs ago | 0.01812389 ETH | ||||
14927478 | 13 hrs ago | 0.01812389 ETH | ||||
14927466 | 13 hrs ago | 0.01815606 ETH | ||||
14927466 | 13 hrs ago | 0.01815606 ETH |
Loading...
Loading
Contract Name:
DODOV2Proxy02
Compiler Version
v0.6.9+commit.3e3065ac
Optimization Enabled:
Yes with 200 runs
Other Settings:
istanbul EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; import {IDODOV2Proxy01} from "./intf/IDODOV2Proxy01.sol"; import {IDODOV2} from "./intf/IDODOV2.sol"; import {IDODOV1} from "./intf/IDODOV1.sol"; import {IDODOApproveProxy} from "./DODOApproveProxy.sol"; import {IDODOSellHelper} from "./helper/DODOSellHelper.sol"; import {IERC20} from "../intf/IERC20.sol"; import {IWETH} from "../intf/IWETH.sol"; import {IUni} from "./intf/IUni.sol"; import {SafeMath} from "../lib/SafeMath.sol"; import {UniversalERC20} from "./lib/UniversalERC20.sol"; import {SafeERC20} from "../lib/SafeERC20.sol"; import {DecimalMath} from "../lib/DecimalMath.sol"; import {ReentrancyGuard} from "../lib/ReentrancyGuard.sol"; import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; import {IDODOAdapter} from "./intf/IDODOAdapter.sol"; /** * @title DODOV2Proxy02 * @author DODO Breeder * * @notice Entrance of trading in DODO platform */ contract DODOV2Proxy02 is IDODOV2Proxy01, ReentrancyGuard, InitializableOwnable { using SafeMath for uint256; using UniversalERC20 for IERC20; // ============ Storage ============ address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public immutable _WETH_; address public immutable _DODO_APPROVE_PROXY_; address public immutable _DODO_SELL_HELPER_; address public immutable _DVM_FACTORY_; mapping (address => bool) public isWhiteListed; // ============ Events ============ event OrderHistory( address fromToken, address toToken, address sender, uint256 fromAmount, uint256 returnAmount ); // ============ Modifiers ============ modifier judgeExpired(uint256 deadLine) { require(deadLine >= block.timestamp, "DODOV2Proxy02: EXPIRED"); _; } fallback() external payable {} receive() external payable {} constructor( address dvmFactory, address payable weth, address dodoApproveProxy, address dodoSellHelper ) public { _DVM_FACTORY_ = dvmFactory; _WETH_ = weth; _DODO_APPROVE_PROXY_ = dodoApproveProxy; _DODO_SELL_HELPER_ = dodoSellHelper; } function addWhiteList (address contractAddr) public onlyOwner { isWhiteListed[contractAddr] = true; } function removeWhiteList (address contractAddr) public onlyOwner { isWhiteListed[contractAddr] = false; } // ============ DVM Functions (create & add liquidity) ============ function createDODOVendingMachine( address baseToken, address quoteToken, uint256 baseInAmount, uint256 quoteInAmount, uint256 lpFeeRate, uint256 i, uint256 k, bool isOpenTWAP, uint256 deadLine ) external override payable preventReentrant judgeExpired(deadLine) returns (address newVendingMachine, uint256 shares) { { address _baseToken = baseToken == _ETH_ADDRESS_ ? _WETH_ : baseToken; address _quoteToken = quoteToken == _ETH_ADDRESS_ ? _WETH_ : quoteToken; newVendingMachine = IDODOV2(_DVM_FACTORY_).createDODOVendingMachine( _baseToken, _quoteToken, lpFeeRate, i, k, isOpenTWAP ); } { address _baseToken = baseToken; address _quoteToken = quoteToken; _deposit( msg.sender, newVendingMachine, _baseToken, baseInAmount, _baseToken == _ETH_ADDRESS_ ); _deposit( msg.sender, newVendingMachine, _quoteToken, quoteInAmount, _quoteToken == _ETH_ADDRESS_ ); } (shares, , ) = IDODOV2(newVendingMachine).buyShares(msg.sender); } function addDVMLiquidity( address dvmAddress, uint256 baseInAmount, uint256 quoteInAmount, uint256 baseMinAmount, uint256 quoteMinAmount, uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH uint256 deadLine ) external override payable preventReentrant judgeExpired(deadLine) returns ( uint256 shares, uint256 baseAdjustedInAmount, uint256 quoteAdjustedInAmount ) { address _dvm = dvmAddress; (baseAdjustedInAmount, quoteAdjustedInAmount) = _addDVMLiquidity( _dvm, baseInAmount, quoteInAmount ); require( baseAdjustedInAmount >= baseMinAmount && quoteAdjustedInAmount >= quoteMinAmount, "DODOV2Proxy02: deposit amount is not enough" ); _deposit(msg.sender, _dvm, IDODOV2(_dvm)._BASE_TOKEN_(), baseAdjustedInAmount, flag == 1); _deposit(msg.sender, _dvm, IDODOV2(_dvm)._QUOTE_TOKEN_(), quoteAdjustedInAmount, flag == 2); (shares, , ) = IDODOV2(_dvm).buyShares(msg.sender); // refund dust eth if (flag == 1 && msg.value > baseAdjustedInAmount) msg.sender.transfer(msg.value - baseAdjustedInAmount); if (flag == 2 && msg.value > quoteAdjustedInAmount) msg.sender.transfer(msg.value - quoteAdjustedInAmount); } function _addDVMLiquidity( address dvmAddress, uint256 baseInAmount, uint256 quoteInAmount ) internal view returns (uint256 baseAdjustedInAmount, uint256 quoteAdjustedInAmount) { (uint256 baseReserve, uint256 quoteReserve) = IDODOV2(dvmAddress).getVaultReserve(); if (quoteReserve == 0 && baseReserve == 0) { baseAdjustedInAmount = baseInAmount; quoteAdjustedInAmount = quoteInAmount; } if (quoteReserve == 0 && baseReserve > 0) { baseAdjustedInAmount = baseInAmount; quoteAdjustedInAmount = 0; } if (quoteReserve > 0 && baseReserve > 0) { uint256 baseIncreaseRatio = DecimalMath.divFloor(baseInAmount, baseReserve); uint256 quoteIncreaseRatio = DecimalMath.divFloor(quoteInAmount, quoteReserve); if (baseIncreaseRatio <= quoteIncreaseRatio) { baseAdjustedInAmount = baseInAmount; quoteAdjustedInAmount = DecimalMath.mulFloor(quoteReserve, baseIncreaseRatio); } else { quoteAdjustedInAmount = quoteInAmount; baseAdjustedInAmount = DecimalMath.mulFloor(baseReserve, quoteIncreaseRatio); } } } // ============ Swap ============ function dodoSwapV2ETHToToken( address toToken, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool, uint256 deadLine ) external override payable judgeExpired(deadLine) returns (uint256 returnAmount) { require(dodoPairs.length > 0, "DODOV2Proxy02: PAIRS_EMPTY"); require(minReturnAmount > 0, "DODOV2Proxy02: RETURN_AMOUNT_ZERO"); uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); IWETH(_WETH_).deposit{value: msg.value}(); IWETH(_WETH_).transfer(dodoPairs[0], msg.value); for (uint256 i = 0; i < dodoPairs.length; i++) { if (i == dodoPairs.length - 1) { if (directions & 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(msg.sender); } else { IDODOV2(dodoPairs[i]).sellQuote(msg.sender); } } else { if (directions & 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } directions = directions >> 1; } returnAmount = IERC20(toToken).balanceOf(msg.sender).sub(originToTokenBalance); require(returnAmount >= minReturnAmount, "DODOV2Proxy02: Return amount is not enough"); emit OrderHistory( _ETH_ADDRESS_, toToken, msg.sender, msg.value, returnAmount ); } function dodoSwapV2TokenToETH( address fromToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool, uint256 deadLine ) external override judgeExpired(deadLine) returns (uint256 returnAmount) { require(dodoPairs.length > 0, "DODOV2Proxy02: PAIRS_EMPTY"); require(minReturnAmount > 0, "DODOV2Proxy02: RETURN_AMOUNT_ZERO"); IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { if (i == dodoPairs.length - 1) { if (directions & 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(address(this)); } else { IDODOV2(dodoPairs[i]).sellQuote(address(this)); } } else { if (directions & 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } directions = directions >> 1; } returnAmount = IWETH(_WETH_).balanceOf(address(this)); require(returnAmount >= minReturnAmount, "DODOV2Proxy02: Return amount is not enough"); IWETH(_WETH_).withdraw(returnAmount); msg.sender.transfer(returnAmount); emit OrderHistory( fromToken, _ETH_ADDRESS_, msg.sender, fromTokenAmount, returnAmount ); } function dodoSwapV2TokenToToken( address fromToken, address toToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool, uint256 deadLine ) external override judgeExpired(deadLine) returns (uint256 returnAmount) { require(dodoPairs.length > 0, "DODOV2Proxy02: PAIRS_EMPTY"); require(minReturnAmount > 0, "DODOV2Proxy02: RETURN_AMOUNT_ZERO"); uint256 originToTokenBalance = IERC20(toToken).balanceOf(msg.sender); IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(fromToken, msg.sender, dodoPairs[0], fromTokenAmount); for (uint256 i = 0; i < dodoPairs.length; i++) { if (i == dodoPairs.length - 1) { if (directions & 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(msg.sender); } else { IDODOV2(dodoPairs[i]).sellQuote(msg.sender); } } else { if (directions& 1 == 0) { IDODOV2(dodoPairs[i]).sellBase(dodoPairs[i + 1]); } else { IDODOV2(dodoPairs[i]).sellQuote(dodoPairs[i + 1]); } } directions = directions >> 1; } returnAmount = IERC20(toToken).balanceOf(msg.sender).sub(originToTokenBalance); require(returnAmount >= minReturnAmount, "DODOV2Proxy02: Return amount is not enough"); emit OrderHistory( fromToken, toToken, msg.sender, fromTokenAmount, returnAmount ); } function externalSwap( address fromToken, address toToken, address approveTarget, address swapTarget, uint256 fromTokenAmount, uint256 minReturnAmount, bytes memory callDataConcat, bool, uint256 deadLine ) external override payable judgeExpired(deadLine) returns (uint256 returnAmount) { require(minReturnAmount > 0, "DODOV2Proxy02: RETURN_AMOUNT_ZERO"); uint256 toTokenOriginBalance = IERC20(toToken).universalBalanceOf(msg.sender); if (fromToken != _ETH_ADDRESS_) { IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens( fromToken, msg.sender, address(this), fromTokenAmount ); IERC20(fromToken).universalApproveMax(approveTarget, fromTokenAmount); } require(isWhiteListed[swapTarget], "DODOV2Proxy02: Not Whitelist Contract"); (bool success, ) = swapTarget.call{value: fromToken == _ETH_ADDRESS_ ? msg.value : 0}(callDataConcat); require(success, "DODOV2Proxy02: External Swap execution Failed"); IERC20(toToken).universalTransfer( msg.sender, IERC20(toToken).universalBalanceOf(address(this)) ); returnAmount = IERC20(toToken).universalBalanceOf(msg.sender).sub(toTokenOriginBalance); require(returnAmount >= minReturnAmount, "DODOV2Proxy02: Return amount is not enough"); emit OrderHistory( fromToken, toToken, msg.sender, fromTokenAmount, returnAmount ); } function dodoSwapV1( address fromToken, address toToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool, uint256 deadLine ) external override payable judgeExpired(deadLine) returns (uint256 returnAmount) { require(dodoPairs.length > 0, "DODOV2Proxy02: PAIRS_EMPTY"); require(minReturnAmount > 0, "DODOV2Proxy02: RETURN_AMOUNT_ZERO"); address _fromToken = fromToken; address _toToken = toToken; _deposit(msg.sender, address(this), _fromToken, fromTokenAmount, _fromToken == _ETH_ADDRESS_); for (uint256 i = 0; i < dodoPairs.length; i++) { address curDodoPair = dodoPairs[i]; if (directions & 1 == 0) { address curDodoBase = IDODOV1(curDodoPair)._BASE_TOKEN_(); uint256 curAmountIn = IERC20(curDodoBase).balanceOf(address(this)); IERC20(curDodoBase).universalApproveMax(curDodoPair, curAmountIn); IDODOV1(curDodoPair).sellBaseToken(curAmountIn, 0, ""); } else { address curDodoQuote = IDODOV1(curDodoPair)._QUOTE_TOKEN_(); uint256 curAmountIn = IERC20(curDodoQuote).balanceOf(address(this)); IERC20(curDodoQuote).universalApproveMax(curDodoPair, curAmountIn); uint256 canBuyBaseAmount = IDODOSellHelper(_DODO_SELL_HELPER_).querySellQuoteToken( curDodoPair, curAmountIn ); IDODOV1(curDodoPair).buyBaseToken(canBuyBaseAmount, curAmountIn, ""); } directions = directions >> 1; } if (_toToken == _ETH_ADDRESS_) { returnAmount = IWETH(_WETH_).balanceOf(address(this)); IWETH(_WETH_).withdraw(returnAmount); } else { returnAmount = IERC20(_toToken).tokenBalanceOf(address(this)); } require(returnAmount >= minReturnAmount, "DODOV2Proxy02: Return amount is not enough"); IERC20(_toToken).universalTransfer(msg.sender, returnAmount); emit OrderHistory(_fromToken, _toToken, msg.sender, fromTokenAmount, returnAmount); } //============ CrowdPooling Functions (bid) ============ // function bid( // address cpAddress, // uint256 quoteAmount, // uint8 flag, // 0 - ERC20, 1 - quoteInETH // uint256 deadLine // ) external override payable preventReentrant judgeExpired(deadLine) { // _deposit(msg.sender, cpAddress, IDODOV2(cpAddress)._QUOTE_TOKEN_(), quoteAmount, flag == 1); // IDODOV2(cpAddress).bid(msg.sender); // } function addLiquidityToV1( address pair, uint256 baseAmount, uint256 quoteAmount, uint256 baseMinShares, uint256 quoteMinShares, uint8 flag, // 0 erc20 In 1 baseInETH 2 quoteIn ETH uint256 deadLine ) external override payable preventReentrant judgeExpired(deadLine) returns(uint256 baseShares, uint256 quoteShares) { address _baseToken = IDODOV1(pair)._BASE_TOKEN_(); address _quoteToken = IDODOV1(pair)._QUOTE_TOKEN_(); _deposit(msg.sender, address(this), _baseToken, baseAmount, flag == 1); _deposit(msg.sender, address(this), _quoteToken, quoteAmount, flag == 2); if(baseAmount > 0) { IERC20(_baseToken).universalApproveMax(pair, baseAmount); baseShares = IDODOV1(pair).depositBaseTo(msg.sender, baseAmount); } if(quoteAmount > 0) { IERC20(_quoteToken).universalApproveMax(pair, quoteAmount); quoteShares = IDODOV1(pair).depositQuoteTo(msg.sender, quoteAmount); } require(baseShares >= baseMinShares && quoteShares >= quoteMinShares,"DODOV2Proxy02: Return DLP is not enough"); } function _deposit( address from, address to, address token, uint256 amount, bool isETH ) internal { if (isETH) { if (amount > 0) { require(msg.value == amount, "ETH_VALUE_WRONG"); IWETH(_WETH_).deposit{value: amount}(); if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount); } } else { IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(token, from, to, amount); } } function _withdraw( address payable to, address token, uint256 amount, bool isETH ) internal { if (isETH) { if (amount > 0) { IWETH(_WETH_).withdraw(amount); to.transfer(amount); } } else { if (amount > 0) { SafeERC20.safeTransfer(IERC20(token), to, amount); } } } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; /** * @title SafeMath * @author DODO Breeder * * @notice Math operations with safety checks that revert on error */ library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "MUL_ERROR"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "DIVIDING_ERROR"); return a / b; } function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { uint256 quotient = div(a, b); uint256 remainder = a - quotient * b; if (remainder > 0) { return quotient + 1; } else { return quotient; } } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SUB_ERROR"); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "ADD_ERROR"); return c; } function sqrt(uint256 x) internal pure returns (uint256 y) { uint256 z = x / 2 + 1; y = x; while (z < y) { y = z; z = (x / z + z) / 2; } } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 This is a simplified version of OpenZepplin's SafeERC20 library */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {IERC20} from "../intf/IERC20.sol"; import {SafeMath} from "./SafeMath.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; /** * @title ReentrancyGuard * @author DODO Breeder * * @notice Protect functions from Reentrancy Attack */ contract ReentrancyGuard { // https://solidity.readthedocs.io/en/latest/control-structures.html?highlight=zero-state#scoping-and-declarations // zero-state of _ENTERED_ is false bool private _ENTERED_; modifier preventReentrant() { require(!_ENTERED_, "REENTRANT"); _ENTERED_ = true; _; _ENTERED_ = false; } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; /** * @title Ownable * @author DODO Breeder * * @notice Ownership related functions */ contract InitializableOwnable { address public _OWNER_; address public _NEW_OWNER_; bool internal _INITIALIZED_; // ============ Events ============ event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // ============ Modifiers ============ modifier notInitialized() { require(!_INITIALIZED_, "DODO_INITIALIZED"); _; } modifier onlyOwner() { require(msg.sender == _OWNER_, "NOT_OWNER"); _; } // ============ Functions ============ function initOwner(address newOwner) public notInitialized { _INITIALIZED_ = true; _OWNER_ = newOwner; } function transferOwnership(address newOwner) public onlyOwner { emit OwnershipTransferPrepared(_OWNER_, newOwner); _NEW_OWNER_ = newOwner; } function claimOwnership() public { require(msg.sender == _NEW_OWNER_, "INVALID_CLAIM"); emit OwnershipTransferred(_OWNER_, _NEW_OWNER_); _OWNER_ = _NEW_OWNER_; _NEW_OWNER_ = address(0); } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {SafeMath} from "./SafeMath.sol"; /** * @title DecimalMath * @author DODO Breeder * * @notice Functions for fixed point number with 18 decimals */ library DecimalMath { using SafeMath for uint256; uint256 internal constant ONE = 10**18; uint256 internal constant ONE2 = 10**36; function mulFloor(uint256 target, uint256 d) internal pure returns (uint256) { return target.mul(d) / (10**18); } function mulCeil(uint256 target, uint256 d) internal pure returns (uint256) { return target.mul(d).divCeil(10**18); } function divFloor(uint256 target, uint256 d) internal pure returns (uint256) { return target.mul(10**18).div(d); } function divCeil(uint256 target, uint256 d) internal pure returns (uint256) { return target.mul(10**18).divCeil(d); } function reciprocalFloor(uint256 target) internal pure returns (uint256) { return uint256(10**36).div(target); } function reciprocalCeil(uint256 target) internal pure returns (uint256) { return uint256(10**36).divCeil(target); } function powFloor(uint256 target, uint256 e) internal pure returns (uint256) { if (e == 0) { return 10 ** 18; } else if (e == 1) { return target; } else { uint p = powFloor(target, e.div(2)); p = p.mul(p) / (10**18); if (e % 2 == 1) { p = p.mul(target) / (10**18); } return p; } } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IWETH { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address src, address dst, uint256 wad ) external returns (bool); function deposit() external payable; function withdraw(uint256 wad) external; }
// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.9; pragma experimental ABIEncoderV2; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); function decimals() external view returns (uint8); function name() external view returns (string memory); function symbol() external view returns (string memory); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; interface IDODOApprove { function claimTokens(address token,address who,address dest,uint256 amount) external; function getDODOProxy() external view returns (address); }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; import {SafeMath} from "../../lib/SafeMath.sol"; import {IERC20} from "../../intf/IERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol"; library UniversalERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); function universalTransfer( IERC20 token, address payable to, uint256 amount ) internal { if (amount > 0) { if (isETH(token)) { to.transfer(amount); } else { token.safeTransfer(to, amount); } } } function universalApproveMax( IERC20 token, address to, uint256 amount ) internal { uint256 allowance = token.allowance(address(this), to); if (allowance < amount) { if (allowance > 0) { token.safeApprove(to, 0); } token.safeApprove(to, uint256(-1)); } } function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { if (isETH(token)) { return who.balance; } else { return token.balanceOf(who); } } function tokenBalanceOf(IERC20 token, address who) internal view returns (uint256) { return token.balanceOf(who); } function isETH(IERC20 token) internal pure returns (bool) { return token == ETH_ADDRESS; } }
pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IUni { function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function token0() external view returns (address); function token1() external view returns (address); }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IDODOV2Proxy01 { function dodoSwapV2ETHToToken( address toToken, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool isIncentive, uint256 deadLine ) external payable returns (uint256 returnAmount); function dodoSwapV2TokenToETH( address fromToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool isIncentive, uint256 deadLine ) external returns (uint256 returnAmount); function dodoSwapV2TokenToToken( address fromToken, address toToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool isIncentive, uint256 deadLine ) external returns (uint256 returnAmount); function createDODOVendingMachine( address baseToken, address quoteToken, uint256 baseInAmount, uint256 quoteInAmount, uint256 lpFeeRate, uint256 i, uint256 k, bool isOpenTWAP, uint256 deadLine ) external payable returns (address newVendingMachine, uint256 shares); function addDVMLiquidity( address dvmAddress, uint256 baseInAmount, uint256 quoteInAmount, uint256 baseMinAmount, uint256 quoteMinAmount, uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH uint256 deadLine ) external payable returns ( uint256 shares, uint256 baseAdjustedInAmount, uint256 quoteAdjustedInAmount ); // function createDODOPrivatePool( // address baseToken, // address quoteToken, // uint256 baseInAmount, // uint256 quoteInAmount, // uint256 lpFeeRate, // uint256 i, // uint256 k, // bool isOpenTwap, // uint256 deadLine // ) external payable returns (address newPrivatePool); // function resetDODOPrivatePool( // address dppAddress, // uint256[] memory paramList, //0 - newLpFeeRate, 1 - newI, 2 - newK // uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3 - quoteOutAmount // uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH // uint256 minBaseReserve, // uint256 minQuoteReserve, // uint256 deadLine // ) external payable; // function bid( // address cpAddress, // uint256 quoteAmount, // uint8 flag, // 0 - ERC20, 1 - quoteInETH // uint256 deadLine // ) external payable; function addLiquidityToV1( address pair, uint256 baseAmount, uint256 quoteAmount, uint256 baseMinShares, uint256 quoteMinShares, uint8 flag, // 0 erc20 Out 1 baseInETH 2 quoteInETH uint256 deadLine ) external payable returns(uint256, uint256); function dodoSwapV1( address fromToken, address toToken, uint256 fromTokenAmount, uint256 minReturnAmount, address[] memory dodoPairs, uint256 directions, bool isIncentive, uint256 deadLine ) external payable returns (uint256 returnAmount); function externalSwap( address fromToken, address toToken, address approveTarget, address to, uint256 fromTokenAmount, uint256 minReturnAmount, bytes memory callDataConcat, bool isIncentive, uint256 deadLine ) external payable returns (uint256 returnAmount); // function mixSwap( // address fromToken, // address toToken, // uint256 fromTokenAmount, // uint256 minReturnAmount, // address[] memory mixAdapters, // address[] memory mixPairs, // address[] memory assetTo, // uint256 directions, // bool isIncentive, // uint256 deadLine // ) external payable returns (uint256 returnAmount); }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IDODOV2 { //========== Common ================== function sellBase(address to) external returns (uint256 receiveQuoteAmount); function sellQuote(address to) external returns (uint256 receiveBaseAmount); function getVaultReserve() external view returns (uint256 baseReserve, uint256 quoteReserve); function _BASE_TOKEN_() external view returns (address); function _QUOTE_TOKEN_() external view returns (address); function getPMMStateForCall() external view returns ( uint256 i, uint256 K, uint256 B, uint256 Q, uint256 B0, uint256 Q0, uint256 R ); function getUserFeeRate(address user) external view returns (uint256 lpFeeRate, uint256 mtFeeRate); function getDODOPoolBidirection(address token0, address token1) external view returns (address[] memory, address[] memory); //========== DODOVendingMachine ======== function createDODOVendingMachine( address baseToken, address quoteToken, uint256 lpFeeRate, uint256 i, uint256 k, bool isOpenTWAP ) external returns (address newVendingMachine); function buyShares(address to) external returns (uint256,uint256,uint256); //========== DODOPrivatePool =========== function createDODOPrivatePool() external returns (address newPrivatePool); function initDODOPrivatePool( address dppAddress, address creator, address baseToken, address quoteToken, uint256 lpFeeRate, uint256 k, uint256 i, bool isOpenTwap ) external; function reset( address operator, uint256 newLpFeeRate, uint256 newI, uint256 newK, uint256 baseOutAmount, uint256 quoteOutAmount, uint256 minBaseReserve, uint256 minQuoteReserve ) external returns (bool); function _OWNER_() external returns (address); //========== CrowdPooling =========== function createCrowdPooling() external returns (address payable newCrowdPooling); function initCrowdPooling( address cpAddress, address creator, address[] memory tokens, uint256[] memory timeLine, uint256[] memory valueList, bool[] memory switches, int globalQuota ) external; function bid(address to) external; }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IDODOV1 { function init( address owner, address supervisor, address maintainer, address baseToken, address quoteToken, address oracle, uint256 lpFeeRate, uint256 mtFeeRate, uint256 k, uint256 gasPriceLimit ) external; function transferOwnership(address newOwner) external; function claimOwnership() external; function sellBaseToken( uint256 amount, uint256 minReceiveQuote, bytes calldata data ) external returns (uint256); function buyBaseToken( uint256 amount, uint256 maxPayQuote, bytes calldata data ) external returns (uint256); function querySellBaseToken(uint256 amount) external view returns (uint256 receiveQuote); function queryBuyBaseToken(uint256 amount) external view returns (uint256 payQuote); function depositBaseTo(address to, uint256 amount) external returns (uint256); function withdrawBase(uint256 amount) external returns (uint256); function withdrawAllBase() external returns (uint256); function depositQuoteTo(address to, uint256 amount) external returns (uint256); function withdrawQuote(uint256 amount) external returns (uint256); function withdrawAllQuote() external returns (uint256); function _BASE_CAPITAL_TOKEN_() external returns (address); function _QUOTE_CAPITAL_TOKEN_() external returns (address); function _BASE_TOKEN_() external view returns (address); function _QUOTE_TOKEN_() external view returns (address); function _R_STATUS_() external view returns (uint8); function _QUOTE_BALANCE_() external view returns (uint256); function _BASE_BALANCE_() external view returns (uint256); function _K_() external view returns (uint256); function _MT_FEE_RATE_() external view returns (uint256); function _LP_FEE_RATE_() external view returns (uint256); function getExpectedTarget() external view returns (uint256 baseTarget, uint256 quoteTarget); function getOraclePrice() external view returns (uint256); function getMidPrice() external view returns (uint256 midPrice); }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; interface IDODOAdapter { function sellBase(address to, address pool, bytes memory data) external; function sellQuote(address to, address pool, bytes memory data) external; }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {IDODOV1} from "../intf/IDODOV1.sol"; import {SafeMath} from "../../lib/SafeMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol"; // import {DODOMath} from "../lib/DODOMath.sol"; interface IDODOSellHelper { function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256); function querySellBaseToken(address dodo, uint256 amount) external view returns (uint256); } library DODOMath { using SafeMath for uint256; /* Integrate dodo curve fron V1 to V2 require V0>=V1>=V2>0 res = (1-k)i(V1-V2)+ikV0*V0(1/V2-1/V1) let V1-V2=delta res = i*delta*(1-k+k(V0^2/V1/V2)) */ function _GeneralIntegrate( uint256 V0, uint256 V1, uint256 V2, uint256 i, uint256 k ) internal pure returns (uint256) { uint256 fairAmount = DecimalMath.mulFloor(i, V1.sub(V2)); // i*delta uint256 V0V0V1V2 = DecimalMath.divCeil(V0.mul(V0).div(V1), V2); uint256 penalty = DecimalMath.mulFloor(k, V0V0V1V2); // k(V0^2/V1/V2) return DecimalMath.mulFloor(fairAmount, DecimalMath.ONE.sub(k).add(penalty)); } /* The same with integration expression above, we have: i*deltaB = (Q2-Q1)*(1-k+kQ0^2/Q1/Q2) Given Q1 and deltaB, solve Q2 This is a quadratic function and the standard version is aQ2^2 + bQ2 + c = 0, where a=1-k -b=(1-k)Q1-kQ0^2/Q1+i*deltaB c=-kQ0^2 and Q2=(-b+sqrt(b^2+4(1-k)kQ0^2))/2(1-k) note: another root is negative, abondan if deltaBSig=true, then Q2>Q1 if deltaBSig=false, then Q2<Q1 */ function _SolveQuadraticFunctionForTrade( uint256 Q0, uint256 Q1, uint256 ideltaB, bool deltaBSig, uint256 k ) internal pure returns (uint256) { // calculate -b value and sig // -b = (1-k)Q1-kQ0^2/Q1+i*deltaB uint256 kQ02Q1 = DecimalMath.mulFloor(k, Q0).mul(Q0).div(Q1); // kQ0^2/Q1 uint256 b = DecimalMath.mulFloor(DecimalMath.ONE.sub(k), Q1); // (1-k)Q1 bool minusbSig = true; if (deltaBSig) { b = b.add(ideltaB); // (1-k)Q1+i*deltaB } else { kQ02Q1 = kQ02Q1.add(ideltaB); // i*deltaB+kQ0^2/Q1 } if (b >= kQ02Q1) { b = b.sub(kQ02Q1); minusbSig = true; } else { b = kQ02Q1.sub(b); minusbSig = false; } // calculate sqrt uint256 squareRoot = DecimalMath.mulFloor( DecimalMath.ONE.sub(k).mul(4), DecimalMath.mulFloor(k, Q0).mul(Q0) ); // 4(1-k)kQ0^2 squareRoot = b.mul(b).add(squareRoot).sqrt(); // sqrt(b*b+4(1-k)kQ0*Q0) // final res uint256 denominator = DecimalMath.ONE.sub(k).mul(2); // 2(1-k) uint256 numerator; if (minusbSig) { numerator = b.add(squareRoot); } else { numerator = squareRoot.sub(b); } if (deltaBSig) { return DecimalMath.divFloor(numerator, denominator); } else { return DecimalMath.divCeil(numerator, denominator); } } /* Start from the integration function i*deltaB = (Q2-Q1)*(1-k+kQ0^2/Q1/Q2) Assume Q2=Q0, Given Q1 and deltaB, solve Q0 let fairAmount = i*deltaB */ function _SolveQuadraticFunctionForTarget( uint256 V1, uint256 k, uint256 fairAmount ) internal pure returns (uint256 V0) { // V0 = V1+V1*(sqrt-1)/2k uint256 sqrt = DecimalMath.divCeil(DecimalMath.mulFloor(k, fairAmount).mul(4), V1); sqrt = sqrt.add(DecimalMath.ONE).mul(DecimalMath.ONE).sqrt(); uint256 premium = DecimalMath.divCeil(sqrt.sub(DecimalMath.ONE), k.mul(2)); // V0 is greater than or equal to V1 according to the solution return DecimalMath.mulFloor(V1, DecimalMath.ONE.add(premium)); } } contract DODOSellHelper { using SafeMath for uint256; enum RStatus {ONE, ABOVE_ONE, BELOW_ONE} uint256 constant ONE = 10**18; struct DODOState { uint256 oraclePrice; uint256 K; uint256 B; uint256 Q; uint256 baseTarget; uint256 quoteTarget; RStatus rStatus; } function querySellBaseToken(address dodo, uint256 amount) public view returns (uint256) { return IDODOV1(dodo).querySellBaseToken(amount); } function querySellQuoteToken(address dodo, uint256 amount) public view returns (uint256) { DODOState memory state; (state.baseTarget, state.quoteTarget) = IDODOV1(dodo).getExpectedTarget(); state.rStatus = RStatus(IDODOV1(dodo)._R_STATUS_()); state.oraclePrice = IDODOV1(dodo).getOraclePrice(); state.Q = IDODOV1(dodo)._QUOTE_BALANCE_(); state.B = IDODOV1(dodo)._BASE_BALANCE_(); state.K = IDODOV1(dodo)._K_(); uint256 boughtAmount; // Determine the status (RStatus) and calculate the amount // based on the state if (state.rStatus == RStatus.ONE) { boughtAmount = _ROneSellQuoteToken(amount, state); } else if (state.rStatus == RStatus.ABOVE_ONE) { boughtAmount = _RAboveSellQuoteToken(amount, state); } else { uint256 backOneBase = state.B.sub(state.baseTarget); uint256 backOneQuote = state.quoteTarget.sub(state.Q); if (amount <= backOneQuote) { boughtAmount = _RBelowSellQuoteToken(amount, state); } else { boughtAmount = backOneBase.add( _ROneSellQuoteToken(amount.sub(backOneQuote), state) ); } } // Calculate fees return DecimalMath.divFloor( boughtAmount, DecimalMath.ONE.add(IDODOV1(dodo)._MT_FEE_RATE_()).add( IDODOV1(dodo)._LP_FEE_RATE_() ) ); } function _ROneSellQuoteToken(uint256 amount, DODOState memory state) internal pure returns (uint256 receiveBaseToken) { uint256 i = DecimalMath.divFloor(ONE, state.oraclePrice); uint256 B2 = DODOMath._SolveQuadraticFunctionForTrade( state.baseTarget, state.baseTarget, DecimalMath.mulFloor(i, amount), false, state.K ); return state.baseTarget.sub(B2); } function _RAboveSellQuoteToken(uint256 amount, DODOState memory state) internal pure returns (uint256 receieBaseToken) { uint256 i = DecimalMath.divFloor(ONE, state.oraclePrice); uint256 B2 = DODOMath._SolveQuadraticFunctionForTrade( state.baseTarget, state.B, DecimalMath.mulFloor(i, amount), false, state.K ); return state.B.sub(B2); } function _RBelowSellQuoteToken(uint256 amount, DODOState memory state) internal pure returns (uint256 receiveBaseToken) { uint256 Q1 = state.Q.add(amount); uint256 i = DecimalMath.divFloor(ONE, state.oraclePrice); return DODOMath._GeneralIntegrate(state.quoteTarget, Q1, state.Q, i, state.K); } }
/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; import {IDODOApprove} from "../intf/IDODOApprove.sol"; import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; interface IDODOApproveProxy { function isAllowedProxy(address _proxy) external view returns (bool); function claimTokens(address token,address who,address dest,uint256 amount) external; } /** * @title DODOApproveProxy * @author DODO Breeder * * @notice Allow different version dodoproxy to claim from DODOApprove */ contract DODOApproveProxy is InitializableOwnable { // ============ Storage ============ uint256 private constant _TIMELOCK_DURATION_ = 3 days; mapping (address => bool) public _IS_ALLOWED_PROXY_; uint256 public _TIMELOCK_; address public _PENDING_ADD_DODO_PROXY_; address public immutable _DODO_APPROVE_; // ============ Modifiers ============ modifier notLocked() { require( _TIMELOCK_ <= block.timestamp, "SetProxy is timelocked" ); _; } constructor(address dodoApporve) public { _DODO_APPROVE_ = dodoApporve; } function init(address owner, address[] memory proxies) external { initOwner(owner); for(uint i = 0; i < proxies.length; i++) _IS_ALLOWED_PROXY_[proxies[i]] = true; } function unlockAddProxy(address newDodoProxy) public onlyOwner { _TIMELOCK_ = block.timestamp + _TIMELOCK_DURATION_; _PENDING_ADD_DODO_PROXY_ = newDodoProxy; } function lockAddProxy() public onlyOwner { _PENDING_ADD_DODO_PROXY_ = address(0); _TIMELOCK_ = 0; } function addDODOProxy() external onlyOwner notLocked() { _IS_ALLOWED_PROXY_[_PENDING_ADD_DODO_PROXY_] = true; lockAddProxy(); } function removeDODOProxy (address oldDodoProxy) public onlyOwner { _IS_ALLOWED_PROXY_[oldDodoProxy] = false; } function claimTokens( address token, address who, address dest, uint256 amount ) external { require(_IS_ALLOWED_PROXY_[msg.sender], "DODOApproveProxy:Access restricted"); IDODOApprove(_DODO_APPROVE_).claimTokens( token, who, dest, amount ); } function isAllowedProxy(address _proxy) external view returns (bool) { return _IS_ALLOWED_PROXY_[_proxy]; } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"dvmFactory","type":"address"},{"internalType":"address payable","name":"weth","type":"address"},{"internalType":"address","name":"dodoApproveProxy","type":"address"},{"internalType":"address","name":"dodoSellHelper","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fromToken","type":"address"},{"indexed":false,"internalType":"address","name":"toToken","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"}],"name":"OrderHistory","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferPrepared","type":"event"},{"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":"_DODO_APPROVE_PROXY_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_DODO_SELL_HELPER_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_DVM_FACTORY_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_NEW_OWNER_","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":"_WETH_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dvmAddress","type":"address"},{"internalType":"uint256","name":"baseInAmount","type":"uint256"},{"internalType":"uint256","name":"quoteInAmount","type":"uint256"},{"internalType":"uint256","name":"baseMinAmount","type":"uint256"},{"internalType":"uint256","name":"quoteMinAmount","type":"uint256"},{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"addDVMLiquidity","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"baseAdjustedInAmount","type":"uint256"},{"internalType":"uint256","name":"quoteAdjustedInAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"uint256","name":"baseAmount","type":"uint256"},{"internalType":"uint256","name":"quoteAmount","type":"uint256"},{"internalType":"uint256","name":"baseMinShares","type":"uint256"},{"internalType":"uint256","name":"quoteMinShares","type":"uint256"},{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"addLiquidityToV1","outputs":[{"internalType":"uint256","name":"baseShares","type":"uint256"},{"internalType":"uint256","name":"quoteShares","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddr","type":"address"}],"name":"addWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"baseToken","type":"address"},{"internalType":"address","name":"quoteToken","type":"address"},{"internalType":"uint256","name":"baseInAmount","type":"uint256"},{"internalType":"uint256","name":"quoteInAmount","type":"uint256"},{"internalType":"uint256","name":"lpFeeRate","type":"uint256"},{"internalType":"uint256","name":"i","type":"uint256"},{"internalType":"uint256","name":"k","type":"uint256"},{"internalType":"bool","name":"isOpenTWAP","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"createDODOVendingMachine","outputs":[{"internalType":"address","name":"newVendingMachine","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"address[]","name":"dodoPairs","type":"address[]"},{"internalType":"uint256","name":"directions","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"dodoSwapV1","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"address[]","name":"dodoPairs","type":"address[]"},{"internalType":"uint256","name":"directions","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"dodoSwapV2ETHToToken","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"address[]","name":"dodoPairs","type":"address[]"},{"internalType":"uint256","name":"directions","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"dodoSwapV2TokenToETH","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"address[]","name":"dodoPairs","type":"address[]"},{"internalType":"uint256","name":"directions","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"dodoSwapV2TokenToToken","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"address","name":"approveTarget","type":"address"},{"internalType":"address","name":"swapTarget","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"bytes","name":"callDataConcat","type":"bytes"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"deadLine","type":"uint256"}],"name":"externalSwap","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"initOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhiteListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddr","type":"address"}],"name":"removeWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61010060405234801561001157600080fd5b50604051613ec1380380613ec18339818101604052608081101561003457600080fd5b508051602082015160408301516060938401516001600160601b031993851b841660e05291841b8316608052831b821660a05290911b1660c05260805160601c60a05160601c60c05160601c60e05160601c613dc26100ff6000398061251852806126de525080610d215280612b8552508061112d5280611f0f5280612c1d5280612e4c52806133e35250806109105280610e7b5280610f1152806114ca528061157f528061192c52806119905280612624528061267452806132f7528061337f5250613dc26000f3fe6080604052600436106101235760003560e01c806369e4e417116100a0578063af1280b011610064578063af1280b014610710578063e7cd4a0414610725578063eb99be1214610758578063f2fde38b1461076d578063f87dc1b7146107a05761012a565b806369e4e417146105b85780636f9170f6146105cd5780638456db15146106145780638b3bb0891461062957806399882c8f146106aa5761012a565b80632042e5c2116100e75780632042e5c2146103625780634e71e0c8146103955780635028bb95146103aa57806354bacd131461046d578063674d94221461054d5761012a565b80630d0092971461012c5780630d4eec8f1461015f5780630dd4ebd91461019057806316048bc4146102765780631e6d24c21461028b5761012a565b3661012a57005b005b34801561013857600080fd5b5061012a6004803603602081101561014f57600080fd5b50356001600160a01b0316610881565b34801561016b57600080fd5b5061017461090e565b604080516001600160a01b039092168252519081900360200190f35b61026460048036036101008110156101a757600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b8111156101e657600080fd5b8201836020820111156101f857600080fd5b803590602001918460208302840111600160201b8311171561021957600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135610932565b60408051918252519081900360200190f35b34801561028257600080fd5b5061017461103f565b34801561029757600080fd5b50610264600480360360e08110156102ae57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b8111156102e457600080fd5b8201836020820111156102f657600080fd5b803590602001918460208302840111600160201b8311171561031757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135611053565b34801561036e57600080fd5b5061012a6004803603602081101561038557600080fd5b50356001600160a01b031661168c565b3480156103a157600080fd5b5061012a6116fd565b610264600480360360c08110156103c057600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156103ef57600080fd5b82018360208201111561040157600080fd5b803590602001918460208302840111600160201b8311171561042257600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550508235935050506020810135151590604001356117c1565b610264600480360361012081101561048457600080fd5b6001600160a01b038235811692602081013582169260408201358316926060830135169160808101359160a0820135919081019060e0810160c0820135600160201b8111156104d257600080fd5b8201836020820111156104e457600080fd5b803590602001918460018302840111600160201b8311171561050557600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060200135611e14565b61059a600480360360e081101561056357600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060ff60a0820135169060c00135612210565b60408051938452602084019290925282820152519081900360600190f35b3480156105c457600080fd5b50610174612516565b3480156105d957600080fd5b50610600600480360360208110156105f057600080fd5b50356001600160a01b031661253a565b604080519115158252519081900360200190f35b34801561062057600080fd5b5061017461254f565b610687600480360361012081101561064057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a08101359060c08101359060e0810135151590610100013561255e565b604080516001600160a01b03909316835260208301919091528051918290030190f35b6106f7600480360360e08110156106c057600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060ff60a0820135169060c00135612848565b6040805192835260208301919091528051918290030190f35b34801561071c57600080fd5b50610174612b83565b34801561073157600080fd5b5061012a6004803603602081101561074857600080fd5b50356001600160a01b0316612ba7565b34801561076457600080fd5b50610174612c1b565b34801561077957600080fd5b5061012a6004803603602081101561079057600080fd5b50356001600160a01b0316612c3f565b3480156107ac57600080fd5b5061026460048036036101008110156107c457600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561080357600080fd5b82018360208201111561081557600080fd5b803590602001918460208302840111600160201b8311171561083657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135612cef565b600154600160a01b900460ff16156108d3576040805162461bcd60e51b815260206004820152601060248201526f1113d113d7d25392551250531256915160821b604482015290519081900360640190fd5b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008142811015610978576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008651116109cb576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b60008711610a0a5760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b8989610a383330848d6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b60005b8851811015610e35576000898281518110610a5257fe5b602002602001015190508860011660001415610bfa576000816001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610aa357600080fd5b505afa158015610ab7573d6000803e3d6000fd5b505050506040513d6020811015610acd57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610b1b57600080fd5b505afa158015610b2f573d6000803e3d6000fd5b505050506040513d6020811015610b4557600080fd5b50519050610b636001600160a01b038316848363ffffffff61344d16565b826001600160a01b0316638dae73338260006040518363ffffffff1660e01b815260040180838152602001828152602001806020018281038252600081526020016020019350505050602060405180830381600087803b158015610bc657600080fd5b505af1158015610bda573d6000803e3d6000fd5b505050506040513d6020811015610bf057600080fd5b50610e2892505050565b6000816001600160a01b031663d4b970466040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3557600080fd5b505afa158015610c49573d6000803e3d6000fd5b505050506040513d6020811015610c5f57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d6020811015610cd757600080fd5b50519050610cf56001600160a01b038316848363ffffffff61344d16565b6040805163ca19ebd960e01b81526001600160a01b0385811660048301526024820184905291516000927f0000000000000000000000000000000000000000000000000000000000000000169163ca19ebd9916044808301926020929190829003018186803b158015610d6757600080fd5b505afa158015610d7b573d6000803e3d6000fd5b505050506040513d6020811015610d9157600080fd5b50516040805163733e738360e11b815260048101839052602481018590526060604482015260006064820181905291519293506001600160a01b0387169263e67ce7069260a480840193602093929083900390910190829087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b505050506040513d6020811015610e2257600080fd5b50505050505b50600197881c9701610a3b565b506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610f7657604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b158015610ec157600080fd5b505afa158015610ed5573d6000803e3d6000fd5b505050506040513d6020811015610eeb57600080fd5b505160408051632e1a7d4d60e01b81526004810183905290519195506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632e1a7d4d9160248082019260009290919082900301818387803b158015610f5957600080fd5b505af1158015610f6d573d6000803e3d6000fd5b50505050610f92565b610f8f6001600160a01b0382163063ffffffff61351716565b93505b88841015610fd15760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b610feb6001600160a01b038216338663ffffffff6135a416565b604080516001600160a01b038085168252831660208201523381830152606081018c9052608081018690529051600080516020613c3f8339815191529181900360a00190a150505098975050505050505050565b60005461010090046001600160a01b031681565b60008142811015611099576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008651116110ec576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b6000871161112b5760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630a5ea4668a338960008151811061116957fe5b60200260200101518c6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b1580156111f357600080fd5b505af1158015611207573d6000803e3d6000fd5b506000925050505b86518110156114a957600187510381141561136657600186166112c95786818151811061123857fe5b60200260200101516001600160a01b031663bd6015b4306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506040513d60208110156112c157600080fd5b506113619050565b8681815181106112d557fe5b60200260200101516001600160a01b031663dd93f59a306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561133457600080fd5b505af1158015611348573d6000803e3d6000fd5b505050506040513d602081101561135e57600080fd5b50505b61149d565b600186166113ef5786818151811061137a57fe5b60200260200101516001600160a01b031663bd6015b488836001018151811061139f57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561133457600080fd5b8681815181106113fb57fe5b60200260200101516001600160a01b031663dd93f59a88836001018151811061142057fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561147057600080fd5b505af1158015611484573d6000803e3d6000fd5b505050506040513d602081101561149a57600080fd5b50505b600195861c950161120f565b50604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b15801561151057600080fd5b505afa158015611524573d6000803e3d6000fd5b505050506040513d602081101561153a57600080fd5b505191508682101561157d5760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156115e357600080fd5b505af11580156115f7573d6000803e3d6000fd5b505060405133925084156108fc02915084906000818181858888f19350505050158015611628573d6000803e3d6000fd5b50604080516001600160a01b038b16815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60208201523381830152606081018a9052608081018490529051600080516020613c3f8339815191529181900360a00190a150979650505050505050565b60005461010090046001600160a01b031633146116dc576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b6001600160a01b03166000908152600260205260409020805460ff19169055565b6001546001600160a01b0316331461174c576040805162461bcd60e51b815260206004820152600d60248201526c494e56414c49445f434c41494d60981b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693610100909204909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36001805460008054610100600160a81b0319166101006001600160a01b038416021790556001600160a01b0319169055565b60008142811015611807576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b600086511161185a576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b600087116118995760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b604080516370a0823160e01b815233600482015290516000916001600160a01b038b16916370a0823191602480820192602092909190829003018186803b1580156118e357600080fd5b505afa1580156118f7573d6000803e3d6000fd5b505050506040513d602081101561190d57600080fd5b505160408051630d0e30db60e41b815290519192506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163d0e30db0913491600480830192600092919082900301818588803b15801561197557600080fd5b505af1158015611989573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb886000815181106119ca57fe5b6020026020010151346040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611a2257600080fd5b505af1158015611a36573d6000803e3d6000fd5b505050506040513d6020811015611a4c57600080fd5b50600090505b8751811015611cec576001885103811415611ba95760018716611b0c57878181518110611a7b57fe5b60200260200101516001600160a01b031663bd6015b4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611ada57600080fd5b505af1158015611aee573d6000803e3d6000fd5b505050506040513d6020811015611b0457600080fd5b50611ba49050565b878181518110611b1857fe5b60200260200101516001600160a01b031663dd93f59a336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b7757600080fd5b505af1158015611b8b573d6000803e3d6000fd5b505050506040513d6020811015611ba157600080fd5b50505b611ce0565b60018716611c3257878181518110611bbd57fe5b60200260200101516001600160a01b031663bd6015b4898360010181518110611be257fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b7757600080fd5b878181518110611c3e57fe5b60200260200101516001600160a01b031663dd93f59a898360010181518110611c6357fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b505050506040513d6020811015611cdd57600080fd5b50505b600196871c9601611a52565b50604080516370a0823160e01b81523360048201529051611d719183916001600160a01b038d16916370a08231916024808301926020929190829003018186803b158015611d3957600080fd5b505afa158015611d4d573d6000803e3d6000fd5b505050506040513d6020811015611d6357600080fd5b50519063ffffffff61361316565b925087831015611db25760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b6040805173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81526001600160a01b038b1660208201523381830152346060820152608081018590529051600080516020613c3f8339815191529181900360a00190a150509695505050505050565b60008142811015611e5a576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008611611e995760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b6000611eb46001600160a01b038c163363ffffffff61365c16565b90506001600160a01b038c1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611f86576040805163052f523360e11b81526001600160a01b038e81166004830152336024830152306044830152606482018b905291517f000000000000000000000000000000000000000000000000000000000000000090921691630a5ea4669160848082019260009290919082900301818387803b158015611f5957600080fd5b505af1158015611f6d573d6000803e3d6000fd5b50611f86925050506001600160a01b038d168b8a61344d565b6001600160a01b03891660009081526002602052604090205460ff16611fdd5760405162461bcd60e51b8152600401808060200182810382526025815260200180613cdb6025913960400191505060405180910390fd5b60006001600160a01b03808b16908e1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461200e576000612010565b345b886040518082805190602001908083835b602083106120405780518252601f199092019160209182019101612021565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146120a2576040519150601f19603f3d011682016040523d82523d6000602084013e6120a7565b606091505b50509050806120e75760405162461bcd60e51b815260040180806020018281038252602d815260200180613d00602d913960400191505060405180910390fd5b61211b336121046001600160a01b038f163063ffffffff61365c16565b6001600160a01b038f16919063ffffffff6135a416565b612144826121386001600160a01b038f163363ffffffff61365c16565b9063ffffffff61361316565b9350878410156121855760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b600080516020613c3f8339815191528d8d338c8860405180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018281526020019550505050505060405180910390a15050509998505050505050505050565b600080548190819060ff1615612259576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905583428110156122aa576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b8a6122b6818c8c613706565b90945092508884108015906122cb5750878310155b6123065760405162461bcd60e51b815260040180806020018281038252602b815260200180613cb0602b913960400191505060405180910390fd5b61237d3382836001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561234457600080fd5b505afa158015612358573d6000803e3d6000fd5b505050506040513d602081101561236e57600080fd5b505187600160ff8d16146132a3565b6123f43382836001600160a01b031663d4b970466040518163ffffffff1660e01b815260040160206040518083038186803b1580156123bb57600080fd5b505afa1580156123cf573d6000803e3d6000fd5b505050506040513d60208110156123e557600080fd5b505186600260ff8d16146132a3565b60408051634c85b42560e01b815233600482015290516001600160a01b03831691634c85b4259160248083019260609291908290030181600087803b15801561243c57600080fd5b505af1158015612450573d6000803e3d6000fd5b505050506040513d606081101561246657600080fd5b50519450600160ff881614801561247c57508334115b156124b25760405133903486900380156108fc02916000818181858888f193505050501580156124b0573d6000803e3d6000fd5b505b8660ff1660021480156124c457508234115b156124fa5760405133903485900380156108fc02916000818181858888f193505050501580156124f8573d6000803e3d6000fd5b505b50506000805460ff191690559199909850909650945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60026020526000908152604090205460ff1681565b6001546001600160a01b031681565b60008054819060ff16156125a5576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905582428110156125f6576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60006001600160a01b038d1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612622578c612644565b7f00000000000000000000000000000000000000000000000000000000000000005b905060006001600160a01b038d1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612672578c612694565b7f00000000000000000000000000000000000000000000000000000000000000005b6040805163e18c40c760e01b81526001600160a01b0385811660048301528381166024830152604482018e9052606482018d9052608482018c90528a151560a483015291519293507f00000000000000000000000000000000000000000000000000000000000000009091169163e18c40c79160c4808201926020929091908290030181600087803b15801561272957600080fd5b505af115801561273d573d6000803e3d6000fd5b505050506040513d602081101561275357600080fd5b505194508d91508c90506127893386848f6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b6127b53386838e6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b505060408051634c85b42560e01b815233600482015290516001600160a01b03851691634c85b4259160248083019260609291908290030181600087803b1580156127ff57600080fd5b505af1158015612813573d6000803e3d6000fd5b505050506040513d606081101561282957600080fd5b50516000805460ff19169055929c929b50919950505050505050505050565b60008054819060ff161561288f576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905582428110156128e0576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008a6001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561291b57600080fd5b505afa15801561292f573d6000803e3d6000fd5b505050506040513d602081101561294557600080fd5b505160408051636a5cb82360e11b815290519192506000916001600160a01b038e169163d4b97046916004808301926020929190829003018186803b15801561298d57600080fd5b505afa1580156129a1573d6000803e3d6000fd5b505050506040513d60208110156129b757600080fd5b505190506129ce3330848e600160ff8d16146132a3565b6129e13330838d8b60ff166002146132a3565b8a15612a7f57612a016001600160a01b0383168d8d63ffffffff61344d16565b6040805163aa06ce9b60e01b8152336004820152602481018d905290516001600160a01b038e169163aa06ce9b9160448083019260209291908290030181600087803b158015612a5057600080fd5b505af1158015612a64573d6000803e3d6000fd5b505050506040513d6020811015612a7a57600080fd5b505194505b8915612b1d57612a9f6001600160a01b0382168d8c63ffffffff61344d16565b604080516317c5e7d960e21b8152336004820152602481018c905290516001600160a01b038e1691635f179f649160448083019260209291908290030181600087803b158015612aee57600080fd5b505af1158015612b02573d6000803e3d6000fd5b505050506040513d6020811015612b1857600080fd5b505193505b888510158015612b2d5750878410155b612b685760405162461bcd60e51b8152600401808060200182810382526027815260200180613c896027913960400191505060405180910390fd5b50506000805460ff1916905550909890975095505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005461010090046001600160a01b03163314612bf7576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b6001600160a01b03166000908152600260205260409020805460ff19166001179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005461010090046001600160a01b03163314612c8f576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b600080546040516001600160a01b038085169361010090930416917fdcf55418cee3220104fef63f979ff3c4097ad240c0c43dcb33ce837748983e6291a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008142811015612d35576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b6000865111612d88576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b60008711612dc75760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b604080516370a0823160e01b815233600482015290516000916001600160a01b038c16916370a0823191602480820192602092909190829003018186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d6020811015612e3b57600080fd5b505187519091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630a5ea466908d9033908b90600090612e8257fe5b60200260200101518d6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b158015612f0c57600080fd5b505af1158015612f20573d6000803e3d6000fd5b506000925050505b87518110156131c257600188510381141561307f5760018716612fe257878181518110612f5157fe5b60200260200101516001600160a01b031663bd6015b4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015612fb057600080fd5b505af1158015612fc4573d6000803e3d6000fd5b505050506040513d6020811015612fda57600080fd5b5061307a9050565b878181518110612fee57fe5b60200260200101516001600160a01b031663dd93f59a336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561304d57600080fd5b505af1158015613061573d6000803e3d6000fd5b505050506040513d602081101561307757600080fd5b50505b6131b6565b600187166131085787818151811061309357fe5b60200260200101516001600160a01b031663bd6015b48983600101815181106130b857fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561304d57600080fd5b87818151811061311457fe5b60200260200101516001600160a01b031663dd93f59a89836001018151811061313957fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561318957600080fd5b505af115801561319d573d6000803e3d6000fd5b505050506040513d60208110156131b357600080fd5b50505b600196871c9601612f28565b50604080516370a0823160e01b8152336004820152905161320f9183916001600160a01b038e16916370a08231916024808301926020929190829003018186803b158015611d3957600080fd5b9250878310156132505760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b604080516001600160a01b03808e1682528c1660208201523381830152606081018b9052608081018590529051600080516020613c3f8339815191529181900360a00190a1505098975050505050505050565b80156133aa5781156133a5578134146132f5576040805162461bcd60e51b815260206004820152600f60248201526e4554485f56414c55455f57524f4e4760881b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561335057600080fd5b505af1158015613364573d6000803e3d6000fd5b505050506001600160a01b038516301490506133a5576133a57f00000000000000000000000000000000000000000000000000000000000000008584613818565b613446565b6040805163052f523360e11b81526001600160a01b038581166004830152878116602483015286811660448301526064820185905291517f000000000000000000000000000000000000000000000000000000000000000090921691630a5ea4669160848082019260009290919082900301818387803b15801561342d57600080fd5b505af1158015613441573d6000803e3d6000fd5b505050505b5050505050565b60408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b15801561349e57600080fd5b505afa1580156134b2573d6000803e3d6000fd5b505050506040513d60208110156134c857600080fd5b50519050818110156135115780156134f5576134f56001600160a01b03851684600063ffffffff61386a16565b6135116001600160a01b0385168460001963ffffffff61386a16565b50505050565b6000826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561356f57600080fd5b505afa158015613583573d6000803e3d6000fd5b505050506040513d602081101561359957600080fd5b505190505b92915050565b801561360e576135b38361397d565b156135f4576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156135ee573d6000803e3d6000fd5b5061360e565b61360e6001600160a01b038416838363ffffffff61381816565b505050565b600082821115613656576040805162461bcd60e51b815260206004820152600960248201526829aaa12fa2a92927a960b91b604482015290519081900360640190fd5b50900390565b60006136678361397d565b1561367d57506001600160a01b0381163161359e565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156136d357600080fd5b505afa1580156136e7573d6000803e3d6000fd5b505050506040513d60208110156136fd57600080fd5b5051905061359e565b600080600080866001600160a01b03166336223ce96040518163ffffffff1660e01b8152600401604080518083038186803b15801561374457600080fd5b505afa158015613758573d6000803e3d6000fd5b505050506040513d604081101561376e57600080fd5b508051602090910151909250905080158015613788575081155b15613794578593508492505b801580156137a25750600082115b156137af57859350600092505b6000811180156137bf5750600082115b1561380e5760006137d087846139a2565b905060006137de87846139a2565b90508082116137fb578795506137f483836139d3565b945061380b565b86945061380884826139d3565b95505b50505b5050935093915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261360e9084906139fd565b8015806138f0575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b1580156138c257600080fd5b505afa1580156138d6573d6000803e3d6000fd5b505050506040513d60208110156138ec57600080fd5b5051155b61392b5760405162461bcd60e51b8152600401808060200182810382526036815260200180613d576036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261360e9084906139fd565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b60006139cc826139c085670de0b6b3a764000063ffffffff613b5216565b9063ffffffff613bad16565b9392505050565b6000670de0b6b3a76400006139ee848463ffffffff613b5216565b816139f557fe5b049392505050565b60006060836001600160a01b0316836040518082805190602001908083835b60208310613a3b5780518252601f199092019160209182019101613a1c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613a9d576040519150601f19603f3d011682016040523d82523d6000602084013e613aa2565b606091505b509150915081613af9576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561351157808060200190516020811015613b1557600080fd5b50516135115760405162461bcd60e51b815260040180806020018281038252602a815260200180613d2d602a913960400191505060405180910390fd5b600082613b615750600061359e565b82820282848281613b6e57fe5b04146139cc576040805162461bcd60e51b815260206004820152600960248201526826aaa62fa2a92927a960b91b604482015290519081900360640190fd5b6000808211613bf4576040805162461bcd60e51b815260206004820152600e60248201526d2224ab24a224a723afa2a92927a960911b604482015290519081900360640190fd5b8183816139f557fefe444f444f563250726f787930323a2052455455524e5f414d4f554e545f5a45524f444f444f563250726f787930323a20455850495245440000000000000000000092ceb067a9883c85aba061e46b9edf505a0d6e81927c4b966ebed543a5221787444f444f563250726f787930323a2052657475726e20616d6f756e74206973206e6f7420656e6f756768444f444f563250726f787930323a2052657475726e20444c50206973206e6f7420656e6f756768444f444f563250726f787930323a206465706f73697420616d6f756e74206973206e6f7420656e6f756768444f444f563250726f787930323a204e6f742057686974656c69737420436f6e7472616374444f444f563250726f787930323a2045787465726e616c205377617020657865637574696f6e204661696c65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220359eb7e72a18e3a9904780feab8784644bfac53f80e75723e17fe9f4fb10578564736f6c634300060900330000000000000000000000005a0c840a7089aa222c4458b3be0947fe5a5006de00000000000000000000000053000000000000000000000000000000000000040000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca484920000000000000000000000008ea40e8da3ae64bad5e77a5f7db346499f543bac
Deployed Bytecode
0x6080604052600436106101235760003560e01c806369e4e417116100a0578063af1280b011610064578063af1280b014610710578063e7cd4a0414610725578063eb99be1214610758578063f2fde38b1461076d578063f87dc1b7146107a05761012a565b806369e4e417146105b85780636f9170f6146105cd5780638456db15146106145780638b3bb0891461062957806399882c8f146106aa5761012a565b80632042e5c2116100e75780632042e5c2146103625780634e71e0c8146103955780635028bb95146103aa57806354bacd131461046d578063674d94221461054d5761012a565b80630d0092971461012c5780630d4eec8f1461015f5780630dd4ebd91461019057806316048bc4146102765780631e6d24c21461028b5761012a565b3661012a57005b005b34801561013857600080fd5b5061012a6004803603602081101561014f57600080fd5b50356001600160a01b0316610881565b34801561016b57600080fd5b5061017461090e565b604080516001600160a01b039092168252519081900360200190f35b61026460048036036101008110156101a757600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b8111156101e657600080fd5b8201836020820111156101f857600080fd5b803590602001918460208302840111600160201b8311171561021957600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135610932565b60408051918252519081900360200190f35b34801561028257600080fd5b5061017461103f565b34801561029757600080fd5b50610264600480360360e08110156102ae57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b8111156102e457600080fd5b8201836020820111156102f657600080fd5b803590602001918460208302840111600160201b8311171561031757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135611053565b34801561036e57600080fd5b5061012a6004803603602081101561038557600080fd5b50356001600160a01b031661168c565b3480156103a157600080fd5b5061012a6116fd565b610264600480360360c08110156103c057600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156103ef57600080fd5b82018360208201111561040157600080fd5b803590602001918460208302840111600160201b8311171561042257600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550508235935050506020810135151590604001356117c1565b610264600480360361012081101561048457600080fd5b6001600160a01b038235811692602081013582169260408201358316926060830135169160808101359160a0820135919081019060e0810160c0820135600160201b8111156104d257600080fd5b8201836020820111156104e457600080fd5b803590602001918460018302840111600160201b8311171561050557600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060200135611e14565b61059a600480360360e081101561056357600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060ff60a0820135169060c00135612210565b60408051938452602084019290925282820152519081900360600190f35b3480156105c457600080fd5b50610174612516565b3480156105d957600080fd5b50610600600480360360208110156105f057600080fd5b50356001600160a01b031661253a565b604080519115158252519081900360200190f35b34801561062057600080fd5b5061017461254f565b610687600480360361012081101561064057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a08101359060c08101359060e0810135151590610100013561255e565b604080516001600160a01b03909316835260208301919091528051918290030190f35b6106f7600480360360e08110156106c057600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060ff60a0820135169060c00135612848565b6040805192835260208301919091528051918290030190f35b34801561071c57600080fd5b50610174612b83565b34801561073157600080fd5b5061012a6004803603602081101561074857600080fd5b50356001600160a01b0316612ba7565b34801561076457600080fd5b50610174612c1b565b34801561077957600080fd5b5061012a6004803603602081101561079057600080fd5b50356001600160a01b0316612c3f565b3480156107ac57600080fd5b5061026460048036036101008110156107c457600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561080357600080fd5b82018360208201111561081557600080fd5b803590602001918460208302840111600160201b8311171561083657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050823593505050602081013515159060400135612cef565b600154600160a01b900460ff16156108d3576040805162461bcd60e51b815260206004820152601060248201526f1113d113d7d25392551250531256915160821b604482015290519081900360640190fd5b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b7f000000000000000000000000530000000000000000000000000000000000000481565b60008142811015610978576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008651116109cb576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b60008711610a0a5760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b8989610a383330848d6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b60005b8851811015610e35576000898281518110610a5257fe5b602002602001015190508860011660001415610bfa576000816001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610aa357600080fd5b505afa158015610ab7573d6000803e3d6000fd5b505050506040513d6020811015610acd57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610b1b57600080fd5b505afa158015610b2f573d6000803e3d6000fd5b505050506040513d6020811015610b4557600080fd5b50519050610b636001600160a01b038316848363ffffffff61344d16565b826001600160a01b0316638dae73338260006040518363ffffffff1660e01b815260040180838152602001828152602001806020018281038252600081526020016020019350505050602060405180830381600087803b158015610bc657600080fd5b505af1158015610bda573d6000803e3d6000fd5b505050506040513d6020811015610bf057600080fd5b50610e2892505050565b6000816001600160a01b031663d4b970466040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3557600080fd5b505afa158015610c49573d6000803e3d6000fd5b505050506040513d6020811015610c5f57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d6020811015610cd757600080fd5b50519050610cf56001600160a01b038316848363ffffffff61344d16565b6040805163ca19ebd960e01b81526001600160a01b0385811660048301526024820184905291516000927f0000000000000000000000008ea40e8da3ae64bad5e77a5f7db346499f543bac169163ca19ebd9916044808301926020929190829003018186803b158015610d6757600080fd5b505afa158015610d7b573d6000803e3d6000fd5b505050506040513d6020811015610d9157600080fd5b50516040805163733e738360e11b815260048101839052602481018590526060604482015260006064820181905291519293506001600160a01b0387169263e67ce7069260a480840193602093929083900390910190829087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b505050506040513d6020811015610e2257600080fd5b50505050505b50600197881c9701610a3b565b506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610f7657604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000530000000000000000000000000000000000000416916370a08231916024808301926020929190829003018186803b158015610ec157600080fd5b505afa158015610ed5573d6000803e3d6000fd5b505050506040513d6020811015610eeb57600080fd5b505160408051632e1a7d4d60e01b81526004810183905290519195506001600160a01b037f00000000000000000000000053000000000000000000000000000000000000041691632e1a7d4d9160248082019260009290919082900301818387803b158015610f5957600080fd5b505af1158015610f6d573d6000803e3d6000fd5b50505050610f92565b610f8f6001600160a01b0382163063ffffffff61351716565b93505b88841015610fd15760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b610feb6001600160a01b038216338663ffffffff6135a416565b604080516001600160a01b038085168252831660208201523381830152606081018c9052608081018690529051600080516020613c3f8339815191529181900360a00190a150505098975050505050505050565b60005461010090046001600160a01b031681565b60008142811015611099576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008651116110ec576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b6000871161112b5760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b7f0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca484926001600160a01b0316630a5ea4668a338960008151811061116957fe5b60200260200101518c6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b1580156111f357600080fd5b505af1158015611207573d6000803e3d6000fd5b506000925050505b86518110156114a957600187510381141561136657600186166112c95786818151811061123857fe5b60200260200101516001600160a01b031663bd6015b4306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506040513d60208110156112c157600080fd5b506113619050565b8681815181106112d557fe5b60200260200101516001600160a01b031663dd93f59a306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561133457600080fd5b505af1158015611348573d6000803e3d6000fd5b505050506040513d602081101561135e57600080fd5b50505b61149d565b600186166113ef5786818151811061137a57fe5b60200260200101516001600160a01b031663bd6015b488836001018151811061139f57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561133457600080fd5b8681815181106113fb57fe5b60200260200101516001600160a01b031663dd93f59a88836001018151811061142057fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561147057600080fd5b505af1158015611484573d6000803e3d6000fd5b505050506040513d602081101561149a57600080fd5b50505b600195861c950161120f565b50604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000530000000000000000000000000000000000000416916370a08231916024808301926020929190829003018186803b15801561151057600080fd5b505afa158015611524573d6000803e3d6000fd5b505050506040513d602081101561153a57600080fd5b505191508682101561157d5760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156115e357600080fd5b505af11580156115f7573d6000803e3d6000fd5b505060405133925084156108fc02915084906000818181858888f19350505050158015611628573d6000803e3d6000fd5b50604080516001600160a01b038b16815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60208201523381830152606081018a9052608081018490529051600080516020613c3f8339815191529181900360a00190a150979650505050505050565b60005461010090046001600160a01b031633146116dc576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b6001600160a01b03166000908152600260205260409020805460ff19169055565b6001546001600160a01b0316331461174c576040805162461bcd60e51b815260206004820152600d60248201526c494e56414c49445f434c41494d60981b604482015290519081900360640190fd5b600154600080546040516001600160a01b0393841693610100909204909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36001805460008054610100600160a81b0319166101006001600160a01b038416021790556001600160a01b0319169055565b60008142811015611807576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b600086511161185a576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b600087116118995760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b604080516370a0823160e01b815233600482015290516000916001600160a01b038b16916370a0823191602480820192602092909190829003018186803b1580156118e357600080fd5b505afa1580156118f7573d6000803e3d6000fd5b505050506040513d602081101561190d57600080fd5b505160408051630d0e30db60e41b815290519192506001600160a01b037f0000000000000000000000005300000000000000000000000000000000000004169163d0e30db0913491600480830192600092919082900301818588803b15801561197557600080fd5b505af1158015611989573d6000803e3d6000fd5b50505050507f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031663a9059cbb886000815181106119ca57fe5b6020026020010151346040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611a2257600080fd5b505af1158015611a36573d6000803e3d6000fd5b505050506040513d6020811015611a4c57600080fd5b50600090505b8751811015611cec576001885103811415611ba95760018716611b0c57878181518110611a7b57fe5b60200260200101516001600160a01b031663bd6015b4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611ada57600080fd5b505af1158015611aee573d6000803e3d6000fd5b505050506040513d6020811015611b0457600080fd5b50611ba49050565b878181518110611b1857fe5b60200260200101516001600160a01b031663dd93f59a336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b7757600080fd5b505af1158015611b8b573d6000803e3d6000fd5b505050506040513d6020811015611ba157600080fd5b50505b611ce0565b60018716611c3257878181518110611bbd57fe5b60200260200101516001600160a01b031663bd6015b4898360010181518110611be257fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b7757600080fd5b878181518110611c3e57fe5b60200260200101516001600160a01b031663dd93f59a898360010181518110611c6357fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b505050506040513d6020811015611cdd57600080fd5b50505b600196871c9601611a52565b50604080516370a0823160e01b81523360048201529051611d719183916001600160a01b038d16916370a08231916024808301926020929190829003018186803b158015611d3957600080fd5b505afa158015611d4d573d6000803e3d6000fd5b505050506040513d6020811015611d6357600080fd5b50519063ffffffff61361316565b925087831015611db25760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b6040805173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81526001600160a01b038b1660208201523381830152346060820152608081018590529051600080516020613c3f8339815191529181900360a00190a150509695505050505050565b60008142811015611e5a576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008611611e995760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b6000611eb46001600160a01b038c163363ffffffff61365c16565b90506001600160a01b038c1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611f86576040805163052f523360e11b81526001600160a01b038e81166004830152336024830152306044830152606482018b905291517f0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca4849290921691630a5ea4669160848082019260009290919082900301818387803b158015611f5957600080fd5b505af1158015611f6d573d6000803e3d6000fd5b50611f86925050506001600160a01b038d168b8a61344d565b6001600160a01b03891660009081526002602052604090205460ff16611fdd5760405162461bcd60e51b8152600401808060200182810382526025815260200180613cdb6025913960400191505060405180910390fd5b60006001600160a01b03808b16908e1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461200e576000612010565b345b886040518082805190602001908083835b602083106120405780518252601f199092019160209182019101612021565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146120a2576040519150601f19603f3d011682016040523d82523d6000602084013e6120a7565b606091505b50509050806120e75760405162461bcd60e51b815260040180806020018281038252602d815260200180613d00602d913960400191505060405180910390fd5b61211b336121046001600160a01b038f163063ffffffff61365c16565b6001600160a01b038f16919063ffffffff6135a416565b612144826121386001600160a01b038f163363ffffffff61365c16565b9063ffffffff61361316565b9350878410156121855760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b600080516020613c3f8339815191528d8d338c8860405180866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018281526020019550505050505060405180910390a15050509998505050505050505050565b600080548190819060ff1615612259576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905583428110156122aa576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b8a6122b6818c8c613706565b90945092508884108015906122cb5750878310155b6123065760405162461bcd60e51b815260040180806020018281038252602b815260200180613cb0602b913960400191505060405180910390fd5b61237d3382836001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561234457600080fd5b505afa158015612358573d6000803e3d6000fd5b505050506040513d602081101561236e57600080fd5b505187600160ff8d16146132a3565b6123f43382836001600160a01b031663d4b970466040518163ffffffff1660e01b815260040160206040518083038186803b1580156123bb57600080fd5b505afa1580156123cf573d6000803e3d6000fd5b505050506040513d60208110156123e557600080fd5b505186600260ff8d16146132a3565b60408051634c85b42560e01b815233600482015290516001600160a01b03831691634c85b4259160248083019260609291908290030181600087803b15801561243c57600080fd5b505af1158015612450573d6000803e3d6000fd5b505050506040513d606081101561246657600080fd5b50519450600160ff881614801561247c57508334115b156124b25760405133903486900380156108fc02916000818181858888f193505050501580156124b0573d6000803e3d6000fd5b505b8660ff1660021480156124c457508234115b156124fa5760405133903485900380156108fc02916000818181858888f193505050501580156124f8573d6000803e3d6000fd5b505b50506000805460ff191690559199909850909650945050505050565b7f0000000000000000000000005a0c840a7089aa222c4458b3be0947fe5a5006de81565b60026020526000908152604090205460ff1681565b6001546001600160a01b031681565b60008054819060ff16156125a5576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905582428110156125f6576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60006001600160a01b038d1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612622578c612644565b7f00000000000000000000000053000000000000000000000000000000000000045b905060006001600160a01b038d1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612672578c612694565b7f00000000000000000000000053000000000000000000000000000000000000045b6040805163e18c40c760e01b81526001600160a01b0385811660048301528381166024830152604482018e9052606482018d9052608482018c90528a151560a483015291519293507f0000000000000000000000005a0c840a7089aa222c4458b3be0947fe5a5006de9091169163e18c40c79160c4808201926020929091908290030181600087803b15801561272957600080fd5b505af115801561273d573d6000803e3d6000fd5b505050506040513d602081101561275357600080fd5b505194508d91508c90506127893386848f6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b6127b53386838e6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132a3565b505060408051634c85b42560e01b815233600482015290516001600160a01b03851691634c85b4259160248083019260609291908290030181600087803b1580156127ff57600080fd5b505af1158015612813573d6000803e3d6000fd5b505050506040513d606081101561282957600080fd5b50516000805460ff19169055929c929b50919950505050505050505050565b60008054819060ff161561288f576040805162461bcd60e51b815260206004820152600960248201526814915153951490539560ba1b604482015290519081900360640190fd5b6000805460ff1916600117905582428110156128e0576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b60008a6001600160a01b0316634a248d2a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561291b57600080fd5b505afa15801561292f573d6000803e3d6000fd5b505050506040513d602081101561294557600080fd5b505160408051636a5cb82360e11b815290519192506000916001600160a01b038e169163d4b97046916004808301926020929190829003018186803b15801561298d57600080fd5b505afa1580156129a1573d6000803e3d6000fd5b505050506040513d60208110156129b757600080fd5b505190506129ce3330848e600160ff8d16146132a3565b6129e13330838d8b60ff166002146132a3565b8a15612a7f57612a016001600160a01b0383168d8d63ffffffff61344d16565b6040805163aa06ce9b60e01b8152336004820152602481018d905290516001600160a01b038e169163aa06ce9b9160448083019260209291908290030181600087803b158015612a5057600080fd5b505af1158015612a64573d6000803e3d6000fd5b505050506040513d6020811015612a7a57600080fd5b505194505b8915612b1d57612a9f6001600160a01b0382168d8c63ffffffff61344d16565b604080516317c5e7d960e21b8152336004820152602481018c905290516001600160a01b038e1691635f179f649160448083019260209291908290030181600087803b158015612aee57600080fd5b505af1158015612b02573d6000803e3d6000fd5b505050506040513d6020811015612b1857600080fd5b505193505b888510158015612b2d5750878410155b612b685760405162461bcd60e51b8152600401808060200182810382526027815260200180613c896027913960400191505060405180910390fd5b50506000805460ff1916905550909890975095505050505050565b7f0000000000000000000000008ea40e8da3ae64bad5e77a5f7db346499f543bac81565b60005461010090046001600160a01b03163314612bf7576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b6001600160a01b03166000908152600260205260409020805460ff19166001179055565b7f0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca4849281565b60005461010090046001600160a01b03163314612c8f576040805162461bcd60e51b81526020600482015260096024820152682727aa2fa7aba722a960b91b604482015290519081900360640190fd5b600080546040516001600160a01b038085169361010090930416917fdcf55418cee3220104fef63f979ff3c4097ad240c0c43dcb33ce837748983e6291a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008142811015612d35576040805162461bcd60e51b81526020600482015260166024820152600080516020613c1f833981519152604482015290519081900360640190fd5b6000865111612d88576040805162461bcd60e51b815260206004820152601a602482015279444f444f563250726f787930323a2050414952535f454d50545960301b604482015290519081900360640190fd5b60008711612dc75760405162461bcd60e51b8152600401808060200182810382526021815260200180613bfe6021913960400191505060405180910390fd5b604080516370a0823160e01b815233600482015290516000916001600160a01b038c16916370a0823191602480820192602092909190829003018186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d6020811015612e3b57600080fd5b505187519091506001600160a01b037f0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca484921690630a5ea466908d9033908b90600090612e8257fe5b60200260200101518d6040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b158015612f0c57600080fd5b505af1158015612f20573d6000803e3d6000fd5b506000925050505b87518110156131c257600188510381141561307f5760018716612fe257878181518110612f5157fe5b60200260200101516001600160a01b031663bd6015b4336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015612fb057600080fd5b505af1158015612fc4573d6000803e3d6000fd5b505050506040513d6020811015612fda57600080fd5b5061307a9050565b878181518110612fee57fe5b60200260200101516001600160a01b031663dd93f59a336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561304d57600080fd5b505af1158015613061573d6000803e3d6000fd5b505050506040513d602081101561307757600080fd5b50505b6131b6565b600187166131085787818151811061309357fe5b60200260200101516001600160a01b031663bd6015b48983600101815181106130b857fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561304d57600080fd5b87818151811061311457fe5b60200260200101516001600160a01b031663dd93f59a89836001018151811061313957fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b15801561318957600080fd5b505af115801561319d573d6000803e3d6000fd5b505050506040513d60208110156131b357600080fd5b50505b600196871c9601612f28565b50604080516370a0823160e01b8152336004820152905161320f9183916001600160a01b038e16916370a08231916024808301926020929190829003018186803b158015611d3957600080fd5b9250878310156132505760405162461bcd60e51b815260040180806020018281038252602a815260200180613c5f602a913960400191505060405180910390fd5b604080516001600160a01b03808e1682528c1660208201523381830152606081018b9052608081018590529051600080516020613c3f8339815191529181900360a00190a1505098975050505050505050565b80156133aa5781156133a5578134146132f5576040805162461bcd60e51b815260206004820152600f60248201526e4554485f56414c55455f57524f4e4760881b604482015290519081900360640190fd5b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561335057600080fd5b505af1158015613364573d6000803e3d6000fd5b505050506001600160a01b038516301490506133a5576133a57f00000000000000000000000053000000000000000000000000000000000000048584613818565b613446565b6040805163052f523360e11b81526001600160a01b038581166004830152878116602483015286811660448301526064820185905291517f0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca4849290921691630a5ea4669160848082019260009290919082900301818387803b15801561342d57600080fd5b505af1158015613441573d6000803e3d6000fd5b505050505b5050505050565b60408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b15801561349e57600080fd5b505afa1580156134b2573d6000803e3d6000fd5b505050506040513d60208110156134c857600080fd5b50519050818110156135115780156134f5576134f56001600160a01b03851684600063ffffffff61386a16565b6135116001600160a01b0385168460001963ffffffff61386a16565b50505050565b6000826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561356f57600080fd5b505afa158015613583573d6000803e3d6000fd5b505050506040513d602081101561359957600080fd5b505190505b92915050565b801561360e576135b38361397d565b156135f4576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156135ee573d6000803e3d6000fd5b5061360e565b61360e6001600160a01b038416838363ffffffff61381816565b505050565b600082821115613656576040805162461bcd60e51b815260206004820152600960248201526829aaa12fa2a92927a960b91b604482015290519081900360640190fd5b50900390565b60006136678361397d565b1561367d57506001600160a01b0381163161359e565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156136d357600080fd5b505afa1580156136e7573d6000803e3d6000fd5b505050506040513d60208110156136fd57600080fd5b5051905061359e565b600080600080866001600160a01b03166336223ce96040518163ffffffff1660e01b8152600401604080518083038186803b15801561374457600080fd5b505afa158015613758573d6000803e3d6000fd5b505050506040513d604081101561376e57600080fd5b508051602090910151909250905080158015613788575081155b15613794578593508492505b801580156137a25750600082115b156137af57859350600092505b6000811180156137bf5750600082115b1561380e5760006137d087846139a2565b905060006137de87846139a2565b90508082116137fb578795506137f483836139d3565b945061380b565b86945061380884826139d3565b95505b50505b5050935093915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261360e9084906139fd565b8015806138f0575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b1580156138c257600080fd5b505afa1580156138d6573d6000803e3d6000fd5b505050506040513d60208110156138ec57600080fd5b5051155b61392b5760405162461bcd60e51b8152600401808060200182810382526036815260200180613d576036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261360e9084906139fd565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b60006139cc826139c085670de0b6b3a764000063ffffffff613b5216565b9063ffffffff613bad16565b9392505050565b6000670de0b6b3a76400006139ee848463ffffffff613b5216565b816139f557fe5b049392505050565b60006060836001600160a01b0316836040518082805190602001908083835b60208310613a3b5780518252601f199092019160209182019101613a1c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613a9d576040519150601f19603f3d011682016040523d82523d6000602084013e613aa2565b606091505b509150915081613af9576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561351157808060200190516020811015613b1557600080fd5b50516135115760405162461bcd60e51b815260040180806020018281038252602a815260200180613d2d602a913960400191505060405180910390fd5b600082613b615750600061359e565b82820282848281613b6e57fe5b04146139cc576040805162461bcd60e51b815260206004820152600960248201526826aaa62fa2a92927a960b91b604482015290519081900360640190fd5b6000808211613bf4576040805162461bcd60e51b815260206004820152600e60248201526d2224ab24a224a723afa2a92927a960911b604482015290519081900360640190fd5b8183816139f557fefe444f444f563250726f787930323a2052455455524e5f414d4f554e545f5a45524f444f444f563250726f787930323a20455850495245440000000000000000000092ceb067a9883c85aba061e46b9edf505a0d6e81927c4b966ebed543a5221787444f444f563250726f787930323a2052657475726e20616d6f756e74206973206e6f7420656e6f756768444f444f563250726f787930323a2052657475726e20444c50206973206e6f7420656e6f756768444f444f563250726f787930323a206465706f73697420616d6f756e74206973206e6f7420656e6f756768444f444f563250726f787930323a204e6f742057686974656c69737420436f6e7472616374444f444f563250726f787930323a2045787465726e616c205377617020657865637574696f6e204661696c65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220359eb7e72a18e3a9904780feab8784644bfac53f80e75723e17fe9f4fb10578564736f6c63430006090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005a0c840a7089aa222c4458b3be0947fe5a5006de00000000000000000000000053000000000000000000000000000000000000040000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca484920000000000000000000000008ea40e8da3ae64bad5e77a5f7db346499f543bac
-----Decoded View---------------
Arg [0] : dvmFactory (address): 0x5a0C840a7089aa222c4458b3BE0947fe5a5006DE
Arg [1] : weth (address): 0x5300000000000000000000000000000000000004
Arg [2] : dodoApproveProxy (address): 0x0218E24dd47f9a1D05418eAa5B9cEDB13Ca48492
Arg [3] : dodoSellHelper (address): 0x8eA40e8Da3ae64Bad5E77a5f7DB346499F543baC
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000005a0c840a7089aa222c4458b3be0947fe5a5006de
Arg [1] : 0000000000000000000000005300000000000000000000000000000000000004
Arg [2] : 0000000000000000000000000218e24dd47f9a1d05418eaa5b9cedb13ca48492
Arg [3] : 0000000000000000000000008ea40e8da3ae64bad5e77a5f7db346499f543bac
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.