Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 10161538 | 1520 days ago | IN | 0 ETH | 0.16878676 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17086588 | 464 days ago | 0.01 ETH | ||||
17086588 | 464 days ago | 0.01 ETH | ||||
17025680 | 473 days ago | 0.01 ETH | ||||
17025680 | 473 days ago | 0.01 ETH | ||||
17024239 | 473 days ago | 0.01 ETH | ||||
17024239 | 473 days ago | 0.01 ETH | ||||
16989003 | 478 days ago | 0.01 ETH | ||||
16989003 | 478 days ago | 0.01 ETH | ||||
16983748 | 479 days ago | 0.01 ETH | ||||
16983748 | 479 days ago | 0.01 ETH | ||||
16983224 | 479 days ago | 0.01 ETH | ||||
16983224 | 479 days ago | 0.01 ETH | ||||
16482718 | 549 days ago | 0.04625 ETH | ||||
16482718 | 549 days ago | 0.04625 ETH | ||||
15924698 | 627 days ago | 0.00067078 ETH | ||||
15924698 | 627 days ago | 0.00067078 ETH | ||||
15923261 | 627 days ago | 0.00068719 ETH | ||||
15923261 | 627 days ago | 0.00068719 ETH | ||||
14961469 | 774 days ago | 0.0029246 ETH | ||||
14961469 | 774 days ago | 0.0029246 ETH | ||||
14664977 | 822 days ago | 0.00576786 ETH | ||||
14664977 | 822 days ago | 0.00576786 ETH | ||||
14432843 | 859 days ago | 0.08130969 ETH | ||||
14432843 | 859 days ago | 0.08130969 ETH | ||||
13936746 | 936 days ago | 0.02882197 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-29 */ // 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; uint256 public constant FLAG_ENABLE_CHI_BURN = 0x10000000000; } 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(0x93054188d876f558f4a66B2EF1d97d16eDf0895B); 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); uint256 confirmed = fromToken.universalBalanceOf(address(this)); _swap(fromToken, toToken, confirmed, 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_CHI_BURN","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
6080604052600080546001600160a01b0319908116736a4ffaafa8dd400676df8076ad6c724867b0e2e8179091556001805490911673b683d83a532e2cb7dfa5275eed3698436371cc9f17905534801561005857600080fd5b5060405162004a9638038062004a968339818101604052604081101561007d57600080fd5b508051602090910151600280546001600160a01b039384166001600160a01b031991821617909155600380549390921692169190911790556149d180620000c56000396000f3fe6080604052600436106104ec5760003560e01c80637a88bdbd1161028c578063c9b42c671161015a578063df1b4e99116100cc578063f11d2ff411610085578063f11d2ff414610e7d578063f4b9fa7514610e92578063f56e281f14610ea7578063f69e204614610ebc578063fa3f110b14610ed1578063fbe4ed9514610ee6576104ec565b8063df1b4e9914610d4c578063e0de8f2214610d61578063e1308b3314610d76578063e2a7515e14610d8b578063e355812314610e53578063e44987b414610e68576104ec565b8063d1ae60631161011e578063d1ae606314610c5d578063d393c3e914610cf8578063d70a2d1f14610d0d578063d77366a414610d22578063dc1536b214610d37578063ddd2f8d014610666576104ec565b8063c9b42c6714610bf4578063cc26e9fc14610c09578063cd240d7514610c1e578063ce74b7ac14610c33578063cede5f6a14610c48576104ec565b8063a734f06e116101fe578063c11f4f11116101b7578063c11f4f1114610b76578063c762a46c14610b8b578063c77b9de614610ba0578063c7f112e414610bb5578063c925777514610bca578063c989b66714610bdf576104ec565b8063a734f06e14610b0d578063b0a7ef2914610b22578063b184a3ae14610b37578063b3bc784414610690578063b69d045614610b4c578063bf2c5a0714610b61576104ec565b8063903548721161025057806390354872146109e1578063944a32e2146109f6578063960d2c1914610ab9578063a1b4d01114610ace578063a2878cb114610ae3578063a4792ab314610af8576104ec565b80637a88bdbd146109785780637e09b9c21461098d578063819faf7b146109a2578063851954fa146109b75780638bdb2afa146109cc576104ec565b80633fc8cef3116103c95780635aa8fb481161033b5780636b5a4ca2116102f45780636b5a4ca21461090f5780636cbc4a6e1461092457806375a8b0121461093957806375b5be2d1461094e57806376c3972614610963578063792e69d7146106ba576104ec565b80635aa8fb48146108915780635ae51b82146108a65780635c0cb479146108bb578063646c4ec4146108d057806364ec4e5c146108e557806368e2a014146108fa576104ec565b806344211d621161038d57806344211d62146108135780634752c680146108285780634a7101d51461083d5780635187c0911461085257806351f1985c1461086757806352a701b41461087c576104ec565b80633fc8cef31461078c5780634037f967146107a157806340ab7b8c146107d4578063423d03f9146107e957806343ee21f0146107fe576104ec565b80632ceb90b81161046257806334b4dabb1161042657806334b4dabb1461070e578063372a26cb14610723578063376e55b7146107385780633ca5b2341461074d5780633cdc5389146107625780633e413bee14610777576104ec565b80632ceb90b8146106a55780632d3b5207146106ba5780632e707bd2146106cf5780632f0fe755146106e45780632f48ab7d146106f9576104ec565b80631d209b65116104b45780631d209b65146106275780632113240d1461063c57806321899d3a1461065157806321a360f51461066657806322320c981461067b57806327a7fbd514610690576104ec565b806305d8aa0a146104fb578063085e2c5b1461052257806312dea160146105cc5780631388b420146105fd5780631398914014610612575b333214156104f957600080fd5b005b34801561050757600080fd5b50610510610efb565b60408051918252519081900360200190f35b34801561052e57600080fd5b50610571600480360360a081101561054557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135610f02565b6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156105b757818101518382015260200161059f565b50505050905001935050505060405180910390f35b3480156105d857600080fd5b506105e161104a565b604080516001600160a01b039092168252519081900360200190f35b34801561060957600080fd5b506105e1611062565b34801561061e57600080fd5b5061051061107a565b34801561063357600080fd5b50610510611080565b34801561064857600080fd5b50610510611088565b34801561065d57600080fd5b5061051061108e565b34801561067257600080fd5b50610510611097565b34801561068757600080fd5b506105e16110a0565b34801561069c57600080fd5b506105106110b8565b3480156106b157600080fd5b506105106110c1565b3480156106c657600080fd5b506105106110ca565b3480156106db57600080fd5b506105106110d2565b3480156106f057600080fd5b506105e16110d7565b34801561070557600080fd5b506105e16110ef565b34801561071a57600080fd5b50610510611107565b34801561072f57600080fd5b506105e161110c565b34801561074457600080fd5b50610510611124565b34801561075957600080fd5b506105e161112d565b34801561076e57600080fd5b506105e1611145565b34801561078357600080fd5b506105e161115d565b34801561079857600080fd5b506105e1611175565b3480156107ad57600080fd5b506105e1600480360360208110156107c457600080fd5b50356001600160a01b031661118d565b3480156107e057600080fd5b506105e1611505565b3480156107f557600080fd5b506105e161151d565b34801561080a57600080fd5b506105e1611535565b34801561081f57600080fd5b50610510611544565b34801561083457600080fd5b50610510611549565b34801561084957600080fd5b50610510611551565b34801561085e57600080fd5b506105e1611556565b34801561087357600080fd5b506105e161156e565b34801561088857600080fd5b506105e1611586565b34801561089d57600080fd5b5061051061159e565b3480156108b257600080fd5b506105106115a4565b3480156108c757600080fd5b506105106115aa565b3480156108dc57600080fd5b506105106115af565b3480156108f157600080fd5b506105106115b9565b34801561090657600080fd5b506105106115c0565b34801561091b57600080fd5b506105e16115c7565b34801561093057600080fd5b506105106115d6565b34801561094557600080fd5b506105106115dd565b34801561095a57600080fd5b506105e16115e3565b34801561096f57600080fd5b506105106115f6565b34801561098457600080fd5b506105106115ff565b34801561099957600080fd5b50610510611604565b3480156109ae57600080fd5b506105e161160b565b3480156109c357600080fd5b506105e1611623565b3480156109d857600080fd5b506105e161163b565b3480156109ed57600080fd5b506105e1611653565b6104f9600480360360a0811015610a0c57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a4657600080fd5b820183602082011115610a5857600080fd5b803590602001918460208302840111600160201b83111715610a7957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061166b915050565b348015610ac557600080fd5b506105e1611ad6565b348015610ada57600080fd5b506105e1611aee565b348015610aef57600080fd5b50610510611b06565b348015610b0457600080fd5b506105e1611b0e565b348015610b1957600080fd5b506105e1611b26565b348015610b2e57600080fd5b50610510611b3e565b348015610b4357600080fd5b506105e1611b44565b348015610b5857600080fd5b506105e1611b5c565b348015610b6d57600080fd5b50610510611b74565b348015610b8257600080fd5b506105e1611b7c565b348015610b9757600080fd5b50610510611b8b565b348015610bac57600080fd5b50610510611b90565b348015610bc157600080fd5b50610510611b96565b348015610bd657600080fd5b506105e1611b9e565b348015610beb57600080fd5b50610510611bb6565b348015610c0057600080fd5b50610510611bbd565b348015610c1557600080fd5b50610510611bc4565b348015610c2a57600080fd5b506105e1611bc9565b348015610c3f57600080fd5b50610510611be1565b348015610c5457600080fd5b506105e1611be9565b348015610c6957600080fd5b506104f9600480360360a0811015610c8057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610cba57600080fd5b820183602082011115610ccc57600080fd5b803590602001918460208302840111600160201b83111715610ced57600080fd5b919350915035611c01565b348015610d0457600080fd5b50610510611c56565b348015610d1957600080fd5b506105e1611c5d565b348015610d2e57600080fd5b506105e1611c75565b348015610d4357600080fd5b50610510611c8d565b348015610d5857600080fd5b50610510611c93565b348015610d6d57600080fd5b506105e1611c9c565b348015610d8257600080fd5b506105e1611cb4565b6104f9600480360360c0811015610da157600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610de057600080fd5b820183602082011115610df257600080fd5b803590602001918460208302840111600160201b83111715610e1357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611ccc915050565b348015610e5f57600080fd5b50610510611dc7565b348015610e7457600080fd5b50610510611dcf565b348015610e8957600080fd5b506105e1611dd7565b348015610e9e57600080fd5b506105e1611def565b348015610eb357600080fd5b50610510611e07565b348015610ec857600080fd5b506105e1611e0c565b348015610edd57600080fd5b50610510611e24565b348015610ef257600080fd5b506105e1611e2c565b6220000081565b6002546040805163085e2c5b60e01b81526001600160a01b03888116600483015287811660248301526044820187905260648201869052608482018590529151600093606093169163085e2c5b9160a48083019287929190829003018186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610fab57600080fd5b815160208301805160405192949293830192919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b82518660208202830111600160201b8211171561100257600080fd5b82525081516020918201928201910280838360005b8381101561102f578181015183820152602001611017565b50505050905001604052505050915091509550959350505050565b7352ae12abe5d8bd778bd5397f99ca900624cfadd481565b73794e6e91555438afc3ccf1c5076a74f42133d08d81565b61200081565b630400000081565b61800081565b64400000000081565b64020000000081565b73a5407eae9ba41422680e2e00537571bcc53efbfd81565b64040000000081565b64800000000081565b600160201b81565b608081565b730316eb71485b0ab14103307bf65a021042c6d38081565b73dac17f958d2ee523a2206206994597c13d831ec781565b604081565b7379a8c46dea5ada233abaffd40f3a0a2b1e5a4f2781565b64100000000081565b734fabb145d64652a948d72533023f6e7a623c7c5381565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60006111a1826001600160a01b0316611e3b565b156111af5750600019611500565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b178152915181516000936060936001600160a01b0388169361138893919290918291908083835b6020831061121a5780518252601f1990920191602091820191016111fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461127b576040519150601f19603f3d011682016040523d82523d6000602084013e611280565b606091505b5091509150816112965760001992505050611500565b6000805b82518160060110156113ef578281600001815181106112b557fe5b6020910101516001600160f81b031916602360f91b1480156112f857508281600101815181106112e157fe5b6020910101516001600160f81b031916607560f81b145b8015611325575082816002018151811061130e57fe5b6020910101516001600160f81b031916601b60fa1b145b8015611352575082816003018151811061133b57fe5b6020910101516001600160f81b031916606360f81b145b801561137f575082816004018151811061136857fe5b6020910101516001600160f81b031916603960f91b145b80156113ac575082816005018151811061139557fe5b6020910101516001600160f81b031916607560f81b145b80156113d957508281600601815181106113c257fe5b6020910101516001600160f81b031916606d60f81b145b156113e757600191506113ef565b60010161129a565b5080611402576000199350505050611500565b60408051600481526024810182526020810180516001600160e01b031663797bf38560e01b178152915181516001600160a01b038916936113889392918291908083835b602083106114655780518252601f199092019160209182019101611446565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d80600081146114c6576040519150601f19603f3d011682016040523d82523d6000602084013e6114cb565b606091505b509093509150826114e3576000199350505050611500565b8180602001905160208110156114f857600080fd5b505193505050505b919050565b731f573d6fb3f13d689ff844b4ce37794d79a7ff1c81565b7345f783cce6b7ff23b2ab2d70e416cdb7d6055f5181565b6003546001600160a01b031681565b601081565b631e00000081565b602081565b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b73a2b47e3d5c44877cca798226b7b8118f9bfb7a5681565b738e870d67f660d95d5be530380d0ec0bd388289e181565b61400081565b61080081565b600881565b6501000000000081565b6202000081565b6210000081565b6001546001600160a01b031681565b6208000081565b61040081565b6e085d4780b73119b644ae5ecd22b37681565b64200000000081565b600281565b6240000081565b73398ec7346dcd622edc5ae82352f02be94c62d11981565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce31581565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b73eb4c2781e4eba804ce9a9803c67d0893436bb27d81565b61167e816280000063ffffffff611e7516565b1561169382634000000063ffffffff611e7516565b151415611ac2576116a2614853565b6116aa611e7b565b905060005b600281101561187d578181600281106116c457fe5b60200201516001600160a01b0316876001600160a01b031614156118755760008282600281106116f057fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172d57600080fd5b505afa158015611741573d6000803e3d6000fd5b505050506040513d602081101561175757600080fd5b50519050600083836002811061176957fe5b60200201516001600160a01b031663c85c93aa88600160006040519080825280602002602001820160405280156117aa578160200160208202803883390190505b506040518463ffffffff1660e01b8152600401808481526020018315151515815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561180a5781810151838201526020016117f2565b50505050905001945050505050602060405180830381600087803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b505050506040513d602081101561185b57600080fd5b5051905061186c828983898961166b565b50505050611acf565b6001016116af565b5060005b6002811015611abf5781816002811061189657fe5b60200201516001600160a01b0316866001600160a01b03161415611ab75760008282600281106118c257fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118ff57600080fd5b505afa158015611913573d6000803e3d6000fd5b505050506040513d602081101561192957600080fd5b5051905061193a8882888888611ec2565b6119548184846002811061194a57fe5b6020020151611ecf565b82826002811061196057fe5b60200201516001600160a01b0316633cfcef64826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156119c957600080fd5b505afa1580156119dd573d6000803e3d6000fd5b505050506040513d60208110156119f357600080fd5b50516040805160008082526020820190925290506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015611a5c578181015183820152602001611a44565b505050509050019350505050602060405180830381600087803b158015611a8257600080fd5b505af1158015611a96573d6000803e3d6000fd5b505050506040513d6020811015611aac57600080fd5b50611acf9350505050565b600101611881565b50505b611acf8585858585611ec2565b5050505050565b7303ef3f37856bd08eb47e2de7abc4ddd2c19b60f281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b634000000081565b737079e8517594e5b21d2b9a0d17cb33f5fe2bca7081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61100081565b7306364f10b501e868329afbc005b3492902d6c76381565b7306af07097c9eeb7fd685c692751d5c66db49c21581565b630800000081565b6000546001600160a01b031681565b600181565b61020081565b638000000081565b7357ab1ec28d129707052df4df418d58a2d46d5f5181565b6280000081565b6204000081565b601681565b739726e9314ef1b96e45f40056bed61a088897313e81565b630200000081565b7352ea46506b9cc5ef470c5bf89f17dc28bb35d85c81565b333014611c0d57600080fd5b611c4e868686868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250611ec2915050565b505050505050565b6201000081565b73f6e2d7f616b67e46d708e4410746e9aab3a4c51881565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b61010081565b64080000000081565b7393054188d876f558f4a66b2ef1d97d16edf0895b81565b731bbe271d15bb64df0bc6cd28df9ff322f2ebd84781565b611ce76001600160a01b03871633308763ffffffff611f8816565b6000611d026001600160a01b0388163063ffffffff6120a716565b9050611d118787838686612151565b6000611d2c6001600160a01b0388163063ffffffff6120a716565b905084811015611d6d5760405162461bcd60e51b81526004018080602001828103825260358152602001806148af6035913960400191505060405180910390fd5b611d876001600160a01b038816338363ffffffff61215e16565b50611dbc33611da56001600160a01b038b163063ffffffff6120a716565b6001600160a01b038b16919063ffffffff61215e16565b505050505050505050565b631000000081565b632000000081565b73a8253a440be331dc4a7395b73948cca6f19dc97d81565b736b175474e89094c44da98b954eedeac495271d0f81565b600481565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b630100000081565b6002546001600160a01b031681565b60006001600160a01b0382161580611e6f57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b16151590565b611e83614853565b50604080518082019091527310ec0d497824e342bcb0edce00959142aaa766dd815273eb66acc3d011056b00ea521f8203580c2e5d3991602082015290565b611acf85858585856121dc565b611ee1826001600160a01b0316611e3b565b611f845760408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915160ff9285169163dd62ed3e916044808301926020929190829003018186803b158015611f3657600080fd5b505afa158015611f4a573d6000803e3d6000fd5b505050506040513d6020811015611f6057600080fd5b5051901c611f8457611f846001600160a01b0383168260001963ffffffff6125dc16565b5050565b80611f92576120a1565b611f9b84611e3b565b15612086576001600160a01b03831633148015611fb85750803410155b611ff35760405162461bcd60e51b815260040180806020018281038252602b8152602001806148e4602b913960400191505060405180910390fd5b6001600160a01b038216301461203b576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612039573d6000803e3d6000fd5b505b8034111561208157336108fc612057348463ffffffff6126b216565b6040518115909202916000818181858888f1935050505015801561207f573d6000803e3d6000fd5b505b6120a1565b6120a16001600160a01b03851684848463ffffffff6126f416565b50505050565b60006120b283611e3b565b156120c857506001600160a01b03811631611e6f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561211e57600080fd5b505afa158015612132573d6000803e3d6000fd5b505050506040513d602081101561214857600080fd5b50519050611e6f565b611acf858585858561274e565b60008161216d575060016121d5565b61217684611e3b565b156121b7576040516001600160a01b0384169083156108fc029084906000818181858888f193505050501580156121b1573d6000803e3d6000fd5b506121d5565b6121d16001600160a01b038516848463ffffffff612a9716565b5060015b9392505050565b836001600160a01b0316856001600160a01b031614156121fb57611acf565b61220d8161080063ffffffff611e7516565b151561222382634000000063ffffffff611e7516565b151514156125cf57612233614871565b61223b612ae9565b905060005b600d8110156123f8578181600d811061225557fe5b60200201516001600160a01b0316876001600160a01b031614156123f05760008282600d811061228157fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122be57600080fd5b505afa1580156122d2573d6000803e3d6000fd5b505050506040513d60208110156122e857600080fd5b505190508282600d81106122f857fe5b60200201516001600160a01b0316632e1a7d4d876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561234257600080fd5b505af1158015612356573d6000803e3d6000fd5b505050506123e88188836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123b557600080fd5b505afa1580156123c9573d6000803e3d6000fd5b505050506040513d60208110156123df57600080fd5b505188886121dc565b505050611acf565b600101612240565b5060005b600d8110156125cc578181600d811061241157fe5b60200201516001600160a01b0316866001600160a01b031614156125c45760008282600d811061243d57fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561247a57600080fd5b505afa15801561248e573d6000803e3d6000fd5b505050506040513d60208110156124a457600080fd5b505190506124b58882888888612c56565b6124c5818484600d811061194a57fe5b8282600d81106124d157fe5b60200201516001600160a01b031663b6b55f25826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561253a57600080fd5b505afa15801561254e573d6000803e3d6000fd5b505050506040513d602081101561256457600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156125a457600080fd5b505af11580156125b8573d6000803e3d6000fd5b50505050505050611acf565b6001016123fc565b50505b611acf8585858585612c56565b6125e583611e3b565b6126ad57600081118015612673575060408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b15801561264557600080fd5b505afa158015612659573d6000803e3d6000fd5b505050506040513d602081101561266f57600080fd5b5051115b15612693576126936001600160a01b03841683600063ffffffff612c6316565b6126ad6001600160a01b038416838363ffffffff612c6316565b505050565b60006121d583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d76565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526120a1908590612e0d565b836001600160a01b0316856001600160a01b0316141561276d57611acf565b612780816208000063ffffffff611e7516565b151561279682634000000063ffffffff611e7516565b15151415612a8a576001600160a01b03851673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156128c457604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b15801561281c57600080fd5b505afa158015612830573d6000803e3d6000fd5b505050506040513d602081101561284657600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561288657600080fd5b505af115801561289a573d6000803e3d6000fd5b505050506128bf73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858585612fc5565b611acf565b6001600160a01b03851673c0829421c1d260bd3cb3e0f06cfe2d52db2ce315141561294257604080516370a0823160e01b8152306004820152905173c0829421c1d260bd3cb3e0f06cfe2d52db2ce31591632e1a7d4d9183916370a08231916024808301926020929190829003018186803b15801561281c57600080fd5b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156129f5576129888573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858561274e565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156129d757600080fd5b505af11580156129eb573d6000803e3d6000fd5b5050505050611acf565b6001600160a01b03841673c0829421c1d260bd3cb3e0f06cfe2d52db2ce3151415612a8a57612a3b8573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858561274e565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3156001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156129d757600080fd5b611acf8585858585612fc5565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526126ad908490612e0d565b612af1614871565b50604080516101a0810182527316de59092dae5ccf4a1e6439d611fd0653f0bd0181527304aa51bbcb46541455ccf1b8bef2ebc5d3787ec960208201527373a052500105205d34daf004eab301916da8190f918101919091527383f798e925bcd4017eb265844fddabb448f1707d606082015273d6ad7a6750a7593e092a9b218d66c0a814a3436e608082015273f61718057901f84c4eec4339ef8f0d86d2b4560060a08201527304bc0ab673d88ae9dbc9da2380cb6b79c4bca9ae60c082015273c2cb1040220768554cf699b0d863a3cd4324ce3260e082015273e6354ed5bc4b393a5aad09f21c46e101e692d4476101008201527326ea744e5b887e5205727f55dfbe8685e3b219516101208201527399d1fa417f94dcd62bfe781a1213c092a47041bc610140820152739777d7e2b60bb01759d0e2f8be2095df444cb07e610160820152731be5d71f2da660bfdee8012ddc58d024448a0a5961018082015290565b611acf8585858585612fd2565b801580612ce9575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d6020811015612ce557600080fd5b5051155b612d245760405162461bcd60e51b81526004018080602001828103825260368152602001806149676036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526126ad908490612e0d565b60008184841115612e055760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612dca578181015183820152602001612db2565b50505050905090810190601f168015612df75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b612e1f826001600160a01b0316613233565b612e70576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612eae5780518252601f199092019160209182019101612e8f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612f10576040519150601f19603f3d011682016040523d82523d6000602084013e612f15565b606091505b509150915081612f6c576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156120a157808060200190516020811015612f8857600080fd5b50516120a15760405162461bcd60e51b815260040180806020018281038252602a81526020018061493d602a913960400191505060405180910390fd5b611acf858585858561166b565b836001600160a01b0316856001600160a01b03161415612ff157611acf565b61300281601063ffffffff611e7516565b151561301882634000000063ffffffff611e7516565b1515141561322657600061302b8661326f565b90506001600160a01b03808216146130e157856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561308357600080fd5b505af1158015613097573d6000803e3d6000fd5b505050506040513d60208110156130ad57600080fd5b50600090506130cb6001600160a01b0383163063ffffffff6120a716565b90506130da8287838787612fd2565b5050611acf565b6130ea8561326f565b90506001600160a01b0380821614613224576131098682868686613467565b60006131246001600160a01b0383163063ffffffff6120a716565b9050613138826001600160a01b0316611e3b565b156131aa57734ddc2d193948926d02f9b1fe9e1daa0718270ed56001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561318c57600080fd5b505af11580156131a0573d6000803e3d6000fd5b50505050506130da565b6131b48287611ecf565b856001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156131fa57600080fd5b505af115801561320e573d6000803e3d6000fd5b505050506040513d602081101561186c57600080fd5b505b611acf8585858585613467565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061326757508115155b949350505050565b60006001600160a01b038216734ddc2d193948926d02f9b1fe9e1daa0718270ed5141561329e57506000611500565b6001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314156132de5750736b175474e89094c44da98b954eedeac495271d0f611500565b6001600160a01b038216736c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e141561331e5750730d8775f648430679a709e98d2b0cb6250d2887ef611500565b6001600160a01b03821673158079ee67fce2f58472a96584a73c7ab9ac95c1141561335e5750731985365e9f78359a9b6ad760e32412f4a445e862611500565b6001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e7563141561339e575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611500565b6001600160a01b03821673c11b1268c1a384e55c48c2391d8d480264a3a7f414156133de5750732260fac5e5542a773aa44fbcfedf7c193bc2c599611500565b6001600160a01b03821673b3319f5d18bc0d84dd1b4825dcde5d5f7266d407141561341e575073e41d2489571d322189246dafa5ebde1f4699f498611500565b6001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc9141561345e575073dac17f958d2ee523a2206206994597c13d831ec7611500565b50600019919050565b611acf8585858585836001600160a01b0316856001600160a01b0316141561348e57611acf565b61349f81602063ffffffff611e7516565b15156134b582634000000063ffffffff611e7516565b1515141561374c5760006134c88661118d565b90506001600160a01b0380821614613618576134ec816001600160a01b0316611e3b565b15613572576040805163081a6b2560e41b81523060048201526024810186905290516001600160a01b038816916381a6b2509160448083019260209291908290030181600087803b15801561354057600080fd5b505af1158015613554573d6000803e3d6000fd5b505050506040513d602081101561356a57600080fd5b506135ee9050565b60408051632770a7eb60e21b81523060048201526024810186905290516001600160a01b03881691639dc29fac9160448083019260209291908290030181600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050506040513d60208110156135eb57600080fd5b50505b60006136096001600160a01b0383163063ffffffff6120a716565b90506130da8287838787613755565b6136218561118d565b90506001600160a01b038082161461374a576136408682868686613755565b600061365b6001600160a01b0383163063ffffffff6120a716565b905061366f826001600160a01b0316611e3b565b156136f15760408051638f6ede1f60e01b815230600482015290516001600160a01b03881691638f6ede1f91849160248082019260209290919082900301818588803b1580156136be57600080fd5b505af11580156136d2573d6000803e3d6000fd5b50505050506040513d60208110156136e957600080fd5b506130da9050565b6136fb8287611ecf565b604080516340c10f1960e01b81523060048201526024810183905290516001600160a01b038816916340c10f199160448083019260209291908290030181600087803b1580156131fa57600080fd5b505b611acf85858585855b611acf85858585855b836001600160a01b0316856001600160a01b0316141561377d57611acf565b61378e81608063ffffffff611e7516565b15156137a482634000000063ffffffff611e7516565b151514156139c35760006137b7866139d0565b90506001600160a01b038082161461383a57856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561380f57600080fd5b505af1158015613823573d6000803e3d6000fd5b50505050613834818686868661375e565b50611acf565b613843856139d0565b90506001600160a01b03808216146139c1576138628682868686613dfa565b600061387d6001600160a01b0383163063ffffffff6120a716565b90506139018273398ec7346dcd622edc5ae82352f02be94c62d1196001600160a01b031663f2f4eb266040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d057600080fd5b505afa1580156138e4573d6000803e3d6000fd5b505050506040513d60208110156138fa57600080fd5b5051611ecf565b73398ec7346dcd622edc5ae82352f02be94c62d11963d2d0e06661392d6001600160a01b038516611e3b565b61393857600061393a565b825b61394c856001600160a01b0316611e3b565b613956578461396c565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301526024820186905261044d604483015251606480830192600092919082900301818588803b1580156125a457600080fd5b505b611acf8585858585613dfa565b60006001600160a01b038216733a3a65aab0dd2a17e3f1947ba16138cd37d08c0414156139ff57506000611500565b6001600160a01b03821673fc1e690f61efd961294b3e1ce3313fbd8aa4f85d1415613a3f5750736b175474e89094c44da98b954eedeac495271d0f611500565b6001600160a01b038216739ba00d6856a4edf4665bca2c2309936572473b7e1415613a7f575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611500565b6001600160a01b03821673625ae63000f46200499120b906716420bd0592401415613abf57507357ab1ec28d129707052df4df418d58a2d46d5f51611500565b6001600160a01b038216736ee0f7bb50a54ab5253da0667b0dc2ee526c30a81415613aff5750734fabb145d64652a948d72533023f6e7a623c7c53611500565b6001600160a01b038216734da9b813057d04baef4e5800e36083717b4a03411415613b3a57506e085d4780b73119b644ae5ecd22b376611500565b6001600160a01b0382167371fc860f7d3a592a4a98740e39db31d25db65ae81415613b7a575073dac17f958d2ee523a2206206994597c13d831ec7611500565b6001600160a01b03821673e1ba0fb44ccb0d11b80f92f4f8ed94ca3ff51d001415613bba5750730d8775f648430679a709e98d2b0cb6250d2887ef611500565b6001600160a01b038216739d91be44c06d373a8a226e1f3b146956083803eb1415613bfa575073dd974d5c2e2928dea5f71b9825b8b646686bd200611500565b6001600160a01b038216737d2d3688df45ce7c552e19c27e007673da9204b81415613c3a57507380fb784b7ed66730e8b1dbd9820afd29931aab03611500565b6001600160a01b03821673a64bd6c70cb9051f6a9ba1f163fdc07e0dfb5f841415613c7a575073514910771af9ca656af840dff83e8264ecf986ca611500565b6001600160a01b038216736fce4a401b6b80ace52baaefe4421bd188e76f6f1415613cba5750730f5d2fb29fb7d3cfee444a200298f468908cc942611500565b6001600160a01b038216737deb5e830be29f91e298ba5ff1356bb7f81469981415613cfa5750739f8f72aa9304c8b593d555f12ef6589cc3a579a2611500565b6001600160a01b0382167371010a9d003445ac60c4e6a7017c1e89a477b4381415613d3a5750731985365e9f78359a9b6ad760e32412f4a445e862611500565b6001600160a01b03821673328c4c80bc7aca0834db37e6600a6c49e12da4de1415613d7a575073c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f611500565b6001600160a01b03821673fc4b8ed459e00e5400be803a9bb3954234fd50e31415613dba5750732260fac5e5542a773aa44fbcfedf7c193bc2c599611500565b6001600160a01b038216736fb0855c404e09c47c3fbca25f08d4e41f9f062f141561345e575073e41d2489571d322189246dafa5ebde1f4699f498611500565b836001600160a01b0316856001600160a01b03161415613e1957611acf565b613e2b8161040063ffffffff611e7516565b1515613e4182634000000063ffffffff611e7516565b151514156140e6576000546001600160a01b0386811691161415613f9f576000805460408051637f8661a160e01b81526004810187905290516001600160a01b0390921692637f8661a19260248084019382900301818387803b158015613ea757600080fd5b505af1158015613ebb573d6000803e3d6000fd5b5050600154604080516370a0823160e01b81523060048201529051600094506001600160a01b0390921692506370a08231916024808301926020929190829003018186803b158015613f0c57600080fd5b505afa158015613f20573d6000803e3d6000fd5b505050506040513d6020811015613f3657600080fd5b505190508015613f7e5760018054606091613f5f916001600160a01b0316908890859087610f02565b600154909250613f7c91506001600160a01b031687848487612151565b505b613834736b175474e89094c44da98b954eedeac495271d0f868686866140ef565b6000546001600160a01b03858116911614156140e657613fd685736b175474e89094c44da98b954eedeac495271d0f8585856140ef565b60005461400190736b175474e89094c44da98b954eedeac495271d0f906001600160a01b0316611ecf565b600054604080516370a0823160e01b815230600482015290516001600160a01b039092169163049878f391736b175474e89094c44da98b954eedeac495271d0f916370a0823191602480820192602092909190829003018186803b15801561406857600080fd5b505afa15801561407c573d6000803e3d6000fd5b505050506040513d602081101561409257600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156140d257600080fd5b505af115801561186c573d6000803e3d6000fd5b611acf85858585855b836001600160a01b0316856001600160a01b0316141561410e57611acf565b61411f81604063ffffffff611e7516565b151561413582634000000063ffffffff611e7516565b151514156143c3576001600160a01b0385167306af07097c9eeb7fd685c692751d5c66db49c2151415614260576040805163ef693bed60e01b81523060048201526024810185905290517306af07097c9eeb7fd685c692751d5c66db49c2159163ef693bed91604480830192600092919082900301818387803b1580156141bb57600080fd5b505af11580156141cf573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516128bf9350736b175474e89094c44da98b954eedeac495271d0f9250879183916370a0823191602480820192602092909190829003018186803b15801561422d57600080fd5b505afa158015614241573d6000803e3d6000fd5b505050506040513d602081101561425757600080fd5b505185856143cc565b6001600160a01b0384167306af07097c9eeb7fd685c692751d5c66db49c21514156143c3576142a685736b175474e89094c44da98b954eedeac495271d0f8585856143cc565b6142d8736b175474e89094c44da98b954eedeac495271d0f7306af07097c9eeb7fd685c692751d5c66db49c215611ecf565b604080516370a0823160e01b8152306004820181905291517306af07097c9eeb7fd685c692751d5c66db49c21592633b4da69f929091736b175474e89094c44da98b954eedeac495271d0f916370a08231916024808301926020929190829003018186803b15801561434957600080fd5b505afa15801561435d573d6000803e3d6000fd5b505050506040513d602081101561437357600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152602483019190915251604480830192600092919082900301818387803b1580156140d257600080fd5b611acf85858585855b60006143d7826144e1565b90506001600160a01b038116156144d45760608351604051908082528060200260200182016040528015614415578160200160208202803883390190505b50905060005b845181101561445a5784818151811061443057fe5b602002602001015160ff1682828151811061444757fe5b602090810291909101015260010161441b565b5061446887838784876146a0565b60005b84518110156144ae57600885828151811061448257fe5b6020026020010151901c60ff1682828151811061449b57fe5b602090810291909101015260010161446b565b506130da82876144cd6001600160a01b0383163063ffffffff6120a716565b84876146a0565b611c4e86868686866146a0565b60006144eb614890565b6040518060e0016040528061020081526020016201000081526020016202000081526020016404000000008152602001640800000000815260200164100000000081526020016420000000008152509050614544614890565b506040805160e08101825273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8152736b175474e89094c44da98b954eedeac495271d0f602082015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489181019190915273dac17f958d2ee523a2206206994597c13d831ec76060820152732260fac5e5542a773aa44fbcfedf7c193bc2c5996080820152731bbe271d15bb64df0bc6cd28df9ff322f2ebd84760a082015273eb4c2781e4eba804ce9a9803c67d0893436bb27d60c082015260005b60078110156146985761463183826007811061461f57fe5b6020020151869063ffffffff611e7516565b15614690576001600160a01b0384161561467c5760405162461bcd60e51b815260040180806020018281038252602e81526020018061490f602e913960400191505060405180910390fd5b81816007811061468857fe5b602002015193505b600101614607565b505050919050565b836001600160a01b0316856001600160a01b031614156146bf57611acf565b611acf85858585856003546040516001600160a01b038781166024830190815287821660448401526064830187905260006084840181905260c4840186905260c060a48501908152875160e486015287519195606095941693637153a8af60e11b938c938c938c938a938d938d9391926101040190602080870191028083838a5b83811015614758578181015183820152602001614740565b50505050905001975050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518082805190602001908083835b602083106147ca5780518252601f1990920191602091820191016147ab565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461482a576040519150601f19603f3d011682016040523d82523d6000602084013e61482f565b606091505b5091509150816000811461484257614849565b3d60208301fd5b5050505050505050565b60405180604001604052806002906020820280388339509192915050565b604051806101a00160405280600d906020820280388339509192915050565b6040518060e00160405280600790602082028038833950919291505056fe4f6e6553706c69743a2061637475616c2072657475726e20616d6f756e74206973206c657373207468616e206d696e52657475726e57726f6e6720757365616765206f66204554482e756e6976657273616c5472616e7366657246726f6d28294f6e6553706c69743a20446f206e6f7420757365206d756c74697061746820776974682065616368206f746865725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a72315820c4c342bbe296ca3f12452c3cbe38ff8890a1ac3feae34e965c8aaeae89cc8c9564736f6c63430005110032000000000000000000000000148f173e363f34755f4f97a13ab53b8b76ee05000000000000000000000000003a2d9db352580eb50018fc86eae32e19070a9982
Deployed Bytecode
0x6080604052600436106104ec5760003560e01c80637a88bdbd1161028c578063c9b42c671161015a578063df1b4e99116100cc578063f11d2ff411610085578063f11d2ff414610e7d578063f4b9fa7514610e92578063f56e281f14610ea7578063f69e204614610ebc578063fa3f110b14610ed1578063fbe4ed9514610ee6576104ec565b8063df1b4e9914610d4c578063e0de8f2214610d61578063e1308b3314610d76578063e2a7515e14610d8b578063e355812314610e53578063e44987b414610e68576104ec565b8063d1ae60631161011e578063d1ae606314610c5d578063d393c3e914610cf8578063d70a2d1f14610d0d578063d77366a414610d22578063dc1536b214610d37578063ddd2f8d014610666576104ec565b8063c9b42c6714610bf4578063cc26e9fc14610c09578063cd240d7514610c1e578063ce74b7ac14610c33578063cede5f6a14610c48576104ec565b8063a734f06e116101fe578063c11f4f11116101b7578063c11f4f1114610b76578063c762a46c14610b8b578063c77b9de614610ba0578063c7f112e414610bb5578063c925777514610bca578063c989b66714610bdf576104ec565b8063a734f06e14610b0d578063b0a7ef2914610b22578063b184a3ae14610b37578063b3bc784414610690578063b69d045614610b4c578063bf2c5a0714610b61576104ec565b8063903548721161025057806390354872146109e1578063944a32e2146109f6578063960d2c1914610ab9578063a1b4d01114610ace578063a2878cb114610ae3578063a4792ab314610af8576104ec565b80637a88bdbd146109785780637e09b9c21461098d578063819faf7b146109a2578063851954fa146109b75780638bdb2afa146109cc576104ec565b80633fc8cef3116103c95780635aa8fb481161033b5780636b5a4ca2116102f45780636b5a4ca21461090f5780636cbc4a6e1461092457806375a8b0121461093957806375b5be2d1461094e57806376c3972614610963578063792e69d7146106ba576104ec565b80635aa8fb48146108915780635ae51b82146108a65780635c0cb479146108bb578063646c4ec4146108d057806364ec4e5c146108e557806368e2a014146108fa576104ec565b806344211d621161038d57806344211d62146108135780634752c680146108285780634a7101d51461083d5780635187c0911461085257806351f1985c1461086757806352a701b41461087c576104ec565b80633fc8cef31461078c5780634037f967146107a157806340ab7b8c146107d4578063423d03f9146107e957806343ee21f0146107fe576104ec565b80632ceb90b81161046257806334b4dabb1161042657806334b4dabb1461070e578063372a26cb14610723578063376e55b7146107385780633ca5b2341461074d5780633cdc5389146107625780633e413bee14610777576104ec565b80632ceb90b8146106a55780632d3b5207146106ba5780632e707bd2146106cf5780632f0fe755146106e45780632f48ab7d146106f9576104ec565b80631d209b65116104b45780631d209b65146106275780632113240d1461063c57806321899d3a1461065157806321a360f51461066657806322320c981461067b57806327a7fbd514610690576104ec565b806305d8aa0a146104fb578063085e2c5b1461052257806312dea160146105cc5780631388b420146105fd5780631398914014610612575b333214156104f957600080fd5b005b34801561050757600080fd5b50610510610efb565b60408051918252519081900360200190f35b34801561052e57600080fd5b50610571600480360360a081101561054557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135610f02565b6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156105b757818101518382015260200161059f565b50505050905001935050505060405180910390f35b3480156105d857600080fd5b506105e161104a565b604080516001600160a01b039092168252519081900360200190f35b34801561060957600080fd5b506105e1611062565b34801561061e57600080fd5b5061051061107a565b34801561063357600080fd5b50610510611080565b34801561064857600080fd5b50610510611088565b34801561065d57600080fd5b5061051061108e565b34801561067257600080fd5b50610510611097565b34801561068757600080fd5b506105e16110a0565b34801561069c57600080fd5b506105106110b8565b3480156106b157600080fd5b506105106110c1565b3480156106c657600080fd5b506105106110ca565b3480156106db57600080fd5b506105106110d2565b3480156106f057600080fd5b506105e16110d7565b34801561070557600080fd5b506105e16110ef565b34801561071a57600080fd5b50610510611107565b34801561072f57600080fd5b506105e161110c565b34801561074457600080fd5b50610510611124565b34801561075957600080fd5b506105e161112d565b34801561076e57600080fd5b506105e1611145565b34801561078357600080fd5b506105e161115d565b34801561079857600080fd5b506105e1611175565b3480156107ad57600080fd5b506105e1600480360360208110156107c457600080fd5b50356001600160a01b031661118d565b3480156107e057600080fd5b506105e1611505565b3480156107f557600080fd5b506105e161151d565b34801561080a57600080fd5b506105e1611535565b34801561081f57600080fd5b50610510611544565b34801561083457600080fd5b50610510611549565b34801561084957600080fd5b50610510611551565b34801561085e57600080fd5b506105e1611556565b34801561087357600080fd5b506105e161156e565b34801561088857600080fd5b506105e1611586565b34801561089d57600080fd5b5061051061159e565b3480156108b257600080fd5b506105106115a4565b3480156108c757600080fd5b506105106115aa565b3480156108dc57600080fd5b506105106115af565b3480156108f157600080fd5b506105106115b9565b34801561090657600080fd5b506105106115c0565b34801561091b57600080fd5b506105e16115c7565b34801561093057600080fd5b506105106115d6565b34801561094557600080fd5b506105106115dd565b34801561095a57600080fd5b506105e16115e3565b34801561096f57600080fd5b506105106115f6565b34801561098457600080fd5b506105106115ff565b34801561099957600080fd5b50610510611604565b3480156109ae57600080fd5b506105e161160b565b3480156109c357600080fd5b506105e1611623565b3480156109d857600080fd5b506105e161163b565b3480156109ed57600080fd5b506105e1611653565b6104f9600480360360a0811015610a0c57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a4657600080fd5b820183602082011115610a5857600080fd5b803590602001918460208302840111600160201b83111715610a7957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061166b915050565b348015610ac557600080fd5b506105e1611ad6565b348015610ada57600080fd5b506105e1611aee565b348015610aef57600080fd5b50610510611b06565b348015610b0457600080fd5b506105e1611b0e565b348015610b1957600080fd5b506105e1611b26565b348015610b2e57600080fd5b50610510611b3e565b348015610b4357600080fd5b506105e1611b44565b348015610b5857600080fd5b506105e1611b5c565b348015610b6d57600080fd5b50610510611b74565b348015610b8257600080fd5b506105e1611b7c565b348015610b9757600080fd5b50610510611b8b565b348015610bac57600080fd5b50610510611b90565b348015610bc157600080fd5b50610510611b96565b348015610bd657600080fd5b506105e1611b9e565b348015610beb57600080fd5b50610510611bb6565b348015610c0057600080fd5b50610510611bbd565b348015610c1557600080fd5b50610510611bc4565b348015610c2a57600080fd5b506105e1611bc9565b348015610c3f57600080fd5b50610510611be1565b348015610c5457600080fd5b506105e1611be9565b348015610c6957600080fd5b506104f9600480360360a0811015610c8057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610cba57600080fd5b820183602082011115610ccc57600080fd5b803590602001918460208302840111600160201b83111715610ced57600080fd5b919350915035611c01565b348015610d0457600080fd5b50610510611c56565b348015610d1957600080fd5b506105e1611c5d565b348015610d2e57600080fd5b506105e1611c75565b348015610d4357600080fd5b50610510611c8d565b348015610d5857600080fd5b50610510611c93565b348015610d6d57600080fd5b506105e1611c9c565b348015610d8257600080fd5b506105e1611cb4565b6104f9600480360360c0811015610da157600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610de057600080fd5b820183602082011115610df257600080fd5b803590602001918460208302840111600160201b83111715610e1357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611ccc915050565b348015610e5f57600080fd5b50610510611dc7565b348015610e7457600080fd5b50610510611dcf565b348015610e8957600080fd5b506105e1611dd7565b348015610e9e57600080fd5b506105e1611def565b348015610eb357600080fd5b50610510611e07565b348015610ec857600080fd5b506105e1611e0c565b348015610edd57600080fd5b50610510611e24565b348015610ef257600080fd5b506105e1611e2c565b6220000081565b6002546040805163085e2c5b60e01b81526001600160a01b03888116600483015287811660248301526044820187905260648201869052608482018590529151600093606093169163085e2c5b9160a48083019287929190829003018186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015610fab57600080fd5b815160208301805160405192949293830192919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b82518660208202830111600160201b8211171561100257600080fd5b82525081516020918201928201910280838360005b8381101561102f578181015183820152602001611017565b50505050905001604052505050915091509550959350505050565b7352ae12abe5d8bd778bd5397f99ca900624cfadd481565b73794e6e91555438afc3ccf1c5076a74f42133d08d81565b61200081565b630400000081565b61800081565b64400000000081565b64020000000081565b73a5407eae9ba41422680e2e00537571bcc53efbfd81565b64040000000081565b64800000000081565b600160201b81565b608081565b730316eb71485b0ab14103307bf65a021042c6d38081565b73dac17f958d2ee523a2206206994597c13d831ec781565b604081565b7379a8c46dea5ada233abaffd40f3a0a2b1e5a4f2781565b64100000000081565b734fabb145d64652a948d72533023f6e7a623c7c5381565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60006111a1826001600160a01b0316611e3b565b156111af5750600019611500565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b178152915181516000936060936001600160a01b0388169361138893919290918291908083835b6020831061121a5780518252601f1990920191602091820191016111fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d806000811461127b576040519150601f19603f3d011682016040523d82523d6000602084013e611280565b606091505b5091509150816112965760001992505050611500565b6000805b82518160060110156113ef578281600001815181106112b557fe5b6020910101516001600160f81b031916602360f91b1480156112f857508281600101815181106112e157fe5b6020910101516001600160f81b031916607560f81b145b8015611325575082816002018151811061130e57fe5b6020910101516001600160f81b031916601b60fa1b145b8015611352575082816003018151811061133b57fe5b6020910101516001600160f81b031916606360f81b145b801561137f575082816004018151811061136857fe5b6020910101516001600160f81b031916603960f91b145b80156113ac575082816005018151811061139557fe5b6020910101516001600160f81b031916607560f81b145b80156113d957508281600601815181106113c257fe5b6020910101516001600160f81b031916606d60f81b145b156113e757600191506113ef565b60010161129a565b5080611402576000199350505050611500565b60408051600481526024810182526020810180516001600160e01b031663797bf38560e01b178152915181516001600160a01b038916936113889392918291908083835b602083106114655780518252601f199092019160209182019101611446565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d80600081146114c6576040519150601f19603f3d011682016040523d82523d6000602084013e6114cb565b606091505b509093509150826114e3576000199350505050611500565b8180602001905160208110156114f857600080fd5b505193505050505b919050565b731f573d6fb3f13d689ff844b4ce37794d79a7ff1c81565b7345f783cce6b7ff23b2ab2d70e416cdb7d6055f5181565b6003546001600160a01b031681565b601081565b631e00000081565b602081565b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b73a2b47e3d5c44877cca798226b7b8118f9bfb7a5681565b738e870d67f660d95d5be530380d0ec0bd388289e181565b61400081565b61080081565b600881565b6501000000000081565b6202000081565b6210000081565b6001546001600160a01b031681565b6208000081565b61040081565b6e085d4780b73119b644ae5ecd22b37681565b64200000000081565b600281565b6240000081565b73398ec7346dcd622edc5ae82352f02be94c62d11981565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce31581565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b73eb4c2781e4eba804ce9a9803c67d0893436bb27d81565b61167e816280000063ffffffff611e7516565b1561169382634000000063ffffffff611e7516565b151415611ac2576116a2614853565b6116aa611e7b565b905060005b600281101561187d578181600281106116c457fe5b60200201516001600160a01b0316876001600160a01b031614156118755760008282600281106116f057fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172d57600080fd5b505afa158015611741573d6000803e3d6000fd5b505050506040513d602081101561175757600080fd5b50519050600083836002811061176957fe5b60200201516001600160a01b031663c85c93aa88600160006040519080825280602002602001820160405280156117aa578160200160208202803883390190505b506040518463ffffffff1660e01b8152600401808481526020018315151515815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561180a5781810151838201526020016117f2565b50505050905001945050505050602060405180830381600087803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b505050506040513d602081101561185b57600080fd5b5051905061186c828983898961166b565b50505050611acf565b6001016116af565b5060005b6002811015611abf5781816002811061189657fe5b60200201516001600160a01b0316866001600160a01b03161415611ab75760008282600281106118c257fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118ff57600080fd5b505afa158015611913573d6000803e3d6000fd5b505050506040513d602081101561192957600080fd5b5051905061193a8882888888611ec2565b6119548184846002811061194a57fe5b6020020151611ecf565b82826002811061196057fe5b60200201516001600160a01b0316633cfcef64826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156119c957600080fd5b505afa1580156119dd573d6000803e3d6000fd5b505050506040513d60208110156119f357600080fd5b50516040805160008082526020820190925290506040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015611a5c578181015183820152602001611a44565b505050509050019350505050602060405180830381600087803b158015611a8257600080fd5b505af1158015611a96573d6000803e3d6000fd5b505050506040513d6020811015611aac57600080fd5b50611acf9350505050565b600101611881565b50505b611acf8585858585611ec2565b5050505050565b7303ef3f37856bd08eb47e2de7abc4ddd2c19b60f281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b634000000081565b737079e8517594e5b21d2b9a0d17cb33f5fe2bca7081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61100081565b7306364f10b501e868329afbc005b3492902d6c76381565b7306af07097c9eeb7fd685c692751d5c66db49c21581565b630800000081565b6000546001600160a01b031681565b600181565b61020081565b638000000081565b7357ab1ec28d129707052df4df418d58a2d46d5f5181565b6280000081565b6204000081565b601681565b739726e9314ef1b96e45f40056bed61a088897313e81565b630200000081565b7352ea46506b9cc5ef470c5bf89f17dc28bb35d85c81565b333014611c0d57600080fd5b611c4e868686868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250611ec2915050565b505050505050565b6201000081565b73f6e2d7f616b67e46d708e4410746e9aab3a4c51881565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b61010081565b64080000000081565b7393054188d876f558f4a66b2ef1d97d16edf0895b81565b731bbe271d15bb64df0bc6cd28df9ff322f2ebd84781565b611ce76001600160a01b03871633308763ffffffff611f8816565b6000611d026001600160a01b0388163063ffffffff6120a716565b9050611d118787838686612151565b6000611d2c6001600160a01b0388163063ffffffff6120a716565b905084811015611d6d5760405162461bcd60e51b81526004018080602001828103825260358152602001806148af6035913960400191505060405180910390fd5b611d876001600160a01b038816338363ffffffff61215e16565b50611dbc33611da56001600160a01b038b163063ffffffff6120a716565b6001600160a01b038b16919063ffffffff61215e16565b505050505050505050565b631000000081565b632000000081565b73a8253a440be331dc4a7395b73948cca6f19dc97d81565b736b175474e89094c44da98b954eedeac495271d0f81565b600481565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b630100000081565b6002546001600160a01b031681565b60006001600160a01b0382161580611e6f57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b16151590565b611e83614853565b50604080518082019091527310ec0d497824e342bcb0edce00959142aaa766dd815273eb66acc3d011056b00ea521f8203580c2e5d3991602082015290565b611acf85858585856121dc565b611ee1826001600160a01b0316611e3b565b611f845760408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915160ff9285169163dd62ed3e916044808301926020929190829003018186803b158015611f3657600080fd5b505afa158015611f4a573d6000803e3d6000fd5b505050506040513d6020811015611f6057600080fd5b5051901c611f8457611f846001600160a01b0383168260001963ffffffff6125dc16565b5050565b80611f92576120a1565b611f9b84611e3b565b15612086576001600160a01b03831633148015611fb85750803410155b611ff35760405162461bcd60e51b815260040180806020018281038252602b8152602001806148e4602b913960400191505060405180910390fd5b6001600160a01b038216301461203b576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612039573d6000803e3d6000fd5b505b8034111561208157336108fc612057348463ffffffff6126b216565b6040518115909202916000818181858888f1935050505015801561207f573d6000803e3d6000fd5b505b6120a1565b6120a16001600160a01b03851684848463ffffffff6126f416565b50505050565b60006120b283611e3b565b156120c857506001600160a01b03811631611e6f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561211e57600080fd5b505afa158015612132573d6000803e3d6000fd5b505050506040513d602081101561214857600080fd5b50519050611e6f565b611acf858585858561274e565b60008161216d575060016121d5565b61217684611e3b565b156121b7576040516001600160a01b0384169083156108fc029084906000818181858888f193505050501580156121b1573d6000803e3d6000fd5b506121d5565b6121d16001600160a01b038516848463ffffffff612a9716565b5060015b9392505050565b836001600160a01b0316856001600160a01b031614156121fb57611acf565b61220d8161080063ffffffff611e7516565b151561222382634000000063ffffffff611e7516565b151514156125cf57612233614871565b61223b612ae9565b905060005b600d8110156123f8578181600d811061225557fe5b60200201516001600160a01b0316876001600160a01b031614156123f05760008282600d811061228157fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122be57600080fd5b505afa1580156122d2573d6000803e3d6000fd5b505050506040513d60208110156122e857600080fd5b505190508282600d81106122f857fe5b60200201516001600160a01b0316632e1a7d4d876040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561234257600080fd5b505af1158015612356573d6000803e3d6000fd5b505050506123e88188836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123b557600080fd5b505afa1580156123c9573d6000803e3d6000fd5b505050506040513d60208110156123df57600080fd5b505188886121dc565b505050611acf565b600101612240565b5060005b600d8110156125cc578181600d811061241157fe5b60200201516001600160a01b0316866001600160a01b031614156125c45760008282600d811061243d57fe5b60200201516001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561247a57600080fd5b505afa15801561248e573d6000803e3d6000fd5b505050506040513d60208110156124a457600080fd5b505190506124b58882888888612c56565b6124c5818484600d811061194a57fe5b8282600d81106124d157fe5b60200201516001600160a01b031663b6b55f25826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561253a57600080fd5b505afa15801561254e573d6000803e3d6000fd5b505050506040513d602081101561256457600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156125a457600080fd5b505af11580156125b8573d6000803e3d6000fd5b50505050505050611acf565b6001016123fc565b50505b611acf8585858585612c56565b6125e583611e3b565b6126ad57600081118015612673575060408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b15801561264557600080fd5b505afa158015612659573d6000803e3d6000fd5b505050506040513d602081101561266f57600080fd5b5051115b15612693576126936001600160a01b03841683600063ffffffff612c6316565b6126ad6001600160a01b038416838363ffffffff612c6316565b505050565b60006121d583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d76565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526120a1908590612e0d565b836001600160a01b0316856001600160a01b0316141561276d57611acf565b612780816208000063ffffffff611e7516565b151561279682634000000063ffffffff611e7516565b15151415612a8a576001600160a01b03851673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156128c457604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b15801561281c57600080fd5b505afa158015612830573d6000803e3d6000fd5b505050506040513d602081101561284657600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561288657600080fd5b505af115801561289a573d6000803e3d6000fd5b505050506128bf73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858585612fc5565b611acf565b6001600160a01b03851673c0829421c1d260bd3cb3e0f06cfe2d52db2ce315141561294257604080516370a0823160e01b8152306004820152905173c0829421c1d260bd3cb3e0f06cfe2d52db2ce31591632e1a7d4d9183916370a08231916024808301926020929190829003018186803b15801561281c57600080fd5b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156129f5576129888573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858561274e565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156129d757600080fd5b505af11580156129eb573d6000803e3d6000fd5b5050505050611acf565b6001600160a01b03841673c0829421c1d260bd3cb3e0f06cfe2d52db2ce3151415612a8a57612a3b8573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85858561274e565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3156001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156129d757600080fd5b611acf8585858585612fc5565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526126ad908490612e0d565b612af1614871565b50604080516101a0810182527316de59092dae5ccf4a1e6439d611fd0653f0bd0181527304aa51bbcb46541455ccf1b8bef2ebc5d3787ec960208201527373a052500105205d34daf004eab301916da8190f918101919091527383f798e925bcd4017eb265844fddabb448f1707d606082015273d6ad7a6750a7593e092a9b218d66c0a814a3436e608082015273f61718057901f84c4eec4339ef8f0d86d2b4560060a08201527304bc0ab673d88ae9dbc9da2380cb6b79c4bca9ae60c082015273c2cb1040220768554cf699b0d863a3cd4324ce3260e082015273e6354ed5bc4b393a5aad09f21c46e101e692d4476101008201527326ea744e5b887e5205727f55dfbe8685e3b219516101208201527399d1fa417f94dcd62bfe781a1213c092a47041bc610140820152739777d7e2b60bb01759d0e2f8be2095df444cb07e610160820152731be5d71f2da660bfdee8012ddc58d024448a0a5961018082015290565b611acf8585858585612fd2565b801580612ce9575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d6020811015612ce557600080fd5b5051155b612d245760405162461bcd60e51b81526004018080602001828103825260368152602001806149676036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526126ad908490612e0d565b60008184841115612e055760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612dca578181015183820152602001612db2565b50505050905090810190601f168015612df75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b612e1f826001600160a01b0316613233565b612e70576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612eae5780518252601f199092019160209182019101612e8f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612f10576040519150601f19603f3d011682016040523d82523d6000602084013e612f15565b606091505b509150915081612f6c576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156120a157808060200190516020811015612f8857600080fd5b50516120a15760405162461bcd60e51b815260040180806020018281038252602a81526020018061493d602a913960400191505060405180910390fd5b611acf858585858561166b565b836001600160a01b0316856001600160a01b03161415612ff157611acf565b61300281601063ffffffff611e7516565b151561301882634000000063ffffffff611e7516565b1515141561322657600061302b8661326f565b90506001600160a01b03808216146130e157856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561308357600080fd5b505af1158015613097573d6000803e3d6000fd5b505050506040513d60208110156130ad57600080fd5b50600090506130cb6001600160a01b0383163063ffffffff6120a716565b90506130da8287838787612fd2565b5050611acf565b6130ea8561326f565b90506001600160a01b0380821614613224576131098682868686613467565b60006131246001600160a01b0383163063ffffffff6120a716565b9050613138826001600160a01b0316611e3b565b156131aa57734ddc2d193948926d02f9b1fe9e1daa0718270ed56001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561318c57600080fd5b505af11580156131a0573d6000803e3d6000fd5b50505050506130da565b6131b48287611ecf565b856001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156131fa57600080fd5b505af115801561320e573d6000803e3d6000fd5b505050506040513d602081101561186c57600080fd5b505b611acf8585858585613467565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061326757508115155b949350505050565b60006001600160a01b038216734ddc2d193948926d02f9b1fe9e1daa0718270ed5141561329e57506000611500565b6001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314156132de5750736b175474e89094c44da98b954eedeac495271d0f611500565b6001600160a01b038216736c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e141561331e5750730d8775f648430679a709e98d2b0cb6250d2887ef611500565b6001600160a01b03821673158079ee67fce2f58472a96584a73c7ab9ac95c1141561335e5750731985365e9f78359a9b6ad760e32412f4a445e862611500565b6001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e7563141561339e575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611500565b6001600160a01b03821673c11b1268c1a384e55c48c2391d8d480264a3a7f414156133de5750732260fac5e5542a773aa44fbcfedf7c193bc2c599611500565b6001600160a01b03821673b3319f5d18bc0d84dd1b4825dcde5d5f7266d407141561341e575073e41d2489571d322189246dafa5ebde1f4699f498611500565b6001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc9141561345e575073dac17f958d2ee523a2206206994597c13d831ec7611500565b50600019919050565b611acf8585858585836001600160a01b0316856001600160a01b0316141561348e57611acf565b61349f81602063ffffffff611e7516565b15156134b582634000000063ffffffff611e7516565b1515141561374c5760006134c88661118d565b90506001600160a01b0380821614613618576134ec816001600160a01b0316611e3b565b15613572576040805163081a6b2560e41b81523060048201526024810186905290516001600160a01b038816916381a6b2509160448083019260209291908290030181600087803b15801561354057600080fd5b505af1158015613554573d6000803e3d6000fd5b505050506040513d602081101561356a57600080fd5b506135ee9050565b60408051632770a7eb60e21b81523060048201526024810186905290516001600160a01b03881691639dc29fac9160448083019260209291908290030181600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050506040513d60208110156135eb57600080fd5b50505b60006136096001600160a01b0383163063ffffffff6120a716565b90506130da8287838787613755565b6136218561118d565b90506001600160a01b038082161461374a576136408682868686613755565b600061365b6001600160a01b0383163063ffffffff6120a716565b905061366f826001600160a01b0316611e3b565b156136f15760408051638f6ede1f60e01b815230600482015290516001600160a01b03881691638f6ede1f91849160248082019260209290919082900301818588803b1580156136be57600080fd5b505af11580156136d2573d6000803e3d6000fd5b50505050506040513d60208110156136e957600080fd5b506130da9050565b6136fb8287611ecf565b604080516340c10f1960e01b81523060048201526024810183905290516001600160a01b038816916340c10f199160448083019260209291908290030181600087803b1580156131fa57600080fd5b505b611acf85858585855b611acf85858585855b836001600160a01b0316856001600160a01b0316141561377d57611acf565b61378e81608063ffffffff611e7516565b15156137a482634000000063ffffffff611e7516565b151514156139c35760006137b7866139d0565b90506001600160a01b038082161461383a57856001600160a01b031663db006a75856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561380f57600080fd5b505af1158015613823573d6000803e3d6000fd5b50505050613834818686868661375e565b50611acf565b613843856139d0565b90506001600160a01b03808216146139c1576138628682868686613dfa565b600061387d6001600160a01b0383163063ffffffff6120a716565b90506139018273398ec7346dcd622edc5ae82352f02be94c62d1196001600160a01b031663f2f4eb266040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d057600080fd5b505afa1580156138e4573d6000803e3d6000fd5b505050506040513d60208110156138fa57600080fd5b5051611ecf565b73398ec7346dcd622edc5ae82352f02be94c62d11963d2d0e06661392d6001600160a01b038516611e3b565b61393857600061393a565b825b61394c856001600160a01b0316611e3b565b613956578461396c565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301526024820186905261044d604483015251606480830192600092919082900301818588803b1580156125a457600080fd5b505b611acf8585858585613dfa565b60006001600160a01b038216733a3a65aab0dd2a17e3f1947ba16138cd37d08c0414156139ff57506000611500565b6001600160a01b03821673fc1e690f61efd961294b3e1ce3313fbd8aa4f85d1415613a3f5750736b175474e89094c44da98b954eedeac495271d0f611500565b6001600160a01b038216739ba00d6856a4edf4665bca2c2309936572473b7e1415613a7f575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611500565b6001600160a01b03821673625ae63000f46200499120b906716420bd0592401415613abf57507357ab1ec28d129707052df4df418d58a2d46d5f51611500565b6001600160a01b038216736ee0f7bb50a54ab5253da0667b0dc2ee526c30a81415613aff5750734fabb145d64652a948d72533023f6e7a623c7c53611500565b6001600160a01b038216734da9b813057d04baef4e5800e36083717b4a03411415613b3a57506e085d4780b73119b644ae5ecd22b376611500565b6001600160a01b0382167371fc860f7d3a592a4a98740e39db31d25db65ae81415613b7a575073dac17f958d2ee523a2206206994597c13d831ec7611500565b6001600160a01b03821673e1ba0fb44ccb0d11b80f92f4f8ed94ca3ff51d001415613bba5750730d8775f648430679a709e98d2b0cb6250d2887ef611500565b6001600160a01b038216739d91be44c06d373a8a226e1f3b146956083803eb1415613bfa575073dd974d5c2e2928dea5f71b9825b8b646686bd200611500565b6001600160a01b038216737d2d3688df45ce7c552e19c27e007673da9204b81415613c3a57507380fb784b7ed66730e8b1dbd9820afd29931aab03611500565b6001600160a01b03821673a64bd6c70cb9051f6a9ba1f163fdc07e0dfb5f841415613c7a575073514910771af9ca656af840dff83e8264ecf986ca611500565b6001600160a01b038216736fce4a401b6b80ace52baaefe4421bd188e76f6f1415613cba5750730f5d2fb29fb7d3cfee444a200298f468908cc942611500565b6001600160a01b038216737deb5e830be29f91e298ba5ff1356bb7f81469981415613cfa5750739f8f72aa9304c8b593d555f12ef6589cc3a579a2611500565b6001600160a01b0382167371010a9d003445ac60c4e6a7017c1e89a477b4381415613d3a5750731985365e9f78359a9b6ad760e32412f4a445e862611500565b6001600160a01b03821673328c4c80bc7aca0834db37e6600a6c49e12da4de1415613d7a575073c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f611500565b6001600160a01b03821673fc4b8ed459e00e5400be803a9bb3954234fd50e31415613dba5750732260fac5e5542a773aa44fbcfedf7c193bc2c599611500565b6001600160a01b038216736fb0855c404e09c47c3fbca25f08d4e41f9f062f141561345e575073e41d2489571d322189246dafa5ebde1f4699f498611500565b836001600160a01b0316856001600160a01b03161415613e1957611acf565b613e2b8161040063ffffffff611e7516565b1515613e4182634000000063ffffffff611e7516565b151514156140e6576000546001600160a01b0386811691161415613f9f576000805460408051637f8661a160e01b81526004810187905290516001600160a01b0390921692637f8661a19260248084019382900301818387803b158015613ea757600080fd5b505af1158015613ebb573d6000803e3d6000fd5b5050600154604080516370a0823160e01b81523060048201529051600094506001600160a01b0390921692506370a08231916024808301926020929190829003018186803b158015613f0c57600080fd5b505afa158015613f20573d6000803e3d6000fd5b505050506040513d6020811015613f3657600080fd5b505190508015613f7e5760018054606091613f5f916001600160a01b0316908890859087610f02565b600154909250613f7c91506001600160a01b031687848487612151565b505b613834736b175474e89094c44da98b954eedeac495271d0f868686866140ef565b6000546001600160a01b03858116911614156140e657613fd685736b175474e89094c44da98b954eedeac495271d0f8585856140ef565b60005461400190736b175474e89094c44da98b954eedeac495271d0f906001600160a01b0316611ecf565b600054604080516370a0823160e01b815230600482015290516001600160a01b039092169163049878f391736b175474e89094c44da98b954eedeac495271d0f916370a0823191602480820192602092909190829003018186803b15801561406857600080fd5b505afa15801561407c573d6000803e3d6000fd5b505050506040513d602081101561409257600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156140d257600080fd5b505af115801561186c573d6000803e3d6000fd5b611acf85858585855b836001600160a01b0316856001600160a01b0316141561410e57611acf565b61411f81604063ffffffff611e7516565b151561413582634000000063ffffffff611e7516565b151514156143c3576001600160a01b0385167306af07097c9eeb7fd685c692751d5c66db49c2151415614260576040805163ef693bed60e01b81523060048201526024810185905290517306af07097c9eeb7fd685c692751d5c66db49c2159163ef693bed91604480830192600092919082900301818387803b1580156141bb57600080fd5b505af11580156141cf573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516128bf9350736b175474e89094c44da98b954eedeac495271d0f9250879183916370a0823191602480820192602092909190829003018186803b15801561422d57600080fd5b505afa158015614241573d6000803e3d6000fd5b505050506040513d602081101561425757600080fd5b505185856143cc565b6001600160a01b0384167306af07097c9eeb7fd685c692751d5c66db49c21514156143c3576142a685736b175474e89094c44da98b954eedeac495271d0f8585856143cc565b6142d8736b175474e89094c44da98b954eedeac495271d0f7306af07097c9eeb7fd685c692751d5c66db49c215611ecf565b604080516370a0823160e01b8152306004820181905291517306af07097c9eeb7fd685c692751d5c66db49c21592633b4da69f929091736b175474e89094c44da98b954eedeac495271d0f916370a08231916024808301926020929190829003018186803b15801561434957600080fd5b505afa15801561435d573d6000803e3d6000fd5b505050506040513d602081101561437357600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152602483019190915251604480830192600092919082900301818387803b1580156140d257600080fd5b611acf85858585855b60006143d7826144e1565b90506001600160a01b038116156144d45760608351604051908082528060200260200182016040528015614415578160200160208202803883390190505b50905060005b845181101561445a5784818151811061443057fe5b602002602001015160ff1682828151811061444757fe5b602090810291909101015260010161441b565b5061446887838784876146a0565b60005b84518110156144ae57600885828151811061448257fe5b6020026020010151901c60ff1682828151811061449b57fe5b602090810291909101015260010161446b565b506130da82876144cd6001600160a01b0383163063ffffffff6120a716565b84876146a0565b611c4e86868686866146a0565b60006144eb614890565b6040518060e0016040528061020081526020016201000081526020016202000081526020016404000000008152602001640800000000815260200164100000000081526020016420000000008152509050614544614890565b506040805160e08101825273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8152736b175474e89094c44da98b954eedeac495271d0f602082015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489181019190915273dac17f958d2ee523a2206206994597c13d831ec76060820152732260fac5e5542a773aa44fbcfedf7c193bc2c5996080820152731bbe271d15bb64df0bc6cd28df9ff322f2ebd84760a082015273eb4c2781e4eba804ce9a9803c67d0893436bb27d60c082015260005b60078110156146985761463183826007811061461f57fe5b6020020151869063ffffffff611e7516565b15614690576001600160a01b0384161561467c5760405162461bcd60e51b815260040180806020018281038252602e81526020018061490f602e913960400191505060405180910390fd5b81816007811061468857fe5b602002015193505b600101614607565b505050919050565b836001600160a01b0316856001600160a01b031614156146bf57611acf565b611acf85858585856003546040516001600160a01b038781166024830190815287821660448401526064830187905260006084840181905260c4840186905260c060a48501908152875160e486015287519195606095941693637153a8af60e11b938c938c938c938a938d938d9391926101040190602080870191028083838a5b83811015614758578181015183820152602001614740565b50505050905001975050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518082805190602001908083835b602083106147ca5780518252601f1990920191602091820191016147ab565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461482a576040519150601f19603f3d011682016040523d82523d6000602084013e61482f565b606091505b5091509150816000811461484257614849565b3d60208301fd5b5050505050505050565b60405180604001604052806002906020820280388339509192915050565b604051806101a00160405280600d906020820280388339509192915050565b6040518060e00160405280600790602082028038833950919291505056fe4f6e6553706c69743a2061637475616c2072657475726e20616d6f756e74206973206c657373207468616e206d696e52657475726e57726f6e6720757365616765206f66204554482e756e6976657273616c5472616e7366657246726f6d28294f6e6553706c69743a20446f206e6f7420757365206d756c74697061746820776974682065616368206f746865725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a265627a7a72315820c4c342bbe296ca3f12452c3cbe38ff8890a1ac3feae34e965c8aaeae89cc8c9564736f6c63430005110032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000148f173e363f34755f4f97a13ab53b8b76ee05000000000000000000000000003a2d9db352580eb50018fc86eae32e19070a9982
-----Decoded View---------------
Arg [0] : _oneSplitView (address): 0x148f173e363F34755F4F97A13Ab53B8B76ee0500
Arg [1] : _oneSplit (address): 0x3A2d9DB352580eB50018fC86eaE32E19070A9982
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000148f173e363f34755f4f97a13ab53b8b76ee0500
Arg [1] : 0000000000000000000000003a2d9db352580eb50018fc86eae32e19070a9982
Deployed Bytecode Sourcemap
138467:2858:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139067:10;139081:9;139067:23;;139059:32;;;;;;138467:2858;5018:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5018:59:0;;;:::i;:::-;;;;;;;;;;;;;;;;139107:615;;8:9:-1;5:2;;;30:1;27;20:12;5:2;139107:615:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;139107: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;139107:615:0;;;;;;;;;;;;;;;;;;38556:132;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38556:132:0;;;:::i;:::-;;;;-1:-1:-1;;;;;38556:132:0;;;;;;;;;;;;;;38981:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38981: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;39465:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39465: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;38228:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38228:80:0;;;:::i;37240:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37240:80:0;;;:::i;3934:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3934:48:0;;;:::i;39370:88::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39370:88:0;;;:::i;6296:66::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6296:66:0;;;:::i;37414:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37414:80:0;;;:::i;38054:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38054:80:0;;;:::i;37153:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37153:80:0;;;:::i;37674:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37674:78:0;;;:::i;102727:1205::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;102727:1205:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;102727:1205:0;-1:-1:-1;;;;;102727:1205:0;;:::i;37067:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37067:79:0;;;:::i;39281:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39281:82:0;;;:::i;138772:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;138772: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;40358:107::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40358:107:0;;;:::i;39093:89::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39093:89:0;;;:::i;37588:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37588: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;6628:60::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6628:60: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;111835:70::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111835: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;37327:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37327: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;39927:100::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39927:100:0;;;:::i;37759:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37759:114:0;;;:::i;38441:108::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38441:108:0;;;:::i;37965:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37965:82:0;;;:::i;124449:1344::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;124449:1344:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;124449:1344:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;124449: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;124449:1344:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;124449:1344:0;;-1:-1:-1;;124449:1344:0;;;-1:-1:-1;124449:1344:0;;-1:-1:-1;;124449:1344:0:i;40472:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40472:96:0;;;:::i;40131:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40131:96:0;;;:::i;5825:66::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5825:66:0;;;:::i;40234:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40234:117:0;;;:::i;36885:87::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36885:87:0;;;:::i;4310:60::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4310:60:0;;;:::i;39562:84::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39562:84:0;;;:::i;37880:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37880:78:0;;;:::i;5609:63::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5609:63:0;;;:::i;111759:69::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;111759: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;37501:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37501: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;36838:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36838:40:0;;;:::i;39747:85::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39747:85:0;;;:::i;5473:59::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5473:59:0;;;:::i;39189:85::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39189:85:0;;;:::i;123770:338::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;123770:338:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;123770:338:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;123770:338:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;123770: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;123770:338:0;;-1:-1:-1;123770:338:0;-1:-1:-1;123770:338:0;;:::i;4566:60::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4566:60:0;;;:::i;38839:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38839:135:0;;;:::i;38317:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38317: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;39653:87::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39653:87:0;;;:::i;38141:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38141:80:0;;;:::i;139730:888::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;139730:888:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;139730:888:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;139730:888: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;139730:888:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;139730:888:0;;-1:-1:-1;;139730:888:0;;;-1:-1:-1;139730:888:0;;-1:-1:-1;;139730:888: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;39839:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39839:81:0;;;:::i;36981:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36981:79:0;;;:::i;3704:50::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3704:50:0;;;:::i;40034:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40034:90:0;;;:::i;5337:58::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5337:58:0;;;:::i;138732:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;138732:33:0;;;:::i;5018:59::-;5069:8;5018:59;:::o;139107:615::-;139566:12;;:148;;;-1:-1:-1;;;139566:148:0;;-1:-1:-1;;;;;139566:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139459:7;;139498:16;;139566:12;;:30;;:148;;;;;139459:7;;139566:148;;;;;;;:12;:148;;;5:2:-1;;;;30:1;27;20:12;5:2;139566:148:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;139566:148:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;139566: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;139566: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;139566:148:0;;421:4:-1;412:14;;;;139566:148:0;;;;;412:14:-1;139566: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;139566:148:0;;;;;;;;;;;139559:155;;;;139107:615;;;;;;;;:::o;38556:132::-;38645:42;38556:132;:::o;38981:105::-;39043:42;38981: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;39465:90::-;39512:42;39465: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;38228:80::-;38265:42;38228:80;:::o;37240:::-;37277:42;37240:80;:::o;3934:48::-;3978:4;3934:48;:::o;39370:88::-;39415:42;39370:88;:::o;6296:66::-;6350:12;6296:66;:::o;37414:80::-;37451:42;37414:80;:::o;38054:::-;38091:42;38054:80;:::o;37153:::-;37190:42;37153:80;:::o;37674:78::-;37709:42;37674:78;:::o;102727:1205::-;102786:6;102809:13;:5;-1:-1:-1;;;;;102809:11:0;;:13::i;:::-;102805:63;;;-1:-1:-1;;;102839:17:0;;102805:63;102952:91;;;22:32:-1;6:49;;102952:91:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;102916:128:0;;;;102881:12;;102895:17;;-1:-1:-1;;;;;102916:25:0;;;102946:4;;102952:91;;102916:128;;;;25:18:-1;102916: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;;;102916: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;;102880:164:0;;;;103060:7;103055:58;;-1:-1:-1;;103084:17:0;;;;;;103055:58;103125:13;;103157:414;103182:4;:11;103174:1;103178;103174:5;:19;103157:414;;;103219:4;103224:1;103228;103224:5;103219:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103219:11:0;-1:-1:-1;;;103219:18:0;:57;;;;;103258:4;103263:1;103267;103263:5;103258:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103258:11:0;-1:-1:-1;;;103258:18:0;103219:57;:96;;;;;103297:4;103302:1;103306;103302:5;103297:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103297:11:0;-1:-1:-1;;;103297:18:0;103219:96;:135;;;;;103336:4;103341:1;103345;103341:5;103336:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103336:11:0;-1:-1:-1;;;103336:18:0;103219:135;:174;;;;;103375:4;103380:1;103384;103380:5;103375:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103375:11:0;-1:-1:-1;;;103375:18:0;103219:174;:213;;;;;103414:4;103419:1;103423;103419:5;103414:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103414:11:0;-1:-1:-1;;;103414:18:0;103219:213;:252;;;;;103453:4;103458:1;103462;103458:5;103453:11;;;;;;;;;;;;;-1:-1:-1;;;;;;103453:11:0;-1:-1:-1;;;103453:18:0;103219:252;103215:345;;;103516:4;103505:15;;103539:5;;103215:345;103195:3;;103157:414;;;;103586:8;103581:59;;-1:-1:-1;;103611:17:0;;;;;;;103581:59;103706:103;;;22:32:-1;6:49;;103706:103:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;103670:140:0;;;;-1:-1:-1;;;;;103670:25:0;;;103700:4;;103706:103;103670:140;;;25:18:-1;103670: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;;;103670: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;103652:158:0;;-1:-1:-1;103652:158:0;-1:-1:-1;103652:158:0;103821:58;;-1:-1:-1;;103850:17:0;;;;;;;103821:58;103909:4;103898:26;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;103898:26:0;;-1:-1:-1;;;;102727:1205:0;;;;:::o;37067:79::-;37103:42;37067:79;:::o;39281:82::-;39320:42;39281:82;:::o;138772:25::-;;;-1:-1:-1;;;;;138772:25:0;;:::o;3817:52::-;3865:4;3817:52;:::o;5402:64::-;5456:10;5402:64;:::o;3876:51::-;3923:4;3876:51;:::o;40358:107::-;40422:42;40358:107;:::o;39093:89::-;39139:42;39093:89;:::o;37588:79::-;37624:42;37588:79;:::o;4440:53::-;4487:6;4440:53;:::o;4253:50::-;4298:5;4253:50;:::o;3761:49::-;3806:4;3761:49;:::o;6628:60::-;6675:13;6628:60;:::o;4658:61::-;4712:7;4658:61;:::o;4878:63::-;4933:8;4878:63;:::o;111835:70::-;;;-1:-1:-1;;;;;111835:70:0;;:::o;4820:51::-;4864:7;4820:51;:::o;4197:49::-;4241:5;4197:49;:::o;37327:80::-;37364:42;37327:80;:::o;6394:68::-;6450:12;6394:68;:::o;3342:49::-;3387:4;3342:49;:::o;5142:59::-;5193:8;5142:59;:::o;39927:100::-;39984:42;39927:100;:::o;37759:114::-;37830:42;37759:114;:::o;38441:108::-;38506:42;38441:108;:::o;37965:82::-;38004:42;37965:82;:::o;124449:1344::-;124694:30;:5;5322:8;124694:30;:11;:30;:::i;:::-;124693:31;124647:42;:5;5881:10;124647:42;:11;:42;:::i;:::-;124646:43;:78;124642:1064;;;124741:22;;:::i;:::-;124766:13;:11;:13::i;:::-;124741:38;-1:-1:-1;124801:6:0;124796:399;124817:13;124813:1;:17;124796:399;;;124880:6;124887:1;124880:9;;;;;;;;;;;-1:-1:-1;;;;;124860:30:0;:9;-1:-1:-1;;;;;124860:30:0;;124856:324;;;124915:17;124935:6;124942:1;124935:9;;;;;;;;;;;-1:-1:-1;;;;;124935:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;124935:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;124935:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;124935:17:0;;-1:-1:-1;124975:14:0;124992:6;124999:1;124992:9;;;;;;;;;;;-1:-1:-1;;;;;124992:25:0;;125018:6;125026:4;125046:1;125032:16;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;125032:16:0;;124992: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;124992:57:0;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;124992:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;124992:57:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;124992:57:0;;-1:-1:-1;125072:59:0;125082:10;125094:7;124992:57;125111:12;125125:5;125072:9;:59::i;:::-;125154:7;;;;;;124856:324;124832:3;;124796:399;;;-1:-1:-1;125216:6:0;125211:484;125232:13;125228:1;:17;125211:484;;;125293:6;125300:1;125293:9;;;;;;;;;;;-1:-1:-1;;;;;125275:28:0;:7;-1:-1:-1;;;;;125275:28:0;;125271:409;;;125328:17;125348:6;125355:1;125348:9;;;;;;;;;;;-1:-1:-1;;;;;125348:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125348:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125348:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125348:17:0;;-1:-1:-1;125388:63:0;125400:9;125348:17;125423:6;125431:12;125445:5;125388:11;:63::i;:::-;125474:56;125499:10;125519:6;125526:1;125519:9;;;;;;;;;;;125474:24;:56::i;:::-;125553:6;125560:1;125553:9;;;;;;;;;;;-1:-1:-1;;;;;125553:23:0;;125577:10;-1:-1:-1;;;;;125577:20:0;;125606:4;125577:35;;;;;;;;;;;;;-1:-1:-1;;;;;125577:35:0;-1:-1:-1;;;;;125577:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125577:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125577:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125577:35:0;125614:16;;;125628:1;125614:16;;;125577:35;125614:16;;;;;;;125553: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;125553:78:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;125553:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;125553:78:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;125654:7:0;;-1:-1:-1;;;;125654:7:0;125271:409;125247:3;;125211:484;;;;124642:1064;;125725:60;125737:9;125748:7;125757:6;125765:12;125779:5;125725:11;:60::i;:::-;124449:1344;;;;;:::o;40472:96::-;40525:42;40472:96;:::o;40131:::-;40184:42;40131:96;:::o;5825:66::-;5881:10;5825:66;:::o;40234:117::-;40308:42;40234:117;:::o;36885:87::-;36929:42;36885:87;:::o;4310:60::-;4364:6;4310:60;:::o;39562:84::-;39603:42;39562:84;:::o;37880:78::-;37915:42;37880:78;:::o;5609:63::-;5663:9;5609:63;:::o;111759:69::-;;;-1:-1:-1;;;;;111759:69:0;;:::o;3284:51::-;3331:4;3284:51;:::o;4107:58::-;4160:5;4107:58;:::o;5898:59::-;5947:10;5898:59;:::o;37501:80::-;37538:42;37501:80;:::o;5278:52::-;5322:8;5278:52;:::o;4751:62::-;4806:7;4751:62;:::o;36838:40::-;36876:2;36838:40;:::o;39747:85::-;39789:42;39747:85;:::o;5473:59::-;5523:9;5473:59;:::o;39189:85::-;39231:42;39189:85;:::o;123770:338::-;123994:10;124016:4;123994:27;123986:36;;;;;;124040:60;124052:9;124063:7;124072:6;124080:12;;124040:60;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;124094:5:0;;-1:-1:-1;124040:11:0;;-1:-1:-1;;124040:60:0:i;:::-;123770:338;;;;;;:::o;4566:60::-;4619:7;4566:60;:::o;38839:135::-;38931:42;38839:135;:::o;38317:117::-;38391:42;38317:117;:::o;4044:56::-;4095:5;4044:56;:::o;6199:65::-;6253:11;6199:65;:::o;39653:87::-;39697:42;39653:87;:::o;38141:80::-;38178:42;38141:80;:::o;139730:888::-;140066:66;-1:-1:-1;;;;;140066:31:0;;140098:10;140118:4;140125:6;140066:66;:31;:66;:::i;:::-;140143:17;140163:43;-1:-1:-1;;;;;140163:28:0;;140200:4;140163:43;:28;:43;:::i;:::-;140143:63;;140217:57;140223:9;140234:7;140243:9;140254:12;140268:5;140217;:57::i;:::-;140287:20;140310:41;-1:-1:-1;;;;;140310:26:0;;140345:4;140310:41;:26;:41;:::i;:::-;140287:64;;140386:9;140370:12;:25;;140362:91;;;;-1:-1:-1;;;140362:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;140464:51;-1:-1:-1;;;;;140464:25:0;;140490:10;140502:12;140464:51;:25;:51;:::i;:::-;-1:-1:-1;140526:84:0;140554:10;140566:43;-1:-1:-1;;;;;140566:28:0;;140603:4;140566:43;:28;:43;:::i;:::-;-1:-1:-1;;;;;140526:27:0;;;:84;;:27;:84;:::i;:::-;;139730:888;;;;;;;;:::o;5679:65::-;5734:10;5679:65;:::o;5751:67::-;5808:10;5751:67;:::o;39839:81::-;39877:42;39839:81;:::o;36981:79::-;37017:42;36981:79;:::o;3704:50::-;3750:4;3704:50;:::o;40034:90::-;40081:42;40034:90;:::o;5337:58::-;5386:9;5337:58;:::o;138732:33::-;;;-1:-1:-1;;;;;138732:33:0;;:::o;33770:166::-;33821:4;-1:-1:-1;;;;;33846:39:0;;;;:81;;-1:-1:-1;;;;;;33889:38:0;;31159:42;33889:38;33846:81;33838:90;33770:166;-1:-1:-1;;33770:166:0:o;36396:117::-;36487:12;36486:19;;;36396:117::o;121209:227::-;121254:15;;:::i;:::-;-1:-1:-1;121282:146:0;;;;;;;;;121310:42;121282:146;;121374:42;121282:146;;;;121209:227;:::o;118843:326::-;119026:135;119051:9;119075:7;119097:6;119118:12;119145:5;119026:10;:135::i;47414:262::-;47499:13;:5;-1:-1:-1;;;;;47499:11:0;;:13::i;:::-;47494:175;;47534:34;;;-1:-1:-1;;;47534:34:0;;47558:4;47534:34;;;;-1:-1:-1;;;;;47534:34:0;;;;;;;;;47572:3;;47534:15;;;;;:34;;;;;;;;;;;;;;:15;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;47534:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47534:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47534:34:0;:41;;47529:129;;47602:40;-1:-1:-1;;;;;47602:22:0;;47625:2;-1:-1:-1;;47602:40:0;:22;:40;:::i;:::-;47414:262;;:::o;31567:617::-;31678:11;31674:50;;31706:7;;31674:50;31740:12;31746:5;31740;:12::i;:::-;31736:441;;;-1:-1:-1;;;;;31777:18:0;;31785:10;31777:18;:41;;;;;31812:6;31799:9;:19;;31777:41;31769:97;;;;-1:-1:-1;;;31769:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31885:19:0;;31899:4;31885:19;31881:97;;31925:37;;-1:-1:-1;;;;;31925:29:0;;;:37;;;;;31955:6;;31925:37;;;;31955:6;31925:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31925:37:0;31881:97;32008:6;31996:9;:18;31992:101;;;32035:10;:42;32055:21;:9;32069:6;32055:21;:13;:21;:::i;:::-;32035:42;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32035:42:0;31992:101;31736:441;;;32125:40;-1:-1:-1;;;;;32125:22:0;;32148:4;32154:2;32158:6;32125:40;:22;:40;:::i;:::-;31567:617;;;;:::o;32952:228::-;33030:7;33054:12;33060:5;33054;:12::i;:::-;33050:123;;;-1:-1:-1;;;;;;33090:11:0;;;33083:18;;33050:123;33141:5;-1:-1:-1;;;;;33141:15:0;;33157:3;33141:20;;;;;;;;;;;;;-1:-1:-1;;;;;33141:20:0;-1:-1:-1;;;;;33141:20:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33141:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33141:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33141:20:0;;-1:-1:-1;33134:27:0;;134519:325;134702:134;134726:9;134750:7;134772:6;134793:12;134820:5;134702:9;:134::i;31211:348::-;31297:4;31318:11;31314:55;;-1:-1:-1;31353:4:0;31346:11;;31314:55;31385:12;31391:5;31385;:12::i;:::-;31381:171;;;31414:37;;-1:-1:-1;;;;;31414:29:0;;;:37;;;;;31444:6;;31414:37;;;;31444:6;31414:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31414:37:0;31381:171;;;31484:30;-1:-1:-1;;;;;31484:18:0;;31503:2;31507:6;31484:30;:18;:30;:::i;:::-;-1:-1:-1;31536:4:0;31381:171;31211:348;;;;;:::o;119177:1375::-;119381:7;-1:-1:-1;;;;;119368:20:0;:9;-1:-1:-1;;;;;119368:20:0;;119364:59;;;119405:7;;119364:59;119485:31;:5;4298;119485:31;:11;:31;:::i;:::-;119439:77;;:42;:5;5881:10;119439:42;:11;:42;:::i;:::-;:77;;;119435:1030;;;119533:25;;:::i;:::-;119561:10;:8;:10::i;:::-;119533:38;-1:-1:-1;119593:6:0;119588:385;119609:14;119605:1;:18;119588:385;;;119673:7;119681:1;119673:10;;;;;;;;;;;-1:-1:-1;;;;;119653:31:0;:9;-1:-1:-1;;;;;119653:31:0;;119649:309;;;119709:17;119729:7;119737:1;119729:10;;;;;;;;;;;-1:-1:-1;;;;;119729:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119729:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119729:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;119729:18:0;;-1:-1:-1;119770:7:0;119778:1;119770:10;;;;;;;;;;;-1:-1:-1;;;;;119770:19:0;;119790:6;119770:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119770:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119770:27:0;;;;119820:89;119831:10;119843:7;119852:10;-1:-1:-1;;;;;119852:20:0;;119881:4;119852:35;;;;;;;;;;;;;-1:-1:-1;;;;;119852:35:0;-1:-1:-1;;;;;119852:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;119852:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119852:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;119852:35:0;119889:12;119903:5;119820:10;:89::i;:::-;119932:7;;;;;119649:309;119625:3;;119588:385;;;-1:-1:-1;119994:6:0;119989:465;120010:14;120006:1;:18;119989:465;;;120072:7;120080:1;120072:10;;;;;;;;;;;-1:-1:-1;;;;;120054:29:0;:7;-1:-1:-1;;;;;120054:29:0;;120050:389;;;120108:17;120128:7;120136:1;120128:10;;;;;;;;;;;-1:-1:-1;;;;;120128:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;120128:18:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120128:18:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;120128:18:0;;-1:-1:-1;120169:63:0;120181:9;120128:18;120204:6;120212:12;120226:5;120169:11;:63::i;:::-;120255:57;120280:10;120300:7;120308:1;120300:10;;;;;;120255:57;120335:7;120343:1;120335:10;;;;;;;;;;;-1:-1:-1;;;;;120335:18:0;;120354:10;-1:-1:-1;;;;;120354:20:0;;120383:4;120354:35;;;;;;;;;;;;;-1:-1:-1;;;;;120354:35:0;-1:-1:-1;;;;;120354:35:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;120354:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120354:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;120354:35:0;120335:55;;;-1:-1:-1;;;;;;120335:55:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;120335:55:0;;;;;;;-1:-1:-1;120335:55:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;120335:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;120335:55:0;;;;120413:7;;;;;120050:389;120026:3;;119989:465;;;;119435:1030;;120484:60;120496:9;120507:7;120516:6;120524:12;120538:5;120484:11;:60::i;32643:301::-;32736:12;32742:5;32736;:12::i;:::-;32731:206;;32778:1;32769:6;:10;:52;;;;-1:-1:-1;32783:34:0;;;-1:-1:-1;;;32783:34:0;;32807:4;32783:34;;;;-1:-1:-1;;;;;32783:34:0;;;;;;;;;32820:1;;32783:15;;;;;:34;;;;;;;;;;;;;;:15;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;32783:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32783:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32783:34:0;:38;32769:52;32765:117;;;32842:24;-1:-1:-1;;;;;32842:17:0;;32860:2;32864:1;32842:24;:17;:24;:::i;:::-;32896:29;-1:-1:-1;;;;;32896:17:0;;32914:2;32918:6;32896:29;:17;:29;:::i;:::-;32643:301;;;:::o;8628:136::-;8686:7;8713:43;8717:1;8720;8713:43;;;;;;;;;;;;;;;;;:3;:43::i;27866:204::-;27993:68;;;-1:-1:-1;;;;;27993:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;27993:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;27967:95:0;;27986:5;;27967:18;:95::i;134852:1958::-;135055:7;-1:-1:-1;;;;;135042:20:0;:9;-1:-1:-1;;;;;135042:20:0;;135038:59;;;135079:7;;135038:59;135159:30;:5;4864:7;135159:30;:11;:30;:::i;:::-;135113:76;;:42;:5;5881:10;135113:42;:11;:42;:::i;:::-;:76;;;135109:1538;;;-1:-1:-1;;;;;135210:17:0;;37709:42;135210:17;135206:332;;;135262:29;;;-1:-1:-1;;;135262:29:0;;135285:4;135262:29;;;;;;37709:42;;135248:13;;37709:42;;135262:14;;:29;;;;;;;;;;;;;;37709:42;135262:29;;;5:2:-1;;;;30:1;27;20:12;5:2;135262:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;135262:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;135262:29:0;135248:44;;;-1:-1:-1;;;;;;135248:44:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;135248:44:0;;;;;;;-1:-1:-1;135248:44:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;135248:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;135248:44:0;;;;135311:186;36929:42;135379:7;135409:6;135438:12;135473:5;135311:11;:186::i;:::-;135516:7;;135206:332;-1:-1:-1;;;;;135558:29:0;;37830:42;135558:29;135554:368;;;135634:41;;;-1:-1:-1;;;135634:41:0;;135669:4;135634:41;;;;;;37830:42;;135608:25;;37830:42;;135634:26;;:41;;;;;;;;;;;;;;37830:42;135634:41;;;5:2:-1;;;;30:1;27;20:12;135554:368:0;-1:-1:-1;;;;;135942:15:0;;37709:42;135942:15;135938:329;;;135978:186;136010:9;36929:42;136076:6;136105:12;136140:5;135978:9;:186::i;:::-;37709:42;-1:-1:-1;;;;;136183:12:0;;136202:21;136183:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;136183:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;136183:43:0;;;;;136245:7;;135938:329;-1:-1:-1;;;;;136287:27:0;;37830:42;136287:27;136283:353;;;136335:186;136367:9;36929:42;136433:6;136462:12;136497:5;136335:9;:186::i;:::-;37830:42;-1:-1:-1;;;;;136540:24:0;;136571:21;136540:55;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;136283:353:0;136666:136;136692:9;136716:7;136738:6;136759:12;136786:5;136666:11;:136::i;27682:176::-;27791:58;;;-1:-1:-1;;;;;27791:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;27791:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;27765:85:0;;27784:5;;27765:18;:85::i;115343:943::-;115385:17;;:::i;:::-;-1:-1:-1;115415:863:0;;;;;;;;115444:42;115415:863;;115509:42;115415:863;;;;115574:42;115415:863;;;;;;;115639:42;115415:863;;;;115704:42;115415:863;;;;115769:42;115415:863;;;;115834:42;115415:863;;;;115899:42;115415:863;;;;115964:42;115415:863;;;;116029:42;115415:863;;;;116094:42;115415:863;;;;116159:42;115415:863;;;;116224:42;115415:863;;;;115343:943;:::o;98119:328::-;98302:137;98329:9;98353:7;98375:6;98396:12;98423:5;98302:12;:137::i;28078:621::-;28448:10;;;28447:62;;-1:-1:-1;28464:39:0;;;-1:-1:-1;;;28464:39:0;;28488:4;28464:39;;;;-1:-1:-1;;;;;28464:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;5:2:-1;;;;30:1;27;20:12;5:2;28464:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28464:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28464:39:0;:44;28447:62;28439:152;;;;-1:-1:-1;;;28439:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28628:62;;;-1:-1:-1;;;;;28628:62:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;28628:62:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;28602:89:0;;28621:5;;28602:18;:89::i;9101:192::-;9187:7;9223:12;9215:6;;;;9207:29;;;;-1:-1:-1;;;9207: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;9207:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9259:5:0;;;9101:192::o;29721:1114::-;30325:27;30333:5;-1:-1:-1;;;;;30325:25:0;;:27::i;:::-;30317:71;;;;;-1:-1:-1;;;30317:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30462:12;30476:23;30511:5;-1:-1:-1;;;;;30503:19:0;30523:4;30503: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;;;30503: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;;30461:67:0;;;;30547:7;30539:52;;;;;-1:-1:-1;;;30539:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30608:17;;:21;30604:224;;30750:10;30739:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30739:30:0;30731:85;;;;-1:-1:-1;;;30731:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124116:325;124299:134;124323:9;124347:7;124369:6;124390:12;124417:5;124299:9;:134::i;98455:1788::-;98661:7;-1:-1:-1;;;;;98648:20:0;:9;-1:-1:-1;;;;;98648:20:0;;98644:59;;;98685:7;;98644:59;98765:34;:5;3865:4;98765:34;:11;:34;:::i;:::-;98719:80;;:42;:5;5881:10;98719:42;:11;:42;:::i;:::-;:80;;;98715:1365;;;98816:17;98836:38;98864:9;98836:27;:38::i;:::-;98816:58;-1:-1:-1;;;;;;98893:24:0;;;;98889:428;;98961:9;-1:-1:-1;;;;;98938:41:0;;98980:6;98938:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;98938:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;98938:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;99006:24:0;;-1:-1:-1;99033:44:0;-1:-1:-1;;;;;99033:29:0;;99071:4;99033:44;:29;:44;:::i;:::-;99006:71;;99105:196;99140:10;99173:7;99203:16;99242:12;99277:5;99105:12;:196::i;:::-;99098:203;;;;98889:428;99346:36;99374:7;99346:27;:36::i;:::-;99333:49;-1:-1:-1;;;;;;99401:24:0;;;;99397:672;;99446:187;99480:9;99512:10;99545:6;99574:12;99609:5;99446:11;:187::i;:::-;99654:24;99681:44;-1:-1:-1;;;;;99681:29:0;;99719:4;99681:44;:29;:44;:::i;:::-;99654:71;;99750:18;:10;-1:-1:-1;;;;;99750:16:0;;:18::i;:::-;99746:283;;;40184:42;-1:-1:-1;;;;;99793:9:0;;99809:16;99793:35;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99793:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99793:35:0;;;;;99746:283;;;99877:54;99902:10;99922:7;99877:24;:54::i;:::-;99977:7;-1:-1:-1;;;;;99954:37:0;;99992:16;99954:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99954:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99954:55:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;99397:672:0;98715:1365;;100099:136;100125:9;100149:7;100171:6;100192:12;100219:5;100099:11;:136::i;24711:619::-;24771:4;25239:20;;25082:66;25279:23;;;;;;:42;;-1:-1:-1;25306:15:0;;;25279:42;25271:51;24711:619;-1:-1:-1;;;;24711:619:0:o;94283:1409::-;94356:6;-1:-1:-1;;;;;94379:59:0;;94395:42;94379:59;94375:115;;;-1:-1:-1;94476:1:0;94462:16;;94375:115;-1:-1:-1;;;;;94504:59:0;;94520:42;94504:59;94500:156;;;-1:-1:-1;94601:42:0;94587:57;;94500:156;-1:-1:-1;;;;;94670:59:0;;94686:42;94670:59;94666:156;;;-1:-1:-1;94767:42:0;94753:57;;94666:156;-1:-1:-1;;;;;94836:59:0;;94852:42;94836:59;94832:156;;;-1:-1:-1;94933:42:0;94919:57;;94832:156;-1:-1:-1;;;;;95002:59:0;;95018:42;95002:59;94998:157;;;-1:-1:-1;95100:42:0;95086:57;;94998:157;-1:-1:-1;;;;;95169:59:0;;95185:42;95169:59;95165:157;;;-1:-1:-1;95267:42:0;95253:57;;95165:157;-1:-1:-1;;;;;95336:59:0;;95352:42;95336:59;95332:156;;;-1:-1:-1;95433:42:0;95419:57;;95332:156;-1:-1:-1;;;;;95502:59:0;;95518:42;95502:59;95498:157;;;-1:-1:-1;95600:42:0;95586:57;;95498:157;-1:-1:-1;;;94283:1409:0;;;:::o;106303:328::-;106486:137;106513:9;106537:7;106559:6;106580:12;106607:5;106845:7;-1:-1:-1;;;;;106832:20:0;:9;-1:-1:-1;;;;;106832:20:0;;106828:59;;;106869:7;;106828:59;106949:33;:5;3923:4;106949:33;:11;:33;:::i;:::-;106903:79;;:42;:5;5881:10;106903:42;:11;:42;:::i;:::-;:79;;;106899:1599;;;106999:17;107019:26;107035:9;107019:15;:26::i;:::-;106999:46;-1:-1:-1;;;;;;107064:24:0;;;;107060:624;;107113:18;:10;-1:-1:-1;;;;;107113:16:0;;:18::i;:::-;107109:245;;;107156:68;;;-1:-1:-1;;;107156:68:0;;107210:4;107156:68;;;;;;;;;;;;-1:-1:-1;;;;;107156:45:0;;;;;:68;;;;;;;;;;;;;;-1:-1:-1;107156:45:0;:68;;;5:2:-1;;;;30:1;27;20:12;5:2;107156:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;107156:68:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;107109:245:0;;-1:-1:-1;107109:245:0;;107273:61;;;-1:-1:-1;;;107273:61:0;;107320:4;107273:61;;;;;;;;;;;;-1:-1:-1;;;;;107273:38:0;;;;;:61;;;;;;;;;;;;;;-1:-1:-1;107273:38:0;:61;;;5:2:-1;;;;30:1;27;20:12;5:2;107273:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;107273:61:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;107109:245:0;107374:24;107401:44;-1:-1:-1;;;;;107401:29:0;;107439:4;107401:44;:29;:44;:::i;:::-;107374:71;;107473:195;107507:10;107540:7;107570:16;107609:12;107644:5;107473:11;:195::i;107060:624::-;107713:24;107729:7;107713:15;:24::i;:::-;107700:37;-1:-1:-1;;;;;;107756:24:0;;;;107752:735;;107801:187;107835:9;107867:10;107900:6;107929:12;107964:5;107801:11;:187::i;:::-;108009:24;108036:44;-1:-1:-1;;;;;108036:29:0;;108074:4;108036:44;:29;:44;:::i;:::-;108009:71;;108105:18;:10;-1:-1:-1;;;;;108105:16:0;;:18::i;:::-;108101:346;;;108148:84;;;-1:-1:-1;;;108148:84:0;;108226:4;108148:84;;;;;;-1:-1:-1;;;;;108148:45:0;;;;;108200:16;;108148:84;;;;;;;;;;;;;;;108200:16;108148:45;:84;;;5:2:-1;;;;30:1;27;20:12;5:2;108148:84:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;108148:84:0;;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108101:346:0;;-1:-1:-1;108101:346:0;;108281:54;108306:10;108326:7;108281:24;:54::i;:::-;108358:69;;;-1:-1:-1;;;108358:69:0;;108403:4;108358:69;;;;;;;;;;;;-1:-1:-1;;;;;108358:36:0;;;;;:69;;;;;;;;;;;;;;-1:-1:-1;108358:36:0;:69;;;5:2:-1;;;;30:1;27;20:12;107752:735:0;106899:1599;;108517:136;108543:9;108567:7;108589:6;108610:12;108637:5;130805:325;130988:134;131012:9;131036:7;131058:6;131079:12;131106:5;131138:1666;131341:7;-1:-1:-1;;;;;131328:20:0;:9;-1:-1:-1;;;;;131328:20:0;;131324:59;;;131365:7;;131324:59;131445:30;:5;4033:4;131445:30;:11;:30;:::i;:::-;131399:76;;:42;:5;5881:10;131399:42;:11;:42;:::i;:::-;:76;;;131395:1246;;;131492:17;131512:34;131536:9;131512:23;:34::i;:::-;131492:54;-1:-1:-1;;;;;;131565:24:0;;;;131561:321;;131629:9;-1:-1:-1;;;;;131610:37:0;;131648:6;131610:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;131610:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;131610:45:0;;;;131683:183;131715:10;131748:7;131778:6;131807:12;131842:5;131683:9;:183::i;:::-;131676:190;;;131561:321;131911:32;131935:7;131911:23;:32::i;:::-;131898:45;-1:-1:-1;;;;;;131962:24:0;;;;131958:672;;132007:187;132041:9;132073:10;132106:6;132135:12;132170:5;132007:11;:187::i;:::-;132215:24;132242:44;-1:-1:-1;;;;;132242:29:0;;132280:4;132242:44;:29;:44;:::i;:::-;132215:71;;132307:49;132332:10;39984:42;-1:-1:-1;;;;;132344:9:0;;:11;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;132344:11:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;132344:11:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;132344:11:0;132307:24;:49::i;:::-;39984:42;132375:12;132394:18;-1:-1:-1;;;;;132394:16:0;;;:18::i;:::-;:41;;132434:1;132394:41;;;132415:16;132394:41;132459:18;:10;-1:-1:-1;;;;;132459:16:0;;:18::i;:::-;:45;;132494:10;132459:45;;;36929:42;132459:45;132375:214;;;-1:-1:-1;;;;;;132375:214:0;;;;;;;-1:-1:-1;;;;;132375:214:0;;;;;;;;;;;;;132566:4;132375:214;;;;;;;;;;-1:-1:-1;;132375:214:0;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;131958:672:0;131395:1246;;132660:136;132686:9;132710:7;132732:6;132753:12;132780:5;132660:11;:136::i;125907:2905::-;125976:6;-1:-1:-1;;;;;125999:59:0;;126015:42;125999:59;125995:115;;;-1:-1:-1;126096:1:0;126082:16;;125995:115;-1:-1:-1;;;;;126124:59:0;;126140:42;126124:59;126120:156;;;-1:-1:-1;126221:42:0;126207:57;;126120:156;-1:-1:-1;;;;;126290:59:0;;126306:42;126290:59;126286:157;;;-1:-1:-1;126388:42:0;126374:57;;126286:157;-1:-1:-1;;;;;126457:59:0;;126473:42;126457:59;126453:157;;;-1:-1:-1;126555:42:0;126541:57;;126453:157;-1:-1:-1;;;;;126624:59:0;;126640:42;126624:59;126620:157;;;-1:-1:-1;126722:42:0;126708:57;;126620:157;-1:-1:-1;;;;;126791:59:0;;126807:42;126791:59;126787:157;;;-1:-1:-1;126889:42:0;126875:57;;126787:157;-1:-1:-1;;;;;126958:59:0;;126974:42;126958:59;126954:157;;;-1:-1:-1;127056:42:0;127042:57;;126954:157;-1:-1:-1;;;;;127125:59:0;;127141:42;127125:59;127121:156;;;-1:-1:-1;127222:42:0;127208:57;;127121:156;-1:-1:-1;;;;;127291:59:0;;127307:42;127291:59;127287:156;;;-1:-1:-1;127388:42:0;127374:57;;127287:156;-1:-1:-1;;;;;127457:59:0;;127473:42;127457:59;127453:157;;;-1:-1:-1;127555:42:0;127541:57;;127453:157;-1:-1:-1;;;;;127624:59:0;;127640:42;127624:59;127620:157;;;-1:-1:-1;127722:42:0;127708:57;;127620:157;-1:-1:-1;;;;;127791:59:0;;127807:42;127791:59;127787:157;;;-1:-1:-1;127889:42:0;127875:57;;127787:157;-1:-1:-1;;;;;127958:59:0;;127974:42;127958:59;127954:156;;;-1:-1:-1;128055:42:0;128041:57;;127954:156;-1:-1:-1;;;;;128124:59:0;;128140:42;128124:59;128120:156;;;-1:-1:-1;128221:42:0;128207:57;;128120:156;-1:-1:-1;;;;;128290:59:0;;128306:42;128290:59;128286:156;;;-1:-1:-1;128387:42:0;128373:57;;128286:156;-1:-1:-1;;;;;128456:59:0;;128472:42;128456:59;128452:157;;;-1:-1:-1;128554:42:0;128540:57;;128452:157;-1:-1:-1;;;;;128623:59:0;;128639:42;128623:59;128619:156;;;-1:-1:-1;128720:42:0;128706:57;;113254:1640;113454:7;-1:-1:-1;;;;;113441:20:0;:9;-1:-1:-1;;;;;113441:20:0;;113437:59;;;113478:7;;113437:59;113558:30;:5;4241;113558:30;:11;:30;:::i;:::-;113512:76;;:42;:5;5881:10;113512:42;:11;:42;:::i;:::-;:76;;;113508:1299;;;113629:4;;-1:-1:-1;;;;;113609:25:0;;;113629:4;;113609:25;113605:907;;;113655:4;;;:17;;;-1:-1:-1;;;113655:17:0;;;;;;;;;;-1:-1:-1;;;;;113655:4:0;;;;:9;;:17;;;;;;;;;;:4;;:17;;;5:2:-1;;;;30:1;27;20:12;5:2;113655:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;113714:3:0;;:28;;;-1:-1:-1;;;113714:28:0;;113736:4;113714:28;;;;;;113693:18;;-1:-1:-1;;;;;;113714:3:0;;;;-1:-1:-1;113714:13:0;;:28;;;;;;;;;;;;;;:3;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;113714:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;113714:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;113714:28:0;;-1:-1:-1;113765:14:0;;113761:530;;113886:3;;;113806:32;;113842:201;;-1:-1:-1;;;;;113886:3:0;;113916:7;;113950:10;;114015:5;113842:17;:201::i;:::-;114100:3;;113804:239;;-1:-1:-1;114068:203:0;;-1:-1:-1;;;;;;114100:3:0;114130:7;114164:10;113804:239;114243:5;114068;:203::i;:::-;113761:530;;114318:178;37017:42;114378:7;114408:6;114437:12;114472:5;114318:11;:178::i;113605:907::-;114550:4;;-1:-1:-1;;;;;114532:23:0;;;114550:4;;114532:23;114528:268;;;114576:56;114588:9;37017:42;114604:6;114612:12;114626:5;114576:11;:56::i;:::-;114691:4;;114653:44;;37017:42;;-1:-1:-1;;;;;114691:4:0;114653:24;:44::i;:::-;114716:4;;114726:28;;;-1:-1:-1;;;114726:28:0;;114748:4;114726:28;;;;;;-1:-1:-1;;;;;114716:4:0;;;;:9;;37017:42;;114726:13;;:28;;;;;;;;;;;;;;;37017:42;114726:28;;;5:2:-1;;;;30:1;27;20:12;5:2;114726:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114726:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;114726:28:0;114716:39;;;-1:-1:-1;;;;;;114716:39:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;114716:39:0;;;;;;;-1:-1:-1;114716:39:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;114716:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;114528:268:0;114826:60;114838:9;114849:7;114858:6;114866:12;114880:5;110189:1274;110389:7;-1:-1:-1;;;;;110376:20:0;:9;-1:-1:-1;;;;;110376:20:0;;110372:59;;;110413:7;;110372:59;110493:30;:5;3978:4;110493:30;:11;:30;:::i;:::-;110447:76;;:42;:5;5881:10;110447:42;:11;:42;:::i;:::-;:76;;;110443:857;;;-1:-1:-1;;;;;110544:25:0;;37915:42;110544:25;110540:326;;;110590:32;;;-1:-1:-1;;;110590:32:0;;110608:4;110590:32;;;;;;;;;;;;37915:42;;110590:9;;:32;;;;;-1:-1:-1;;110590:32:0;;;;;;;-1:-1:-1;37915:42:0;110590:32;;;5:2:-1;;;;30:1;27;20:12;5:2;110590:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;110740:28:0;;;-1:-1:-1;;;110740:28:0;;110762:4;110740:28;;;;;;110650:200;;-1:-1:-1;37017:42:0;;-1:-1:-1;110710:7:0;;37017:42;;110740:13;;:28;;;;;;;;;;;;;;;37017:42;110740:28;;;5:2:-1;;;;30:1;27;20:12;5:2;110740:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110740:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;110740:28:0;110791:12;110826:5;110650:11;:200::i;110540:326::-;-1:-1:-1;;;;;110886:23:0;;37915:42;110886:23;110882:407;;;110930:180;110964:9;37017:42;111022:6;111051:12;111086:5;110930:11;:180::i;:::-;111131:44;37017:42;37915;111131:24;:44::i;:::-;111219:28;;;-1:-1:-1;;;111219:28:0;;111212:4;111219:28;;;;;;;;37915:42;;111194:9;;111212:4;;37017:42;;111219:13;;:28;;;;;;;;;;;;;;37017:42;111219:28;;;5:2:-1;;;;30:1;27;20:12;5:2;111219:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111219:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;111219:28:0;111194:54;;;-1:-1:-1;;;;;;111194:54:0;;;;;;;-1:-1:-1;;;;;111194:54:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;111194:54:0;;;;;;;-1:-1:-1;111194:54:0;;;;5:2:-1;;;;30:1;27;20:12;110882:407:0;111319:136;111345:9;111369:7;111391:6;111412:12;111439:5;93000:1163;93183:15;93201:25;93220:5;93201:18;:25::i;:::-;93183:43;-1:-1:-1;;;;;;93243:21:0;;;93239:768;;93281:21;93319:12;:19;93305:34;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;93305:34:0;-1:-1:-1;93281:58:0;-1:-1:-1;93359:6:0;93354:114;93375:12;:19;93371:1;:23;93354:114;;;93430:12;93443:1;93430:15;;;;;;;;;;;;;;93448:4;93430:22;93420:4;93425:1;93420:7;;;;;;;;;;;;;;;;;:32;93396:3;;93354:114;;;;93482:153;93512:9;93540:8;93567:6;93592:4;93615:5;93482:11;:153::i;:::-;93657:6;93652:121;93673:12;:19;93669:1;:23;93652:121;;;93748:1;93729:12;93742:1;93729:15;;;;;;;;;;;;;;:20;;93753:4;93728:29;93718:4;93723:1;93718:7;;;;;;;;;;;;;;;;;:39;93694:3;;93652:121;;;-1:-1:-1;93787:187:0;93817:8;93844:7;93870:42;-1:-1:-1;;;;;93870:27:0;;93906:4;93870:42;:27;:42;:::i;:::-;93931:4;93954:5;93787:11;:187::i;93239:768::-;94019:136;94045:9;94069:7;94091:6;94112:12;94139:5;94019:11;:136::i;89830:903::-;89895:15;89923:26;;:::i;:::-;:334;;;;;;;;4160:5;89923:334;;;;4619:7;89923:334;;;;4712:7;89923:334;;;;6156:11;89923:334;;;;6253:11;89923:334;;;;6350:12;89923:334;;;;6450:12;89923:334;;;;;90270:29;;:::i;:::-;-1:-1:-1;90270:184:0;;;;;;;;36929:42;90270:184;;37017:42;90270:184;;;;37190:42;90270:184;;;;;;;37277:42;90270:184;;;;38091:42;90270:184;;;;38178:42;90270:184;;;;38004:42;90270:184;;;;-1:-1:-1;90467:259:0;90488:15;90484:1;:19;90467:259;;;90529:24;90541:8;90550:1;90541:11;;;;;;;;;;;90529:5;;:24;:11;:24;:::i;:::-;90525:190;;;-1:-1:-1;;;;;90582:21:0;;;90574:80;;;;-1:-1:-1;;;90574:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90684:12;90697:1;90684:15;;;;;;;;;;;90673:26;;90525:190;90505:3;;90467:259;;;;89830:903;;;;;:::o;72048:431::-;72282:7;-1:-1:-1;;;;;72269:20:0;:9;-1:-1:-1;;;;;72269:20:0;;72265:59;;;72306:7;;72265:59;72336:135;72361:9;72385:7;72407:6;72428:12;72455:5;140858:8;;140895:228;;-1:-1:-1;;;;;140895:228:0;;;;;;;;;;;;;;;;;;;;;;140815:12;140895:228;;;;;;;;;;;;;;;;;;;;;;;;;;;140815:12;;140829:17;;140858:8;;;-1:-1:-1;;;140936:18:0;140973:9;;141001:7;;141027:6;;140815:12;;141072;;141103:5;;140895:228;;;;;;;;;;;;;;140815: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;140895:228:0;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;140895:228:0;;;;-1:-1:-1;;;;;140895: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;;;140895:228:0;140850: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;;;140850: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;;140814:320:0;;;;141178:7;141261:1;141256:48;;;;141171:133;;141256:48;141287:14;141282:2;141276:4;141272:13;141265:37;141171:133;;141156:159;;;;;;;:::o;138467:2858::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138467:2858:0;;;-1:-1:-1;;138467:2858:0:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138467:2858:0;;;-1:-1:-1;;138467:2858:0:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;138467:2858:0;;;-1:-1:-1;;138467:2858:0:o
Swarm Source
bzzr://c4c342bbe296ca3f12452c3cbe38ff8890a1ac3feae34e965c8aaeae89cc8c95
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BSC | 100.00% | $2.46 | 1 | $2.46 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.