Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
10329000 | 1666 days ago | 0.09011619 ETH | ||||
10329000 | 1666 days ago | 0.09011619 ETH | ||||
10290858 | 1672 days ago | 0.3 ETH | ||||
10290858 | 1672 days ago | 0.3 ETH | ||||
10275035 | 1675 days ago | 0.5 ETH | ||||
10275035 | 1675 days ago | 0.5 ETH | ||||
10223611 | 1683 days ago | 27.86500893 ETH | ||||
10223611 | 1683 days ago | 27.86500893 ETH | ||||
10203004 | 1686 days ago | 8.5 ETH | ||||
10203004 | 1686 days ago | 8.5 ETH | ||||
10174766 | 1690 days ago | 0.06549857 ETH | ||||
10174766 | 1690 days ago | 0.06549857 ETH | ||||
10174697 | 1690 days ago | 50 ETH | ||||
10174697 | 1690 days ago | 50 ETH | ||||
10174694 | 1690 days ago | 30 ETH | ||||
10174694 | 1690 days ago | 30 ETH | ||||
10174647 | 1690 days ago | 1.41548645 ETH | ||||
10174647 | 1690 days ago | 1.41548645 ETH | ||||
10174560 | 1690 days ago | 0.71837905 ETH | ||||
10174560 | 1690 days ago | 0.71837905 ETH | ||||
10174360 | 1690 days ago | 1.98358867 ETH | ||||
10174360 | 1690 days ago | 1.98358867 ETH | ||||
10174331 | 1690 days ago | 1.96056469 ETH | ||||
10174331 | 1690 days ago | 1.96056469 ETH | ||||
10174287 | 1690 days ago | 26.17926974 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
OneSplitWrap
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-05-23 */ // File: @openzeppelin/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/IOneSplit.sol pragma solidity ^0.5.0; // // || // || // \/ // +--------------+ // | OneSplitWrap | // +--------------+ // || // || (delegatecall) // \/ // +--------------+ // | OneSplit | // +--------------+ // // contract IOneSplitConsts { // flags = FLAG_DISABLE_UNISWAP + FLAG_DISABLE_KYBER + ... uint256 public constant FLAG_DISABLE_UNISWAP = 0x01; uint256 public constant FLAG_DISABLE_KYBER = 0x02; uint256 public constant FLAG_ENABLE_KYBER_UNISWAP_RESERVE = 0x100000000; // Turned off by default uint256 public constant FLAG_ENABLE_KYBER_OASIS_RESERVE = 0x200000000; // Turned off by default uint256 public constant FLAG_ENABLE_KYBER_BANCOR_RESERVE = 0x400000000; // Turned off by default uint256 public constant FLAG_DISABLE_BANCOR = 0x04; uint256 public constant FLAG_DISABLE_OASIS = 0x08; uint256 public constant FLAG_DISABLE_COMPOUND = 0x10; uint256 public constant FLAG_DISABLE_FULCRUM = 0x20; uint256 public constant FLAG_DISABLE_CHAI = 0x40; uint256 public constant FLAG_DISABLE_AAVE = 0x80; uint256 public constant FLAG_DISABLE_SMART_TOKEN = 0x100; uint256 public constant FLAG_ENABLE_MULTI_PATH_ETH = 0x200; // Turned off by default uint256 public constant FLAG_DISABLE_BDAI = 0x400; uint256 public constant FLAG_DISABLE_IEARN = 0x800; uint256 public constant FLAG_DISABLE_CURVE_COMPOUND = 0x1000; uint256 public constant FLAG_DISABLE_CURVE_USDT = 0x2000; uint256 public constant FLAG_DISABLE_CURVE_Y = 0x4000; uint256 public constant FLAG_DISABLE_CURVE_BINANCE = 0x8000; uint256 public constant FLAG_ENABLE_MULTI_PATH_DAI = 0x10000; // Turned off by default uint256 public constant FLAG_ENABLE_MULTI_PATH_USDC = 0x20000; // Turned off by default uint256 public constant FLAG_DISABLE_CURVE_SYNTHETIX = 0x40000; uint256 public constant FLAG_DISABLE_WETH = 0x80000; uint256 public constant FLAG_ENABLE_UNISWAP_COMPOUND = 0x100000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH uint256 public constant FLAG_ENABLE_UNISWAP_CHAI = 0x200000; // Works only when ETH<>DAI or FLAG_ENABLE_MULTI_PATH_ETH uint256 public constant FLAG_ENABLE_UNISWAP_AAVE = 0x400000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH uint256 public constant FLAG_DISABLE_IDLE = 0x800000; uint256 public constant FLAG_DISABLE_MOONISWAP = 0x1000000; uint256 public constant FLAG_DISABLE_UNISWAP_V2_ALL = 0x1E000000; uint256 public constant FLAG_DISABLE_UNISWAP_V2 = 0x2000000; uint256 public constant FLAG_DISABLE_UNISWAP_V2_ETH = 0x4000000; uint256 public constant FLAG_DISABLE_UNISWAP_V2_DAI = 0x8000000; uint256 public constant FLAG_DISABLE_UNISWAP_V2_USDC = 0x10000000; uint256 public constant FLAG_DISABLE_ALL_SPLIT_SOURCES = 0x20000000; uint256 public constant FLAG_DISABLE_ALL_WRAP_SOURCES = 0x40000000; uint256 public constant FLAG_DISABLE_CURVE_PAX = 0x80000000; uint256 public constant FLAG_DISABLE_CURVE_RENBTC = 0x100000000; uint256 public constant FLAG_DISABLE_CURVE_TBTC = 0x200000000; uint256 public constant FLAG_ENABLE_MULTI_PATH_USDT = 0x400000000; // Turned off by default uint256 public constant FLAG_ENABLE_MULTI_PATH_WBTC = 0x800000000; // Turned off by default uint256 public constant FLAG_ENABLE_MULTI_PATH_TBTC = 0x1000000000; // Turned off by default uint256 public constant FLAG_ENABLE_MULTI_PATH_RENBTC = 0x2000000000; // Turned off by default uint256 public constant FLAG_DISABLE_DFORCE_SWAP = 0x4000000000; uint256 public constant FLAG_DISABLE_SHELL = 0x8000000000; } contract IOneSplit is IOneSplitConsts { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ); function swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 minReturn, uint256[] memory distribution, uint256 flags ) public payable; } // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/interface/IUniswapExchange.sol pragma solidity ^0.5.0; interface IUniswapExchange { function getEthToTokenInputPrice(uint256 ethSold) external view returns (uint256 tokensBought); function getTokenToEthInputPrice(uint256 tokensSold) external view returns (uint256 ethBought); function ethToTokenSwapInput(uint256 minTokens, uint256 deadline) external payable returns (uint256 tokensBought); function tokenToEthSwapInput(uint256 tokensSold, uint256 minEth, uint256 deadline) external returns (uint256 ethBought); function tokenToTokenSwapInput( uint256 tokensSold, uint256 minTokensBought, uint256 minEthBought, uint256 deadline, address tokenAddr ) external returns (uint256 tokensBought); } // File: contracts/interface/IUniswapFactory.sol pragma solidity ^0.5.0; interface IUniswapFactory { function getExchange(IERC20 token) external view returns (IUniswapExchange exchange); } // File: contracts/interface/IKyberNetworkContract.sol pragma solidity ^0.5.0; interface IKyberNetworkContract { function searchBestRate(IERC20 src, IERC20 dest, uint256 srcAmount, bool usePermissionless) external view returns (address reserve, uint256 rate); } // File: contracts/interface/IKyberNetworkProxy.sol pragma solidity ^0.5.0; interface IKyberNetworkProxy { function getExpectedRate(IERC20 src, IERC20 dest, uint256 srcQty) external view returns (uint256 expectedRate, uint256 slippageRate); function tradeWithHint( IERC20 src, uint256 srcAmount, IERC20 dest, address destAddress, uint256 maxDestAmount, uint256 minConversionRate, address walletId, bytes calldata hint ) external payable returns (uint256); function kyberNetworkContract() external view returns (IKyberNetworkContract); // TODO: Limit usage by tx.gasPrice // function maxGasPrice() external view returns (uint256); // TODO: Limit usage by user cap // function getUserCapInWei(address user) external view returns (uint256); // function getUserCapInTokenWei(address user, IERC20 token) external view returns (uint256); } // File: contracts/interface/IKyberUniswapReserve.sol pragma solidity ^0.5.0; interface IKyberUniswapReserve { function uniswapFactory() external view returns (address); } // File: contracts/interface/IKyberOasisReserve.sol pragma solidity ^0.5.0; interface IKyberOasisReserve { function otc() external view returns (address); } // File: contracts/interface/IKyberBancorReserve.sol pragma solidity ^0.5.0; contract IKyberBancorReserve { function bancorEth() public view returns (address); } // File: contracts/interface/IBancorNetwork.sol pragma solidity ^0.5.0; interface IBancorNetwork { function getReturnByPath(address[] calldata path, uint256 amount) external view returns (uint256 returnAmount, uint256 conversionFee); function claimAndConvert(address[] calldata path, uint256 amount, uint256 minReturn) external returns (uint256); function convert(address[] calldata path, uint256 amount, uint256 minReturn) external payable returns (uint256); } // File: contracts/interface/IBancorContractRegistry.sol pragma solidity ^0.5.0; contract IBancorContractRegistry { function addressOf(bytes32 contractName) external view returns (address); } // File: contracts/interface/IBancorConverterRegistry.sol pragma solidity ^0.5.0; interface IBancorConverterRegistry { function getConvertibleTokenSmartTokenCount(IERC20 convertibleToken) external view returns(uint256); function getConvertibleTokenSmartTokens(IERC20 convertibleToken) external view returns(address[] memory); function getConvertibleTokenSmartToken(IERC20 convertibleToken, uint256 index) external view returns(address); function isConvertibleTokenSmartToken(IERC20 convertibleToken, address value) external view returns(bool); } // File: contracts/interface/IBancorEtherToken.sol pragma solidity ^0.5.0; contract IBancorEtherToken is IERC20 { function deposit() external payable; function withdraw(uint256 amount) external; } // File: contracts/interface/IOasisExchange.sol pragma solidity ^0.5.0; interface IOasisExchange { function getBuyAmount(IERC20 buyGem, IERC20 payGem, uint256 payAmt) external view returns (uint256 fillAmt); function sellAllAmount(IERC20 payGem, uint256 payAmt, IERC20 buyGem, uint256 minFillAmount) external returns (uint256 fillAmt); } // File: contracts/interface/IWETH.sol pragma solidity ^0.5.0; contract IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 amount) external; } // File: contracts/interface/ICurve.sol pragma solidity ^0.5.0; interface ICurve { // solium-disable-next-line mixedcase function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns(uint256 dy); // solium-disable-next-line mixedcase function get_dy(int128 i, int128 j, uint256 dx) external view returns(uint256 dy); // solium-disable-next-line mixedcase function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 minDy) external; // solium-disable-next-line mixedcase function exchange(int128 i, int128 j, uint256 dx, uint256 minDy) external; } // File: contracts/interface/IChai.sol pragma solidity ^0.5.0; interface IPot { function dsr() external view returns (uint256); function chi() external view returns (uint256); function rho() external view returns (uint256); function drip() external returns (uint256); function join(uint256) external; function exit(uint256) external; } contract IChai is IERC20 { function POT() public view returns (IPot); function join(address dst, uint256 wad) external; function exit(address src, uint256 wad) external; } library ChaiHelper { IPot private constant POT = IPot(0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7); uint256 private constant RAY = 10**27; function _mul(uint256 x, uint256 y) private pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x); } function _rmul(uint256 x, uint256 y) private pure returns (uint256 z) { // always rounds down z = _mul(x, y) / RAY; } function _rdiv(uint256 x, uint256 y) private pure returns (uint256 z) { // always rounds down z = _mul(x, RAY) / y; } function rpow(uint256 x, uint256 n, uint256 base) private pure returns (uint256 z) { // solium-disable-next-line security/no-inline-assembly assembly { switch x case 0 { switch n case 0 { z := base } default { z := 0 } } default { switch mod(n, 2) case 0 { z := base } default { z := x } let half := div(base, 2) // for rounding. for { n := div(n, 2) } n { n := div(n, 2) } { let xx := mul(x, x) if iszero(eq(div(xx, x), x)) { revert(0, 0) } let xxRound := add(xx, half) if lt(xxRound, xx) { revert(0, 0) } x := div(xxRound, base) if mod(n, 2) { let zx := mul(z, x) if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) } let zxRound := add(zx, half) if lt(zxRound, zx) { revert(0, 0) } z := div(zxRound, base) } } } } } function potDrip() private view returns (uint256) { return _rmul(rpow(POT.dsr(), now - POT.rho(), RAY), POT.chi()); } function daiToChai( IChai, /*chai*/ uint256 amount ) internal view returns (uint256) { uint256 chi = (now > POT.rho()) ? potDrip() : POT.chi(); return _rdiv(amount, chi); } function chaiToDai( IChai, /*chai*/ uint256 amount ) internal view returns (uint256) { uint256 chi = (now > POT.rho()) ? potDrip() : POT.chi(); return _rmul(chi, amount); } } // File: contracts/interface/ICompound.sol pragma solidity ^0.5.0; contract ICompound { function markets(address cToken) external view returns (bool isListed, uint256 collateralFactorMantissa); } contract ICompoundToken is IERC20 { function underlying() external view returns (address); function exchangeRateStored() external view returns (uint256); function mint(uint256 mintAmount) external returns (uint256); function redeem(uint256 redeemTokens) external returns (uint256); } contract ICompoundEther is IERC20 { function mint() external payable; function redeem(uint256 redeemTokens) external returns (uint256); } // File: contracts/interface/IAaveToken.sol pragma solidity ^0.5.0; contract IAaveToken is IERC20 { function underlyingAssetAddress() external view returns (IERC20); function redeem(uint256 amount) external; } interface IAaveLendingPool { function core() external view returns (address); function deposit(IERC20 token, uint256 amount, uint16 refCode) external payable; } // File: contracts/interface/IMooniswap.sol pragma solidity ^0.5.0; interface IMooniswapRegistry { function target() external view returns(IMooniswap); } interface IMooniswap { function getReturn( IERC20 fromToken, IERC20 toToken, uint256 amount ) external view returns(uint256 returnAmount); function swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 minReturn ) external payable returns(uint256 returnAmount); } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity ^0.5.5; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } } // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol pragma solidity ^0.5.0; /** * @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; using Address for address; 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)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @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 require(address(token).isContract(), "SafeERC20: call to non-contract"); // 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"); } } } // File: contracts/UniversalERC20.sol pragma solidity ^0.5.0; library UniversalERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); function universalTransfer(IERC20 token, address to, uint256 amount) internal returns(bool) { if (amount == 0) { return true; } if (isETH(token)) { address(uint160(to)).transfer(amount); } else { token.safeTransfer(to, amount); return true; } } function universalTransferFrom(IERC20 token, address from, address to, uint256 amount) internal { if (amount == 0) { return; } if (isETH(token)) { require(from == msg.sender && msg.value >= amount, "Wrong useage of ETH.universalTransferFrom()"); if (to != address(this)) { address(uint160(to)).transfer(amount); } if (msg.value > amount) { msg.sender.transfer(msg.value.sub(amount)); } } else { token.safeTransferFrom(from, to, amount); } } function universalTransferFromSenderToThis(IERC20 token, uint256 amount) internal { if (amount == 0) { return; } if (isETH(token)) { if (msg.value > amount) { // Return remainder if exist msg.sender.transfer(msg.value.sub(amount)); } } else { token.safeTransferFrom(msg.sender, address(this), amount); } } function universalApprove(IERC20 token, address to, uint256 amount) internal { if (!isETH(token)) { if (amount > 0 && token.allowance(address(this), to) > 0) { token.safeApprove(to, 0); } token.safeApprove(to, amount); } } function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { if (isETH(token)) { return who.balance; } else { return token.balanceOf(who); } } function universalDecimals(IERC20 token) internal view returns (uint256) { if (isETH(token)) { return 18; } (bool success, bytes memory data) = address(token).staticcall.gas(10000)( abi.encodeWithSignature("decimals()") ); if (!success || data.length == 0) { (success, data) = address(token).staticcall.gas(10000)( abi.encodeWithSignature("DECIMALS()") ); } return (success && data.length > 0) ? abi.decode(data, (uint256)) : 18; } function isETH(IERC20 token) internal pure returns(bool) { return (address(token) == address(ZERO_ADDRESS) || address(token) == address(ETH_ADDRESS)); } } // File: contracts/interface/IUniswapV2Exchange.sol pragma solidity ^0.5.0; interface IUniswapV2Exchange { function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; } library UniswapV2ExchangeLib { using SafeMath for uint256; using UniversalERC20 for IERC20; function getReturn( IUniswapV2Exchange exchange, IERC20 fromToken, IERC20 toToken, uint amountIn ) internal view returns (uint256) { uint256 reserveIn = fromToken.universalBalanceOf(address(exchange)); uint256 reserveOut = toToken.universalBalanceOf(address(exchange)); uint256 amountInWithFee = amountIn.mul(997); uint256 numerator = amountInWithFee.mul(reserveOut); uint256 denominator = reserveIn.mul(1000).add(amountInWithFee); return (denominator == 0) ? 0 : numerator.div(denominator); } } // File: contracts/interface/IUniswapV2Factory.sol pragma solidity ^0.5.0; interface IUniswapV2Factory { function getPair(IERC20 tokenA, IERC20 tokenB) external view returns (IUniswapV2Exchange pair); } // File: contracts/interface/IDForceSwap.sol pragma solidity ^0.5.0; interface IDForceSwap { function getAmountByInput(IERC20 input, IERC20 output, uint256 amount) external view returns(uint256); function swap(IERC20 input, IERC20 output, uint256 amount) external; } // File: contracts/interface/IShell.sol pragma solidity ^0.5.0; interface IShell { function viewOriginTrade( address origin, address target, uint256 originAmount ) external view returns (uint256); function swapByOrigin( address origin, address target, uint256 originAmount, uint256 minTargetAmount, uint256 deadline ) external returns (uint256); } // File: contracts/OneSplitBase.sol pragma solidity ^0.5.0; //import "./interface/IBancorNetworkPathFinder.sol"; contract IOneSplitView is IOneSplitConsts { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ); } library DisableFlags { function check(uint256 flags, uint256 flag) internal pure returns(bool) { return (flags & flag) != 0; } } contract OneSplitRoot { using SafeMath for uint256; using DisableFlags for uint256; using UniversalERC20 for IERC20; using UniversalERC20 for IWETH; using UniversalERC20 for IBancorEtherToken; using UniswapV2ExchangeLib for IUniswapV2Exchange; using ChaiHelper for IChai; uint256 constant public DEXES_COUNT = 22; IERC20 constant public ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); IERC20 constant public dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); IERC20 constant public bnt = IERC20(0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C); IERC20 constant public usdc = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); IERC20 constant public usdt = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); IERC20 constant public tusd = IERC20(0x0000000000085d4780B73119b644AE5ecd22b376); IERC20 constant public busd = IERC20(0x4Fabb145d64652a948d72533023f6E7A623C7C53); IERC20 constant public susd = IERC20(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51); IERC20 constant public pax = IERC20(0x8E870D67F660D95d5be530380D0eC0bd388289E1); IWETH constant public weth = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); IBancorEtherToken constant public bancorEtherToken = IBancorEtherToken(0xc0829421C1d260BD3cB3E0F06cfE2D52db2cE315); IChai constant public chai = IChai(0x06AF07097C9Eeb7fD685c692751D5C66dB49c215); IERC20 constant public renbtc = IERC20(0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D); IERC20 constant public wbtc = IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599); IERC20 constant public tbtc = IERC20(0x1bBE271d15Bb64dF0bc6CD28Df9Ff322F2eBD847); IERC20 constant public hbtc = IERC20(0x0316EB71485b0Ab14103307bf65a021042c6d380); IKyberNetworkProxy constant public kyberNetworkProxy = IKyberNetworkProxy(0x818E6FECD516Ecc3849DAf6845e3EC868087B755); IUniswapFactory constant public uniswapFactory = IUniswapFactory(0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95); IBancorContractRegistry constant public bancorContractRegistry = IBancorContractRegistry(0x52Ae12ABe5D8BD778BD5397F99cA900624CfADD4); //IBancorNetworkPathFinder constant public bancorNetworkPathFinder = IBancorNetworkPathFinder(0x6F0cD8C4f6F06eAB664C7E3031909452b4B72861); IBancorConverterRegistry constant public bancorConverterRegistry = IBancorConverterRegistry(0xf6E2D7F616B67E46D708e4410746E9AAb3a4C518); IOasisExchange constant public oasisExchange = IOasisExchange(0x794e6e91555438aFc3ccF1c5076A74F42133d08D); ICurve constant public curveCompound = ICurve(0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56); ICurve constant public curveUsdt = ICurve(0x52EA46506B9CC5Ef470C5bf89f17Dc28bB35D85C); ICurve constant public curveY = ICurve(0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51); ICurve constant public curveBinance = ICurve(0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27); ICurve constant public curveSynthetix = ICurve(0xA5407eAE9Ba41422680e2e00537571bcC53efBfD); ICurve constant public curvePax = ICurve(0x06364f10B501e868329afBc005b3492902d6C763); ICurve constant public curveRenBtc = ICurve(0x8474c1236F0Bc23830A23a41aBB81B2764bA9f4F); ICurve constant public curveTBtc = ICurve(0x9726e9314eF1b96E45f40056bEd61A088897313E); IShell constant public shell = IShell(0xA8253a440Be331dC4a7395B73948cCa6F19Dc97D); IAaveLendingPool constant public aave = IAaveLendingPool(0x398eC7346DcD622eDc5ae82352F02bE94C62d119); ICompound constant public compound = ICompound(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B); ICompoundEther constant public cETH = ICompoundEther(0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5); IMooniswapRegistry constant public mooniswapRegistry = IMooniswapRegistry(0x7079E8517594e5b21d2B9a0D17cb33F5FE2bca70); IUniswapV2Factory constant public uniswapV2 = IUniswapV2Factory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); IDForceSwap constant public dforceSwap = IDForceSwap(0x03eF3f37856bD08eb47E2dE7ABc4Ddd2c19B60F2); function _buildBancorPath( IERC20 fromToken, IERC20 toToken ) internal view returns(address[] memory path) { if (fromToken == toToken) { return new address[](0); } if (fromToken.isETH()) { fromToken = bancorEtherToken; } if (toToken.isETH()) { toToken = bancorEtherToken; } if (fromToken == bnt || toToken == bnt) { path = new address[](3); } else { path = new address[](5); } address fromConverter; address toConverter; if (fromToken != bnt) { (bool success, bytes memory data) = address(bancorConverterRegistry).staticcall.gas(10000)(abi.encodeWithSelector( bancorConverterRegistry.getConvertibleTokenSmartToken.selector, fromToken.isETH() ? bnt : fromToken, 0 )); if (!success) { return new address[](0); } fromConverter = abi.decode(data, (address)); if (fromConverter == address(0)) { return new address[](0); } } if (toToken != bnt) { (bool success, bytes memory data) = address(bancorConverterRegistry).staticcall.gas(10000)(abi.encodeWithSelector( bancorConverterRegistry.getConvertibleTokenSmartToken.selector, toToken.isETH() ? bnt : toToken, 0 )); if (!success) { return new address[](0); } toConverter = abi.decode(data, (address)); if (toConverter == address(0)) { return new address[](0); } } if (toToken == bnt) { path[0] = address(fromToken); path[1] = fromConverter; path[2] = address(bnt); return path; } if (fromToken == bnt) { path[0] = address(bnt); path[1] = toConverter; path[2] = address(toToken); return path; } path[0] = address(fromToken); path[1] = fromConverter; path[2] = address(bnt); path[3] = toConverter; path[4] = address(toToken); return path; } function _getCompoundToken(IERC20 token) internal pure returns(ICompoundToken) { if (token.isETH()) { // ETH return ICompoundToken(0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5); } if (token == IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F)) { // DAI return ICompoundToken(0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643); } if (token == IERC20(0x0D8775F648430679A709E98d2b0Cb6250d2887EF)) { // BAT return ICompoundToken(0x6C8c6b02E7b2BE14d4fA6022Dfd6d75921D90E4E); } if (token == IERC20(0x1985365e9f78359a9B6AD760e32412f4a445E862)) { // REP return ICompoundToken(0x158079Ee67Fce2f58472A96584A73C7Ab9AC95c1); } if (token == IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)) { // USDC return ICompoundToken(0x39AA39c021dfbaE8faC545936693aC917d5E7563); } if (token == IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599)) { // WBTC return ICompoundToken(0xC11b1268C1A384e55C48c2391d8d480264A3A7F4); } if (token == IERC20(0xE41d2489571d322189246DaFA5ebDe1F4699F498)) { // ZRX return ICompoundToken(0xB3319f5D18Bc0D84dD1b4825Dcde5d5f7266d407); } if (token == IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7)) { // USDT return ICompoundToken(0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9); } return ICompoundToken(0); } function _getAaveToken(IERC20 token) internal pure returns(IAaveToken) { if (token.isETH()) { // ETH return IAaveToken(0x3a3A65aAb0dd2A17E3F1947bA16138cd37d08c04); } if (token == IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F)) { // DAI return IAaveToken(0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d); } if (token == IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)) { // USDC return IAaveToken(0x9bA00D6856a4eDF4665BcA2C2309936572473B7E); } if (token == IERC20(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51)) { // SUSD return IAaveToken(0x625aE63000f46200499120B906716420bd059240); } if (token == IERC20(0x4Fabb145d64652a948d72533023f6E7A623C7C53)) { // BUSD return IAaveToken(0x6Ee0f7BB50a54AB5253dA0667B0Dc2ee526C30a8); } if (token == IERC20(0x0000000000085d4780B73119b644AE5ecd22b376)) { // TUSD return IAaveToken(0x4DA9b813057D04BAef4e5800E36083717b4a0341); } if (token == IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7)) { // USDT return IAaveToken(0x71fc860F7D3A592A4a98740e39dB31d25db65ae8); } if (token == IERC20(0x0D8775F648430679A709E98d2b0Cb6250d2887EF)) { // BAT return IAaveToken(0xE1BA0FB44CCb0D11b80F92f4f8Ed94CA3fF51D00); } if (token == IERC20(0xdd974D5C2e2928deA5F71b9825b8b646686BD200)) { // KNC return IAaveToken(0x9D91BE44C06d373a8a226E1f3b146956083803eB); } if (token == IERC20(0x80fB784B7eD66730e8b1DBd9820aFD29931aab03)) { // LEND return IAaveToken(0x7D2D3688Df45Ce7C552E19c27e007673da9204B8); } if (token == IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA)) { // LINK return IAaveToken(0xA64BD6C70Cb9051F6A9ba1F163Fdc07E0DfB5F84); } if (token == IERC20(0x0F5D2fB29fb7d3CFeE444a200298f468908cC942)) { // MANA return IAaveToken(0x6FCE4A401B6B80ACe52baAefE4421Bd188e76F6f); } if (token == IERC20(0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2)) { // MKR return IAaveToken(0x7deB5e830be29F91E298ba5FF1356BB7f8146998); } if (token == IERC20(0x1985365e9f78359a9B6AD760e32412f4a445E862)) { // REP return IAaveToken(0x71010A9D003445aC60C4e6A7017c1E89A477B438); } if (token == IERC20(0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F)) { // SNX return IAaveToken(0x328C4c80BC7aCa0834Db37e6600A6c49E12Da4DE); } if (token == IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599)) { // WBTC return IAaveToken(0xFC4B8ED459e00e5400be803A9BB3954234FD50e3); } if (token == IERC20(0xE41d2489571d322189246DaFA5ebDe1F4699F498)) { // ZRX return IAaveToken(0x6Fb0855c404E09c47C3fBCA25f08d4E41f9F062f); } return IAaveToken(0); } function _infiniteApproveIfNeeded(IERC20 token, address to) internal { if (!token.isETH()) { if ((token.allowance(address(this), to) >> 255) == 0) { token.universalApprove(to, uint256(- 1)); } } } } contract OneSplitViewWrapBase is IOneSplitView, OneSplitRoot { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags // See constants in IOneSplit.sol ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return _getExpectedReturnFloor( fromToken, toToken, amount, parts, flags ); } function _getExpectedReturnFloor( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags // See constants in IOneSplit.sol ) internal view returns( uint256 returnAmount, uint256[] memory distribution ); } contract OneSplitView is IOneSplitView, OneSplitRoot { function log(uint256) external view { } function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags // See constants in IOneSplit.sol ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { distribution = new uint256[](DEXES_COUNT); if (fromToken == toToken) { return (amount, distribution); } bool invert = flags.check(FLAG_DISABLE_ALL_SPLIT_SOURCES); function(IERC20,IERC20,uint256,uint256) view returns(uint256)[DEXES_COUNT] memory reserves = [ invert != flags.check(FLAG_DISABLE_UNISWAP) ? _calculateNoReturn : calculateUniswapReturn, invert != flags.check(FLAG_DISABLE_KYBER) ? _calculateNoReturn : calculateKyberReturn, invert != flags.check(FLAG_DISABLE_BANCOR) ? _calculateNoReturn : calculateBancorReturn, invert != flags.check(FLAG_DISABLE_OASIS) ? _calculateNoReturn : calculateOasisReturn, invert != flags.check(FLAG_DISABLE_CURVE_COMPOUND) ? _calculateNoReturn : calculateCurveCompound, invert != flags.check(FLAG_DISABLE_CURVE_USDT) ? _calculateNoReturn : calculateCurveUsdt, invert != flags.check(FLAG_DISABLE_CURVE_Y) ? _calculateNoReturn : calculateCurveY, invert != flags.check(FLAG_DISABLE_CURVE_BINANCE) ? _calculateNoReturn : calculateCurveBinance, invert != flags.check(FLAG_DISABLE_CURVE_SYNTHETIX) ? _calculateNoReturn : calculateCurveSynthetix, (true) != flags.check(FLAG_ENABLE_UNISWAP_COMPOUND) ? _calculateNoReturn : calculateUniswapCompound, (true) != flags.check(FLAG_ENABLE_UNISWAP_CHAI) ? _calculateNoReturn : calculateUniswapChai, (true) != flags.check(FLAG_ENABLE_UNISWAP_AAVE) ? _calculateNoReturn : calculateUniswapAave, invert != flags.check(FLAG_DISABLE_MOONISWAP) ? _calculateNoReturn : calculateMooniswap, invert != flags.check(FLAG_DISABLE_UNISWAP_V2) ? _calculateNoReturn : calculateUniswapV2, invert != flags.check(FLAG_DISABLE_UNISWAP_V2_ETH) ? _calculateNoReturn : calculateUniswapV2ETH, invert != flags.check(FLAG_DISABLE_UNISWAP_V2_DAI) ? _calculateNoReturn : calculateUniswapV2DAI, invert != flags.check(FLAG_DISABLE_UNISWAP_V2_USDC) ? _calculateNoReturn : calculateUniswapV2USDC, invert != flags.check(FLAG_DISABLE_CURVE_PAX) ? _calculateNoReturn : calculateCurvePax, invert != flags.check(FLAG_DISABLE_CURVE_RENBTC) ? _calculateNoReturn : calculateCurveRenBtc, invert != flags.check(FLAG_DISABLE_CURVE_TBTC) ? _calculateNoReturn : calculateCurveTBtc, invert != flags.check(FLAG_DISABLE_DFORCE_SWAP) ? _calculateNoReturn : calculateDforceSwap, invert != flags.check(FLAG_DISABLE_SHELL) ? _calculateNoReturn : calculateShell ]; uint256[DEXES_COUNT] memory rates; uint256[DEXES_COUNT] memory fullRates; for (uint i = 0; i < rates.length; i++) { rates[i] = reserves[i](fromToken, toToken, amount.div(parts), flags); this.log(rates[i]); fullRates[i] = rates[i]; } for (uint j = 0; j < parts; j++) { // Find best part uint256 bestIndex = 0; for (uint i = 1; i < rates.length; i++) { if (rates[i] > rates[bestIndex]) { bestIndex = i; } } // Add best part returnAmount = returnAmount.add(rates[bestIndex]); distribution[bestIndex]++; // Avoid CompilerError: Stack too deep uint256 srcAmount = amount; // Recalc part if needed if (j + 1 < parts) { uint256 newRate = reserves[bestIndex]( fromToken, toToken, srcAmount.mul(distribution[bestIndex] + 1).div(parts), flags ); if (newRate > fullRates[bestIndex]) { rates[bestIndex] = newRate.sub(fullRates[bestIndex]); } else { rates[bestIndex] = 0; } this.log(rates[bestIndex]); fullRates[bestIndex] = newRate; } } } // View Helpers function calculateCurveCompound( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0); if (i == 0 || j == 0) { return 0; } return curveCompound.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurveUsdt( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0); if (i == 0 || j == 0) { return 0; } return curveUsdt.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurveY( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == tusd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == tusd ? 4 : 0); if (i == 0 || j == 0) { return 0; } return curveY.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurveBinance( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == busd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == busd ? 4 : 0); if (i == 0 || j == 0) { return 0; } return curveBinance.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurveSynthetix( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == susd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == susd ? 4 : 0); if (i == 0 || j == 0) { return 0; } return curveSynthetix.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurvePax( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == pax ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == pax ? 4 : 0); if (i == 0 || j == 0) { return 0; } return curvePax.get_dy_underlying(i - 1, j - 1, amount); } function calculateCurveRenBtc( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == renbtc ? 1 : 0) + (fromToken == wbtc ? 2 : 0); int128 j = (destToken == renbtc ? 1 : 0) + (destToken == wbtc ? 2 : 0); if (i == 0 || j == 0) { return 0; } return curveRenBtc.get_dy(i - 1, j - 1, amount); } function calculateCurveTBtc( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { int128 i = (fromToken == tbtc ? 1 : 0) + (fromToken == wbtc ? 2 : 0) + (fromToken == hbtc ? 3 : 0); int128 j = (destToken == tbtc ? 1 : 0) + (destToken == wbtc ? 2 : 0) + (destToken == hbtc ? 3 : 0); if (i == 0 || j == 0) { return 0; } return curveTBtc.get_dy(i - 1, j - 1, amount); } function calculateShell( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns (uint256) { (bool success, bytes memory data) = address(shell).staticcall(abi.encodeWithSelector( shell.viewOriginTrade.selector, fromToken, destToken, amount )); if (!success || data.length == 0) { return 0; } return abi.decode(data, (uint256)); } function calculateDforceSwap( IERC20 fromToken, IERC20 destToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { (bool success, bytes memory data) = address(dforceSwap).staticcall( abi.encodeWithSelector( dforceSwap.getAmountByInput.selector, fromToken, destToken, amount ) ); if (!success || data.length == 0) { return 0; } uint256 result = abi.decode(data, (uint256)); uint256 available = destToken.universalBalanceOf(address(dforceSwap)); if (result > available) { return 0; } return result; } function calculateUniswapReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { uint256 returnAmount = amount; if (!fromToken.isETH()) { IUniswapExchange fromExchange = uniswapFactory.getExchange(fromToken); if (fromExchange != IUniswapExchange(0)) { (bool success, bytes memory data) = address(fromExchange).staticcall.gas(200000)( abi.encodeWithSelector( fromExchange.getTokenToEthInputPrice.selector, returnAmount ) ); if (success) { returnAmount = abi.decode(data, (uint256)); } else { returnAmount = 0; } } else { returnAmount = 0; } } if (!toToken.isETH()) { IUniswapExchange toExchange = uniswapFactory.getExchange(toToken); if (toExchange != IUniswapExchange(0)) { (bool success, bytes memory data) = address(toExchange).staticcall.gas(200000)( abi.encodeWithSelector( toExchange.getEthToTokenInputPrice.selector, returnAmount ) ); if (success) { returnAmount = abi.decode(data, (uint256)); } else { returnAmount = 0; } } else { returnAmount = 0; } } return returnAmount; } function calculateUniswapCompound( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (!fromToken.isETH() && !toToken.isETH()) { return 0; } if (!fromToken.isETH()) { ICompoundToken fromCompound = _getCompoundToken(fromToken); if (fromCompound != ICompoundToken(0)) { return calculateUniswapReturn( fromCompound, toToken, amount.mul(1e18).div(fromCompound.exchangeRateStored()), flags ); } } else { ICompoundToken toCompound = _getCompoundToken(toToken); if (toCompound != ICompoundToken(0)) { return calculateUniswapReturn( fromToken, toCompound, amount, flags ).mul(toCompound.exchangeRateStored()).div(1e18); } } return 0; } function calculateUniswapChai( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (fromToken == dai && toToken.isETH()) { return calculateUniswapReturn( chai, toToken, chai.daiToChai(amount), flags ); } if (fromToken.isETH() && toToken == dai) { return chai.chaiToDai(calculateUniswapReturn( fromToken, chai, amount, flags )); } return 0; } function calculateUniswapAave( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (!fromToken.isETH() && !toToken.isETH()) { return 0; } if (!fromToken.isETH()) { IAaveToken fromAave = _getAaveToken(fromToken); if (fromAave != IAaveToken(0)) { return calculateUniswapReturn( fromAave, toToken, amount, flags ); } } else { IAaveToken toAave = _getAaveToken(toToken); if (toAave != IAaveToken(0)) { return calculateUniswapReturn( fromToken, toAave, amount, flags ); } } return 0; } function calculateKyberReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { (bool success, bytes memory data) = address(kyberNetworkProxy).staticcall.gas(2300)(abi.encodeWithSelector( kyberNetworkProxy.kyberNetworkContract.selector )); if (!success) { return 0; } IKyberNetworkContract kyberNetworkContract = IKyberNetworkContract(abi.decode(data, (address))); if (fromToken.isETH() || toToken.isETH()) { return _calculateKyberReturnWithEth(kyberNetworkContract, fromToken, toToken, amount, flags); } uint256 value = _calculateKyberReturnWithEth(kyberNetworkContract, fromToken, ETH_ADDRESS, amount, flags); if (value == 0) { return 0; } return _calculateKyberReturnWithEth(kyberNetworkContract, ETH_ADDRESS, toToken, value, flags); } function _calculateKyberReturnWithEth( IKyberNetworkContract kyberNetworkContract, IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { require(fromToken.isETH() || toToken.isETH(), "One of the tokens should be ETH"); (bool success, bytes memory data) = address(kyberNetworkContract).staticcall.gas(1500000)(abi.encodeWithSelector( kyberNetworkContract.searchBestRate.selector, fromToken.isETH() ? ETH_ADDRESS : fromToken, toToken.isETH() ? ETH_ADDRESS : toToken, amount, true )); if (!success) { return 0; } (address reserve, uint256 rate) = abi.decode(data, (address,uint256)); if (rate == 0) { return 0; } if ((reserve == 0x31E085Afd48a1d6e51Cc193153d625e8f0514C7F && !flags.check(FLAG_ENABLE_KYBER_UNISWAP_RESERVE)) || (reserve == 0x1E158c0e93c30d24e918Ef83d1e0bE23595C3c0f && !flags.check(FLAG_ENABLE_KYBER_OASIS_RESERVE)) || (reserve == 0x053AA84FCC676113a57e0EbB0bD1913839874bE4 && !flags.check(FLAG_ENABLE_KYBER_BANCOR_RESERVE))) { return 0; } if (!flags.check(FLAG_ENABLE_KYBER_UNISWAP_RESERVE)) { (success,) = reserve.staticcall.gas(2300)(abi.encodeWithSelector( IKyberUniswapReserve(reserve).uniswapFactory.selector )); if (success) { return 0; } } if (!flags.check(FLAG_ENABLE_KYBER_OASIS_RESERVE)) { (success,) = reserve.staticcall.gas(2300)(abi.encodeWithSelector( IKyberOasisReserve(reserve).otc.selector )); if (success) { return 0; } } if (!flags.check(FLAG_ENABLE_KYBER_BANCOR_RESERVE)) { (success,) = reserve.staticcall.gas(2300)(abi.encodeWithSelector( IKyberBancorReserve(reserve).bancorEth.selector )); if (success) { return 0; } } return rate.mul(amount) .mul(10 ** IERC20(toToken).universalDecimals()) .div(10 ** IERC20(fromToken).universalDecimals()) .div(1e18); } function calculateBancorReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { IBancorNetwork bancorNetwork = IBancorNetwork(bancorContractRegistry.addressOf("BancorNetwork")); address[] memory path = _buildBancorPath(fromToken, toToken); (bool success, bytes memory data) = address(bancorNetwork).staticcall.gas(500000)( abi.encodeWithSelector( bancorNetwork.getReturnByPath.selector, path, amount ) ); if (!success) { return 0; } (uint256 returnAmount,) = abi.decode(data, (uint256,uint256)); return returnAmount; } function calculateOasisReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { (bool success, bytes memory data) = address(oasisExchange).staticcall.gas(500000)( abi.encodeWithSelector( oasisExchange.getBuyAmount.selector, toToken.isETH() ? weth : toToken, fromToken.isETH() ? weth : fromToken, amount ) ); if (!success) { return 0; } return abi.decode(data, (uint256)); } function calculateMooniswap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { IMooniswap mooniswap = mooniswapRegistry.target(); (bool success, bytes memory data) = address(mooniswap).staticcall.gas(1000000)( abi.encodeWithSelector( mooniswap.getReturn.selector, fromToken, toToken, amount ) ); if (!success) { return 0; } return abi.decode(data, (uint256)); } function calculateUniswapV2( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*flags*/ ) public view returns(uint256) { IERC20 fromTokenReal = fromToken.isETH() ? weth : fromToken; IERC20 toTokenReal = toToken.isETH() ? weth : toToken; IUniswapV2Exchange fromExchange = uniswapV2.getPair(fromTokenReal, toTokenReal); if (fromExchange != IUniswapV2Exchange(0)) { return fromExchange.getReturn(fromTokenReal, toTokenReal, amount); } } function calculateUniswapV2ETH( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (fromToken.isETH() || fromToken == weth || toToken.isETH() || toToken == weth) { return 0; } return calculateUniswapV2OverMidToken( fromToken, weth, toToken, amount, flags ); } function calculateUniswapV2DAI( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (fromToken == dai || toToken == dai) { return 0; } return calculateUniswapV2OverMidToken( fromToken, dai, toToken, amount, flags ); } function calculateUniswapV2USDC( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { if (fromToken == usdc || toToken == usdc) { return 0; } return calculateUniswapV2OverMidToken( fromToken, usdc, toToken, amount, flags ); } function calculateUniswapV2OverMidToken( IERC20 fromToken, IERC20 midToken, IERC20 toToken, uint256 amount, uint256 flags ) public view returns(uint256) { return calculateUniswapV2( midToken, toToken, calculateUniswapV2(fromToken, midToken, amount, flags), flags ); } function _calculateNoReturn( IERC20 /*fromToken*/, IERC20 /*toToken*/, uint256 /*amount*/, uint256 /*flags*/ ) internal view returns(uint256) { this; } } contract OneSplitBaseWrap is IOneSplit, OneSplitRoot { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags // See constants in IOneSplit.sol ) internal { if (fromToken == toToken) { return; } _swapFloor( fromToken, toToken, amount, distribution, flags ); } function _swapFloor( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 /*flags*/ // See constants in IOneSplit.sol ) internal; } contract OneSplit is IOneSplit, OneSplitRoot { IOneSplitView public oneSplitView; constructor(IOneSplitView _oneSplitView) public { oneSplitView = _oneSplitView; } function() external payable { // solium-disable-next-line security/no-tx-origin require(msg.sender != tx.origin); } function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return oneSplitView.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } function swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 /*minReturn*/, uint256[] memory distribution, uint256 /*flags*/ // See constants in IOneSplit.sol ) public payable { if (fromToken == toToken) { return; } function(IERC20,IERC20,uint256) returns(uint256)[DEXES_COUNT] memory reserves = [ _swapOnUniswap, _swapOnKyber, _swapOnBancor, _swapOnOasis, _swapOnCurveCompound, _swapOnCurveUsdt, _swapOnCurveY, _swapOnCurveBinance, _swapOnCurveSynthetix, _swapOnUniswapCompound, _swapOnUniswapChai, _swapOnUniswapAave, _swapOnMooniswap, _swapOnUniswapV2, _swapOnUniswapV2ETH, _swapOnUniswapV2DAI, _swapOnUniswapV2USDC, _swapOnCurvePax, _swapOnCurveRenBtc, _swapOnCurveTBtc, _swapOnDforceSwap, _swapOnShell ]; require(distribution.length <= reserves.length, "OneSplit: Distribution array should not exceed reserves array size"); uint256 parts = 0; uint256 lastNonZeroIndex = 0; for (uint i = 0; i < distribution.length; i++) { if (distribution[i] > 0) { parts = parts.add(distribution[i]); lastNonZeroIndex = i; } } require(parts > 0, "OneSplit: distribution should contain non-zeros"); uint256 remainingAmount = amount; for (uint i = 0; i < distribution.length; i++) { if (distribution[i] == 0) { continue; } uint256 swapAmount = amount.mul(distribution[i]).div(parts); if (i == lastNonZeroIndex) { swapAmount = remainingAmount; } remainingAmount -= swapAmount; reserves[i](fromToken, toToken, swapAmount); } } // Swap helpers function _swapOnCurveCompound( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveCompound)); curveCompound.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnCurveUsdt( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveUsdt)); curveUsdt.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnCurveY( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == tusd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == tusd ? 4 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveY)); curveY.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnCurveBinance( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == busd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == busd ? 4 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveBinance)); curveBinance.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnCurveSynthetix( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == susd ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == susd ? 4 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveSynthetix)); curveSynthetix.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnCurvePax( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == dai ? 1 : 0) + (fromToken == usdc ? 2 : 0) + (fromToken == usdt ? 3 : 0) + (fromToken == pax ? 4 : 0); int128 j = (destToken == dai ? 1 : 0) + (destToken == usdc ? 2 : 0) + (destToken == usdt ? 3 : 0) + (destToken == pax ? 4 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curvePax)); curvePax.exchange_underlying(i - 1, j - 1, amount, 0); } function _swapOnShell( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns (uint256) { _infiniteApproveIfNeeded(fromToken, address(shell)); return shell.swapByOrigin( address(fromToken), address(toToken), amount, 0, now + 50 ); } function _swapOnCurveRenBtc( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == renbtc ? 1 : 0) + (fromToken == wbtc ? 2 : 0); int128 j = (destToken == renbtc ? 1 : 0) + (destToken == wbtc ? 2 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveRenBtc)); curveRenBtc.exchange(i - 1, j - 1, amount, 0); } function _swapOnCurveTBtc( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { int128 i = (fromToken == tbtc ? 1 : 0) + (fromToken == wbtc ? 2 : 0) + (fromToken == hbtc ? 3 : 0); int128 j = (destToken == tbtc ? 1 : 0) + (destToken == wbtc ? 2 : 0) + (destToken == hbtc ? 3 : 0); if (i == 0 || j == 0) { return 0; } _infiniteApproveIfNeeded(fromToken, address(curveTBtc)); curveTBtc.exchange(i - 1, j - 1, amount, 0); } function _swapOnDforceSwap( IERC20 fromToken, IERC20 destToken, uint256 amount ) internal returns(uint256) { _infiniteApproveIfNeeded(fromToken, address(dforceSwap)); dforceSwap.swap(fromToken, destToken, amount); } function _swapOnUniswap( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { uint256 returnAmount = amount; if (!fromToken.isETH()) { IUniswapExchange fromExchange = uniswapFactory.getExchange(fromToken); if (fromExchange != IUniswapExchange(0)) { _infiniteApproveIfNeeded(fromToken, address(fromExchange)); returnAmount = fromExchange.tokenToEthSwapInput(returnAmount, 1, now); } } if (!toToken.isETH()) { IUniswapExchange toExchange = uniswapFactory.getExchange(toToken); if (toExchange != IUniswapExchange(0)) { returnAmount = toExchange.ethToTokenSwapInput.value(returnAmount)(1, now); } } return returnAmount; } function _swapOnUniswapCompound( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { if (!fromToken.isETH()) { ICompoundToken fromCompound = _getCompoundToken(fromToken); _infiniteApproveIfNeeded(fromToken, address(fromCompound)); fromCompound.mint(amount); return _swapOnUniswap(IERC20(fromCompound), toToken, IERC20(fromCompound).universalBalanceOf(address(this))); } if (!toToken.isETH()) { ICompoundToken toCompound = _getCompoundToken(toToken); uint256 compoundAmount = _swapOnUniswap(fromToken, IERC20(toCompound), amount); toCompound.redeem(compoundAmount); return toToken.universalBalanceOf(address(this)); } return 0; } function _swapOnUniswapChai( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { if (fromToken == dai) { _infiniteApproveIfNeeded(fromToken, address(chai)); chai.join(address(this), amount); return _swapOnUniswap(IERC20(chai), toToken, IERC20(chai).universalBalanceOf(address(this))); } if (toToken == dai) { uint256 chaiAmount = _swapOnUniswap(fromToken, IERC20(chai), amount); chai.exit(address(this), chaiAmount); return toToken.universalBalanceOf(address(this)); } return 0; } function _swapOnUniswapAave( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { if (!fromToken.isETH()) { IAaveToken fromAave = _getAaveToken(fromToken); _infiniteApproveIfNeeded(fromToken, aave.core()); aave.deposit(fromToken, amount, 1101); return _swapOnUniswap(IERC20(fromAave), toToken, IERC20(fromAave).universalBalanceOf(address(this))); } if (!toToken.isETH()) { IAaveToken toAave = _getAaveToken(toToken); uint256 aaveAmount = _swapOnUniswap(fromToken, IERC20(toAave), amount); toAave.redeem(aaveAmount); return aaveAmount; } return 0; } function _swapOnMooniswap( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { IMooniswap mooniswap = mooniswapRegistry.target(); _infiniteApproveIfNeeded(fromToken, address(mooniswap)); return mooniswap.swap.value(fromToken.isETH() ? amount : 0)( fromToken, toToken, amount, 0 ); } function _swapOnKyber( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { _infiniteApproveIfNeeded(fromToken, address(kyberNetworkProxy)); return kyberNetworkProxy.tradeWithHint.value(fromToken.isETH() ? amount : 0)( fromToken.isETH() ? ETH_ADDRESS : fromToken, amount, toToken.isETH() ? ETH_ADDRESS : toToken, address(this), 1 << 255, 0, 0x4D37f28D2db99e8d35A6C725a5f1749A085850a3, "" ); } function _swapOnBancor( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { if (fromToken.isETH()) { bancorEtherToken.deposit.value(amount)(); } IBancorNetwork bancorNetwork = IBancorNetwork(bancorContractRegistry.addressOf("BancorNetwork")); address[] memory path = _buildBancorPath(fromToken, toToken); _infiniteApproveIfNeeded(fromToken.isETH() ? bancorEtherToken : fromToken, address(bancorNetwork)); uint256 returnAmount = bancorNetwork.claimAndConvert(path, amount, 1); if (toToken.isETH()) { bancorEtherToken.withdraw(bancorEtherToken.balanceOf(address(this))); } return returnAmount; } function _swapOnOasis( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { if (fromToken.isETH()) { weth.deposit.value(amount)(); } _infiniteApproveIfNeeded(fromToken.isETH() ? weth : fromToken, address(oasisExchange)); uint256 returnAmount = oasisExchange.sellAllAmount( fromToken.isETH() ? weth : fromToken, amount, toToken.isETH() ? weth : toToken, 1 ); if (toToken.isETH()) { weth.withdraw(weth.balanceOf(address(this))); } return returnAmount; } function _swapOnUniswapV2Internal( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256 returnAmount) { if (fromToken.isETH()) { weth.deposit.value(amount)(); } IERC20 fromTokenReal = fromToken.isETH() ? weth : fromToken; IERC20 toTokenReal = toToken.isETH() ? weth : toToken; IUniswapV2Exchange exchange = uniswapV2.getPair(fromTokenReal, toTokenReal); returnAmount = exchange.getReturn(fromTokenReal, toTokenReal, amount); fromTokenReal.universalTransfer(address(exchange), amount); if (uint256(address(fromTokenReal)) < uint256(address(toTokenReal))) { exchange.swap(0, returnAmount, address(this), ""); } else { exchange.swap(returnAmount, 0, address(this), ""); } if (toToken.isETH()) { weth.withdraw(weth.balanceOf(address(this))); } } function _swapOnUniswapV2OverMid( IERC20 fromToken, IERC20 midToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { return _swapOnUniswapV2Internal( midToken, toToken, _swapOnUniswapV2Internal( fromToken, midToken, amount ) ); } function _swapOnUniswapV2( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { return _swapOnUniswapV2Internal( fromToken, toToken, amount ); } function _swapOnUniswapV2ETH( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { return _swapOnUniswapV2OverMid( fromToken, weth, toToken, amount ); } function _swapOnUniswapV2DAI( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { return _swapOnUniswapV2OverMid( fromToken, dai, toToken, amount ); } function _swapOnUniswapV2USDC( IERC20 fromToken, IERC20 toToken, uint256 amount ) internal returns(uint256) { return _swapOnUniswapV2OverMid( fromToken, usdc, toToken, amount ); } } // File: contracts/OneSplitMultiPath.sol pragma solidity ^0.5.0; contract OneSplitMultiPathBase is IOneSplitConsts, OneSplitRoot { function _getMultiPathToken(uint256 flags) internal pure returns(IERC20 midToken) { uint256[7] memory allFlags = [ FLAG_ENABLE_MULTI_PATH_ETH, FLAG_ENABLE_MULTI_PATH_DAI, FLAG_ENABLE_MULTI_PATH_USDC, FLAG_ENABLE_MULTI_PATH_USDT, FLAG_ENABLE_MULTI_PATH_WBTC, FLAG_ENABLE_MULTI_PATH_TBTC, FLAG_ENABLE_MULTI_PATH_RENBTC ]; IERC20[7] memory allMidTokens = [ ETH_ADDRESS, dai, usdc, usdt, wbtc, tbtc, renbtc ]; for (uint i = 0; i < allFlags.length; i++) { if (flags.check(allFlags[i])) { require(midToken == IERC20(0), "OneSplit: Do not use multipath with each other"); midToken = allMidTokens[i]; } } } } contract OneSplitMultiPathView is OneSplitViewWrapBase, OneSplitMultiPathBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns ( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } IERC20 midToken = _getMultiPathToken(flags); if (midToken != IERC20(0)) { if ((fromToken.isETH() && midToken.isETH()) || (toToken.isETH() && midToken.isETH()) || fromToken == midToken || toToken == midToken) { super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } (returnAmount, distribution) = super.getExpectedReturn( fromToken, midToken, amount, parts, flags | FLAG_DISABLE_BANCOR | FLAG_DISABLE_CURVE_COMPOUND | FLAG_DISABLE_CURVE_USDT | FLAG_DISABLE_CURVE_Y | FLAG_DISABLE_CURVE_BINANCE | FLAG_DISABLE_CURVE_PAX ); uint256[] memory dist; (returnAmount, dist) = super.getExpectedReturn( midToken, toToken, returnAmount, parts, flags | FLAG_DISABLE_BANCOR | FLAG_DISABLE_CURVE_COMPOUND | FLAG_DISABLE_CURVE_USDT | FLAG_DISABLE_CURVE_Y | FLAG_DISABLE_CURVE_BINANCE | FLAG_DISABLE_CURVE_PAX ); for (uint i = 0; i < distribution.length; i++) { distribution[i] = distribution[i].add(dist[i] << 8); } return (returnAmount, distribution); } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitMultiPath is OneSplitBaseWrap, OneSplitMultiPathBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { IERC20 midToken = _getMultiPathToken(flags); if (midToken != IERC20(0)) { uint256[] memory dist = new uint256[](distribution.length); for (uint i = 0; i < distribution.length; i++) { dist[i] = distribution[i] & 0xFF; } super._swap( fromToken, midToken, amount, dist, flags ); for (uint i = 0; i < distribution.length; i++) { dist[i] = (distribution[i] >> 8) & 0xFF; } super._swap( midToken, toToken, midToken.universalBalanceOf(address(this)), dist, flags ); return; } super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: contracts/OneSplitCompound.sol pragma solidity ^0.5.0; contract OneSplitCompoundBase { function _getCompoundUnderlyingToken(IERC20 token) internal pure returns(IERC20) { if (token == IERC20(0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5)) { // ETH return IERC20(0); } if (token == IERC20(0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643)) { // DAI return IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); } if (token == IERC20(0x6C8c6b02E7b2BE14d4fA6022Dfd6d75921D90E4E)) { // BAT return IERC20(0x0D8775F648430679A709E98d2b0Cb6250d2887EF); } if (token == IERC20(0x158079Ee67Fce2f58472A96584A73C7Ab9AC95c1)) { // REP return IERC20(0x1985365e9f78359a9B6AD760e32412f4a445E862); } if (token == IERC20(0x39AA39c021dfbaE8faC545936693aC917d5E7563)) { // USDC return IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); } if (token == IERC20(0xC11b1268C1A384e55C48c2391d8d480264A3A7F4)) { // WBTC return IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599); } if (token == IERC20(0xB3319f5D18Bc0D84dD1b4825Dcde5d5f7266d407)) { // ZRX return IERC20(0xE41d2489571d322189246DaFA5ebDe1F4699F498); } if (token == IERC20(0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9)) { // USDT return IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); } return IERC20(-1); } } contract OneSplitCompoundView is OneSplitViewWrapBase, OneSplitCompoundBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return _compoundGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _compoundGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) private view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_COMPOUND)) { IERC20 underlying = _getCompoundUnderlyingToken(fromToken); if (underlying != IERC20(-1)) { uint256 compoundRate = ICompoundToken(address(fromToken)).exchangeRateStored(); return _compoundGetExpectedReturn( underlying, toToken, amount.mul(compoundRate).div(1e18), parts, flags ); } underlying = _getCompoundUnderlyingToken(toToken); if (underlying != IERC20(-1)) { uint256 compoundRate = ICompoundToken(address(toToken)).exchangeRateStored(); (returnAmount, distribution) = super.getExpectedReturn( fromToken, underlying, amount, parts, flags ); returnAmount = returnAmount.mul(1e18).div(compoundRate); return (returnAmount, distribution); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitCompound is OneSplitBaseWrap, OneSplitCompoundBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _compundSwap( fromToken, toToken, amount, distribution, flags ); } function _compundSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) private { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_COMPOUND)) { IERC20 underlying = _getCompoundUnderlyingToken(fromToken); if (underlying != IERC20(-1)) { ICompoundToken(address(fromToken)).redeem(amount); uint256 underlyingAmount = underlying.universalBalanceOf(address(this)); return _compundSwap( underlying, toToken, underlyingAmount, distribution, flags ); } underlying = _getCompoundUnderlyingToken(toToken); if (underlying != IERC20(-1)) { super._swap( fromToken, underlying, amount, distribution, flags ); uint256 underlyingAmount = underlying.universalBalanceOf(address(this)); if (underlying.isETH()) { cETH.mint.value(underlyingAmount)(); } else { _infiniteApproveIfNeeded(underlying, address(toToken)); ICompoundToken(address(toToken)).mint(underlyingAmount); } return; } } return super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: @openzeppelin/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } } // File: contracts/interface/IFulcrum.sol pragma solidity ^0.5.0; contract IFulcrumToken is IERC20 { function tokenPrice() external view returns (uint256); function loanTokenAddress() external view returns (address); function mintWithEther(address receiver) external payable returns (uint256 mintAmount); function mint(address receiver, uint256 depositAmount) external returns (uint256 mintAmount); function burnToEther(address receiver, uint256 burnAmount) external returns (uint256 loanAmountPaid); function burn(address receiver, uint256 burnAmount) external returns (uint256 loanAmountPaid); } // File: contracts/OneSplitFulcrum.sol pragma solidity ^0.5.0; contract OneSplitFulcrumBase { using UniversalERC20 for IERC20; function _isFulcrumToken(IERC20 token) public view returns(IERC20) { if (token.isETH()) { return IERC20(-1); } (bool success, bytes memory data) = address(token).staticcall.gas(5000)(abi.encodeWithSelector( ERC20Detailed(address(token)).name.selector )); if (!success) { return IERC20(-1); } bool foundBZX = false; for (uint i = 0; i + 6 < data.length; i++) { if (data[i + 0] == "F" && data[i + 1] == "u" && data[i + 2] == "l" && data[i + 3] == "c" && data[i + 4] == "r" && data[i + 5] == "u" && data[i + 6] == "m") { foundBZX = true; break; } } if (!foundBZX) { return IERC20(-1); } (success, data) = address(token).staticcall.gas(5000)(abi.encodeWithSelector( IFulcrumToken(address(token)).loanTokenAddress.selector )); if (!success) { return IERC20(-1); } return abi.decode(data, (IERC20)); } } contract OneSplitFulcrumView is OneSplitViewWrapBase, OneSplitFulcrumBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return _fulcrumGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _fulcrumGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) private view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_FULCRUM)) { IERC20 underlying = _isFulcrumToken(fromToken); if (underlying != IERC20(-1)) { uint256 fulcrumRate = IFulcrumToken(address(fromToken)).tokenPrice(); return _fulcrumGetExpectedReturn( underlying, toToken, amount.mul(fulcrumRate).div(1e18), parts, flags ); } underlying = _isFulcrumToken(toToken); if (underlying != IERC20(-1)) { uint256 fulcrumRate = IFulcrumToken(address(toToken)).tokenPrice(); (returnAmount, distribution) = super.getExpectedReturn( fromToken, underlying, amount, parts, flags ); returnAmount = returnAmount.mul(1e18).div(fulcrumRate); return (returnAmount, distribution); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitFulcrum is OneSplitBaseWrap, OneSplitFulcrumBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _fulcrumSwap( fromToken, toToken, amount, distribution, flags ); } function _fulcrumSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) private { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_FULCRUM)) { IERC20 underlying = _isFulcrumToken(fromToken); if (underlying != IERC20(-1)) { if (underlying.isETH()) { IFulcrumToken(address(fromToken)).burnToEther(address(this), amount); } else { IFulcrumToken(address(fromToken)).burn(address(this), amount); } uint256 underlyingAmount = underlying.universalBalanceOf(address(this)); return super._swap( underlying, toToken, underlyingAmount, distribution, flags ); } underlying = _isFulcrumToken(toToken); if (underlying != IERC20(-1)) { super._swap( fromToken, underlying, amount, distribution, flags ); uint256 underlyingAmount = underlying.universalBalanceOf(address(this)); if (underlying.isETH()) { IFulcrumToken(address(toToken)).mintWithEther.value(underlyingAmount)(address(this)); } else { _infiniteApproveIfNeeded(underlying, address(toToken)); IFulcrumToken(address(toToken)).mint(address(this), underlyingAmount); } return; } } return super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: contracts/OneSplitChai.sol pragma solidity ^0.5.0; contract OneSplitChaiView is OneSplitViewWrapBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_CHAI)) { if (fromToken == IERC20(chai)) { return super.getExpectedReturn( dai, toToken, chai.chaiToDai(amount), parts, flags ); } if (toToken == IERC20(chai)) { (returnAmount, distribution) = super.getExpectedReturn( fromToken, dai, amount, parts, flags ); return (chai.daiToChai(returnAmount), distribution); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitChai is OneSplitBaseWrap { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_CHAI)) { if (fromToken == IERC20(chai)) { chai.exit(address(this), amount); return super._swap( dai, toToken, dai.balanceOf(address(this)), distribution, flags ); } if (toToken == IERC20(chai)) { super._swap( fromToken, dai, amount, distribution, flags ); _infiniteApproveIfNeeded(dai, address(chai)); chai.join(address(this), dai.balanceOf(address(this))); return; } } return super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: contracts/interface/IBdai.sol pragma solidity ^0.5.0; contract IBdai is IERC20 { function join(uint256) external; function exit(uint256) external; } // File: contracts/OneSplitBdai.sol pragma solidity ^0.5.0; contract OneSplitBdaiBase { IBdai public bdai = IBdai(0x6a4FFAafa8DD400676Df8076AD6c724867b0e2e8); IERC20 public btu = IERC20(0xb683D83a532e2Cb7DFa5275eED3698436371cc9f); } contract OneSplitBdaiView is OneSplitViewWrapBase, OneSplitBdaiBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns (uint256 returnAmount, uint256[] memory distribution) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_BDAI)) { if (fromToken == IERC20(bdai)) { return super.getExpectedReturn( dai, toToken, amount, parts, flags ); } if (toToken == IERC20(bdai)) { return super.getExpectedReturn( fromToken, dai, amount, parts, flags ); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitBdai is OneSplitBaseWrap, OneSplitBdaiBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_BDAI)) { if (fromToken == IERC20(bdai)) { bdai.exit(amount); uint256 btuBalance = btu.balanceOf(address(this)); if (btuBalance > 0) { (,uint256[] memory btuDistribution) = getExpectedReturn( btu, toToken, btuBalance, 1, flags ); _swap( btu, toToken, btuBalance, btuDistribution, flags ); } return super._swap( dai, toToken, amount, distribution, flags ); } if (toToken == IERC20(bdai)) { super._swap(fromToken, dai, amount, distribution, flags); _infiniteApproveIfNeeded(dai, address(bdai)); bdai.join(dai.balanceOf(address(this))); return; } } return super._swap(fromToken, toToken, amount, distribution, flags); } } // File: contracts/interface/IIearn.sol pragma solidity ^0.5.0; contract IIearn is IERC20 { function token() external view returns(IERC20); function calcPoolValueInToken() external view returns(uint256); function deposit(uint256 _amount) external; function withdraw(uint256 _shares) external; } // File: contracts/OneSplitIearn.sol pragma solidity ^0.5.0; contract OneSplitIearnBase { function _yTokens() internal pure returns(IIearn[13] memory) { return [ IIearn(0x16de59092dAE5CcF4A1E6439D611fd0653f0Bd01), IIearn(0x04Aa51bbcB46541455cCF1B8bef2ebc5d3787EC9), IIearn(0x73a052500105205d34Daf004eAb301916DA8190f), IIearn(0x83f798e925BcD4017Eb265844FDDAbb448f1707D), IIearn(0xd6aD7a6750A7593E092a9B218d66C0A814a3436e), IIearn(0xF61718057901F84C4eEC4339EF8f0D86D2B45600), IIearn(0x04bC0Ab673d88aE9dbC9DA2380cB6B79C4BCa9aE), IIearn(0xC2cB1040220768554cf699b0d863A3cd4324ce32), IIearn(0xE6354ed5bC4b393a5Aad09f21c46E101e692d447), IIearn(0x26EA744E5B887E5205727f55dFBE8685e3b21951), IIearn(0x99d1Fa417f94dcD62BfE781a1213c092a47041Bc), IIearn(0x9777d7E2b60bB01759D0E2f8be2095df444cb07E), IIearn(0x1bE5d71F2dA660BFdee8012dDc58D024448A0A59) ]; } } contract OneSplitIearnView is OneSplitViewWrapBase, OneSplitIearnBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns (uint256 returnAmount, uint256[] memory distribution) { return _iearnGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _iearnGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) private view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (!flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == !flags.check(FLAG_DISABLE_IEARN)) { IIearn[13] memory yTokens = _yTokens(); for (uint i = 0; i < yTokens.length; i++) { if (fromToken == IERC20(yTokens[i])) { return _iearnGetExpectedReturn( yTokens[i].token(), toToken, amount .mul(yTokens[i].calcPoolValueInToken()) .div(yTokens[i].totalSupply()), parts, flags ); } } for (uint i = 0; i < yTokens.length; i++) { if (toToken == IERC20(yTokens[i])) { (uint256 ret, uint256[] memory dist) = super.getExpectedReturn( fromToken, yTokens[i].token(), amount, parts, flags ); return ( ret .mul(yTokens[i].totalSupply()) .div(yTokens[i].calcPoolValueInToken()), dist ); } } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitIearn is OneSplitBaseWrap, OneSplitIearnBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _iearnSwap( fromToken, toToken, amount, distribution, flags ); } function _iearnSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) private { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_IEARN)) { IIearn[13] memory yTokens = _yTokens(); for (uint i = 0; i < yTokens.length; i++) { if (fromToken == IERC20(yTokens[i])) { IERC20 underlying = yTokens[i].token(); yTokens[i].withdraw(amount); _iearnSwap(underlying, toToken, underlying.balanceOf(address(this)), distribution, flags); return; } } for (uint i = 0; i < yTokens.length; i++) { if (toToken == IERC20(yTokens[i])) { IERC20 underlying = yTokens[i].token(); super._swap(fromToken, underlying, amount, distribution, flags); _infiniteApproveIfNeeded(underlying, address(yTokens[i])); yTokens[i].deposit(underlying.balanceOf(address(this))); return; } } } return super._swap(fromToken, toToken, amount, distribution, flags); } } // File: contracts/interface/IIdle.sol pragma solidity ^0.5.0; contract IIdle is IERC20 { function token() external view returns (IERC20); function tokenPrice() external view returns (uint256); function mintIdleToken(uint256 _amount, uint256[] calldata _clientProtocolAmounts) external returns (uint256 mintedTokens); function redeemIdleToken(uint256 _amount, bool _skipRebalance, uint256[] calldata _clientProtocolAmounts) external returns (uint256 redeemedTokens); } // File: contracts/OneSplitIdle.sol pragma solidity ^0.5.0; contract OneSplitIdleBase { function _idleTokens() internal pure returns(IIdle[2] memory) { return [ IIdle(0x10eC0D497824e342bCB0EDcE00959142aAa766dD), IIdle(0xeB66ACc3d011056B00ea521F8203580C2E5d3991) ]; } } contract OneSplitIdleView is OneSplitViewWrapBase, OneSplitIdleBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns (uint256 /*returnAmount*/, uint256[] memory /*distribution*/) { return _idleGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _idleGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) internal view returns (uint256 returnAmount, uint256[] memory distribution) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (!flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == !flags.check(FLAG_DISABLE_IDLE)) { IIdle[2] memory tokens = _idleTokens(); for (uint i = 0; i < tokens.length; i++) { if (fromToken == IERC20(tokens[i])) { return _idleGetExpectedReturn( tokens[i].token(), toToken, amount.mul(tokens[i].tokenPrice()).div(1e18), parts, flags ); } } for (uint i = 0; i < tokens.length; i++) { if (toToken == IERC20(tokens[i])) { (uint256 ret, uint256[] memory dist) = super.getExpectedReturn( fromToken, tokens[i].token(), amount, parts, flags ); return ( ret.mul(1e18).div(tokens[i].tokenPrice()), dist ); } } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitIdle is OneSplitBaseWrap, OneSplitIdleBase { function _superOneSplitIdleSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] calldata distribution, uint256 flags ) external { require(msg.sender == address(this)); return super._swap(fromToken, toToken, amount, distribution, flags); } function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _idleSwap( fromToken, toToken, amount, distribution, flags ); } function _idleSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) public payable { if (!flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == !flags.check(FLAG_DISABLE_IDLE)) { IIdle[2] memory tokens = _idleTokens(); for (uint i = 0; i < tokens.length; i++) { if (fromToken == IERC20(tokens[i])) { IERC20 underlying = tokens[i].token(); uint256 minted = tokens[i].redeemIdleToken(amount, true, new uint256[](0)); _idleSwap(underlying, toToken, minted, distribution, flags); return; } } for (uint i = 0; i < tokens.length; i++) { if (toToken == IERC20(tokens[i])) { IERC20 underlying = tokens[i].token(); super._swap(fromToken, underlying, amount, distribution, flags); _infiniteApproveIfNeeded(underlying, address(tokens[i])); tokens[i].mintIdleToken(underlying.balanceOf(address(this)), new uint256[](0)); return; } } } return super._swap(fromToken, toToken, amount, distribution, flags); } } // File: contracts/OneSplitAave.sol pragma solidity ^0.5.0; contract OneSplitAaveBase { function _getAaveUnderlyingToken(IERC20 token) internal pure returns(IERC20) { if (token == IERC20(0x3a3A65aAb0dd2A17E3F1947bA16138cd37d08c04)) { // ETH return IERC20(0); } if (token == IERC20(0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d)) { // DAI return IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); } if (token == IERC20(0x9bA00D6856a4eDF4665BcA2C2309936572473B7E)) { // USDC return IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); } if (token == IERC20(0x625aE63000f46200499120B906716420bd059240)) { // SUSD return IERC20(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51); } if (token == IERC20(0x6Ee0f7BB50a54AB5253dA0667B0Dc2ee526C30a8)) { // BUSD return IERC20(0x4Fabb145d64652a948d72533023f6E7A623C7C53); } if (token == IERC20(0x4DA9b813057D04BAef4e5800E36083717b4a0341)) { // TUSD return IERC20(0x0000000000085d4780B73119b644AE5ecd22b376); } if (token == IERC20(0x71fc860F7D3A592A4a98740e39dB31d25db65ae8)) { // USDT return IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); } if (token == IERC20(0xE1BA0FB44CCb0D11b80F92f4f8Ed94CA3fF51D00)) { // BAT return IERC20(0x0D8775F648430679A709E98d2b0Cb6250d2887EF); } if (token == IERC20(0x9D91BE44C06d373a8a226E1f3b146956083803eB)) { // KNC return IERC20(0xdd974D5C2e2928deA5F71b9825b8b646686BD200); } if (token == IERC20(0x7D2D3688Df45Ce7C552E19c27e007673da9204B8)) { // LEND return IERC20(0x80fB784B7eD66730e8b1DBd9820aFD29931aab03); } if (token == IERC20(0xA64BD6C70Cb9051F6A9ba1F163Fdc07E0DfB5F84)) { // LINK return IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA); } if (token == IERC20(0x6FCE4A401B6B80ACe52baAefE4421Bd188e76F6f)) { // MANA return IERC20(0x0F5D2fB29fb7d3CFeE444a200298f468908cC942); } if (token == IERC20(0x7deB5e830be29F91E298ba5FF1356BB7f8146998)) { // MKR return IERC20(0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2); } if (token == IERC20(0x71010A9D003445aC60C4e6A7017c1E89A477B438)) { // REP return IERC20(0x1985365e9f78359a9B6AD760e32412f4a445E862); } if (token == IERC20(0x328C4c80BC7aCa0834Db37e6600A6c49E12Da4DE)) { // SNX return IERC20(0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F); } if (token == IERC20(0xFC4B8ED459e00e5400be803A9BB3954234FD50e3)) { // WBTC return IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599); } if (token == IERC20(0x6Fb0855c404E09c47C3fBCA25f08d4E41f9F062f)) { // ZRX return IERC20(0xE41d2489571d322189246DaFA5ebDe1F4699F498); } return IERC20(-1); } } contract OneSplitAaveView is OneSplitViewWrapBase, OneSplitAaveBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return _aaveGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _aaveGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) private view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, distribution); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_AAVE)) { IERC20 underlying = _getAaveUnderlyingToken(fromToken); if (underlying != IERC20(-1)) { return _aaveGetExpectedReturn( underlying, toToken, amount, parts, flags ); } underlying = _getAaveUnderlyingToken(toToken); if (underlying != IERC20(-1)) { return super.getExpectedReturn( fromToken, underlying, amount, parts, flags ); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitAave is OneSplitBaseWrap, OneSplitAaveBase { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _aaveSwap( fromToken, toToken, amount, distribution, flags ); } function _aaveSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) private { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_AAVE)) { IERC20 underlying = _getAaveUnderlyingToken(fromToken); if (underlying != IERC20(-1)) { IAaveToken(address(fromToken)).redeem(amount); return _aaveSwap( underlying, toToken, amount, distribution, flags ); } underlying = _getAaveUnderlyingToken(toToken); if (underlying != IERC20(-1)) { super._swap( fromToken, underlying, amount, distribution, flags ); uint256 underlyingAmount = underlying.universalBalanceOf(address(this)); _infiniteApproveIfNeeded(underlying, aave.core()); aave.deposit.value(underlying.isETH() ? underlyingAmount : 0)( underlying.isETH() ? ETH_ADDRESS : underlying, underlyingAmount, 1101 ); return; } } return super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: contracts/OneSplitWeth.sol pragma solidity ^0.5.0; contract OneSplitWethView is OneSplitViewWrapBase { function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { return _wethGetExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _wethGetExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) private view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_WETH)) { if (fromToken == weth || fromToken == bancorEtherToken) { return super.getExpectedReturn(ETH_ADDRESS, toToken, amount, parts, flags); } if (toToken == weth || toToken == bancorEtherToken) { return super.getExpectedReturn(fromToken, ETH_ADDRESS, amount, parts, flags); } } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitWeth is OneSplitBaseWrap { function _swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { _wethSwap( fromToken, toToken, amount, distribution, flags ); } function _wethSwap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) private { if (fromToken == toToken) { return; } if (flags.check(FLAG_DISABLE_ALL_WRAP_SOURCES) == flags.check(FLAG_DISABLE_WETH)) { if (fromToken == weth) { weth.withdraw(weth.balanceOf(address(this))); super._swap( ETH_ADDRESS, toToken, amount, distribution, flags ); return; } if (fromToken == bancorEtherToken) { bancorEtherToken.withdraw(bancorEtherToken.balanceOf(address(this))); super._swap( ETH_ADDRESS, toToken, amount, distribution, flags ); return; } if (toToken == weth) { _wethSwap( fromToken, ETH_ADDRESS, amount, distribution, flags ); weth.deposit.value(address(this).balance)(); return; } if (toToken == bancorEtherToken) { _wethSwap( fromToken, ETH_ADDRESS, amount, distribution, flags ); bancorEtherToken.deposit.value(address(this).balance)(); return; } } return super._swap( fromToken, toToken, amount, distribution, flags ); } } // File: contracts/OneSplit.sol pragma solidity ^0.5.0; //import "./OneSplitSmartToken.sol"; contract OneSplitViewWrap is OneSplitViewWrapBase, OneSplitMultiPathView, OneSplitChaiView, OneSplitBdaiView, OneSplitAaveView, OneSplitFulcrumView, OneSplitCompoundView, OneSplitIearnView, OneSplitIdleView, OneSplitWethView //OneSplitSmartTokenView { IOneSplitView public oneSplitView; constructor(IOneSplitView _oneSplit) public { oneSplitView = _oneSplit; } function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) public view returns( uint256 returnAmount, uint256[] memory distribution ) { if (fromToken == toToken) { return (amount, new uint256[](DEXES_COUNT)); } return super.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } function _getExpectedReturnFloor( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags ) internal view returns( uint256 returnAmount, uint256[] memory distribution ) { return oneSplitView.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } } contract OneSplitWrap is OneSplitBaseWrap, OneSplitMultiPath, OneSplitChai, OneSplitBdai, OneSplitAave, OneSplitFulcrum, OneSplitCompound, OneSplitIearn, OneSplitIdle, OneSplitWeth //OneSplitSmartToken { IOneSplitView public oneSplitView; IOneSplit public oneSplit; constructor(IOneSplitView _oneSplitView, IOneSplit _oneSplit) public { oneSplitView = _oneSplitView; oneSplit = _oneSplit; } function() external payable { // solium-disable-next-line security/no-tx-origin require(msg.sender != tx.origin); } function getExpectedReturn( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 parts, uint256 flags // 1 - Uniswap, 2 - Kyber, 4 - Bancor, 8 - Oasis, 16 - Compound, 32 - Fulcrum, 64 - Chai, 128 - Aave, 256 - SmartToken, 1024 - bDAI ) public view returns( uint256 /*returnAmount*/, uint256[] memory /*distribution*/ ) { return oneSplitView.getExpectedReturn( fromToken, toToken, amount, parts, flags ); } function swap( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256 minReturn, uint256[] memory distribution, // [Uniswap, Kyber, Bancor, Oasis] uint256 flags // 16 - Compound, 32 - Fulcrum, 64 - Chai, 128 - Aave, 256 - SmartToken, 1024 - bDAI ) public payable { fromToken.universalTransferFrom(msg.sender, address(this), amount); _swap(fromToken, toToken, amount, distribution, flags); uint256 returnAmount = toToken.universalBalanceOf(address(this)); require(returnAmount >= minReturn, "OneSplit: actual return amount is less than minReturn"); toToken.universalTransfer(msg.sender, returnAmount); fromToken.universalTransfer(msg.sender, fromToken.universalBalanceOf(address(this))); } function _swapFloor( IERC20 fromToken, IERC20 toToken, uint256 amount, uint256[] memory distribution, uint256 flags ) internal { (bool success, bytes memory data) = address(oneSplit).delegatecall( abi.encodeWithSelector( this.swap.selector, fromToken, toToken, amount, 0, distribution, flags ) ); assembly { switch success // delegatecall returns 0 on error. case 0 { revert(add(data, 32), returndatasize) } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IOneSplitView","name":"_oneSplitView","type":"address"},{"internalType":"contract IOneSplit","name":"_oneSplit","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"DEXES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_AAVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_ALL_SPLIT_SOURCES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_ALL_WRAP_SOURCES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_BANCOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_BDAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CHAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_COMPOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_BINANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_COMPOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_PAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_RENBTC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_SYNTHETIX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_TBTC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_USDT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_CURVE_Y","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_DFORCE_SWAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_FULCRUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_IDLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_IEARN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_KYBER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_MOONISWAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_OASIS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_SHELL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_SMART_TOKEN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP_V2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP_V2_ALL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP_V2_DAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP_V2_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_UNISWAP_V2_USDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_DISABLE_WETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_KYBER_BANCOR_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_KYBER_OASIS_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_KYBER_UNISWAP_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_DAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_RENBTC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_TBTC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_USDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_USDT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_MULTI_PATH_WBTC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_UNISWAP_AAVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_UNISWAP_CHAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FLAG_ENABLE_UNISWAP_COMPOUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"_idleSwap","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"_isFulcrumToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"_superOneSplitIdleSwap","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"aave","outputs":[{"internalType":"contract IAaveLendingPool","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bancorContractRegistry","outputs":[{"internalType":"contract IBancorContractRegistry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bancorConverterRegistry","outputs":[{"internalType":"contract IBancorConverterRegistry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bancorEtherToken","outputs":[{"internalType":"contract IBancorEtherToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bdai","outputs":[{"internalType":"contract IBdai","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bnt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"btu","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"busd","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cETH","outputs":[{"internalType":"contract ICompoundEther","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"chai","outputs":[{"internalType":"contract IChai","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"compound","outputs":[{"internalType":"contract ICompound","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveBinance","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveCompound","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curvePax","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveRenBtc","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveSynthetix","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveTBtc","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveUsdt","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curveY","outputs":[{"internalType":"contract ICurve","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dforceSwap","outputs":[{"internalType":"contract IDForceSwap","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"parts","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"getExpectedReturn","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hbtc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kyberNetworkProxy","outputs":[{"internalType":"contract IKyberNetworkProxy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mooniswapRegistry","outputs":[{"internalType":"contract IMooniswapRegistry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oasisExchange","outputs":[{"internalType":"contract IOasisExchange","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oneSplit","outputs":[{"internalType":"contract IOneSplit","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oneSplitView","outputs":[{"internalType":"contract IOneSplitView","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pax","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"renbtc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"shell","outputs":[{"internalType":"contract IShell","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"susd","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"fromToken","type":"address"},{"internalType":"contract IERC20","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"swap","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"tbtc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tusd","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"uniswapFactory","outputs":[{"internalType":"contract IUniswapFactory","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"uniswapV2","outputs":[{"internalType":"contract IUniswapV2Factory","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"usdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"wbtc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052600080546001600160a01b0319908116736a4ffaafa8dd400676df8076ad6c724867b0e2e8179091556001805490911673b683d83a532e2cb7dfa5275eed3698436371cc9f17905534801561005857600080fd5b5060405162004a4438038062004a448339818101604052604081101561007d57600080fd5b508051602090910151600280546001600160a01b039384166001600160a01b0319918216179091556003805493909216921691909117905561497f80620000c56000396000f3fe6080604052600436106104e15760003560e01c80637e09b9c211610281578063c9b42c671161015a578063df1b4e99116100cc578063f11d2ff411610085578063f11d2ff414610e5d578063f4b9fa7514610e72578063f56e281f14610e87578063f69e204614610e9c578063fa3f110b14610eb1578063fbe4ed9514610ec6576104e1565b8063df1b4e9914610d2c578063e0de8f2214610d41578063e1308b3314610d56578063e2a7515e14610d6b578063e355812314610e33578063e44987b414610e48576104e1565b8063d1ae60631161011e578063d1ae606314610c3d578063d393c3e914610cd8578063d70a2d1f14610ced578063d77366a414610d02578063dc1536b214610d17578063ddd2f8d01461065b576104e1565b8063c9b42c6714610bd4578063cc26e9fc14610be9578063cd240d7514610bfe578063ce74b7ac14610c13578063cede5f6a14610c28576104e1565b8063b0a7ef29116101f3578063c11f4f11116101b7578063c11f4f1114610b56578063c762a46c14610b6b578063c77b9de614610b80578063c7f112e414610b95578063c925777514610baa578063c989b66714610bbf576104e1565b8063b0a7ef2914610b02578063b184a3ae14610b17578063b3bc784414610685578063b69d045614610b2c578063bf2c5a0714610b41576104e1565b8063944a32e211610245578063944a32e2146109d6578063960d2c1914610a99578063a1b4d01114610aae578063a2878cb114610ac3578063a4792ab314610ad8578063a734f06e14610aed576104e1565b80637e09b9c21461096d578063819faf7b14610982578063851954fa146109975780638bdb2afa146109ac57806390354872146109c1576104e1565b80633fc8cef3116103be5780635aa8fb48116103305780636cbc4a6e116102e95780636cbc4a6e1461090457806375a8b0121461091957806375b5be2d1461092e57806376c3972614610943578063792e69d7146106af5780637a88bdbd14610958576104e1565b80635aa8fb48146108865780635ae51b821461089b5780635c0cb479146108b057806364ec4e5c146108c557806368e2a014146108da5780636b5a4ca2146108ef576104e1565b806344211d621161038257806344211d62146108085780634752c6801461081d5780634a7101d5146108325780635187c0911461084757806351f1985c1461085c57806352a701b414610871576104e1565b80633fc8cef3146107815780634037f9671461079657806340ab7b8c146107c9578063423d03f9146107de57806343ee21f0146107f3576104e1565b80632ceb90b81161045757806334b4dabb1161041b57806334b4dabb14610703578063372a26cb14610718578063376e55b71461072d5780633ca5b234146107425780633cdc5389146107575780633e413bee1461076c576104e1565b80632ceb90b81461069a5780632d3b5207146106af5780632e707bd2146106c45780632f0fe755146106d95780632f48ab7d146106ee576104e1565b80631d209b65116104a95780631d209b651461061c5780632113240d1461063157806321899d3a1461064657806321a360f51461065b57806322320c981461067057806327a7fbd514610685576104e1565b806305d8aa0a146104f0578063085e2c5b1461051757806312dea160146105c15780631388b420146105f25780631398914014610607575b333214156104ee57600080fd5b005b3480156104fc57600080fd5b50610505610edb565b60408051918252519081900360200190f35b34801561052357600080fd5b50610566600480360360a081101561053a57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135610ee2565b6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156105ac578181015183820152602001610594565b50505050905001935050505060405180910390f35b3480156105cd57600080fd5b506105d661102a565b604080516001600160a01b039092168252519081900360200190f35b3480156105fe57600080fd5b506105d6611042565b34801561061357600080fd5b5061050561105a565b34801561062857600080fd5b50610505611060565b34801561063d57600080fd5b50610505611068565b34801561065257600080fd5b5061050561106e565b34801561066757600080fd5b50610505611077565b34801561067c57600080fd5b506105d6611080565b34801561069157600080fd5b50610505611098565b3480156106a657600080fd5b506105056110a1565b3480156106bb57600080fd5b506105056110aa565b3480156106d057600080fd5b506105056110b2565b3480156106e557600080fd5b506105d66110b7565b3480156106fa57600080fd5b506105d66110cf565b34801561070f57600080fd5b506105056110e7565b34801561072457600080fd5b506105d66110ec565b34801561073957600080fd5b50610505611104565b34801561074e57600080fd5b506105d661110d565b34801561076357600080fd5b506105d6611125565b34801561077857600080fd5b506105d661113d565b34801561078d57600080fd5b506105d6611155565b3480156107a257600080fd5b506105d6600480360360208110156107b957600080fd5b50356001600160a01b031661116d565b3480156107d557600080fd5b506105d66114e5565b3480156107ea57600080fd5b506105d66114fd565b3480156107ff57600080fd5b506105d6611515565b34801561081457600080fd5b50610505611524565b34801561082957600080fd5b50610505611529565b34801561083e57600080fd5b50610505611531565b34801561085357600080fd5b506105d6611536565b34801561086857600080fd5b506105d661154e565b34801561087d57600080fd5b506105d6611566565b34801561089257600080fd5b5061050561157e565b3480156108a757600080fd5b50610505611584565b3480156108bc57600080fd5b5061050561158a565b3480156108d157600080fd5b5061050561158f565b3480156108e657600080fd5b50610505611596565b3480156108fb57600080fd5b506105d661159d565b34801561091057600080fd5b506105056115ac565b34801561092557600080fd5b506105056115b3565b34801561093a57600080fd5b506105d66115b9565b34801561094f57600080fd5b506105056115cc565b34801561096457600080fd5b506105056115d5565b34801561097957600080fd5b506105056115da565b34801561098e57600080fd5b506105d66115e1565b3480156109a357600080fd5b506105d66115f9565b3480156109b857600080fd5b506105d6611611565b3480156109cd57600080fd5b506105d6611629565b6104ee600480360360a08110156109ec57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a2657600080fd5b820183602082011115610a3857600080fd5b803590602001918460208302840111600160201b83111715610a5957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611641915050565b348015610aa557600080fd5b506105d6611aac565b348015610aba57600080fd5b506105d6611ac4565b348015610acf57600080fd5b50610505611adc565b348015610ae457600080fd5b506105d6611ae4565b348015610af957600080fd5b506105d6611afc565b348015610b0e57600080fd5b50610505611b14565b348015610b2357600080fd5b506105d6611b1a565b348015610b3857600080fd5b506105d6611b32565b348015610b4d57600080fd5b50610505611b4a565b348015610b6257600080fd5b506105d6611b52565b348015610b7757600080fd5b50610505611b61565b348015610b8c57600080fd5b50610505611b66565b348015610ba157600080fd5b50610505611b6c565b348015610bb657600080fd5b506105d6611b74565b348015610bcb57600080fd5b50610505611b8c565b348015610be057600080fd5b50610505611b93565b348015610bf557600080fd5b50610505611b9a565b348015610c0a57600080fd5b506105d6611b9f565b348015610c1f57600080fd5b50610505611bb7565b348015610c3457600080fd5b506105d6611bbf565b348015610c4957600080fd5b506104ee600480360360a0811015610c6057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610c9a57600080fd5b820183602082011115610cac57600080fd5b803590602001918460208302840111600160201b83111715610ccd57600080fd5b919350915035611bd7565b348015610ce457600080fd5b50610505611c2c565b348015610cf957600080fd5b506105d6611c33565b348015610d0e57600080fd5b506105d6611c4b565b348015610d2357600080fd5b50610505611c63565b348015610d3857600080fd5b50610505611c69565b348015610d4d57600080fd5b506105d6611c72565b348015610d6257600080fd5b506105d6611c8a565b6104ee600480360360c0811015610d8157600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610dc057600080fd5b820183602082011115610dd257600080fd5b803590602001918460208302840111600160201b83111715610df357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611ca2915050565b348015610e3f57600080fd5b50610505611d7f565b348015610e5457600080fd5b50610505611d87565b348015610e6957600080fd5b506105d6611d8f565b348015610e7e57600080fd5b506105d6611da7565b348015610e9357600080fd5b50610505611dbf565b348015610ea857600080fd5b506105d6611dc4565b348015610ebd57600080fd5b50610505611ddc565b348015610ed257600080fd5b506105d6611de4565b6220000081565b6002546040805163085e2c5b60e01b81526001600160a01b03888116600483015287811660248301526044820187905260648201869052608482018590529151600093606093169163085e2c5b9160a48083019287929190829003018186803b158015610f4e57600080fd5b505afa158015610f62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610f8b57600080fd5b815160208301805160405192949293830192919084600160201b821115610fb157600080fd5b908301906020820185811115610fc657600080fd5b82518660208202830111600160201b82111715610fe257600080fd5b82525081516020918201928201910280838360005b8381101561100f578181015183820152602001610ff7565b50505050905001604052505050915091509550959350505050565b7352ae12abe5d8bd778bd5397f99ca900624cfadd481565b73794e6e91555438afc3ccf1c5076a74f42133d08d81565b61200081565b630400000081565b61800081565b64400000000081565b64020000000081565b73a5407eae9ba41422680e2e00537571bcc53efbfd81565b64040000000081565b64800000000081565b600160201b81565b608081565b730316eb71485b0ab14103307bf65a021042c6d38081565b73dac17f958d2ee523a2206206994597c13d831ec781565b604081565b7379a8c46dea5ada233abaffd40f3a0a2b1e5a4f2781565b64100000000081565b734fabb145d64652a948d72533023f6e7a623c7c5381565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000611181826001600160a01b0316611df3565b1561118f57506000196114e0565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b178152915181516000936060936001600160a01b0388169361138893919290918291908083835b602083106111fa5780518252601f1990920191602091820191016111db565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461125b576040519150601f19603f3d011682016040523d82523d6000602084013e611260565b606091505b50915091508161127657600019925050506114e0565b6000805b82518160060110156113cf5782816000018151811061129557fe5b6020910101516001600160f81b031916602360f91b1480156112d857508281600101815181106112c157fe5b6020910101516001600160f81b031916607560f81b145b801561130557508281600201815181106112ee57fe5b6020910101516001600160f81b031916601b60fa1b145b8015611332575082816003018151811061131b57fe5b6020910101516001600160f81b031916606360f81b145b801561135f575082816004018151811061134857fe5b6020910101516001600160f81b031916603960f91b145b801561138c575082816005018151811061137557fe5b6020910101516001600160f81b031916607560f81b145b80156113b957508281600601815181106113a257fe5b6020910101516001600160f81b031916606d60f81b145b156113c757600191506113cf565b60010161127a565b50806113e25760001993505050506114e0565b60408051600481526024810182526020810180516001600160e01b031663797bf38560e01b178152915181516001600160a01b038916936113889392918291908083835b602083106114455780518252601f199092019160209182019101611426565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d80600081146114a6576040519150601f19603f3d011682016040523d82523d6000602084013e6114ab565b606091505b509093509150826114c35760001993505050506114e0565b8180602001905160208110156114d857600080fd5b505193505050505b919050565b731f573d6fb3f13d689ff844b4ce37794d79a7ff1c81565b7345f783cce6b7ff23b2ab2d70e416cdb7d6055f5181565b6003546001600160a01b031681565b601081565b631e00000081565b602081565b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b73a2b47e3d5c44877cca798226b7b8118f9bfb7a5681565b738e870d67f660d95d5be530380d0ec0bd388289e181565b61400081565b61080081565b600881565b6202000081565b6210000081565b6001546001600160a01b031681565b6208000081565b61040081565b6e085d4780b73119b644ae5ecd22b37681565b64200000000081565b600281565b6240000081565b73398ec7346dcd622edc5ae82352f02be94c62d11981565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce31581565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b73eb4c2781e4eba804ce9a9803c67d0893436bb27d81565b611654816280000063ffffffff611e2d16565b1561166982634000000063ffffffff611e2d16565b151415611a9857611678614801565b611680611e33565b905060005b60028110156118535781816002811061169a57fe5b60200201516001600160a01b0316876001600160a01b0316141561184b5760008282600281106116c657fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561170357600080fd5b505afa158015611717573d6000803e3d6000fd5b505050506040513d602081101561172d57600080fd5b50519050600083836002811061173f57fe5b60200201516001600160a01b031663c85c93aa8860016000604051908082528060200260200182016040528015611780578160200160208202803883390190505b506040518463ffffffff1660e01b8152600401808481526020018315151515815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156117e05781810151838201526020016117c8565b50505050905001945050505050602060405180830381600087803b15801561180757600080fd5b505af115801561181b573d6000803e3d6000fd5b505050506040513d602081101561183157600080fd5b505190506118428289838989611641565b50505050611aa5565b600101611685565b5060005b6002811015611a955781816002811061186c57fe5b60200201516001600160a01b0316866001600160a01b03161415611a8d57600082826002811061189857fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118d557600080fd5b505afa1580156118e9573d6000803e3d6000fd5b505050506040513d60208110156118ff57600080fd5b505190506119108882888888611e7a565b61192a8184846002811061192057fe5b6020020151611e87565b82826002811061193657fe5b60200201516001600160a01b0316633cfcef64826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561199f57600080fd5b505afa1580156119b3573d6000803e3d6000fd5b505050506040513d60208110156119c957600080fd5b50516040805160008082526020820190925290506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015611a32578181015183820152602001611a1a565b505050509050019350505050602060405180830381600087803b158015611a5857600080fd5b505af1158015611a6c573d6000803e3d6000fd5b505050506040513d6020811015611a8257600080fd5b50611aa59350505050565b600101611857565b50505b611aa58585858585611e7a565b5050505050565b7303ef3f37856bd08eb47e2de7abc4ddd2c19b60f281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b634000000081565b737079e8517594e5b21d2b9a0d17cb33f5fe2bca7081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61100081565b7306364f10b501e868329afbc005b3492902d6c76381565b7306af07097c9eeb7fd685c692751d5c66db49c21581565b630800000081565b6000546001600160a01b031681565b600181565b61020081565b638000000081565b7357ab1ec28d129707052df4df418d58a2d46d5f5181565b6280000081565b6204000081565b601681565b739726e9314ef1b96e45f40056bed61a088897313e81565b630200000081565b7352ea46506b9cc5ef470c5bf89f17dc28bb35d85c81565b333014611be357600080fd5b611c24868686868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250611e7a915050565b505050505050565b6201000081565b73f6e2d7f616b67e46d708e4410746e9aab3a4c51881565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b61010081565b64080000000081565b738474c1236f0bc23830a23a41abb81b2764ba9f4f81565b731bbe271d15bb64df0bc6cd28df9ff322f2ebd84781565b611cbd6001600160a01b03871633308763ffffffff611f4016565b611cca868686858561205f565b6000611ce56001600160a01b0387163063ffffffff61206c16565b905083811015611d265760405162461bcd60e51b815260040180806020018281038252603581526020018061485d6035913960400191505060405180910390fd5b611d406001600160a01b038716338363ffffffff61211616565b50611d7533611d5e6001600160a01b038a163063ffffffff61206c16565b6001600160a01b038a16919063ffffffff61211616565b5050505050505050565b631000000081565b632000000081565b73a8253a440be331dc4a7395b73948cca6f19dc97d81565b736b175474e89094c44da98b954eedeac495271d0f81565b600481565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b630100000081565b6002546001600160a01b031681565b60006001600160a01b0382161580611e2757506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b16151590565b611e3b614801565b50604080518082019091527310ec0d497824e342bcb0edce00959142aaa766dd815273eb66acc3d011056b00ea521f8203580c2e5d3991602082015290565b611aa58585858585612194565b611e99826001600160a01b0316611df3565b611f3c5760408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915160ff9285169163dd62ed3e916044808301926020929190829003018186803b158015611eee57600080fd5b505afa158015611f02573d6000803e3d6000fd5b505050506040513d6020811015611f1857600080fd5b5051901c611f3c57611f3c6001600160a01b0383168260001963ffffffff61259416565b5050565b80611f4a57612059565b611f5384611df3565b1561203e576001600160a01b03831633148015611f705750803410155b611fab5760405162461bcd60e51b815260040180806020018281038252602b815260200180614892602b913960400191505060405180910390fd5b6001600160a01b0382163014611ff3576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015611ff1573d6000803e3d6000fd5b505b8034111561203957336108fc61200f348463ffffffff61266a16565b6040518115909202916000818181858888f19350505050158015612037573d6000803e3d6000fd5b505b612059565b6120596001600160a01b03851684848463ffffffff6126ac16565b50505050565b611aa58585858585612706565b600061207783611df3565b1561208d57506001600160a01b03811631611e27565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156120e357600080fd5b505afa1580156120f7573d6000803e3d6000fd5b505050506040513d602081101561210d57600080fd5b50519050611e27565b6000816121255750600161218d565b61212e84611df3565b1561216f576040516001600160a01b0384169083156108fc029084906000818181858888f19350505050158015612169573d6000803e3d6000fd5b5061218d565b6121896001600160a01b038516848463ffffffff612a4f16565b5060015b9392505050565b836001600160a01b0316856001600160a01b031614156121b357611aa5565b6121c58161080063ffffffff611e2d16565b15156121db82634000000063ffffffff611e2d16565b15151415612587576121eb61481f565b6121f3612aa1565b905060005b600d8110156123b0578181600d811061220d57fe5b60200201516001600160a01b0316876001600160a01b031614156123a85760008282600d811061223957fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561227657600080fd5b505afa15801561228a573d6000803e3d6000fd5b505050506040513d60208110156122a057600080fd5b505190508282600d81106122b057fe5b60200201516001600160a01b0316632e1a7d4d876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156122fa57600080fd5b505af115801561230e573d6000803e3d6000fd5b505050506123a08188836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561236d57600080fd5b505afa158015612381573d6000803e3d6000fd5b505050506040513d602081101561239757600080fd5b50518888612194565b505050611aa5565b6001016121f8565b5060005b600d811015612584578181600d81106123c957fe5b60200201516001600160a01b0316866001600160a01b0316141561257c5760008282600d81106123f557fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561243257600080fd5b505afa158015612446573d6000803e3d6000fd5b505050506040513d602081101561245c57600080fd5b5051905061246d8882888888612c0e565b61247d818484600d811061192057fe5b8282600d811061248957fe5b60200201516001600160a01b031663b6b55f25826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156124f257600080fd5b505afa158015612506573d6000803e3d6000fd5b505050506040513d602081101561251c57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561255c57600080fd5b505af1158015612570573d6000803e3d6000fd5b50505050505050611aa5565b6001016123b4565b50505b611aa58585858585612c0e565b61259d83611df3565b6126655760008111801561262b575060408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b1580156125fd57600080fd5b505afa158015612611573d6000803e3d6000fd5b505050506040513d602081101561262757600080fd5b5051115b1561264b5761264b6001600160a01b03841683600063ffffffff612c1b16565b6126656001600160a01b038416838363ffffffff612c1b16565b505050565b600061218d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d2e565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612059908590612dc5565b836001600160a01b0316856001600160a01b0316141561272557611aa5565b612738816208000063ffffffff611e2d16565b151561274e82634000000063ffffffff611e2d16565b15151415612a42576001600160a01b03851673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561287c57604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156127d457600080fd5b505afa1580156127e8573d6000803e3d6000fd5b505050506040513d60208110156127fe57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b5050505061287773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858585612f7d565b611aa5565b6001600160a01b03851673c0829421c1d260bd3cb3e0f06cfe2d52db2ce31514156128fa57604080516370a0823160e01b8152306004820152905173c0829421c1d260bd3cb3e0f06cfe2d52db2ce31591632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156127d457600080fd5b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156129ad576129408573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858585612706565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b15801561298f57600080fd5b505af11580156129a3573d6000803e3d6000fd5b5050505050611aa5565b6001600160a01b03841673c0829421c1d260bd3cb3e0f06cfe2d52db2ce3151415612a42576129f38573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858585612706565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3156001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b15801561298f57600080fd5b611aa58585858585612f7d565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612665908490612dc5565b612aa961481f565b50604080516101a0810182527316de59092dae5ccf4a1e6439d611fd0653f0bd0181527304aa51bbcb46541455ccf1b8bef2ebc5d3787ec960208201527373a052500105205d34daf004eab301916da8190f918101919091527383f798e925bcd4017eb265844fddabb448f1707d606082015273d6ad7a6750a7593e092a9b218d66c0a814a3436e608082015273f61718057901f84c4eec4339ef8f0d86d2b4560060a08201527304bc0ab673d88ae9dbc9da2380cb6b79c4bca9ae60c082015273c2cb1040220768554cf699b0d863a3cd4324ce3260e082015273e6354ed5bc4b393a5aad09f21c46e101e692d4476101008201527326ea744e5b887e5205727f55dfbe8685e3b219516101208201527399d1fa417f94dcd62bfe781a1213c092a47041bc610140820152739777d7e2b60bb01759d0e2f8be2095df444cb07e610160820152731be5d71f2da660bfdee8012ddc58d024448a0a5961018082015290565b611aa58585858585612f8a565b801580612ca1575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612c7357600080fd5b505afa158015612c87573d6000803e3d6000fd5b505050506040513d6020811015612c9d57600080fd5b5051155b612cdc5760405162461bcd60e51b81526004018080602001828103825260368152602001806149156036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612665908490612dc5565b60008184841115612dbd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d82578181015183820152602001612d6a565b50505050905090810190601f168015612daf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b612dd7826001600160a01b03166131eb565b612e28576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612e665780518252601f199092019160209182019101612e47565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612ec8576040519150601f19603f3d011682016040523d82523d6000602084013e612ecd565b606091505b509150915081612f24576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561205957808060200190516020811015612f4057600080fd5b50516120595760405162461bcd60e51b815260040180806020018281038252602a8152602001806148eb602a913960400191505060405180910390fd5b611aa58585858585611641565b836001600160a01b0316856001600160a01b03161415612fa957611aa5565b612fba81601063ffffffff611e2d16565b1515612fd082634000000063ffffffff611e2d16565b151514156131de576000612fe386613227565b90506001600160a01b038082161461309957856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561303b57600080fd5b505af115801561304f573d6000803e3d6000fd5b505050506040513d602081101561306557600080fd5b50600090506130836001600160a01b0383163063ffffffff61206c16565b90506130928287838787612f8a565b5050611aa5565b6130a285613227565b90506001600160a01b03808216146131dc576130c1868286868661341f565b60006130dc6001600160a01b0383163063ffffffff61206c16565b90506130f0826001600160a01b0316611df3565b1561316257734ddc2d193948926d02f9b1fe9e1daa0718270ed56001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561314457600080fd5b505af1158015613158573d6000803e3d6000fd5b5050505050613092565b61316c8287611e87565b856001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156131b257600080fd5b505af11580156131c6573d6000803e3d6000fd5b505050506040513d602081101561184257600080fd5b505b611aa5858585858561341f565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061321f57508115155b949350505050565b60006001600160a01b038216734ddc2d193948926d02f9b1fe9e1daa0718270ed51415613256575060006114e0565b6001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314156132965750736b175474e89094c44da98b954eedeac495271d0f6114e0565b6001600160a01b038216736c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e14156132d65750730d8775f648430679a709e98d2b0cb6250d2887ef6114e0565b6001600160a01b03821673158079ee67fce2f58472a96584a73c7ab9ac95c114156133165750731985365e9f78359a9b6ad760e32412f4a445e8626114e0565b6001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e75631415613356575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486114e0565b6001600160a01b03821673c11b1268c1a384e55c48c2391d8d480264a3a7f414156133965750732260fac5e5542a773aa44fbcfedf7c193bc2c5996114e0565b6001600160a01b03821673b3319f5d18bc0d84dd1b4825dcde5d5f7266d40714156133d6575073e41d2489571d322189246dafa5ebde1f4699f4986114e0565b6001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc91415613416575073dac17f958d2ee523a2206206994597c13d831ec76114e0565b50600019919050565b611aa58585858585836001600160a01b0316856001600160a01b0316141561344657611aa5565b61345781602063ffffffff611e2d16565b151561346d82634000000063ffffffff611e2d16565b151514156137045760006134808661116d565b90506001600160a01b03808216146135d0576134a4816001600160a01b0316611df3565b1561352a576040805163081a6b2560e41b81523060048201526024810186905290516001600160a01b038816916381a6b2509160448083019260209291908290030181600087803b1580156134f857600080fd5b505af115801561350c573d6000803e3d6000fd5b505050506040513d602081101561352257600080fd5b506135a69050565b60408051632770a7eb60e21b81523060048201526024810186905290516001600160a01b03881691639dc29fac9160448083019260209291908290030181600087803b15801561357957600080fd5b505af115801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b50505b60006135c16001600160a01b0383163063ffffffff61206c16565b9050613092828783878761370d565b6135d98561116d565b90506001600160a01b0380821614613702576135f8868286868661370d565b60006136136001600160a01b0383163063ffffffff61206c16565b9050613627826001600160a01b0316611df3565b156136a95760408051638f6ede1f60e01b815230600482015290516001600160a01b03881691638f6ede1f91849160248082019260209290919082900301818588803b15801561367657600080fd5b505af115801561368a573d6000803e3d6000fd5b50505050506040513d60208110156136a157600080fd5b506130929050565b6136b38287611e87565b604080516340c10f1960e01b81523060048201526024810183905290516001600160a01b038816916340c10f199160448083019260209291908290030181600087803b1580156131b257600080fd5b505b611aa585858585855b611aa585858585855b836001600160a01b0316856001600160a01b0316141561373557611aa5565b61374681608063ffffffff611e2d16565b151561375c82634000000063ffffffff611e2d16565b1515141561397b57600061376f86613988565b90506001600160a01b03808216146137f257856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050506137ec8186868686613716565b50611aa5565b6137fb85613988565b90506001600160a01b03808216146139795761381a8682868686613db2565b60006138356001600160a01b0383163063ffffffff61206c16565b90506138b98273398ec7346dcd622edc5ae82352f02be94c62d1196001600160a01b031663f2f4eb266040518163ffffffff1660e01b815260040160206040518083038186803b15801561388857600080fd5b505afa15801561389c573d6000803e3d6000fd5b505050506040513d60208110156138b257600080fd5b5051611e87565b73398ec7346dcd622edc5ae82352f02be94c62d11963d2d0e0666138e56001600160a01b038516611df3565b6138f05760006138f2565b825b613904856001600160a01b0316611df3565b61390e5784613924565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301526024820186905261044d604483015251606480830192600092919082900301818588803b15801561255c57600080fd5b505b611aa58585858585613db2565b60006001600160a01b038216733a3a65aab0dd2a17e3f1947ba16138cd37d08c0414156139b7575060006114e0565b6001600160a01b03821673fc1e690f61efd961294b3e1ce3313fbd8aa4f85d14156139f75750736b175474e89094c44da98b954eedeac495271d0f6114e0565b6001600160a01b038216739ba00d6856a4edf4665bca2c2309936572473b7e1415613a37575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486114e0565b6001600160a01b03821673625ae63000f46200499120b906716420bd0592401415613a7757507357ab1ec28d129707052df4df418d58a2d46d5f516114e0565b6001600160a01b038216736ee0f7bb50a54ab5253da0667b0dc2ee526c30a81415613ab75750734fabb145d64652a948d72533023f6e7a623c7c536114e0565b6001600160a01b038216734da9b813057d04baef4e5800e36083717b4a03411415613af257506e085d4780b73119b644ae5ecd22b3766114e0565b6001600160a01b0382167371fc860f7d3a592a4a98740e39db31d25db65ae81415613b32575073dac17f958d2ee523a2206206994597c13d831ec76114e0565b6001600160a01b03821673e1ba0fb44ccb0d11b80f92f4f8ed94ca3ff51d001415613b725750730d8775f648430679a709e98d2b0cb6250d2887ef6114e0565b6001600160a01b038216739d91be44c06d373a8a226e1f3b146956083803eb1415613bb2575073dd974d5c2e2928dea5f71b9825b8b646686bd2006114e0565b6001600160a01b038216737d2d3688df45ce7c552e19c27e007673da9204b81415613bf257507380fb784b7ed66730e8b1dbd9820afd29931aab036114e0565b6001600160a01b03821673a64bd6c70cb9051f6a9ba1f163fdc07e0dfb5f841415613c32575073514910771af9ca656af840dff83e8264ecf986ca6114e0565b6001600160a01b038216736fce4a401b6b80ace52baaefe4421bd188e76f6f1415613c725750730f5d2fb29fb7d3cfee444a200298f468908cc9426114e0565b6001600160a01b038216737deb5e830be29f91e298ba5ff1356bb7f81469981415613cb25750739f8f72aa9304c8b593d555f12ef6589cc3a579a26114e0565b6001600160a01b0382167371010a9d003445ac60c4e6a7017c1e89a477b4381415613cf25750731985365e9f78359a9b6ad760e32412f4a445e8626114e0565b6001600160a01b03821673328c4c80bc7aca0834db37e6600a6c49e12da4de1415613d32575073c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f6114e0565b6001600160a01b03821673fc4b8ed459e00e5400be803a9bb3954234fd50e31415613d725750732260fac5e5542a773aa44fbcfedf7c193bc2c5996114e0565b6001600160a01b038216736fb0855c404e09c47c3fbca25f08d4e41f9f062f1415613416575073e41d2489571d322189246dafa5ebde1f4699f4986114e0565b836001600160a01b0316856001600160a01b03161415613dd157611aa5565b613de38161040063ffffffff611e2d16565b1515613df982634000000063ffffffff611e2d16565b1515141561409e576000546001600160a01b0386811691161415613f57576000805460408051637f8661a160e01b81526004810187905290516001600160a01b0390921692637f8661a19260248084019382900301818387803b158015613e5f57600080fd5b505af1158015613e73573d6000803e3d6000fd5b5050600154604080516370a0823160e01b81523060048201529051600094506001600160a01b0390921692506370a08231916024808301926020929190829003018186803b158015613ec457600080fd5b505afa158015613ed8573d6000803e3d6000fd5b505050506040513d6020811015613eee57600080fd5b505190508015613f365760018054606091613f17916001600160a01b0316908890859087610ee2565b600154909250613f3491506001600160a01b03168784848761205f565b505b6137ec736b175474e89094c44da98b954eedeac495271d0f868686866140a7565b6000546001600160a01b038581169116141561409e57613f8e85736b175474e89094c44da98b954eedeac495271d0f8585856140a7565b600054613fb990736b175474e89094c44da98b954eedeac495271d0f906001600160a01b0316611e87565b600054604080516370a0823160e01b815230600482015290516001600160a01b039092169163049878f391736b175474e89094c44da98b954eedeac495271d0f916370a0823191602480820192602092909190829003018186803b15801561402057600080fd5b505afa158015614034573d6000803e3d6000fd5b505050506040513d602081101561404a57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561408a57600080fd5b505af1158015611842573d6000803e3d6000fd5b611aa585858585855b836001600160a01b0316856001600160a01b031614156140c657611aa5565b6140d781604063ffffffff611e2d16565b15156140ed82634000000063ffffffff611e2d16565b1515141561437b576001600160a01b0385167306af07097c9eeb7fd685c692751d5c66db49c2151415614218576040805163ef693bed60e01b81523060048201526024810185905290517306af07097c9eeb7fd685c692751d5c66db49c2159163ef693bed91604480830192600092919082900301818387803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516128779350736b175474e89094c44da98b954eedeac495271d0f9250879183916370a0823191602480820192602092909190829003018186803b1580156141e557600080fd5b505afa1580156141f9573d6000803e3d6000fd5b505050506040513d602081101561420f57600080fd5b50518585614384565b6001600160a01b0384167306af07097c9eeb7fd685c692751d5c66db49c215141561437b5761425e85736b175474e89094c44da98b954eedeac495271d0f858585614384565b614290736b175474e89094c44da98b954eedeac495271d0f7306af07097c9eeb7fd685c692751d5c66db49c215611e87565b604080516370a0823160e01b8152306004820181905291517306af07097c9eeb7fd685c692751d5c66db49c21592633b4da69f929091736b175474e89094c44da98b954eedeac495271d0f916370a08231916024808301926020929190829003018186803b15801561430157600080fd5b505afa158015614315573d6000803e3d6000fd5b505050506040513d602081101561432b57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152602483019190915251604480830192600092919082900301818387803b15801561408a57600080fd5b611aa585858585855b600061438f82614499565b90506001600160a01b0381161561448c57606083516040519080825280602002602001820160405280156143cd578160200160208202803883390190505b50905060005b8451811015614412578481815181106143e857fe5b602002602001015160ff168282815181106143ff57fe5b60209081029190910101526001016143d3565b506144208783878487614658565b60005b845181101561446657600885828151811061443a57fe5b6020026020010151901c60ff1682828151811061445357fe5b6020908102919091010152600101614423565b5061309282876144856001600160a01b0383163063ffffffff61206c16565b8487614658565b611c248686868686614658565b60006144a361483e565b6040518060e00160405280610200815260200162010000815260200162020000815260200164040000000081526020016408000000008152602001641000000000815260200164200000000081525090506144fc61483e565b506040805160e08101825273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8152736b175474e89094c44da98b954eedeac495271d0f602082015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489181019190915273dac17f958d2ee523a2206206994597c13d831ec76060820152732260fac5e5542a773aa44fbcfedf7c193bc2c5996080820152731bbe271d15bb64df0bc6cd28df9ff322f2ebd84760a082015273eb4c2781e4eba804ce9a9803c67d0893436bb27d60c082015260005b6007811015614650576145e98382600781106145d757fe5b6020020151869063ffffffff611e2d16565b15614648576001600160a01b038416156146345760405162461bcd60e51b815260040180806020018281038252602e8152602001806148bd602e913960400191505060405180910390fd5b81816007811061464057fe5b602002015193505b6001016145bf565b505050919050565b836001600160a01b0316856001600160a01b0316141561467757611aa5565b611aa585858585856003546040516001600160a01b038781166024830190815287821660448401526064830187905260006084840181905260c4840186905260c060a48501908152875160e486015287519195606095941693637153a8af60e11b938c938c938c938a938d938d9391926101040190602080870191028083838a5b838110156147105781810151838201526020016146f8565b50505050905001975050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518082805190602001908083835b602083106147825780518252601f199092019160209182019101614763565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d80600081146147e2576040519150601f19603f3d011682016040523d82523d6000602084013e6147e7565b606091505b509150915081600081146147fa57611d75565b3d60208301fd5b60405180604001604052806002906020820280388339509192915050565b604051806101a00160405280600d906020820280388339509192915050565b6040518060e00160405280600790602082028038833950919291505056fe4f6e6553706c69743a2061637475616c2072657475726e20616d6f756e74206973206c657373207468616e206d696e52657475726e57726f6e6720757365616765206f66204554482e756e6976657273616c5472616e7366657246726f6d28294f6e6553706c69743a20446f206e6f7420757365206d756c74697061746820776974682065616368206f746865725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a7231582049b17a8f8dfea0e5a985bc859466ccb2c8bdbc145929b2e2294f1dbb71a2b54464736f6c63430005110032000000000000000000000000847d12559c0c20a87b2db40e79ad9fc1c58f686a0000000000000000000000000090db2f1171e6134961bc1db52ea916fbb2edac
Deployed Bytecode
0x6080604052600436106104e15760003560e01c80637e09b9c211610281578063c9b42c671161015a578063df1b4e99116100cc578063f11d2ff411610085578063f11d2ff414610e5d578063f4b9fa7514610e72578063f56e281f14610e87578063f69e204614610e9c578063fa3f110b14610eb1578063fbe4ed9514610ec6576104e1565b8063df1b4e9914610d2c578063e0de8f2214610d41578063e1308b3314610d56578063e2a7515e14610d6b578063e355812314610e33578063e44987b414610e48576104e1565b8063d1ae60631161011e578063d1ae606314610c3d578063d393c3e914610cd8578063d70a2d1f14610ced578063d77366a414610d02578063dc1536b214610d17578063ddd2f8d01461065b576104e1565b8063c9b42c6714610bd4578063cc26e9fc14610be9578063cd240d7514610bfe578063ce74b7ac14610c13578063cede5f6a14610c28576104e1565b8063b0a7ef29116101f3578063c11f4f11116101b7578063c11f4f1114610b56578063c762a46c14610b6b578063c77b9de614610b80578063c7f112e414610b95578063c925777514610baa578063c989b66714610bbf576104e1565b8063b0a7ef2914610b02578063b184a3ae14610b17578063b3bc784414610685578063b69d045614610b2c578063bf2c5a0714610b41576104e1565b8063944a32e211610245578063944a32e2146109d6578063960d2c1914610a99578063a1b4d01114610aae578063a2878cb114610ac3578063a4792ab314610ad8578063a734f06e14610aed576104e1565b80637e09b9c21461096d578063819faf7b14610982578063851954fa146109975780638bdb2afa146109ac57806390354872146109c1576104e1565b80633fc8cef3116103be5780635aa8fb48116103305780636cbc4a6e116102e95780636cbc4a6e1461090457806375a8b0121461091957806375b5be2d1461092e57806376c3972614610943578063792e69d7146106af5780637a88bdbd14610958576104e1565b80635aa8fb48146108865780635ae51b821461089b5780635c0cb479146108b057806364ec4e5c146108c557806368e2a014146108da5780636b5a4ca2146108ef576104e1565b806344211d621161038257806344211d62146108085780634752c6801461081d5780634a7101d5146108325780635187c0911461084757806351f1985c1461085c57806352a701b414610871576104e1565b80633fc8cef3146107815780634037f9671461079657806340ab7b8c146107c9578063423d03f9146107de57806343ee21f0146107f3576104e1565b80632ceb90b81161045757806334b4dabb1161041b57806334b4dabb14610703578063372a26cb14610718578063376e55b71461072d5780633ca5b234146107425780633cdc5389146107575780633e413bee1461076c576104e1565b80632ceb90b81461069a5780632d3b5207146106af5780632e707bd2146106c45780632f0fe755146106d95780632f48ab7d146106ee576104e1565b80631d209b65116104a95780631d209b651461061c5780632113240d1461063157806321899d3a1461064657806321a360f51461065b57806322320c981461067057806327a7fbd514610685576104e1565b806305d8aa0a146104f0578063085e2c5b1461051757806312dea160146105c15780631388b420146105f25780631398914014610607575b333214156104ee57600080fd5b005b3480156104fc57600080fd5b50610505610edb565b60408051918252519081900360200190f35b34801561052357600080fd5b50610566600480360360a081101561053a57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135610ee2565b6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156105ac578181015183820152602001610594565b50505050905001935050505060405180910390f35b3480156105cd57600080fd5b506105d661102a565b604080516001600160a01b039092168252519081900360200190f35b3480156105fe57600080fd5b506105d6611042565b34801561061357600080fd5b5061050561105a565b34801561062857600080fd5b50610505611060565b34801561063d57600080fd5b50610505611068565b34801561065257600080fd5b5061050561106e565b34801561066757600080fd5b50610505611077565b34801561067c57600080fd5b506105d6611080565b34801561069157600080fd5b50610505611098565b3480156106a657600080fd5b506105056110a1565b3480156106bb57600080fd5b506105056110aa565b3480156106d057600080fd5b506105056110b2565b3480156106e557600080fd5b506105d66110b7565b3480156106fa57600080fd5b506105d66110cf565b34801561070f57600080fd5b506105056110e7565b34801561072457600080fd5b506105d66110ec565b34801561073957600080fd5b50610505611104565b34801561074e57600080fd5b506105d661110d565b34801561076357600080fd5b506105d6611125565b34801561077857600080fd5b506105d661113d565b34801561078d57600080fd5b506105d6611155565b3480156107a257600080fd5b506105d6600480360360208110156107b957600080fd5b50356001600160a01b031661116d565b3480156107d557600080fd5b506105d66114e5565b3480156107ea57600080fd5b506105d66114fd565b3480156107ff57600080fd5b506105d6611515565b34801561081457600080fd5b50610505611524565b34801561082957600080fd5b50610505611529565b34801561083e57600080fd5b50610505611531565b34801561085357600080fd5b506105d6611536565b34801561086857600080fd5b506105d661154e565b34801561087d57600080fd5b506105d6611566565b34801561089257600080fd5b5061050561157e565b3480156108a757600080fd5b50610505611584565b3480156108bc57600080fd5b5061050561158a565b3480156108d157600080fd5b5061050561158f565b3480156108e657600080fd5b50610505611596565b3480156108fb57600080fd5b506105d661159d565b34801561091057600080fd5b506105056115ac565b34801561092557600080fd5b506105056115b3565b34801561093a57600080fd5b506105d66115b9565b34801561094f57600080fd5b506105056115cc565b34801561096457600080fd5b506105056115d5565b34801561097957600080fd5b506105056115da565b34801561098e57600080fd5b506105d66115e1565b3480156109a357600080fd5b506105d66115f9565b3480156109b857600080fd5b506105d6611611565b3480156109cd57600080fd5b506105d6611629565b6104ee600480360360a08110156109ec57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a2657600080fd5b820183602082011115610a3857600080fd5b803590602001918460208302840111600160201b83111715610a5957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611641915050565b348015610aa557600080fd5b506105d6611aac565b348015610aba57600080fd5b506105d6611ac4565b348015610acf57600080fd5b50610505611adc565b348015610ae457600080fd5b506105d6611ae4565b348015610af957600080fd5b506105d6611afc565b348015610b0e57600080fd5b50610505611b14565b348015610b2357600080fd5b506105d6611b1a565b348015610b3857600080fd5b506105d6611b32565b348015610b4d57600080fd5b50610505611b4a565b348015610b6257600080fd5b506105d6611b52565b348015610b7757600080fd5b50610505611b61565b348015610b8c57600080fd5b50610505611b66565b348015610ba157600080fd5b50610505611b6c565b348015610bb657600080fd5b506105d6611b74565b348015610bcb57600080fd5b50610505611b8c565b348015610be057600080fd5b50610505611b93565b348015610bf557600080fd5b50610505611b9a565b348015610c0a57600080fd5b506105d6611b9f565b348015610c1f57600080fd5b50610505611bb7565b348015610c3457600080fd5b506105d6611bbf565b348015610c4957600080fd5b506104ee600480360360a0811015610c6057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610c9a57600080fd5b820183602082011115610cac57600080fd5b803590602001918460208302840111600160201b83111715610ccd57600080fd5b919350915035611bd7565b348015610ce457600080fd5b50610505611c2c565b348015610cf957600080fd5b506105d6611c33565b348015610d0e57600080fd5b506105d6611c4b565b348015610d2357600080fd5b50610505611c63565b348015610d3857600080fd5b50610505611c69565b348015610d4d57600080fd5b506105d6611c72565b348015610d6257600080fd5b506105d6611c8a565b6104ee600480360360c0811015610d8157600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610dc057600080fd5b820183602082011115610dd257600080fd5b803590602001918460208302840111600160201b83111715610df357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611ca2915050565b348015610e3f57600080fd5b50610505611d7f565b348015610e5457600080fd5b50610505611d87565b348015610e6957600080fd5b506105d6611d8f565b348015610e7e57600080fd5b506105d6611da7565b348015610e9357600080fd5b50610505611dbf565b348015610ea857600080fd5b506105d6611dc4565b348015610ebd57600080fd5b50610505611ddc565b348015610ed257600080fd5b506105d6611de4565b6220000081565b6002546040805163085e2c5b60e01b81526001600160a01b03888116600483015287811660248301526044820187905260648201869052608482018590529151600093606093169163085e2c5b9160a48083019287929190829003018186803b158015610f4e57600080fd5b505afa158015610f62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610f8b57600080fd5b815160208301805160405192949293830192919084600160201b821115610fb157600080fd5b908301906020820185811115610fc657600080fd5b82518660208202830111600160201b82111715610fe257600080fd5b82525081516020918201928201910280838360005b8381101561100f578181015183820152602001610ff7565b50505050905001604052505050915091509550959350505050565b7352ae12abe5d8bd778bd5397f99ca900624cfadd481565b73794e6e91555438afc3ccf1c5076a74f42133d08d81565b61200081565b630400000081565b61800081565b64400000000081565b64020000000081565b73a5407eae9ba41422680e2e00537571bcc53efbfd81565b64040000000081565b64800000000081565b600160201b81565b608081565b730316eb71485b0ab14103307bf65a021042c6d38081565b73dac17f958d2ee523a2206206994597c13d831ec781565b604081565b7379a8c46dea5ada233abaffd40f3a0a2b1e5a4f2781565b64100000000081565b734fabb145d64652a948d72533023f6e7a623c7c5381565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000611181826001600160a01b0316611df3565b1561118f57506000196114e0565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b178152915181516000936060936001600160a01b0388169361138893919290918291908083835b602083106111fa5780518252601f1990920191602091820191016111db565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461125b576040519150601f19603f3d011682016040523d82523d6000602084013e611260565b606091505b50915091508161127657600019925050506114e0565b6000805b82518160060110156113cf5782816000018151811061129557fe5b6020910101516001600160f81b031916602360f91b1480156112d857508281600101815181106112c157fe5b6020910101516001600160f81b031916607560f81b145b801561130557508281600201815181106112ee57fe5b6020910101516001600160f81b031916601b60fa1b145b8015611332575082816003018151811061131b57fe5b6020910101516001600160f81b031916606360f81b145b801561135f575082816004018151811061134857fe5b6020910101516001600160f81b031916603960f91b145b801561138c575082816005018151811061137557fe5b6020910101516001600160f81b031916607560f81b145b80156113b957508281600601815181106113a257fe5b6020910101516001600160f81b031916606d60f81b145b156113c757600191506113cf565b60010161127a565b50806113e25760001993505050506114e0565b60408051600481526024810182526020810180516001600160e01b031663797bf38560e01b178152915181516001600160a01b038916936113889392918291908083835b602083106114455780518252601f199092019160209182019101611426565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d80600081146114a6576040519150601f19603f3d011682016040523d82523d6000602084013e6114ab565b606091505b509093509150826114c35760001993505050506114e0565b8180602001905160208110156114d857600080fd5b505193505050505b919050565b731f573d6fb3f13d689ff844b4ce37794d79a7ff1c81565b7345f783cce6b7ff23b2ab2d70e416cdb7d6055f5181565b6003546001600160a01b031681565b601081565b631e00000081565b602081565b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b73a2b47e3d5c44877cca798226b7b8118f9bfb7a5681565b738e870d67f660d95d5be530380d0ec0bd388289e181565b61400081565b61080081565b600881565b6202000081565b6210000081565b6001546001600160a01b031681565b6208000081565b61040081565b6e085d4780b73119b644ae5ecd22b37681565b64200000000081565b600281565b6240000081565b73398ec7346dcd622edc5ae82352f02be94c62d11981565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce31581565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b73eb4c2781e4eba804ce9a9803c67d0893436bb27d81565b611654816280000063ffffffff611e2d16565b1561166982634000000063ffffffff611e2d16565b151415611a9857611678614801565b611680611e33565b905060005b60028110156118535781816002811061169a57fe5b60200201516001600160a01b0316876001600160a01b0316141561184b5760008282600281106116c657fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561170357600080fd5b505afa158015611717573d6000803e3d6000fd5b505050506040513d602081101561172d57600080fd5b50519050600083836002811061173f57fe5b60200201516001600160a01b031663c85c93aa8860016000604051908082528060200260200182016040528015611780578160200160208202803883390190505b506040518463ffffffff1660e01b8152600401808481526020018315151515815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156117e05781810151838201526020016117c8565b50505050905001945050505050602060405180830381600087803b15801561180757600080fd5b505af115801561181b573d6000803e3d6000fd5b505050506040513d602081101561183157600080fd5b505190506118428289838989611641565b50505050611aa5565b600101611685565b5060005b6002811015611a955781816002811061186c57fe5b60200201516001600160a01b0316866001600160a01b03161415611a8d57600082826002811061189857fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118d557600080fd5b505afa1580156118e9573d6000803e3d6000fd5b505050506040513d60208110156118ff57600080fd5b505190506119108882888888611e7a565b61192a8184846002811061192057fe5b6020020151611e87565b82826002811061193657fe5b60200201516001600160a01b0316633cfcef64826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561199f57600080fd5b505afa1580156119b3573d6000803e3d6000fd5b505050506040513d60208110156119c957600080fd5b50516040805160008082526020820190925290506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015611a32578181015183820152602001611a1a565b505050509050019350505050602060405180830381600087803b158015611a5857600080fd5b505af1158015611a6c573d6000803e3d6000fd5b505050506040513d6020811015611a8257600080fd5b50611aa59350505050565b600101611857565b50505b611aa58585858585611e7a565b5050505050565b7303ef3f37856bd08eb47e2de7abc4ddd2c19b60f281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b634000000081565b737079e8517594e5b21d2b9a0d17cb33f5fe2bca7081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61100081565b7306364f10b501e868329afbc005b3492902d6c76381565b7306af07097c9eeb7fd685c692751d5c66db49c21581565b630800000081565b6000546001600160a01b031681565b600181565b61020081565b638000000081565b7357ab1ec28d129707052df4df418d58a2d46d5f5181565b6280000081565b6204000081565b601681565b739726e9314ef1b96e45f40056bed61a088897313e81565b630200000081565b7352ea46506b9cc5ef470c5bf89f17dc28bb35d85c81565b333014611be357600080fd5b611c24868686868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250611e7a915050565b505050505050565b6201000081565b73f6e2d7f616b67e46d708e4410746e9aab3a4c51881565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b61010081565b64080000000081565b738474c1236f0bc23830a23a41abb81b2764ba9f4f81565b731bbe271d15bb64df0bc6cd28df9ff322f2ebd84781565b611cbd6001600160a01b03871633308763ffffffff611f4016565b611cca868686858561205f565b6000611ce56001600160a01b0387163063ffffffff61206c16565b905083811015611d265760405162461bcd60e51b815260040180806020018281038252603581526020018061485d6035913960400191505060405180910390fd5b611d406001600160a01b038716338363ffffffff61211616565b50611d7533611d5e6001600160a01b038a163063ffffffff61206c16565b6001600160a01b038a16919063ffffffff61211616565b5050505050505050565b631000000081565b632000000081565b73a8253a440be331dc4a7395b73948cca6f19dc97d81565b736b175474e89094c44da98b954eedeac495271d0f81565b600481565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b630100000081565b6002546001600160a01b031681565b60006001600160a01b0382161580611e2757506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b16151590565b611e3b614801565b50604080518082019091527310ec0d497824e342bcb0edce00959142aaa766dd815273eb66acc3d011056b00ea521f8203580c2e5d3991602082015290565b611aa58585858585612194565b611e99826001600160a01b0316611df3565b611f3c5760408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915160ff9285169163dd62ed3e916044808301926020929190829003018186803b158015611eee57600080fd5b505afa158015611f02573d6000803e3d6000fd5b505050506040513d6020811015611f1857600080fd5b5051901c611f3c57611f3c6001600160a01b0383168260001963ffffffff61259416565b5050565b80611f4a57612059565b611f5384611df3565b1561203e576001600160a01b03831633148015611f705750803410155b611fab5760405162461bcd60e51b815260040180806020018281038252602b815260200180614892602b913960400191505060405180910390fd5b6001600160a01b0382163014611ff3576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015611ff1573d6000803e3d6000fd5b505b8034111561203957336108fc61200f348463ffffffff61266a16565b6040518115909202916000818181858888f19350505050158015612037573d6000803e3d6000fd5b505b612059565b6120596001600160a01b03851684848463ffffffff6126ac16565b50505050565b611aa58585858585612706565b600061207783611df3565b1561208d57506001600160a01b03811631611e27565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156120e357600080fd5b505afa1580156120f7573d6000803e3d6000fd5b505050506040513d602081101561210d57600080fd5b50519050611e27565b6000816121255750600161218d565b61212e84611df3565b1561216f576040516001600160a01b0384169083156108fc029084906000818181858888f19350505050158015612169573d6000803e3d6000fd5b5061218d565b6121896001600160a01b038516848463ffffffff612a4f16565b5060015b9392505050565b836001600160a01b0316856001600160a01b031614156121b357611aa5565b6121c58161080063ffffffff611e2d16565b15156121db82634000000063ffffffff611e2d16565b15151415612587576121eb61481f565b6121f3612aa1565b905060005b600d8110156123b0578181600d811061220d57fe5b60200201516001600160a01b0316876001600160a01b031614156123a85760008282600d811061223957fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561227657600080fd5b505afa15801561228a573d6000803e3d6000fd5b505050506040513d60208110156122a057600080fd5b505190508282600d81106122b057fe5b60200201516001600160a01b0316632e1a7d4d876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156122fa57600080fd5b505af115801561230e573d6000803e3d6000fd5b505050506123a08188836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561236d57600080fd5b505afa158015612381573d6000803e3d6000fd5b505050506040513d602081101561239757600080fd5b50518888612194565b505050611aa5565b6001016121f8565b5060005b600d811015612584578181600d81106123c957fe5b60200201516001600160a01b0316866001600160a01b0316141561257c5760008282600d81106123f557fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561243257600080fd5b505afa158015612446573d6000803e3d6000fd5b505050506040513d602081101561245c57600080fd5b5051905061246d8882888888612c0e565b61247d818484600d811061192057fe5b8282600d811061248957fe5b60200201516001600160a01b031663b6b55f25826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156124f257600080fd5b505afa158015612506573d6000803e3d6000fd5b505050506040513d602081101561251c57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561255c57600080fd5b505af1158015612570573d6000803e3d6000fd5b50505050505050611aa5565b6001016123b4565b50505b611aa58585858585612c0e565b61259d83611df3565b6126655760008111801561262b575060408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b1580156125fd57600080fd5b505afa158015612611573d6000803e3d6000fd5b505050506040513d602081101561262757600080fd5b5051115b1561264b5761264b6001600160a01b03841683600063ffffffff612c1b16565b6126656001600160a01b038416838363ffffffff612c1b16565b505050565b600061218d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d2e565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612059908590612dc5565b836001600160a01b0316856001600160a01b0316141561272557611aa5565b612738816208000063ffffffff611e2d16565b151561274e82634000000063ffffffff611e2d16565b15151415612a42576001600160a01b03851673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561287c57604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156127d457600080fd5b505afa1580156127e8573d6000803e3d6000fd5b505050506040513d60208110156127fe57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b5050505061287773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858585612f7d565b611aa5565b6001600160a01b03851673c0829421c1d260bd3cb3e0f06cfe2d52db2ce31514156128fa57604080516370a0823160e01b8152306004820152905173c0829421c1d260bd3cb3e0f06cfe2d52db2ce31591632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156127d457600080fd5b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156129ad576129408573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858585612706565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b15801561298f57600080fd5b505af11580156129a3573d6000803e3d6000fd5b5050505050611aa5565b6001600160a01b03841673c0829421c1d260bd3cb3e0f06cfe2d52db2ce3151415612a42576129f38573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858585612706565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3156001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b15801561298f57600080fd5b611aa58585858585612f7d565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612665908490612dc5565b612aa961481f565b50604080516101a0810182527316de59092dae5ccf4a1e6439d611fd0653f0bd0181527304aa51bbcb46541455ccf1b8bef2ebc5d3787ec960208201527373a052500105205d34daf004eab301916da8190f918101919091527383f798e925bcd4017eb265844fddabb448f1707d606082015273d6ad7a6750a7593e092a9b218d66c0a814a3436e608082015273f61718057901f84c4eec4339ef8f0d86d2b4560060a08201527304bc0ab673d88ae9dbc9da2380cb6b79c4bca9ae60c082015273c2cb1040220768554cf699b0d863a3cd4324ce3260e082015273e6354ed5bc4b393a5aad09f21c46e101e692d4476101008201527326ea744e5b887e5205727f55dfbe8685e3b219516101208201527399d1fa417f94dcd62bfe781a1213c092a47041bc610140820152739777d7e2b60bb01759d0e2f8be2095df444cb07e610160820152731be5d71f2da660bfdee8012ddc58d024448a0a5961018082015290565b611aa58585858585612f8a565b801580612ca1575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612c7357600080fd5b505afa158015612c87573d6000803e3d6000fd5b505050506040513d6020811015612c9d57600080fd5b5051155b612cdc5760405162461bcd60e51b81526004018080602001828103825260368152602001806149156036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612665908490612dc5565b60008184841115612dbd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d82578181015183820152602001612d6a565b50505050905090810190601f168015612daf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b612dd7826001600160a01b03166131eb565b612e28576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612e665780518252601f199092019160209182019101612e47565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612ec8576040519150601f19603f3d011682016040523d82523d6000602084013e612ecd565b606091505b509150915081612f24576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561205957808060200190516020811015612f4057600080fd5b50516120595760405162461bcd60e51b815260040180806020018281038252602a8152602001806148eb602a913960400191505060405180910390fd5b611aa58585858585611641565b836001600160a01b0316856001600160a01b03161415612fa957611aa5565b612fba81601063ffffffff611e2d16565b1515612fd082634000000063ffffffff611e2d16565b151514156131de576000612fe386613227565b90506001600160a01b038082161461309957856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561303b57600080fd5b505af115801561304f573d6000803e3d6000fd5b505050506040513d602081101561306557600080fd5b50600090506130836001600160a01b0383163063ffffffff61206c16565b90506130928287838787612f8a565b5050611aa5565b6130a285613227565b90506001600160a01b03808216146131dc576130c1868286868661341f565b60006130dc6001600160a01b0383163063ffffffff61206c16565b90506130f0826001600160a01b0316611df3565b1561316257734ddc2d193948926d02f9b1fe9e1daa0718270ed56001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561314457600080fd5b505af1158015613158573d6000803e3d6000fd5b5050505050613092565b61316c8287611e87565b856001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156131b257600080fd5b505af11580156131c6573d6000803e3d6000fd5b505050506040513d602081101561184257600080fd5b505b611aa5858585858561341f565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061321f57508115155b949350505050565b60006001600160a01b038216734ddc2d193948926d02f9b1fe9e1daa0718270ed51415613256575060006114e0565b6001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314156132965750736b175474e89094c44da98b954eedeac495271d0f6114e0565b6001600160a01b038216736c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e14156132d65750730d8775f648430679a709e98d2b0cb6250d2887ef6114e0565b6001600160a01b03821673158079ee67fce2f58472a96584a73c7ab9ac95c114156133165750731985365e9f78359a9b6ad760e32412f4a445e8626114e0565b6001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e75631415613356575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486114e0565b6001600160a01b03821673c11b1268c1a384e55c48c2391d8d480264a3a7f414156133965750732260fac5e5542a773aa44fbcfedf7c193bc2c5996114e0565b6001600160a01b03821673b3319f5d18bc0d84dd1b4825dcde5d5f7266d40714156133d6575073e41d2489571d322189246dafa5ebde1f4699f4986114e0565b6001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc91415613416575073dac17f958d2ee523a2206206994597c13d831ec76114e0565b50600019919050565b611aa58585858585836001600160a01b0316856001600160a01b0316141561344657611aa5565b61345781602063ffffffff611e2d16565b151561346d82634000000063ffffffff611e2d16565b151514156137045760006134808661116d565b90506001600160a01b03808216146135d0576134a4816001600160a01b0316611df3565b1561352a576040805163081a6b2560e41b81523060048201526024810186905290516001600160a01b038816916381a6b2509160448083019260209291908290030181600087803b1580156134f857600080fd5b505af115801561350c573d6000803e3d6000fd5b505050506040513d602081101561352257600080fd5b506135a69050565b60408051632770a7eb60e21b81523060048201526024810186905290516001600160a01b03881691639dc29fac9160448083019260209291908290030181600087803b15801561357957600080fd5b505af115801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b50505b60006135c16001600160a01b0383163063ffffffff61206c16565b9050613092828783878761370d565b6135d98561116d565b90506001600160a01b0380821614613702576135f8868286868661370d565b60006136136001600160a01b0383163063ffffffff61206c16565b9050613627826001600160a01b0316611df3565b156136a95760408051638f6ede1f60e01b815230600482015290516001600160a01b03881691638f6ede1f91849160248082019260209290919082900301818588803b15801561367657600080fd5b505af115801561368a573d6000803e3d6000fd5b50505050506040513d60208110156136a157600080fd5b506130929050565b6136b38287611e87565b604080516340c10f1960e01b81523060048201526024810183905290516001600160a01b038816916340c10f199160448083019260209291908290030181600087803b1580156131b257600080fd5b505b611aa585858585855b611aa585858585855b836001600160a01b0316856001600160a01b0316141561373557611aa5565b61374681608063ffffffff611e2d16565b151561375c82634000000063ffffffff611e2d16565b1515141561397b57600061376f86613988565b90506001600160a01b03808216146137f257856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050506137ec8186868686613716565b50611aa5565b6137fb85613988565b90506001600160a01b03808216146139795761381a8682868686613db2565b60006138356001600160a01b0383163063ffffffff61206c16565b90506138b98273398ec7346dcd622edc5ae82352f02be94c62d1196001600160a01b031663f2f4eb266040518163ffffffff1660e01b815260040160206040518083038186803b15801561388857600080fd5b505afa15801561389c573d6000803e3d6000fd5b505050506040513d60208110156138b257600080fd5b5051611e87565b73398ec7346dcd622edc5ae82352f02be94c62d11963d2d0e0666138e56001600160a01b038516611df3565b6138f05760006138f2565b825b613904856001600160a01b0316611df3565b61390e5784613924565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301526024820186905261044d604483015251606480830192600092919082900301818588803b15801561255c57600080fd5b505b611aa58585858585613db2565b60006001600160a01b038216733a3a65aab0dd2a17e3f1947ba16138cd37d08c0414156139b7575060006114e0565b6001600160a01b03821673fc1e690f61efd961294b3e1ce3313fbd8aa4f85d14156139f75750736b175474e89094c44da98b954eedeac495271d0f6114e0565b6001600160a01b038216739ba00d6856a4edf4665bca2c2309936572473b7e1415613a37575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486114e0565b6001600160a01b03821673625ae63000f46200499120b906716420bd0592401415613a7757507357ab1ec28d129707052df4df418d58a2d46d5f516114e0565b6001600160a01b038216736ee0f7bb50a54ab5253da0667b0dc2ee526c30a81415613ab75750734fabb145d64652a948d72533023f6e7a623c7c536114e0565b6001600160a01b038216734da9b813057d04baef4e5800e36083717b4a03411415613af257506e085d4780b73119b644ae5ecd22b3766114e0565b6001600160a01b0382167371fc860f7d3a592a4a98740e39db31d25db65ae81415613b32575073dac17f958d2ee523a2206206994597c13d831ec76114e0565b6001600160a01b03821673e1ba0fb44ccb0d11b80f92f4f8ed94ca3ff51d001415613b725750730d8775f648430679a709e98d2b0cb6250d2887ef6114e0565b6001600160a01b038216739d91be44c06d373a8a226e1f3b146956083803eb1415613bb2575073dd974d5c2e2928dea5f71b9825b8b646686bd2006114e0565b6001600160a01b038216737d2d3688df45ce7c552e19c27e007673da9204b81415613bf257507380fb784b7ed66730e8b1dbd9820afd29931aab036114e0565b6001600160a01b03821673a64bd6c70cb9051f6a9ba1f163fdc07e0dfb5f841415613c32575073514910771af9ca656af840dff83e8264ecf986ca6114e0565b6001600160a01b038216736fce4a401b6b80ace52baaefe4421bd188e76f6f1415613c725750730f5d2fb29fb7d3cfee444a200298f468908cc9426114e0565b6001600160a01b038216737deb5e830be29f91e298ba5ff1356bb7f81469981415613cb25750739f8f72aa9304c8b593d555f12ef6589cc3a579a26114e0565b6001600160a01b0382167371010a9d003445ac60c4e6a7017c1e89a477b4381415613cf25750731985365e9f78359a9b6ad760e32412f4a445e8626114e0565b6001600160a01b03821673328c4c80bc7aca0834db37e6600a6c49e12da4de1415613d32575073c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f6114e0565b6001600160a01b03821673fc4b8ed459e00e5400be803a9bb3954234fd50e31415613d725750732260fac5e5542a773aa44fbcfedf7c193bc2c5996114e0565b6001600160a01b038216736fb0855c404e09c47c3fbca25f08d4e41f9f062f1415613416575073e41d2489571d322189246dafa5ebde1f4699f4986114e0565b836001600160a01b0316856001600160a01b03161415613dd157611aa5565b613de38161040063ffffffff611e2d16565b1515613df982634000000063ffffffff611e2d16565b1515141561409e576000546001600160a01b0386811691161415613f57576000805460408051637f8661a160e01b81526004810187905290516001600160a01b0390921692637f8661a19260248084019382900301818387803b158015613e5f57600080fd5b505af1158015613e73573d6000803e3d6000fd5b5050600154604080516370a0823160e01b81523060048201529051600094506001600160a01b0390921692506370a08231916024808301926020929190829003018186803b158015613ec457600080fd5b505afa158015613ed8573d6000803e3d6000fd5b505050506040513d6020811015613eee57600080fd5b505190508015613f365760018054606091613f17916001600160a01b0316908890859087610ee2565b600154909250613f3491506001600160a01b03168784848761205f565b505b6137ec736b175474e89094c44da98b954eedeac495271d0f868686866140a7565b6000546001600160a01b038581169116141561409e57613f8e85736b175474e89094c44da98b954eedeac495271d0f8585856140a7565b600054613fb990736b175474e89094c44da98b954eedeac495271d0f906001600160a01b0316611e87565b600054604080516370a0823160e01b815230600482015290516001600160a01b039092169163049878f391736b175474e89094c44da98b954eedeac495271d0f916370a0823191602480820192602092909190829003018186803b15801561402057600080fd5b505afa158015614034573d6000803e3d6000fd5b505050506040513d602081101561404a57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561408a57600080fd5b505af1158015611842573d6000803e3d6000fd5b611aa585858585855b836001600160a01b0316856001600160a01b031614156140c657611aa5565b6140d781604063ffffffff611e2d16565b15156140ed82634000000063ffffffff611e2d16565b1515141561437b576001600160a01b0385167306af07097c9eeb7fd685c692751d5c66db49c2151415614218576040805163ef693bed60e01b81523060048201526024810185905290517306af07097c9eeb7fd685c692751d5c66db49c2159163ef693bed91604480830192600092919082900301818387803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516128779350736b175474e89094c44da98b954eedeac495271d0f9250879183916370a0823191602480820192602092909190829003018186803b1580156141e557600080fd5b505afa1580156141f9573d6000803e3d6000fd5b505050506040513d602081101561420f57600080fd5b50518585614384565b6001600160a01b0384167306af07097c9eeb7fd685c692751d5c66db49c215141561437b5761425e85736b175474e89094c44da98b954eedeac495271d0f858585614384565b614290736b175474e89094c44da98b954eedeac495271d0f7306af07097c9eeb7fd685c692751d5c66db49c215611e87565b604080516370a0823160e01b8152306004820181905291517306af07097c9eeb7fd685c692751d5c66db49c21592633b4da69f929091736b175474e89094c44da98b954eedeac495271d0f916370a08231916024808301926020929190829003018186803b15801561430157600080fd5b505afa158015614315573d6000803e3d6000fd5b505050506040513d602081101561432b57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152602483019190915251604480830192600092919082900301818387803b15801561408a57600080fd5b611aa585858585855b600061438f82614499565b90506001600160a01b0381161561448c57606083516040519080825280602002602001820160405280156143cd578160200160208202803883390190505b50905060005b8451811015614412578481815181106143e857fe5b602002602001015160ff168282815181106143ff57fe5b60209081029190910101526001016143d3565b506144208783878487614658565b60005b845181101561446657600885828151811061443a57fe5b6020026020010151901c60ff1682828151811061445357fe5b6020908102919091010152600101614423565b5061309282876144856001600160a01b0383163063ffffffff61206c16565b8487614658565b611c248686868686614658565b60006144a361483e565b6040518060e00160405280610200815260200162010000815260200162020000815260200164040000000081526020016408000000008152602001641000000000815260200164200000000081525090506144fc61483e565b506040805160e08101825273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8152736b175474e89094c44da98b954eedeac495271d0f602082015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489181019190915273dac17f958d2ee523a2206206994597c13d831ec76060820152732260fac5e5542a773aa44fbcfedf7c193bc2c5996080820152731bbe271d15bb64df0bc6cd28df9ff322f2ebd84760a082015273eb4c2781e4eba804ce9a9803c67d0893436bb27d60c082015260005b6007811015614650576145e98382600781106145d757fe5b6020020151869063ffffffff611e2d16565b15614648576001600160a01b038416156146345760405162461bcd60e51b815260040180806020018281038252602e8152602001806148bd602e913960400191505060405180910390fd5b81816007811061464057fe5b602002015193505b6001016145bf565b505050919050565b836001600160a01b0316856001600160a01b0316141561467757611aa5565b611aa585858585856003546040516001600160a01b038781166024830190815287821660448401526064830187905260006084840181905260c4840186905260c060a48501908152875160e486015287519195606095941693637153a8af60e11b938c938c938c938a938d938d9391926101040190602080870191028083838a5b838110156147105781810151838201526020016146f8565b50505050905001975050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518082805190602001908083835b602083106147825780518252601f199092019160209182019101614763565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d80600081146147e2576040519150601f19603f3d011682016040523d82523d6000602084013e6147e7565b606091505b509150915081600081146147fa57611d75565b3d60208301fd5b60405180604001604052806002906020820280388339509192915050565b604051806101a00160405280600d906020820280388339509192915050565b6040518060e00160405280600790602082028038833950919291505056fe4f6e6553706c69743a2061637475616c2072657475726e20616d6f756e74206973206c657373207468616e206d696e52657475726e57726f6e6720757365616765206f66204554482e756e6976657273616c5472616e7366657246726f6d28294f6e6553706c69743a20446f206e6f7420757365206d756c74697061746820776974682065616368206f746865725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a7231582049b17a8f8dfea0e5a985bc859466ccb2c8bdbc145929b2e2294f1dbb71a2b54464736f6c63430005110032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000847d12559c0c20a87b2db40e79ad9fc1c58f686a0000000000000000000000000090db2f1171e6134961bc1db52ea916fbb2edac
-----Decoded View---------------
Arg [0] : _oneSplitView (address): 0x847d12559C0c20A87B2db40e79ad9FC1C58F686A
Arg [1] : _oneSplit (address): 0x0090Db2F1171e6134961Bc1Db52EA916fbb2edAC
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000847d12559c0c20a87b2db40e79ad9fc1c58f686a
Arg [1] : 0000000000000000000000000090db2f1171e6134961bc1db52ea916fbb2edac
Deployed Bytecode Sourcemap
138400:2783:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139000:10;139014:9;139000:23;;138992:32;;;;;;138400:2783;5018:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5018:59:0;;;:::i;:::-;;;;;;;;;;;;;;;;139040:615;;8:9:-1;5:2;;;30:1;27;20:12;5:2;139040:615:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;139040:615:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;139040:615:0;;;;;;;;;;;;;;;;;;38489:132;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38489:132:0;;;:::i;:::-;;;;-1:-1:-1;;;;;38489:132:0;;;;;;;;;;;;;;38914:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38914:105:0;;;:::i;4377:56::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4377:56:0;;;:::i;5539:63::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5539:63:0;;;:::i;4500:59::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4500:59:0;;;:::i;6494:63::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6494:63:0;;;:::i;3501:69::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3501:69:0;;;:::i;39398:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39398:90:0;;;:::i;6102:65::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6102:65:0;;;:::i;6564:57::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6564:57:0;;;:::i;3398:71::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3398:71:0;;;:::i;3989:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3989:48:0;;;:::i;38161:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38161:80:0;;;:::i;37173:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37173:80:0;;;:::i;3934:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3934:48:0;;;:::i;39303:88::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39303:88:0;;;:::i;6296:66::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6296:66:0;;;:::i;37347:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37347:80:0;;;:::i;37987:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37987:80:0;;;:::i;37086:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37086:80:0;;;:::i;37607:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37607:78:0;;;:::i;102660:1205::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;102660:1205:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;102660:1205:0;-1:-1:-1;;;;;102660:1205:0;;:::i;37000:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37000:79:0;;;:::i;39214:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39214:82:0;;;:::i;138705:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;138705:25:0;;;:::i;3817:52::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3817:52:0;;;:::i;5402:64::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5402:64:0;;;:::i;3876:51::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3876:51:0;;;:::i;40291:107::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40291:107:0;;;:::i;39026:89::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39026:89:0;;;:::i;37521:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37521:79:0;;;:::i;4440:53::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4440:53:0;;;:::i;4253:50::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4253:50:0;;;:::i;3761:49::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3761:49:0;;;:::i;4658:61::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4658:61:0;;;:::i;4878:63::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4878:63:0;;;:::i;111768:70::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111768:70:0;;;:::i;4820:51::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4820:51:0;;;:::i;4197:49::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4197:49:0;;;:::i;37260:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37260:80:0;;;:::i;6394:68::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6394:68:0;;;:::i;3342:49::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3342:49:0;;;:::i;5142:59::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5142:59:0;;;:::i;39860:100::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39860:100:0;;;:::i;37692:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37692:114:0;;;:::i;38374:108::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38374:108:0;;;:::i;37898:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37898:82:0;;;:::i;124382:1344::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;124382:1344:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;124382:1344:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;124382:1344:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;124382:1344:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;124382:1344:0;;-1:-1:-1;;124382:1344:0;;;-1:-1:-1;124382:1344:0;;-1:-1:-1;;124382:1344:0:i;40405:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40405:96:0;;;:::i;40064:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40064:96:0;;;:::i;5825:66::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5825:66:0;;;:::i;40167:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40167:117:0;;;:::i;36818:87::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36818:87:0;;;:::i;4310:60::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4310:60:0;;;:::i;39495:84::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39495:84:0;;;:::i;37813:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37813:78:0;;;:::i;5609:63::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5609:63:0;;;:::i;111692:69::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111692:69:0;;;:::i;3284:51::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3284:51:0;;;:::i;4107:58::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4107:58:0;;;:::i;5898:59::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5898:59:0;;;:::i;37434:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37434:80:0;;;:::i;5278:52::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5278:52:0;;;:::i;4751:62::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4751:62:0;;;:::i;36771:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36771:40:0;;;:::i;39680:85::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39680:85:0;;;:::i;5473:59::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5473:59:0;;;:::i;39122:85::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39122:85:0;;;:::i;123703:338::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;123703:338:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;123703:338:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;123703:338:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;123703:338:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;123703:338:0;;-1:-1:-1;123703:338:0;-1:-1:-1;123703:338:0;;:::i;4566:60::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4566:60:0;;;:::i;38772:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38772:135:0;;;:::i;38250:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38250:117:0;;;:::i;4044:56::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4044:56:0;;;:::i;6199:65::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6199:65:0;;;:::i;39586:87::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39586:87:0;;;:::i;38074:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38074:80:0;;;:::i;139663:813::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;139663:813:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;139663:813:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;139663:813:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;139663:813:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;139663:813:0;;-1:-1:-1;;139663:813:0;;;-1:-1:-1;139663:813:0;;-1:-1:-1;;139663:813:0:i;5679:65::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5679:65:0;;;:::i;5751:67::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5751:67:0;;;:::i;39772:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39772:81:0;;;:::i;36914:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36914:79:0;;;:::i;3704:50::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3704:50:0;;;:::i;39967:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39967:90:0;;;:::i;5337:58::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5337:58:0;;;:::i;138665:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;138665:33:0;;;:::i;5018:59::-;5069:8;5018:59;:::o;139040:615::-;139499:12;;:148;;;-1:-1:-1;;;139499:148:0;;-1:-1:-1;;;;;139499:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139392:7;;139431:16;;139499:12;;:30;;:148;;;;;139392:7;;139499:148;;;;;;;:12;:148;;;5:2:-1;;;;30:1;27;20:12;5:2;139499:148:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;139499:148:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;139499:148:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;139499:148:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;139499:148:0;;421:4:-1;412:14;;;;139499:148:0;;;;;412:14:-1;139499:148:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;139499:148:0;;;;;;;;;;;139492:155;;;;139040:615;;;;;;;;:::o;38489:132::-;38578:42;38489:132;:::o;38914:105::-;38976:42;38914:105;:::o;4377:56::-;4427:6;4377:56;:::o;5539:63::-;5593:9;5539:63;:::o;4500:59::-;4553:6;4500:59;:::o;6494:63::-;6545:12;6494:63;:::o;3501:69::-;3559:11;3501:69;:::o;39398:90::-;39445:42;39398:90;:::o;6102:65::-;6156:11;6102:65;:::o;6564:57::-;6609:12;6564:57;:::o;3398:71::-;-1:-1:-1;;;3398:71:0;:::o;3989:48::-;4033:4;3989:48;:::o;38161:80::-;38198:42;38161:80;:::o;37173:::-;37210:42;37173:80;:::o;3934:48::-;3978:4;3934:48;:::o;39303:88::-;39348:42;39303:88;:::o;6296:66::-;6350:12;6296:66;:::o;37347:80::-;37384:42;37347:80;:::o;37987:::-;38024:42;37987:80;:::o;37086:::-;37123:42;37086:80;:::o;37607:78::-;37642:42;37607:78;:::o;102660:1205::-;102719:6;102742:13;:5;-1:-1:-1;;;;;102742:11:0;;:13::i;:::-;102738:63;;;-1:-1:-1;;;102772:17:0;;102738:63;102885:91;;;22:32:-1;6:49;;102885:91:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;102849:128:0;;;;102814:12;;102828:17;;-1:-1:-1;;;;;102849:25:0;;;102879:4;;102885:91;;102849:128;;;;25:18:-1;102849:128:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;102849:128:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;102813:164:0;;;;102993:7;102988:58;;-1:-1:-1;;103017:17:0;;;;;;102988:58;103058:13;;103090:414;103115:4;:11;103107:1;103111;103107:5;:19;103090:414;;;103152:4;103157:1;103161;103157:5;103152:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103152:11:0;-1:-1:-1;;;103152:18:0;:57;;;;;103191:4;103196:1;103200;103196:5;103191:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103191:11:0;-1:-1:-1;;;103191:18:0;103152:57;:96;;;;;103230:4;103235:1;103239;103235:5;103230:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103230:11:0;-1:-1:-1;;;103230:18:0;103152:96;:135;;;;;103269:4;103274:1;103278;103274:5;103269:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103269:11:0;-1:-1:-1;;;103269:18:0;103152:135;:174;;;;;103308:4;103313:1;103317;103313:5;103308:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103308:11:0;-1:-1:-1;;;103308:18:0;103152:174;:213;;;;;103347:4;103352:1;103356;103352:5;103347:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103347:11:0;-1:-1:-1;;;103347:18:0;103152:213;:252;;;;;103386:4;103391:1;103395;103391:5;103386:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103386:11:0;-1:-1:-1;;;103386:18:0;103152:252;103148:345;;;103449:4;103438:15;;103472:5;;103148:345;103128:3;;103090:414;;;;103519:8;103514:59;;-1:-1:-1;;103544:17:0;;;;;;;103514:59;103639:103;;;22:32:-1;6:49;;103639:103:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;103603:140:0;;;;-1:-1:-1;;;;;103603:25:0;;;103633:4;;103639:103;103603:140;;;25:18:-1;103603:140:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;103603:140:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;103585:158:0;;-1:-1:-1;103585:158:0;-1:-1:-1;103585:158:0;103754:58;;-1:-1:-1;;103783:17:0;;;;;;;103754:58;103842:4;103831:26;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;103831:26:0;;-1:-1:-1;;;;102660:1205:0;;;;:::o;37000:79::-;37036:42;37000:79;:::o;39214:82::-;39253:42;39214:82;:::o;138705:25::-;;;-1:-1:-1;;;;;138705:25:0;;:::o;3817:52::-;3865:4;3817:52;:::o;5402:64::-;5456:10;5402:64;:::o;3876:51::-;3923:4;3876:51;:::o;40291:107::-;40355:42;40291:107;:::o;39026:89::-;39072:42;39026:89;:::o;37521:79::-;37557:42;37521:79;:::o;4440:53::-;4487:6;4440:53;:::o;4253:50::-;4298:5;4253:50;:::o;3761:49::-;3806:4;3761:49;:::o;4658:61::-;4712:7;4658:61;:::o;4878:63::-;4933:8;4878:63;:::o;111768:70::-;;;-1:-1:-1;;;;;111768:70:0;;:::o;4820:51::-;4864:7;4820:51;:::o;4197:49::-;4241:5;4197:49;:::o;37260:80::-;37297:42;37260:80;:::o;6394:68::-;6450:12;6394:68;:::o;3342:49::-;3387:4;3342:49;:::o;5142:59::-;5193:8;5142:59;:::o;39860:100::-;39917:42;39860:100;:::o;37692:114::-;37763:42;37692:114;:::o;38374:108::-;38439:42;38374:108;:::o;37898:82::-;37937:42;37898:82;:::o;124382:1344::-;124627:30;:5;5322:8;124627:30;:11;:30;:::i;:::-;124626:31;124580:42;:5;5881:10;124580:42;:11;:42;:::i;:::-;124579:43;:78;124575:1064;;;124674:22;;:::i;:::-;124699:13;:11;:13::i;:::-;124674:38;-1:-1:-1;124734:6:0;124729:399;124750:13;124746:1;:17;124729:399;;;124813:6;124820:1;124813:9;;;;;;;;;;;-1:-1:-1;;;;;124793:30:0;:9;-1:-1:-1;;;;;124793:30:0;;124789:324;;;124848:17;124868:6;124875:1;124868:9;;;;;;;;;;;-1:-1:-1;;;;;124868:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;124868:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;124868:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;124868:17:0;;-1:-1:-1;124908:14:0;124925:6;124932:1;124925:9;;;;;;;;;;;-1:-1:-1;;;;;124925:25:0;;124951:6;124959:4;124979:1;124965:16;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;124965:16:0;;124925:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;124925:57:0;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;124925:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;124925:57:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;124925:57:0;;-1:-1:-1;125005:59:0;125015:10;125027:7;124925:57;125044:12;125058:5;125005:9;:59::i;:::-;125087:7;;;;;;124789:324;124765:3;;124729:399;;;-1:-1:-1;125149:6:0;125144:484;125165:13;125161:1;:17;125144:484;;;125226:6;125233:1;125226:9;;;;;;;;;;;-1:-1:-1;;;;;125208:28:0;:7;-1:-1:-1;;;;;125208:28:0;;125204:409;;;125261:17;125281:6;125288:1;125281:9;;;;;;;;;;;-1:-1:-1;;;;;125281:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125281:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125281:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125281:17:0;;-1:-1:-1;125321:63:0;125333:9;125281:17;125356:6;125364:12;125378:5;125321:11;:63::i;:::-;125407:56;125432:10;125452:6;125459:1;125452:9;;;;;;;;;;;125407:24;:56::i;:::-;125486:6;125493:1;125486:9;;;;;;;;;;;-1:-1:-1;;;;;125486:23:0;;125510:10;-1:-1:-1;;;;;125510:20:0;;125539:4;125510:35;;;;;;;;;;;;;-1:-1:-1;;;;;125510:35:0;-1:-1:-1;;;;;125510:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125510:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125510:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125510:35:0;125547:16;;;125561:1;125547:16;;;125510:35;125547:16;;;;;;;125486:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;125486:78:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125486:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125486:78:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125587:7:0;;-1:-1:-1;;;;125587:7:0;125204:409;125180:3;;125144:484;;;;124575:1064;;125658:60;125670:9;125681:7;125690:6;125698:12;125712:5;125658:11;:60::i;:::-;124382:1344;;;;;:::o;40405:96::-;40458:42;40405:96;:::o;40064:::-;40117:42;40064:96;:::o;5825:66::-;5881:10;5825:66;:::o;40167:117::-;40241:42;40167:117;:::o;36818:87::-;36862:42;36818:87;:::o;4310:60::-;4364:6;4310:60;:::o;39495:84::-;39536:42;39495:84;:::o;37813:78::-;37848:42;37813:78;:::o;5609:63::-;5663:9;5609:63;:::o;111692:69::-;;;-1:-1:-1;;;;;111692:69:0;;:::o;3284:51::-;3331:4;3284:51;:::o;4107:58::-;4160:5;4107:58;:::o;5898:59::-;5947:10;5898:59;:::o;37434:80::-;37471:42;37434:80;:::o;5278:52::-;5322:8;5278:52;:::o;4751:62::-;4806:7;4751:62;:::o;36771:40::-;36809:2;36771:40;:::o;39680:85::-;39722:42;39680:85;:::o;5473:59::-;5523:9;5473:59;:::o;39122:85::-;39164:42;39122:85;:::o;123703:338::-;123927:10;123949:4;123927:27;123919:36;;;;;;123973:60;123985:9;123996:7;124005:6;124013:12;;123973:60;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;124027:5:0;;-1:-1:-1;123973:11:0;;-1:-1:-1;;123973:60:0:i;:::-;123703:338;;;;;;:::o;4566:60::-;4619:7;4566:60;:::o;38772:135::-;38864:42;38772:135;:::o;38250:117::-;38324:42;38250:117;:::o;4044:56::-;4095:5;4044:56;:::o;6199:65::-;6253:11;6199:65;:::o;39586:87::-;39630:42;39586:87;:::o;38074:80::-;38111:42;38074:80;:::o;139663:813::-;139999:66;-1:-1:-1;;;;;139999:31:0;;140031:10;140051:4;140058:6;139999:66;:31;:66;:::i;:::-;140078:54;140084:9;140095:7;140104:6;140112:12;140126:5;140078;:54::i;:::-;140145:20;140168:41;-1:-1:-1;;;;;140168:26:0;;140203:4;140168:41;:26;:41;:::i;:::-;140145:64;;140244:9;140228:12;:25;;140220:91;;;;-1:-1:-1;;;140220:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;140322:51;-1:-1:-1;;;;;140322:25:0;;140348:10;140360:12;140322:51;:25;:51;:::i;:::-;-1:-1:-1;140384:84:0;140412:10;140424:43;-1:-1:-1;;;;;140424:28:0;;140461:4;140424:43;:28;:43;:::i;:::-;-1:-1:-1;;;;;140384:27:0;;;:84;;:27;:84;:::i;:::-;;139663:813;;;;;;;:::o;5679:65::-;5734:10;5679:65;:::o;5751:67::-;5808:10;5751:67;:::o;39772:81::-;39810:42;39772:81;:::o;36914:79::-;36950:42;36914:79;:::o;3704:50::-;3750:4;3704:50;:::o;39967:90::-;40014:42;39967:90;:::o;5337:58::-;5386:9;5337:58;:::o;138665:33::-;;;-1:-1:-1;;;;;138665:33:0;;:::o;33703:166::-;33754:4;-1:-1:-1;;;;;33779:39:0;;;;:81;;-1:-1:-1;;;;;;33822:38:0;;31092:42;33822:38;33779:81;33771:90;33703:166;-1:-1:-1;;33703:166:0:o;36329:117::-;36420:12;36419:19;;;36329:117::o;121142:227::-;121187:15;;:::i;:::-;-1:-1:-1;121215:146:0;;;;;;;;;121243:42;121215:146;;121307:42;121215:146;;;;121142:227;:::o;118776:326::-;118959:135;118984:9;119008:7;119030:6;119051:12;119078:5;118959:10;:135::i;47347:262::-;47432:13;:5;-1:-1:-1;;;;;47432:11:0;;:13::i;:::-;47427:175;;47467:34;;;-1:-1:-1;;;47467:34:0;;47491:4;47467:34;;;;-1:-1:-1;;;;;47467:34:0;;;;;;;;;47505:3;;47467:15;;;;;:34;;;;;;;;;;;;;;:15;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;47467:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47467:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47467:34:0;:41;;47462:129;;47535:40;-1:-1:-1;;;;;47535:22:0;;47558:2;-1:-1:-1;;47535:40:0;:22;:40;:::i;:::-;47347:262;;:::o;31500:617::-;31611:11;31607:50;;31639:7;;31607:50;31673:12;31679:5;31673;:12::i;:::-;31669:441;;;-1:-1:-1;;;;;31710:18:0;;31718:10;31710:18;:41;;;;;31745:6;31732:9;:19;;31710:41;31702:97;;;;-1:-1:-1;;;31702:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31818:19:0;;31832:4;31818:19;31814:97;;31858:37;;-1:-1:-1;;;;;31858:29:0;;;:37;;;;;31888:6;;31858:37;;;;31888:6;31858:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31858:37:0;31814:97;31941:6;31929:9;:18;31925:101;;;31968:10;:42;31988:21;:9;32002:6;31988:21;:13;:21;:::i;:::-;31968:42;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31968:42:0;31925:101;31669:441;;;32058:40;-1:-1:-1;;;;;32058:22:0;;32081:4;32087:2;32091:6;32058:40;:22;:40;:::i;:::-;31500:617;;;;:::o;134452:325::-;134635:134;134659:9;134683:7;134705:6;134726:12;134753:5;134635:9;:134::i;32885:228::-;32963:7;32987:12;32993:5;32987;:12::i;:::-;32983:123;;;-1:-1:-1;;;;;;33023:11:0;;;33016:18;;32983:123;33074:5;-1:-1:-1;;;;;33074:15:0;;33090:3;33074:20;;;;;;;;;;;;;-1:-1:-1;;;;;33074:20:0;-1:-1:-1;;;;;33074:20:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33074:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33074:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33074:20:0;;-1:-1:-1;33067:27:0;;31144:348;31230:4;31251:11;31247:55;;-1:-1:-1;31286:4:0;31279:11;;31247:55;31318:12;31324:5;31318;:12::i;:::-;31314:171;;;31347:37;;-1:-1:-1;;;;;31347:29:0;;;:37;;;;;31377:6;;31347:37;;;;31377:6;31347:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31347:37:0;31314:171;;;31417:30;-1:-1:-1;;;;;31417:18:0;;31436:2;31440:6;31417:30;:18;:30;:::i;:::-;-1:-1:-1;31469:4:0;31314:171;31144:348;;;;;:::o;119110:1375::-;119314:7;-1:-1:-1;;;;;119301:20:0;:9;-1:-1:-1;;;;;119301:20:0;;119297:59;;;119338:7;;119297:59;119418:31;:5;4298;119418:31;:11;:31;:::i;:::-;119372:77;;:42;:5;5881:10;119372:42;:11;:42;:::i;:::-;:77;;;119368:1030;;;119466:25;;:::i;:::-;119494:10;:8;:10::i;:::-;119466:38;-1:-1:-1;119526:6:0;119521:385;119542:14;119538:1;:18;119521:385;;;119606:7;119614:1;119606:10;;;;;;;;;;;-1:-1:-1;;;;;119586:31:0;:9;-1:-1:-1;;;;;119586:31:0;;119582:309;;;119642:17;119662:7;119670:1;119662:10;;;;;;;;;;;-1:-1:-1;;;;;119662:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119662:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119662:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;119662:18:0;;-1:-1:-1;119703:7:0;119711:1;119703:10;;;;;;;;;;;-1:-1:-1;;;;;119703:19:0;;119723:6;119703:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119703:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119703:27:0;;;;119753:89;119764:10;119776:7;119785:10;-1:-1:-1;;;;;119785:20:0;;119814:4;119785:35;;;;;;;;;;;;;-1:-1:-1;;;;;119785:35:0;-1:-1:-1;;;;;119785:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119785:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119785:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;119785:35:0;119822:12;119836:5;119753:10;:89::i;:::-;119865:7;;;;;119582:309;119558:3;;119521:385;;;-1:-1:-1;119927:6:0;119922:465;119943:14;119939:1;:18;119922:465;;;120005:7;120013:1;120005:10;;;;;;;;;;;-1:-1:-1;;;;;119987:29:0;:7;-1:-1:-1;;;;;119987:29:0;;119983:389;;;120041:17;120061:7;120069:1;120061:10;;;;;;;;;;;-1:-1:-1;;;;;120061:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;120061:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120061:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;120061:18:0;;-1:-1:-1;120102:63:0;120114:9;120061:18;120137:6;120145:12;120159:5;120102:11;:63::i;:::-;120188:57;120213:10;120233:7;120241:1;120233:10;;;;;;120188:57;120268:7;120276:1;120268:10;;;;;;;;;;;-1:-1:-1;;;;;120268:18:0;;120287:10;-1:-1:-1;;;;;120287:20:0;;120316:4;120287:35;;;;;;;;;;;;;-1:-1:-1;;;;;120287:35:0;-1:-1:-1;;;;;120287:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;120287:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120287:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;120287:35:0;120268:55;;;-1:-1:-1;;;;;;120268:55:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;120268:55:0;;;;;;;-1:-1:-1;120268:55:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;120268:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120268:55:0;;;;120346:7;;;;;119983:389;119959:3;;119922:465;;;;119368:1030;;120417:60;120429:9;120440:7;120449:6;120457:12;120471:5;120417:11;:60::i;32576:301::-;32669:12;32675:5;32669;:12::i;:::-;32664:206;;32711:1;32702:6;:10;:52;;;;-1:-1:-1;32716:34:0;;;-1:-1:-1;;;32716:34:0;;32740:4;32716:34;;;;-1:-1:-1;;;;;32716:34:0;;;;;;;;;32753:1;;32716:15;;;;;:34;;;;;;;;;;;;;;:15;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;32716:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32716:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32716:34:0;:38;32702:52;32698:117;;;32775:24;-1:-1:-1;;;;;32775:17:0;;32793:2;32797:1;32775:24;:17;:24;:::i;:::-;32829:29;-1:-1:-1;;;;;32829:17:0;;32847:2;32851:6;32829:29;:17;:29;:::i;:::-;32576:301;;;:::o;8561:136::-;8619:7;8646:43;8650:1;8653;8646:43;;;;;;;;;;;;;;;;;:3;:43::i;27799:204::-;27926:68;;;-1:-1:-1;;;;;27926:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;27926:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;27900:95:0;;27919:5;;27900:18;:95::i;134785:1958::-;134988:7;-1:-1:-1;;;;;134975:20:0;:9;-1:-1:-1;;;;;134975:20:0;;134971:59;;;135012:7;;134971:59;135092:30;:5;4864:7;135092:30;:11;:30;:::i;:::-;135046:76;;:42;:5;5881:10;135046:42;:11;:42;:::i;:::-;:76;;;135042:1538;;;-1:-1:-1;;;;;135143:17:0;;37642:42;135143:17;135139:332;;;135195:29;;;-1:-1:-1;;;135195:29:0;;135218:4;135195:29;;;;;;37642:42;;135181:13;;37642:42;;135195:14;;:29;;;;;;;;;;;;;;37642:42;135195:29;;;5:2:-1;;;;30:1;27;20:12;5:2;135195:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;135195:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;135195:29:0;135181:44;;;-1:-1:-1;;;;;;135181:44:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;135181:44:0;;;;;;;-1:-1:-1;135181:44:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;135181:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;135181:44:0;;;;135244:186;36862:42;135312:7;135342:6;135371:12;135406:5;135244:11;:186::i;:::-;135449:7;;135139:332;-1:-1:-1;;;;;135491:29:0;;37763:42;135491:29;135487:368;;;135567:41;;;-1:-1:-1;;;135567:41:0;;135602:4;135567:41;;;;;;37763:42;;135541:25;;37763:42;;135567:26;;:41;;;;;;;;;;;;;;37763:42;135567:41;;;5:2:-1;;;;30:1;27;20:12;135487:368:0;-1:-1:-1;;;;;135875:15:0;;37642:42;135875:15;135871:329;;;135911:186;135943:9;36862:42;136009:6;136038:12;136073:5;135911:9;:186::i;:::-;37642:42;-1:-1:-1;;;;;136116:12:0;;136135:21;136116:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;136116:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;136116:43:0;;;;;136178:7;;135871:329;-1:-1:-1;;;;;136220:27:0;;37763:42;136220:27;136216:353;;;136268:186;136300:9;36862:42;136366:6;136395:12;136430:5;136268:9;:186::i;:::-;37763:42;-1:-1:-1;;;;;136473:24:0;;136504:21;136473:55;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;136216:353:0;136599:136;136625:9;136649:7;136671:6;136692:12;136719:5;136599:11;:136::i;27615:176::-;27724:58;;;-1:-1:-1;;;;;27724:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;27724:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;27698:85:0;;27717:5;;27698:18;:85::i;115276:943::-;115318:17;;:::i;:::-;-1:-1:-1;115348:863:0;;;;;;;;115377:42;115348:863;;115442:42;115348:863;;;;115507:42;115348:863;;;;;;;115572:42;115348:863;;;;115637:42;115348:863;;;;115702:42;115348:863;;;;115767:42;115348:863;;;;115832:42;115348:863;;;;115897:42;115348:863;;;;115962:42;115348:863;;;;116027:42;115348:863;;;;116092:42;115348:863;;;;116157:42;115348:863;;;;115276:943;:::o;98052:328::-;98235:137;98262:9;98286:7;98308:6;98329:12;98356:5;98235:12;:137::i;28011:621::-;28381:10;;;28380:62;;-1:-1:-1;28397:39:0;;;-1:-1:-1;;;28397:39:0;;28421:4;28397:39;;;;-1:-1:-1;;;;;28397:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;5:2:-1;;;;30:1;27;20:12;5:2;28397:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28397:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28397:39:0;:44;28380:62;28372:152;;;;-1:-1:-1;;;28372:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28561:62;;;-1:-1:-1;;;;;28561:62:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;28561:62:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;28535:89:0;;28554:5;;28535:18;:89::i;9034:192::-;9120:7;9156:12;9148:6;;;;9140:29;;;;-1:-1:-1;;;9140:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;9140:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9192:5:0;;;9034:192::o;29654:1114::-;30258:27;30266:5;-1:-1:-1;;;;;30258:25:0;;:27::i;:::-;30250:71;;;;;-1:-1:-1;;;30250:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30395:12;30409:23;30444:5;-1:-1:-1;;;;;30436:19:0;30456:4;30436:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;30436:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;30394:67:0;;;;30480:7;30472:52;;;;;-1:-1:-1;;;30472:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30541:17;;:21;30537:224;;30683:10;30672:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30672:30:0;30664:85;;;;-1:-1:-1;;;30664:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124049:325;124232:134;124256:9;124280:7;124302:6;124323:12;124350:5;124232:9;:134::i;98388:1788::-;98594:7;-1:-1:-1;;;;;98581:20:0;:9;-1:-1:-1;;;;;98581:20:0;;98577:59;;;98618:7;;98577:59;98698:34;:5;3865:4;98698:34;:11;:34;:::i;:::-;98652:80;;:42;:5;5881:10;98652:42;:11;:42;:::i;:::-;:80;;;98648:1365;;;98749:17;98769:38;98797:9;98769:27;:38::i;:::-;98749:58;-1:-1:-1;;;;;;98826:24:0;;;;98822:428;;98894:9;-1:-1:-1;;;;;98871:41:0;;98913:6;98871:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;98871:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;98871:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;98939:24:0;;-1:-1:-1;98966:44:0;-1:-1:-1;;;;;98966:29:0;;99004:4;98966:44;:29;:44;:::i;:::-;98939:71;;99038:196;99073:10;99106:7;99136:16;99175:12;99210:5;99038:12;:196::i;:::-;99031:203;;;;98822:428;99279:36;99307:7;99279:27;:36::i;:::-;99266:49;-1:-1:-1;;;;;;99334:24:0;;;;99330:672;;99379:187;99413:9;99445:10;99478:6;99507:12;99542:5;99379:11;:187::i;:::-;99587:24;99614:44;-1:-1:-1;;;;;99614:29:0;;99652:4;99614:44;:29;:44;:::i;:::-;99587:71;;99683:18;:10;-1:-1:-1;;;;;99683:16:0;;:18::i;:::-;99679:283;;;40117:42;-1:-1:-1;;;;;99726:9:0;;99742:16;99726:35;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99726:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99726:35:0;;;;;99679:283;;;99810:54;99835:10;99855:7;99810:24;:54::i;:::-;99910:7;-1:-1:-1;;;;;99887:37:0;;99925:16;99887:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99887:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99887:55:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;99330:672:0;98648:1365;;100032:136;100058:9;100082:7;100104:6;100125:12;100152:5;100032:11;:136::i;24644:619::-;24704:4;25172:20;;25015:66;25212:23;;;;;;:42;;-1:-1:-1;25239:15:0;;;25212:42;25204:51;24644:619;-1:-1:-1;;;;24644:619:0:o;94216:1409::-;94289:6;-1:-1:-1;;;;;94312:59:0;;94328:42;94312:59;94308:115;;;-1:-1:-1;94409:1:0;94395:16;;94308:115;-1:-1:-1;;;;;94437:59:0;;94453:42;94437:59;94433:156;;;-1:-1:-1;94534:42:0;94520:57;;94433:156;-1:-1:-1;;;;;94603:59:0;;94619:42;94603:59;94599:156;;;-1:-1:-1;94700:42:0;94686:57;;94599:156;-1:-1:-1;;;;;94769:59:0;;94785:42;94769:59;94765:156;;;-1:-1:-1;94866:42:0;94852:57;;94765:156;-1:-1:-1;;;;;94935:59:0;;94951:42;94935:59;94931:157;;;-1:-1:-1;95033:42:0;95019:57;;94931:157;-1:-1:-1;;;;;95102:59:0;;95118:42;95102:59;95098:157;;;-1:-1:-1;95200:42:0;95186:57;;95098:157;-1:-1:-1;;;;;95269:59:0;;95285:42;95269:59;95265:156;;;-1:-1:-1;95366:42:0;95352:57;;95265:156;-1:-1:-1;;;;;95435:59:0;;95451:42;95435:59;95431:157;;;-1:-1:-1;95533:42:0;95519:57;;95431:157;-1:-1:-1;;;94216:1409:0;;;:::o;106236:328::-;106419:137;106446:9;106470:7;106492:6;106513:12;106540:5;106778:7;-1:-1:-1;;;;;106765:20:0;:9;-1:-1:-1;;;;;106765:20:0;;106761:59;;;106802:7;;106761:59;106882:33;:5;3923:4;106882:33;:11;:33;:::i;:::-;106836:79;;:42;:5;5881:10;106836:42;:11;:42;:::i;:::-;:79;;;106832:1599;;;106932:17;106952:26;106968:9;106952:15;:26::i;:::-;106932:46;-1:-1:-1;;;;;;106997:24:0;;;;106993:624;;107046:18;:10;-1:-1:-1;;;;;107046:16:0;;:18::i;:::-;107042:245;;;107089:68;;;-1:-1:-1;;;107089:68:0;;107143:4;107089:68;;;;;;;;;;;;-1:-1:-1;;;;;107089:45:0;;;;;:68;;;;;;;;;;;;;;-1:-1:-1;107089:45:0;:68;;;5:2:-1;;;;30:1;27;20:12;5:2;107089:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;107089:68:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;107042:245:0;;-1:-1:-1;107042:245:0;;107206:61;;;-1:-1:-1;;;107206:61:0;;107253:4;107206:61;;;;;;;;;;;;-1:-1:-1;;;;;107206:38:0;;;;;:61;;;;;;;;;;;;;;-1:-1:-1;107206:38:0;:61;;;5:2:-1;;;;30:1;27;20:12;5:2;107206:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;107206:61:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;107042:245:0;107307:24;107334:44;-1:-1:-1;;;;;107334:29:0;;107372:4;107334:44;:29;:44;:::i;:::-;107307:71;;107406:195;107440:10;107473:7;107503:16;107542:12;107577:5;107406:11;:195::i;106993:624::-;107646:24;107662:7;107646:15;:24::i;:::-;107633:37;-1:-1:-1;;;;;;107689:24:0;;;;107685:735;;107734:187;107768:9;107800:10;107833:6;107862:12;107897:5;107734:11;:187::i;:::-;107942:24;107969:44;-1:-1:-1;;;;;107969:29:0;;108007:4;107969:44;:29;:44;:::i;:::-;107942:71;;108038:18;:10;-1:-1:-1;;;;;108038:16:0;;:18::i;:::-;108034:346;;;108081:84;;;-1:-1:-1;;;108081:84:0;;108159:4;108081:84;;;;;;-1:-1:-1;;;;;108081:45:0;;;;;108133:16;;108081:84;;;;;;;;;;;;;;;108133:16;108081:45;:84;;;5:2:-1;;;;30:1;27;20:12;5:2;108081:84:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;108081:84:0;;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108034:346:0;;-1:-1:-1;108034:346:0;;108214:54;108239:10;108259:7;108214:24;:54::i;:::-;108291:69;;;-1:-1:-1;;;108291:69:0;;108336:4;108291:69;;;;;;;;;;;;-1:-1:-1;;;;;108291:36:0;;;;;:69;;;;;;;;;;;;;;-1:-1:-1;108291:36:0;:69;;;5:2:-1;;;;30:1;27;20:12;107685:735:0;106832:1599;;108450:136;108476:9;108500:7;108522:6;108543:12;108570:5;130738:325;130921:134;130945:9;130969:7;130991:6;131012:12;131039:5;131071:1666;131274:7;-1:-1:-1;;;;;131261:20:0;:9;-1:-1:-1;;;;;131261:20:0;;131257:59;;;131298:7;;131257:59;131378:30;:5;4033:4;131378:30;:11;:30;:::i;:::-;131332:76;;:42;:5;5881:10;131332:42;:11;:42;:::i;:::-;:76;;;131328:1246;;;131425:17;131445:34;131469:9;131445:23;:34::i;:::-;131425:54;-1:-1:-1;;;;;;131498:24:0;;;;131494:321;;131562:9;-1:-1:-1;;;;;131543:37:0;;131581:6;131543:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;131543:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;131543:45:0;;;;131616:183;131648:10;131681:7;131711:6;131740:12;131775:5;131616:9;:183::i;:::-;131609:190;;;131494:321;131844:32;131868:7;131844:23;:32::i;:::-;131831:45;-1:-1:-1;;;;;;131895:24:0;;;;131891:672;;131940:187;131974:9;132006:10;132039:6;132068:12;132103:5;131940:11;:187::i;:::-;132148:24;132175:44;-1:-1:-1;;;;;132175:29:0;;132213:4;132175:44;:29;:44;:::i;:::-;132148:71;;132240:49;132265:10;39917:42;-1:-1:-1;;;;;132277:9:0;;:11;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;132277:11:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;132277:11:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;132277:11:0;132240:24;:49::i;:::-;39917:42;132308:12;132327:18;-1:-1:-1;;;;;132327:16:0;;;:18::i;:::-;:41;;132367:1;132327:41;;;132348:16;132327:41;132392:18;:10;-1:-1:-1;;;;;132392:16:0;;:18::i;:::-;:45;;132427:10;132392:45;;;36862:42;132392:45;132308:214;;;-1:-1:-1;;;;;;132308:214:0;;;;;;;-1:-1:-1;;;;;132308:214:0;;;;;;;;;;;;;132499:4;132308:214;;;;;;;;;;-1:-1:-1;;132308:214:0;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;131891:672:0;131328:1246;;132593:136;132619:9;132643:7;132665:6;132686:12;132713:5;132593:11;:136::i;125840:2905::-;125909:6;-1:-1:-1;;;;;125932:59:0;;125948:42;125932:59;125928:115;;;-1:-1:-1;126029:1:0;126015:16;;125928:115;-1:-1:-1;;;;;126057:59:0;;126073:42;126057:59;126053:156;;;-1:-1:-1;126154:42:0;126140:57;;126053:156;-1:-1:-1;;;;;126223:59:0;;126239:42;126223:59;126219:157;;;-1:-1:-1;126321:42:0;126307:57;;126219:157;-1:-1:-1;;;;;126390:59:0;;126406:42;126390:59;126386:157;;;-1:-1:-1;126488:42:0;126474:57;;126386:157;-1:-1:-1;;;;;126557:59:0;;126573:42;126557:59;126553:157;;;-1:-1:-1;126655:42:0;126641:57;;126553:157;-1:-1:-1;;;;;126724:59:0;;126740:42;126724:59;126720:157;;;-1:-1:-1;126822:42:0;126808:57;;126720:157;-1:-1:-1;;;;;126891:59:0;;126907:42;126891:59;126887:157;;;-1:-1:-1;126989:42:0;126975:57;;126887:157;-1:-1:-1;;;;;127058:59:0;;127074:42;127058:59;127054:156;;;-1:-1:-1;127155:42:0;127141:57;;127054:156;-1:-1:-1;;;;;127224:59:0;;127240:42;127224:59;127220:156;;;-1:-1:-1;127321:42:0;127307:57;;127220:156;-1:-1:-1;;;;;127390:59:0;;127406:42;127390:59;127386:157;;;-1:-1:-1;127488:42:0;127474:57;;127386:157;-1:-1:-1;;;;;127557:59:0;;127573:42;127557:59;127553:157;;;-1:-1:-1;127655:42:0;127641:57;;127553:157;-1:-1:-1;;;;;127724:59:0;;127740:42;127724:59;127720:157;;;-1:-1:-1;127822:42:0;127808:57;;127720:157;-1:-1:-1;;;;;127891:59:0;;127907:42;127891:59;127887:156;;;-1:-1:-1;127988:42:0;127974:57;;127887:156;-1:-1:-1;;;;;128057:59:0;;128073:42;128057:59;128053:156;;;-1:-1:-1;128154:42:0;128140:57;;128053:156;-1:-1:-1;;;;;128223:59:0;;128239:42;128223:59;128219:156;;;-1:-1:-1;128320:42:0;128306:57;;128219:156;-1:-1:-1;;;;;128389:59:0;;128405:42;128389:59;128385:157;;;-1:-1:-1;128487:42:0;128473:57;;128385:157;-1:-1:-1;;;;;128556:59:0;;128572:42;128556:59;128552:156;;;-1:-1:-1;128653:42:0;128639:57;;113187:1640;113387:7;-1:-1:-1;;;;;113374:20:0;:9;-1:-1:-1;;;;;113374:20:0;;113370:59;;;113411:7;;113370:59;113491:30;:5;4241;113491:30;:11;:30;:::i;:::-;113445:76;;:42;:5;5881:10;113445:42;:11;:42;:::i;:::-;:76;;;113441:1299;;;113562:4;;-1:-1:-1;;;;;113542:25:0;;;113562:4;;113542:25;113538:907;;;113588:4;;;:17;;;-1:-1:-1;;;113588:17:0;;;;;;;;;;-1:-1:-1;;;;;113588:4:0;;;;:9;;:17;;;;;;;;;;:4;;:17;;;5:2:-1;;;;30:1;27;20:12;5:2;113588:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;113647:3:0;;:28;;;-1:-1:-1;;;113647:28:0;;113669:4;113647:28;;;;;;113626:18;;-1:-1:-1;;;;;;113647:3:0;;;;-1:-1:-1;113647:13:0;;:28;;;;;;;;;;;;;;:3;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;113647:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113647:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;113647:28:0;;-1:-1:-1;113698:14:0;;113694:530;;113819:3;;;113739:32;;113775:201;;-1:-1:-1;;;;;113819:3:0;;113849:7;;113883:10;;113948:5;113775:17;:201::i;:::-;114033:3;;113737:239;;-1:-1:-1;114001:203:0;;-1:-1:-1;;;;;;114033:3:0;114063:7;114097:10;113737:239;114176:5;114001;:203::i;:::-;113694:530;;114251:178;36950:42;114311:7;114341:6;114370:12;114405:5;114251:11;:178::i;113538:907::-;114483:4;;-1:-1:-1;;;;;114465:23:0;;;114483:4;;114465:23;114461:268;;;114509:56;114521:9;36950:42;114537:6;114545:12;114559:5;114509:11;:56::i;:::-;114624:4;;114586:44;;36950:42;;-1:-1:-1;;;;;114624:4:0;114586:24;:44::i;:::-;114649:4;;114659:28;;;-1:-1:-1;;;114659:28:0;;114681:4;114659:28;;;;;;-1:-1:-1;;;;;114649:4:0;;;;:9;;36950:42;;114659:13;;:28;;;;;;;;;;;;;;;36950:42;114659:28;;;5:2:-1;;;;30:1;27;20:12;5:2;114659:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114659:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;114659:28:0;114649:39;;;-1:-1:-1;;;;;;114649:39:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;114649:39:0;;;;;;;-1:-1:-1;114649:39:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;114649:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;114461:268:0;114759:60;114771:9;114782:7;114791:6;114799:12;114813:5;110122:1274;110322:7;-1:-1:-1;;;;;110309:20:0;:9;-1:-1:-1;;;;;110309:20:0;;110305:59;;;110346:7;;110305:59;110426:30;:5;3978:4;110426:30;:11;:30;:::i;:::-;110380:76;;:42;:5;5881:10;110380:42;:11;:42;:::i;:::-;:76;;;110376:857;;;-1:-1:-1;;;;;110477:25:0;;37848:42;110477:25;110473:326;;;110523:32;;;-1:-1:-1;;;110523:32:0;;110541:4;110523:32;;;;;;;;;;;;37848:42;;110523:9;;:32;;;;;-1:-1:-1;;110523:32:0;;;;;;;-1:-1:-1;37848:42:0;110523:32;;;5:2:-1;;;;30:1;27;20:12;5:2;110523:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;110673:28:0;;;-1:-1:-1;;;110673:28:0;;110695:4;110673:28;;;;;;110583:200;;-1:-1:-1;36950:42:0;;-1:-1:-1;110643:7:0;;36950:42;;110673:13;;:28;;;;;;;;;;;;;;;36950:42;110673:28;;;5:2:-1;;;;30:1;27;20:12;5:2;110673:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110673:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;110673:28:0;110724:12;110759:5;110583:11;:200::i;110473:326::-;-1:-1:-1;;;;;110819:23:0;;37848:42;110819:23;110815:407;;;110863:180;110897:9;36950:42;110955:6;110984:12;111019:5;110863:11;:180::i;:::-;111064:44;36950:42;37848;111064:24;:44::i;:::-;111152:28;;;-1:-1:-1;;;111152:28:0;;111145:4;111152:28;;;;;;;;37848:42;;111127:9;;111145:4;;36950:42;;111152:13;;:28;;;;;;;;;;;;;;36950:42;111152:28;;;5:2:-1;;;;30:1;27;20:12;5:2;111152:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111152:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;111152:28:0;111127:54;;;-1:-1:-1;;;;;;111127:54:0;;;;;;;-1:-1:-1;;;;;111127:54:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;111127:54:0;;;;;;;-1:-1:-1;111127:54:0;;;;5:2:-1;;;;30:1;27;20:12;110815:407:0;111252:136;111278:9;111302:7;111324:6;111345:12;111372:5;92933:1163;93116:15;93134:25;93153:5;93134:18;:25::i;:::-;93116:43;-1:-1:-1;;;;;;93176:21:0;;;93172:768;;93214:21;93252:12;:19;93238:34;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;93238:34:0;-1:-1:-1;93214:58:0;-1:-1:-1;93292:6:0;93287:114;93308:12;:19;93304:1;:23;93287:114;;;93363:12;93376:1;93363:15;;;;;;;;;;;;;;93381:4;93363:22;93353:4;93358:1;93353:7;;;;;;;;;;;;;;;;;:32;93329:3;;93287:114;;;;93415:153;93445:9;93473:8;93500:6;93525:4;93548:5;93415:11;:153::i;:::-;93590:6;93585:121;93606:12;:19;93602:1;:23;93585:121;;;93681:1;93662:12;93675:1;93662:15;;;;;;;;;;;;;;:20;;93686:4;93661:29;93651:4;93656:1;93651:7;;;;;;;;;;;;;;;;;:39;93627:3;;93585:121;;;-1:-1:-1;93720:187:0;93750:8;93777:7;93803:42;-1:-1:-1;;;;;93803:27:0;;93839:4;93803:42;:27;:42;:::i;:::-;93864:4;93887:5;93720:11;:187::i;93172:768::-;93952:136;93978:9;94002:7;94024:6;94045:12;94072:5;93952:11;:136::i;89763:903::-;89828:15;89856:26;;:::i;:::-;:334;;;;;;;;4160:5;89856:334;;;;4619:7;89856:334;;;;4712:7;89856:334;;;;6156:11;89856:334;;;;6253:11;89856:334;;;;6350:12;89856:334;;;;6450:12;89856:334;;;;;90203:29;;:::i;:::-;-1:-1:-1;90203:184:0;;;;;;;;36862:42;90203:184;;36950:42;90203:184;;;;37123:42;90203:184;;;;;;;37210:42;90203:184;;;;38024:42;90203:184;;;;38111:42;90203:184;;;;37937:42;90203:184;;;;-1:-1:-1;90400:259:0;90421:15;90417:1;:19;90400:259;;;90462:24;90474:8;90483:1;90474:11;;;;;;;;;;;90462:5;;:24;:11;:24;:::i;:::-;90458:190;;;-1:-1:-1;;;;;90515:21:0;;;90507:80;;;;-1:-1:-1;;;90507:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90617:12;90630:1;90617:15;;;;;;;;;;;90606:26;;90458:190;90438:3;;90400:259;;;;89763:903;;;;;:::o;71981:431::-;72215:7;-1:-1:-1;;;;;72202:20:0;:9;-1:-1:-1;;;;;72202:20:0;;72198:59;;;72239:7;;72198:59;72269:135;72294:9;72318:7;72340:6;72361:12;72388:5;140716:8;;140753:228;;-1:-1:-1;;;;;140753:228:0;;;;;;;;;;;;;;;;;;;;;;140673:12;140753:228;;;;;;;;;;;;;;;;;;;;;;;;;;;140673:12;;140687:17;;140716:8;;;-1:-1:-1;;;140794:18:0;140831:9;;140859:7;;140885:6;;140673:12;;140930;;140961:5;;140753:228;;;;;;;;;;;;;;140673:12;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;140753:228:0;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;140753:228:0;;;;-1:-1:-1;;;;;140753:228:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;140753:228:0;140708:284;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;140708:284:0;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;140672:320:0;;;;141036:7;141119:1;141114:48;;;;141029:133;;141114:48;141145:14;141140:2;141134:4;141130:13;141123:37;138400:2783;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138400:2783:0;;;-1:-1:-1;;138400:2783:0:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138400:2783:0;;;-1:-1:-1;;138400:2783:0:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138400:2783:0;;;-1:-1:-1;;138400:2783:0:o
Swarm Source
bzzr://49b17a8f8dfea0e5a985bc859466ccb2c8bdbc145929b2e2294f1dbb71a2b544
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BSC | 100.00% | $4.85 | 1 | $4.85 |
Loading...
Loading
[ 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.