BasketDAO has reported that their BMIBurner contract has a vulnerability. More information here.
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 42 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Burn BMI To USDC | 14372591 | 976 days ago | IN | 0 ETH | 0.09027131 | ||||
Burn BMI To USDC | 14104315 | 1018 days ago | IN | 0 ETH | 0.23597236 | ||||
Burn BMI To USDC | 13820300 | 1062 days ago | IN | 0 ETH | 0.23165814 | ||||
Burn BMI To USDC | 13770635 | 1070 days ago | IN | 0 ETH | 0.20445738 | ||||
Burn BMI To USDC | 13751008 | 1073 days ago | IN | 0 ETH | 0.30998979 | ||||
Burn BMI To USDC | 13656846 | 1088 days ago | IN | 0 ETH | 0.33622643 | ||||
Burn BMI To USDC | 13632715 | 1092 days ago | IN | 0 ETH | 0.47274243 | ||||
Burn BMI To USDC | 13588276 | 1099 days ago | IN | 0 ETH | 0.80096985 | ||||
Burn BMI To USDC | 13585461 | 1099 days ago | IN | 0 ETH | 1.01694546 | ||||
Burn BMI To USDC | 13484048 | 1115 days ago | IN | 0 ETH | 0.34874955 | ||||
Burn BMI To USDC | 13480025 | 1116 days ago | IN | 0 ETH | 0.14341851 | ||||
Burn BMI To USDC | 13472704 | 1117 days ago | IN | 0 ETH | 0.1836656 | ||||
Burn BMI To USDC | 13459457 | 1119 days ago | IN | 0 ETH | 0.25283764 | ||||
Burn BMI To USDC | 13459073 | 1119 days ago | IN | 0 ETH | 0.25122976 | ||||
Burn BMI To USDC | 13454207 | 1120 days ago | IN | 0 ETH | 0.17924352 | ||||
Burn BMI To USDC | 13445716 | 1121 days ago | IN | 0 ETH | 0.20525151 | ||||
Burn BMI To USDC | 13310415 | 1142 days ago | IN | 0 ETH | 0.36068672 | ||||
Burn BMI To USDC | 13310338 | 1142 days ago | IN | 0 ETH | 0.15188145 | ||||
Burn BMI To USDC | 13273283 | 1148 days ago | IN | 0 ETH | 0.2548861 | ||||
Burn BMI To USDC | 13229131 | 1155 days ago | IN | 0 ETH | 0.30574126 | ||||
Burn BMI To USDC | 13186341 | 1161 days ago | IN | 0 ETH | 1.7620278 | ||||
Burn BMI To USDC | 13110322 | 1173 days ago | IN | 0 ETH | 0.51349543 | ||||
Burn BMI To USDC | 13063444 | 1180 days ago | IN | 0 ETH | 0.21215243 | ||||
Burn BMI To USDC | 13063074 | 1180 days ago | IN | 0 ETH | 0.28596432 | ||||
Burn BMI To USDC | 13061744 | 1181 days ago | IN | 0 ETH | 0.18065445 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
BMIBurner
Compiler Version
v0.7.3+commit.9bfce1f6
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; import "./IBasket.sol"; import "./BMIZapper.sol"; contract BMIBurner is BMIZapper { using SafeERC20 for IERC20; constructor() {} function burnBMIToUSDC(uint256 _amount, uint256 _minRecv) public returns (uint256) { // Burn BMI IERC20(BMI).safeTransferFrom(msg.sender, address(this), _amount); (address[] memory constituients, ) = IBasket(BMI).getAssetsAndBalances(); IBasket(BMI).burn(_amount); // Convert BMI for (uint256 i = 0; i < constituients.length; i++) { _fromBMIConstituentToUSDC(constituients[i], IERC20(constituients[i]).balanceOf(address(this))); } uint256 usdcBal = IERC20(USDC).balanceOf(address(this)); require(usdcBal >= _minRecv, "!min-usdc"); IERC20(USDC).safeTransfer(msg.sender, usdcBal); return usdcBal; } }
// SPDX-License-Identifier: BSD-4-Clause /* * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.7.0; /** * Smart contract library of mathematical functions operating with signed * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is * basically a simple fraction whose numerator is signed 128-bit integer and * denominator is 2^64. As long as denominator is always the same, there is no * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are * represented by int128 type holding only the numerator. */ library ABDKMath64x64 { /* * Minimum value signed 64.64-bit fixed point number may have. */ int128 private constant MIN_64x64 = -0x80000000000000000000000000000000; /* * Maximum value signed 64.64-bit fixed point number may have. */ int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; /** * Convert signed 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromInt (int256 x) internal pure returns (int128) { require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into signed 64-bit integer number * rounding down. * * @param x signed 64.64-bit fixed point number * @return signed 64-bit integer number */ function toInt (int128 x) internal pure returns (int64) { return int64 (x >> 64); } /** * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromUInt (uint256 x) internal pure returns (int128) { require (x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into unsigned 64-bit integer * number rounding down. Revert on underflow. * * @param x signed 64.64-bit fixed point number * @return unsigned 64-bit integer number */ function toUInt (int128 x) internal pure returns (uint64) { require (x >= 0); return uint64 (x >> 64); } /** * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point * number rounding down. Revert on overflow. * * @param x signed 128.128-bin fixed point number * @return signed 64.64-bit fixed point number */ function from128x128 (int256 x) internal pure returns (int128) { int256 result = x >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Convert signed 64.64 fixed point number into signed 128.128 fixed point * number. * * @param x signed 64.64-bit fixed point number * @return signed 128.128 fixed point number */ function to128x128 (int128 x) internal pure returns (int256) { return int256 (x) << 64; } /** * Calculate x + y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function add (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) + y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x - y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sub (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) - y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding down. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function mul (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) * y >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point * number and y is signed 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y signed 256-bit integer number * @return signed 256-bit integer number */ function muli (int128 x, int256 y) internal pure returns (int256) { if (x == MIN_64x64) { require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && y <= 0x1000000000000000000000000000000000000000000000000); return -y << 63; } else { bool negativeResult = false; if (x < 0) { x = -x; negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint256 absoluteResult = mulu (x, uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (absoluteResult); } } } /** * Calculate x * y rounding down, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y unsigned 256-bit integer number * @return unsigned 256-bit integer number */ function mulu (int128 x, uint256 y) internal pure returns (uint256) { if (y == 0) return 0; require (x >= 0); uint256 lo = (uint256 (x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64; uint256 hi = uint256 (x) * (y >> 128); require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); hi <<= 64; require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo); return hi + lo; } /** * Calculate x / y rounding towards zero. Revert on overflow or when y is * zero. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function div (int128 x, int128 y) internal pure returns (int128) { require (y != 0); int256 result = (int256 (x) << 64) / y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x / y rounding towards zero, where x and y are signed 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x signed 256-bit integer number * @param y signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function divi (int256 x, int256 y) internal pure returns (int128) { require (y != 0); bool negativeResult = false; if (x < 0) { x = -x; // We rely on overflow behavior here negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint128 absoluteResult = divuu (uint256 (x), uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function divu (uint256 x, uint256 y) internal pure returns (int128) { require (y != 0); uint128 result = divuu (x, y); require (result <= uint128 (MAX_64x64)); return int128 (result); } /** * Calculate -x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function neg (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return -x; } /** * Calculate |x|. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function abs (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return x < 0 ? -x : x; } /** * Calculate 1 / x rounding towards zero. Revert on overflow or when x is * zero. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function inv (int128 x) internal pure returns (int128) { require (x != 0); int256 result = int256 (0x100000000000000000000000000000000) / x; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function avg (int128 x, int128 y) internal pure returns (int128) { return int128 ((int256 (x) + int256 (y)) >> 1); } /** * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down. * Revert on overflow or in case x * y is negative. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function gavg (int128 x, int128 y) internal pure returns (int128) { int256 m = int256 (x) * int256 (y); require (m >= 0); require (m < 0x4000000000000000000000000000000000000000000000000000000000000000); return int128 (sqrtu (uint256 (m))); } /** * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y uint256 value * @return signed 64.64-bit fixed point number */ function pow (int128 x, uint256 y) internal pure returns (int128) { uint256 absoluteResult; bool negativeResult = false; if (x >= 0) { absoluteResult = powu (uint256 (x) << 63, y); } else { // We rely on overflow behavior here absoluteResult = powu (uint256 (uint128 (-x)) << 63, y); negativeResult = y & 1 > 0; } absoluteResult >>= 63; if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } /** * Calculate sqrt (x) rounding down. Revert if x < 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sqrt (int128 x) internal pure returns (int128) { require (x >= 0); return int128 (sqrtu (uint256 (x) << 64)); } /** * Calculate binary logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function log_2 (int128 x) internal pure returns (int128) { require (x > 0); int256 msb = 0; int256 xc = x; if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 result = msb - 64 << 64; uint256 ux = uint256 (x) << uint256 (127 - msb); for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) { ux *= ux; uint256 b = ux >> 255; ux >>= 127 + b; result += bit * int256 (b); } return int128 (result); } /** * Calculate natural logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function ln (int128 x) internal pure returns (int128) { require (x > 0); return int128 ( uint256 (log_2 (x)) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128); } /** * Calculate binary exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp_2 (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow uint256 result = 0x80000000000000000000000000000000; if (x & 0x8000000000000000 > 0) result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (x & 0x4000000000000000 > 0) result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (x & 0x2000000000000000 > 0) result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (x & 0x1000000000000000 > 0) result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (x & 0x800000000000000 > 0) result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (x & 0x400000000000000 > 0) result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (x & 0x200000000000000 > 0) result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (x & 0x100000000000000 > 0) result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (x & 0x80000000000000 > 0) result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (x & 0x40000000000000 > 0) result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (x & 0x20000000000000 > 0) result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (x & 0x10000000000000 > 0) result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (x & 0x8000000000000 > 0) result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (x & 0x4000000000000 > 0) result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (x & 0x2000000000000 > 0) result = result * 0x1000162E525EE054754457D5995292026 >> 128; if (x & 0x1000000000000 > 0) result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (x & 0x800000000000 > 0) result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (x & 0x400000000000 > 0) result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (x & 0x200000000000 > 0) result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (x & 0x100000000000 > 0) result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (x & 0x80000000000 > 0) result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (x & 0x40000000000 > 0) result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (x & 0x20000000000 > 0) result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (x & 0x10000000000 > 0) result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (x & 0x8000000000 > 0) result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (x & 0x4000000000 > 0) result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (x & 0x2000000000 > 0) result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (x & 0x1000000000 > 0) result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (x & 0x800000000 > 0) result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (x & 0x400000000 > 0) result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (x & 0x200000000 > 0) result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (x & 0x100000000 > 0) result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (x & 0x80000000 > 0) result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (x & 0x40000000 > 0) result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (x & 0x20000000 > 0) result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (x & 0x10000000 > 0) result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (x & 0x8000000 > 0) result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (x & 0x4000000 > 0) result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (x & 0x2000000 > 0) result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (x & 0x1000000 > 0) result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (x & 0x800000 > 0) result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (x & 0x400000 > 0) result = result * 0x100000000002C5C85FDF477B662B26945 >> 128; if (x & 0x200000 > 0) result = result * 0x10000000000162E42FEFA3AE53369388C >> 128; if (x & 0x100000 > 0) result = result * 0x100000000000B17217F7D1D351A389D40 >> 128; if (x & 0x80000 > 0) result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (x & 0x40000 > 0) result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (x & 0x20000 > 0) result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (x & 0x10000 > 0) result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (x & 0x8000 > 0) result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (x & 0x4000 > 0) result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (x & 0x2000 > 0) result = result * 0x1000000000000162E42FEFA39F02B772C >> 128; if (x & 0x1000 > 0) result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (x & 0x800 > 0) result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (x & 0x400 > 0) result = result * 0x100000000000002C5C85FDF473DEA871F >> 128; if (x & 0x200 > 0) result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (x & 0x100 > 0) result = result * 0x100000000000000B17217F7D1CF79E949 >> 128; if (x & 0x80 > 0) result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (x & 0x40 > 0) result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (x & 0x20 > 0) result = result * 0x100000000000000162E42FEFA39EF366F >> 128; if (x & 0x10 > 0) result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (x & 0x8 > 0) result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (x & 0x4 > 0) result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (x & 0x2 > 0) result = result * 0x1000000000000000162E42FEFA39EF358 >> 128; if (x & 0x1 > 0) result = result * 0x10000000000000000B17217F7D1CF79AB >> 128; result >>= uint256 (63 - (x >> 64)); require (result <= uint256 (MAX_64x64)); return int128 (result); } /** * Calculate natural exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow return exp_2 ( int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128)); } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return unsigned 64.64-bit fixed point number */ function divuu (uint256 x, uint256 y) private pure returns (uint128) { require (y != 0); uint256 result; if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) result = (x << 64) / y; else { uint256 msb = 192; uint256 xc = x >> 192; if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1); require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 hi = result * (y >> 128); uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 xh = x >> 192; uint256 xl = x << 64; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here lo = hi << 128; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here assert (xh == hi >> 128); result += xl / y; } require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return uint128 (result); } /** * Calculate x^y assuming 0^0 is 1, where x is unsigned 129.127 fixed point * number and y is unsigned 256-bit integer number. Revert on overflow. * * @param x unsigned 129.127-bit fixed point number * @param y uint256 value * @return unsigned 129.127-bit fixed point number */ function powu (uint256 x, uint256 y) private pure returns (uint256) { if (y == 0) return 0x80000000000000000000000000000000; else if (x == 0) return 0; else { int256 msb = 0; uint256 xc = x; if (xc >= 0x100000000000000000000000000000000) { xc >>= 128; msb += 128; } if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 xe = msb - 127; if (xe > 0) x >>= uint256 (xe); else x <<= uint256 (-xe); uint256 result = 0x80000000000000000000000000000000; int256 re = 0; while (y > 0) { if (y & 1 > 0) { result = result * x; y -= 1; re += xe; if (result >= 0x8000000000000000000000000000000000000000000000000000000000000000) { result >>= 128; re += 1; } else result >>= 127; if (re < -127) return 0; // Underflow require (re < 128); // Overflow } else { x = x * x; y >>= 1; xe <<= 1; if (x >= 0x8000000000000000000000000000000000000000000000000000000000000000) { x >>= 128; xe += 1; } else x >>= 127; if (xe < -127) return 0; // Underflow require (xe < 128); // Overflow } } if (re > 0) result <<= uint256 (re); else if (re < 0) result >>= uint256 (-re); return result; } } /** * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer * number. * * @param x unsigned 256-bit integer number * @return unsigned 128-bit integer number */ function sqrtu (uint256 x) private pure returns (uint128) { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return uint128 (r < r1 ? r : r1); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @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) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @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]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; import "./ICToken.sol"; import "./IYearn.sol"; import "./ILendingPoolV2.sol"; import "./IBasket.sol"; import "./IATokenV2.sol"; import "./ICurveZap.sol"; import "./ICurve.sol"; import "./ABDKMath64x64.sol"; import "./ERC20.sol"; import "./IERC20.sol"; import "./SafeERC20.sol"; import "./SafeMath.sol"; import "./Ownable.sol"; contract BMIZapper is Ownable { using SafeERC20 for IERC20; using SafeMath for uint256; using ABDKMath64x64 for int128; using ABDKMath64x64 for uint256; // Auxillery address constant AAVE_LENDING_POOL_V2 = 0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9; // Tokens // BMI address constant BMI = 0x0aC00355F80E289f53BF368C9Bdb70f5c114C44B; // Bare address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address constant TUSD = 0x0000000000085d4780B73119b644AE5ecd22b376; address constant SUSD = 0x57Ab1ec28D129707052df4dF418D58a2D46d5f51; address constant BUSD = 0x4Fabb145d64652a948d72533023f6E7A623C7C53; address constant USDP = 0x1456688345527bE1f37E9e627DA0837D6f08C925; address constant FRAX = 0x853d955aCEf822Db058eb8505911ED77F175b99e; address constant ALUSD = 0xBC6DA0FE9aD5f3b0d58160288917AA56653660E9; address constant LUSD = 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0; address constant USDN = 0x674C6Ad92Fd080e4004b2312b45f796a192D27a0; // Yearn address constant yDAI = 0x19D3364A399d251E894aC732651be8B0E4e85001; address constant yUSDC = 0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9; address constant yUSDT = 0x7Da96a3891Add058AdA2E826306D812C638D87a7; address constant yTUSD = 0x37d19d1c4E1fa9DC47bD1eA12f742a0887eDa74a; address constant ySUSD = 0xa5cA62D95D24A4a350983D5B8ac4EB8638887396; // Yearn CRV address constant yCRV = 0x4B5BfD52124784745c1071dcB244C6688d2533d3; // Y Pool address constant ycrvSUSD = 0x5a770DbD3Ee6bAF2802D29a901Ef11501C44797A; address constant ycrvYBUSD = 0x8ee57c05741aA9DB947A744E713C15d4d19D8822; address constant ycrvBUSD = 0x6Ede7F19df5df6EF23bD5B9CeDb651580Bdf56Ca; address constant ycrvUSDP = 0xC4dAf3b5e2A9e93861c3FBDd25f1e943B8D87417; address constant ycrvFRAX = 0xB4AdA607B9d6b2c9Ee07A275e9616B84AC560139; address constant ycrvALUSD = 0xA74d4B67b3368E83797a35382AFB776bAAE4F5C8; address constant ycrvLUSD = 0x5fA5B62c8AF877CB37031e0a3B2f34A78e3C56A6; address constant ycrvUSDN = 0x3B96d491f067912D18563d56858Ba7d6EC67a6fa; address constant ycrvIB = 0x27b7b1ad7288079A66d12350c828D3C00A6F07d7; address constant ycrvThree = 0x84E13785B5a27879921D6F685f041421C7F482dA; address constant ycrvDUSD = 0x30FCf7c6cDfC46eC237783D94Fc78553E79d4E9C; address constant ycrvMUSD = 0x8cc94ccd0f3841a468184aCA3Cc478D2148E1757; address constant ycrvUST = 0x1C6a9783F812b3Af3aBbf7de64c3cD7CC7D1af44; // Aave address constant aDAI = 0x028171bCA77440897B824Ca71D1c56caC55b68A3; address constant aUSDC = 0xBcca60bB61934080951369a648Fb03DF4F96263C; address constant aUSDT = 0x3Ed3B47Dd13EC9a98b44e6204A523E766B225811; address constant aTUSD = 0x101cc05f4A51C0319f570d5E146a8C625198e636; address constant aSUSD = 0x6C5024Cd4F8A59110119C56f8933403A539555EB; // Compound address constant cDAI = 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643; address constant cUSDC = 0x39AA39c021dfbaE8faC545936693aC917d5E7563; address constant cUSDT = 0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9; address constant cTUSD = 0x12392F67bdf24faE0AF363c24aC620a2f67DAd86; // Curve address constant crvY = 0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8; address constant crvYPool = 0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51; address constant crvYZap = 0xbBC81d23Ea2c3ec7e56D39296F0cbB648873a5d3; address constant crvSUSD = 0xC25a3A3b969415c80451098fa907EC722572917F; address constant crvSUSDPool = 0xA5407eAE9Ba41422680e2e00537571bcC53efBfD; address constant crvSUSDZap = 0xFCBa3E75865d2d561BE8D220616520c171F12851; address constant crvYBUSD = 0x3B3Ac5386837Dc563660FB6a0937DFAa5924333B; address constant crvYBUSDPool = 0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27; address constant crvYBUSDZap = 0xb6c057591E073249F2D9D88Ba59a46CFC9B59EdB; address constant crvThree = 0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490; address constant crvThreePool = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7; address constant crvUSDP = 0x7Eb40E450b9655f4B3cC4259BCC731c63ff55ae6; address constant crvUSDPPool = 0x42d7025938bEc20B69cBae5A77421082407f053A; address constant crvUSDPZap = 0x3c8cAee4E09296800f8D29A68Fa3837e2dae4940; address constant crvDUSD = 0x3a664Ab939FD8482048609f652f9a0B0677337B9; address constant crvDUSDPool = 0x8038C01A0390a8c547446a0b2c18fc9aEFEcc10c; address constant crvDUSDZap = 0x61E10659fe3aa93d036d099405224E4Ac24996d0; address constant crvMUSD = 0x1AEf73d49Dedc4b1778d0706583995958Dc862e6; address constant crvMUSDPool = 0x8474DdbE98F5aA3179B3B3F5942D724aFcdec9f6; address constant crvMUSDZap = 0x803A2B40c5a9BB2B86DD630B274Fa2A9202874C2; address constant crvUST = 0x94e131324b6054c0D789b190b2dAC504e4361b53; address constant crvUSTPool = 0x890f4e345B1dAED0367A877a1612f86A1f86985f; address constant crvUSTZap = 0xB0a0716841F2Fc03fbA72A891B8Bb13584F52F2d; address constant crvUSDN = 0x4f3E8F405CF5aFC05D68142F3783bDfE13811522; address constant crvUSDNPool = 0x0f9cb53Ebe405d49A0bbdBD291A65Ff571bC83e1; address constant crvUSDNZap = 0x094d12e5b541784701FD8d65F11fc0598FBC6332; address constant crvIB = 0x5282a4eF67D9C33135340fB3289cc1711c13638C; address constant crvIBPool = 0x2dded6Da1BF5DBdF597C45fcFaa3194e53EcfeAF; address constant crvBUSD = 0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a; address constant crvFRAX = 0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B; address constant crvALUSD = 0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c; address constant crvLUSD = 0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA; address constant crvMetaZapper = 0xA79828DF1850E8a3A3064576f380D90aECDD3359; // **** Constructor **** constructor() {} function recoverERC20(address _token) public onlyOwner { IERC20(_token).safeTransfer(msg.sender, IERC20(_token).balanceOf(address(this))); } function recoverERC20s(address[] memory _tokens) public onlyOwner { for (uint256 i = 0; i < _tokens.length; i++) { IERC20(_tokens[i]).safeTransfer(msg.sender, IERC20(_tokens[i]).balanceOf(address(this))); } } // **** View only functions **** // // Estimates USDC equilavent for yearn crv and crv pools function calcUSDCEquilavent(address _from, uint256 _amount) public view returns (uint256) { if (_isYearnCRV(_from)) { _amount = _amount.mul(IYearn(_from).pricePerShare()).div(1e18); _from = IYearn(_from).token(); } if (_from == crvY || _from == crvSUSD || _from == crvThree || _from == crvYBUSD) { address zap = crvYZap; if (_from == crvSUSD) { zap = crvSUSDZap; } else if (_from == crvThree) { zap = crvThreePool; } else if (_from == crvYBUSD) { zap = crvYBUSDZap; } return ICurveZapSimple(zap).calc_withdraw_one_coin(_amount, 1); } else if (_from == crvUSDN || _from == crvUSDP || _from == crvDUSD || _from == crvMUSD || _from == crvUST) { address zap = crvUSDNZap; if (_from == crvUSDP) { zap = crvUSDPZap; } else if (_from == crvDUSD) { zap = crvDUSDZap; } else if (_from == crvMUSD) { zap = crvMUSDZap; } else if (_from == crvUST) { zap = crvUSTZap; } return ICurveZapSimple(zap).calc_withdraw_one_coin(_amount, 2); } else if (_from == crvIB) { return ICurveZapSimple(crvIBPool).calc_withdraw_one_coin(_amount, 1, true); } else { // Meta pools, USDC is 2nd index return ICurveZapSimple(crvMetaZapper).calc_withdraw_one_coin(_from, _amount, 2); } } function getUnderlyingAmount(address _derivative, uint256 _amount) public view returns (address, uint256) { if (_isAave(_derivative)) { return (IATokenV2(_derivative).UNDERLYING_ASSET_ADDRESS(), _amount); } if (_isCompound(_derivative)) { uint256 rate = ICToken(_derivative).exchangeRateStored(); address underlying = ICToken(_derivative).underlying(); uint256 underlyingDecimals = ERC20(underlying).decimals(); uint256 mantissa = 18 + underlyingDecimals - 8; uint256 oneCTokenInUnderlying = rate.mul(1e18).div(10**mantissa); return (underlying, _amount.mul(oneCTokenInUnderlying).div(1e8)); } // YearnCRV just or CRV return USDC if (_isCRV(_derivative) || _isYearnCRV(_derivative)) { return (USDC, calcUSDCEquilavent(_derivative, _amount)); } if (_isYearn(_derivative)) { _amount = _amount.mul(IYearn(_derivative).pricePerShare()).div(1e18); if (_derivative == yDAI) { return (DAI, _amount); } if (_derivative == yUSDC) { return (USDC, _amount); } if (_derivative == yUSDT) { return (USDT, _amount); } if (_derivative == yTUSD) { return (TUSD, _amount); } if (_derivative == ySUSD) { return (SUSD, _amount); } } return (_derivative, _amount); } // **** Stateful functions **** function zapToBMI( address _from, uint256 _amount, address _fromUnderlying, uint256 _fromUnderlyingAmount, uint256 _minBMIRecv, address[] memory _bmiConstituents, uint256[] memory _bmiConstituentsWeightings, address _aggregator, bytes memory _aggregatorData, bool refundDust ) public returns (uint256) { uint256 sum = 0; for (uint256 i = 0; i < _bmiConstituentsWeightings.length; i++) { sum = sum.add(_bmiConstituentsWeightings[i]); } // Sum should be between 0.999 and 1.000 assert(sum <= 1e18); assert(sum >= 999e15); // Transfer to contract IERC20(_from).safeTransferFrom(msg.sender, address(this), _amount); // Primitive if (_isBare(_from)) { _primitiveToBMI(_from, _amount, _bmiConstituents, _bmiConstituentsWeightings, _aggregator, _aggregatorData); } // Yearn (primitive) else if (_isYearn(_from)) { IYearn(_from).withdraw(); _primitiveToBMI( _fromUnderlying, _fromUnderlyingAmount, _bmiConstituents, _bmiConstituentsWeightings, _aggregator, _aggregatorData ); } // Yearn (primitive) else if (_isYearnCRV(_from)) { IYearn(_from).withdraw(); address crvToken = IYearn(_from).token(); _crvToPrimitive(crvToken, IERC20(crvToken).balanceOf(address(this))); _primitiveToBMI( USDC, IERC20(USDC).balanceOf(address(this)), _bmiConstituents, _bmiConstituentsWeightings, address(0), "" ); } // Compound else if (_isCompound(_from)) { require(ICToken(_from).redeem(_amount) == 0, "!ctoken-redeem"); _primitiveToBMI( _fromUnderlying, _fromUnderlyingAmount, _bmiConstituents, _bmiConstituentsWeightings, _aggregator, _aggregatorData ); } // Aave else if (_isAave(_from)) { IERC20(_from).safeApprove(AAVE_LENDING_POOL_V2, 0); IERC20(_from).safeApprove(AAVE_LENDING_POOL_V2, _amount); ILendingPoolV2(AAVE_LENDING_POOL_V2).withdraw(_fromUnderlying, type(uint256).max, address(this)); _primitiveToBMI( _fromUnderlying, _fromUnderlyingAmount, _bmiConstituents, _bmiConstituentsWeightings, _aggregator, _aggregatorData ); } // Curve else { _crvToPrimitive(_from, _amount); _primitiveToBMI( USDC, IERC20(USDC).balanceOf(address(this)), _bmiConstituents, _bmiConstituentsWeightings, address(0), "" ); } // Checks uint256 _bmiBal = IERC20(BMI).balanceOf(address(this)); require(_bmiBal >= _minBMIRecv, "!min-mint"); IERC20(BMI).safeTransfer(msg.sender, _bmiBal); // Convert back dust to USDC and refund remaining USDC to usd if (refundDust) { for (uint256 i = 0; i < _bmiConstituents.length; i++) { _fromBMIConstituentToUSDC(_bmiConstituents[i], IERC20(_bmiConstituents[i]).balanceOf(address(this))); } IERC20(USDC).safeTransfer(msg.sender, IERC20(USDC).balanceOf(address(this))); } return _bmiBal; } // **** Internal helpers **** function _crvToPrimitive(address _from, uint256 _amount) internal { // Remove via zap to USDC if (_from == crvY || _from == crvSUSD || _from == crvYBUSD) { address zap = crvYZap; if (_from == crvSUSD) { zap = crvSUSDZap; } else if (_from == crvYBUSD) { zap = crvYBUSDZap; } IERC20(_from).safeApprove(zap, 0); IERC20(_from).safeApprove(zap, _amount); ICurveZapSimple(zap).remove_liquidity_one_coin(_amount, 1, 0, false); } else if (_from == crvUSDP || _from == crvUSDN || _from == crvDUSD || _from == crvMUSD || _from == crvUST) { address zap = crvUSDNZap; if (_from == crvUSDP) { zap = crvUSDPZap; } else if (_from == crvDUSD) { zap = crvDUSDZap; } else if (_from == crvMUSD) { zap = crvMUSDZap; } else if (_from == crvUST) { zap = crvUSTZap; } IERC20(_from).safeApprove(zap, 0); IERC20(_from).safeApprove(zap, _amount); ICurveZapSimple(zap).remove_liquidity_one_coin(_amount, 2, 0); } else if (_from == crvIB) { IERC20(_from).safeApprove(crvIBPool, 0); IERC20(_from).safeApprove(crvIBPool, _amount); ICurveZapSimple(crvIBPool).remove_liquidity_one_coin(_amount, 1, 0, true); } else if (_from == crvThree) { address zap = crvThreePool; IERC20(_from).safeApprove(zap, 0); IERC20(_from).safeApprove(zap, _amount); ICurveZapSimple(zap).remove_liquidity_one_coin(_amount, 1, 0); } else { // Meta pools, USDC is 2nd index IERC20(_from).safeApprove(crvMetaZapper, 0); IERC20(_from).safeApprove(crvMetaZapper, _amount); ICurveZapSimple(crvMetaZapper).remove_liquidity_one_coin(_from, _amount, 2, 0, address(this)); } } function _primitiveToBMI( address _token, uint256 _amount, address[] memory _bmiConstituents, uint256[] memory _bmiConstituentsWeightings, address _aggregator, bytes memory _aggregatorData ) internal { // Offset, DAI = 0, USDC = 1, USDT = 2 uint256 offset = 0; // Primitive to USDC (if not already USDC) if (_token != DAI && _token != USDC && _token != USDT) { IERC20(_token).safeApprove(_aggregator, 0); IERC20(_token).safeApprove(_aggregator, _amount); (bool success, ) = _aggregator.call(_aggregatorData); require(success, "!swap"); // Always goes to USDC // If we swapping _token = USDC; } if (_token == USDC) { offset = 1; } else if (_token == USDT) { offset = 2; } // Amount to mint uint256 amountToMint; uint256 bmiSupply = IERC20(BMI).totalSupply(); uint256 tokenBal = IERC20(_token).balanceOf(address(this)); uint256 tokenAmount; for (uint256 i = 0; i < _bmiConstituents.length; i++) { // Weighting of the token for BMI constituient tokenAmount = tokenBal.mul(_bmiConstituentsWeightings[i]).div(1e18); _toBMIConstituent(_token, _bmiConstituents[i], tokenAmount, offset); // Get amount to Mint amountToMint = _approveBMIAndGetMintableAmount(bmiSupply, _bmiConstituents[i], amountToMint); } // Mint BASK IBasket(BMI).mint(amountToMint); } function _approveBMIAndGetMintableAmount( uint256 _bmiTotalSupply, address _bmiConstituient, uint256 _curMintAmount ) internal returns (uint256) { uint256 bal = IERC20(_bmiConstituient).balanceOf(address(this)); uint256 bmiBal = IERC20(_bmiConstituient).balanceOf(BMI); IERC20(_bmiConstituient).safeApprove(BMI, 0); IERC20(_bmiConstituient).safeApprove(BMI, bal); // Calculate how much BMI we can mint at max // Formula: min(e for e in bmiSupply * tokenWeHave[e] / tokenInBMI[e]) if (_curMintAmount == 0) { return _bmiTotalSupply.mul(bal).div(bmiBal); } uint256 temp = _bmiTotalSupply.mul(bal).div(bmiBal); if (temp < _curMintAmount) { return temp; } return _curMintAmount; } function _toBMIConstituent( address _fromToken, address _toToken, uint256 _amount, uint256 _curveOffset ) internal { uint256 bal; uint256[4] memory depositAmounts4 = [uint256(0), uint256(0), uint256(0), uint256(0)]; if (_toToken == ySUSD) { IERC20(_fromToken).safeApprove(crvSUSDPool, 0); IERC20(_fromToken).safeApprove(crvSUSDPool, _amount); ICurvePool(crvSUSDPool).exchange(int128(_curveOffset), 3, _amount, 0); bal = IERC20(SUSD).balanceOf(address(this)); IERC20(SUSD).safeApprove(ySUSD, 0); IERC20(SUSD).safeApprove(ySUSD, bal); } // Gen 1 pools else if ( _toToken == yCRV || _toToken == ycrvSUSD || _toToken == ycrvYBUSD || _toToken == ycrvUSDN || _toToken == ycrvUSDP || _toToken == ycrvDUSD || _toToken == ycrvMUSD || _toToken == ycrvUST ) { address crvToken = IYearn(_toToken).token(); address zap = crvYZap; if (_toToken == ycrvSUSD) { zap = crvSUSDZap; } else if (_toToken == ycrvYBUSD) { zap = crvYBUSDZap; } else if (_toToken == ycrvUSDN) { zap = crvUSDNZap; _curveOffset += 1; } else if (_toToken == ycrvUSDP) { zap = crvUSDPZap; _curveOffset += 1; } else if (_toToken == ycrvDUSD) { zap = crvDUSDZap; _curveOffset += 1; } else if (_toToken == ycrvMUSD) { zap = crvMUSDZap; _curveOffset += 1; } else if (_toToken == ycrvUST) { zap = crvUSTZap; _curveOffset += 1; } depositAmounts4[_curveOffset] = _amount; IERC20(_fromToken).safeApprove(zap, 0); IERC20(_fromToken).safeApprove(zap, _amount); ICurveZapSimple(zap).add_liquidity(depositAmounts4, 0); bal = IERC20(crvToken).balanceOf(address(this)); IERC20(crvToken).safeApprove(_toToken, 0); IERC20(crvToken).safeApprove(_toToken, bal); } else if (_toToken == ycrvThree || _toToken == ycrvIB) { address crvToken = IYearn(_toToken).token(); uint256[3] memory depositAmounts3 = [uint256(0), uint256(0), uint256(0)]; depositAmounts3[_curveOffset] = _amount; address zap = crvThreePool; if (_toToken == ycrvIB) { zap = crvIBPool; } IERC20(_fromToken).safeApprove(zap, 0); IERC20(_fromToken).safeApprove(zap, _amount); if (_toToken == ycrvThree) { ICurveZapSimple(zap).add_liquidity(depositAmounts3, 0); } else { ICurveZapSimple(zap).add_liquidity(depositAmounts3, 0, true); } bal = IERC20(crvToken).balanceOf(address(this)); IERC20(crvToken).safeApprove(_toToken, 0); IERC20(crvToken).safeApprove(_toToken, bal); } // Meta pools else if (_toToken == ycrvBUSD || _toToken == ycrvFRAX || _toToken == ycrvALUSD || _toToken == ycrvLUSD) { // CRV Token = CRV Pool address crvToken = IYearn(_toToken).token(); depositAmounts4[_curveOffset + 1] = _amount; IERC20(_fromToken).safeApprove(crvMetaZapper, 0); IERC20(_fromToken).safeApprove(crvMetaZapper, _amount); ICurveZapSimple(crvMetaZapper).add_liquidity(crvToken, depositAmounts4, 0); bal = IERC20(crvToken).balanceOf(address(this)); IERC20(crvToken).safeApprove(_toToken, 0); IERC20(crvToken).safeApprove(_toToken, bal); } IYearn(_toToken).deposit(); } function _fromBMIConstituentToUSDC(address _fromToken, uint256 _amount) internal { if (_isYearnCRV(_fromToken)) { _crvToPrimitive(IYearn(_fromToken).token(), IYearn(_fromToken).withdraw(_amount)); } } function _isBare(address _token) internal pure returns (bool) { return (_token == DAI || _token == USDC || _token == USDT || _token == TUSD || _token == SUSD || _token == BUSD || _token == USDP || _token == FRAX || _token == ALUSD || _token == LUSD || _token == USDN); } function _isYearn(address _token) internal pure returns (bool) { return (_token == yDAI || _token == yUSDC || _token == yUSDT || _token == yTUSD || _token == ySUSD); } function _isYearnCRV(address _token) internal pure returns (bool) { return (_token == yCRV || _token == ycrvSUSD || _token == ycrvYBUSD || _token == ycrvBUSD || _token == ycrvUSDP || _token == ycrvFRAX || _token == ycrvALUSD || _token == ycrvLUSD || _token == ycrvUSDN || _token == ycrvThree || _token == ycrvIB || _token == ycrvMUSD || _token == ycrvUST || _token == ycrvDUSD); } function _isCRV(address _token) internal pure returns (bool) { return (_token == crvY || _token == crvSUSD || _token == crvYBUSD || _token == crvBUSD || _token == crvUSDP || _token == crvFRAX || _token == crvALUSD || _token == crvLUSD || _token == crvThree || _token == crvUSDN || _token == crvDUSD || _token == crvMUSD || _token == crvUST || _token == crvIB); } function _isCompound(address _token) internal pure returns (bool) { return (_token == cDAI || _token == cUSDC || _token == cUSDT || _token == cTUSD); } function _isAave(address _token) internal pure returns (bool) { return (_token == aDAI || _token == aUSDC || _token == aUSDT || _token == aTUSD || _token == aSUSD); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Context.sol"; import "./IERC20.sol"; import "./SafeMath.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * 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 virtual returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface IATokenV2 { function ATOKEN_REVISION() external view returns (uint256); function DOMAIN_SEPARATOR() external view returns (bytes32); function EIP712_REVISION() external view returns (bytes memory); function PERMIT_TYPEHASH() external view returns (bytes32); function POOL() external view returns (address); function RESERVE_TREASURY_ADDRESS() external view returns (address); function UINT_MAX_VALUE() external view returns (uint256); function UNDERLYING_ASSET_ADDRESS() external view returns (address); function _nonces(address) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address user) external view returns (uint256); function burn( address user, address receiverOfUnderlying, uint256 amount, uint256 index ) external; function decimals() external view returns (uint8); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function initialize( uint8 underlyingAssetDecimals, string memory tokenName, string memory tokenSymbol ) external; function mint( address user, uint256 amount, uint256 index ) external returns (bool); function mintToTreasury(uint256 amount, uint256 index) external; function name() external view returns (string memory); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function scaledBalanceOf(address user) external view returns (uint256); function scaledTotalSupply() external view returns (uint256); function symbol() external view returns (string memory); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); function transferOnLiquidation( address from, address to, uint256 value ) external; function transferUnderlyingTo(address target, uint256 amount) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface IBasket { function transfer(address dst, uint256 amount) external returns (bool); function totalSupply() external view returns (uint256); function mint(uint256) external; function getOne() external view returns (address[] memory, uint256[] memory); function getAssetsAndBalances() external view returns (address[] memory, uint256[] memory); function burn(uint256) external; function viewMint(uint256 _amountOut) external view returns (uint256[] memory _amountsIn); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface ICToken { function _acceptAdmin() external returns (uint256); function _addReserves(uint256 addAmount) external returns (uint256); function _reduceReserves(uint256 reduceAmount) external returns (uint256); function _setComptroller(address newComptroller) external returns (uint256); function _setImplementation( address implementation_, bool allowResign, bytes memory becomeImplementationData ) external; function _setInterestRateModel(address newInterestRateModel) external returns (uint256); function _setPendingAdmin(address newPendingAdmin) external returns (uint256); function _setReserveFactor(uint256 newReserveFactorMantissa) external returns (uint256); function accrualBlockNumber() external view returns (uint256); function accrueInterest() external returns (uint256); function admin() external view returns (address); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address owner) external view returns (uint256); function balanceOfUnderlying(address owner) external returns (uint256); function borrow(uint256 borrowAmount) external returns (uint256); function borrowBalanceCurrent(address account) external returns (uint256); function borrowBalanceStored(address account) external view returns (uint256); function borrowIndex() external view returns (uint256); function borrowRatePerBlock() external view returns (uint256); function comptroller() external view returns (address); function decimals() external view returns (uint8); function delegateToImplementation(bytes memory data) external returns (bytes memory); function delegateToViewImplementation(bytes memory data) external view returns (bytes memory); function exchangeRateCurrent() external returns (uint256); function exchangeRateStored() external view returns (uint256); function getAccountSnapshot(address account) external view returns ( uint256, uint256, uint256, uint256 ); function getCash() external view returns (uint256); function implementation() external view returns (address); function interestRateModel() external view returns (address); function isCToken() external view returns (bool); function liquidateBorrow( address borrower, uint256 repayAmount, address cTokenCollateral ) external returns (uint256); function mint(uint256 mintAmount) external returns (uint256); function name() external view returns (string memory); function pendingAdmin() external view returns (address); function redeem(uint256 redeemTokens) external returns (uint256); function redeemUnderlying(uint256 redeemAmount) external returns (uint256); function repayBorrow(uint256 repayAmount) external returns (uint256); function repayBorrowBehalf(address borrower, uint256 repayAmount) external returns (uint256); function reserveFactorMantissa() external view returns (uint256); function seize( address liquidator, address borrower, uint256 seizeTokens ) external returns (uint256); function supplyRatePerBlock() external view returns (uint256); function symbol() external view returns (string memory); function totalBorrows() external view returns (uint256); function totalBorrowsCurrent() external returns (uint256); function totalReserves() external view returns (uint256); function totalSupply() external view returns (uint256); function transfer(address dst, uint256 amount) external returns (bool); function transferFrom( address src, address dst, uint256 amount ) external returns (bool); function underlying() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface ICurvePool { function exchange( int128 i, int128 j, uint256 _dx, uint256 _min_dy ) external; function get_dy( int128 i, int128 j, uint256 _dx ) external view returns (uint256); function get_virtual_price() external view returns (uint256); } interface ICurveLINK { function A() external view returns (uint256); function A_precise() external view returns (uint256); function get_virtual_price() external view returns (uint256); function calc_token_amount(uint256[2] memory _amounts, bool _is_deposit) external view returns (uint256); function add_liquidity(uint256[2] memory _amounts, uint256 _min_mint_amount) external returns (uint256); function get_dy( int128 i, int128 j, uint256 _dx ) external view returns (uint256); function exchange( int128 i, int128 j, uint256 _dx, uint256 _min_dy ) external returns (uint256); function remove_liquidity(uint256 _amount, uint256[2] memory _min_amounts) external returns (uint256[2] memory); function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount) external returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 _min_amount ) external returns (uint256); function ramp_A(uint256 _future_A, uint256 _future_time) external; function stop_ramp_A() external; function commit_new_fee(uint256 _new_fee, uint256 _new_admin_fee) external; function apply_new_fee() external; function revert_new_parameters() external; function commit_transfer_ownership(address _owner) external; function apply_transfer_ownership() external; function revert_transfer_ownership() external; function admin_balances(uint256 i) external view returns (uint256); function withdraw_admin_fees() external; function donate_admin_fees() external; function kill_me() external; function unkill_me() external; function coins(uint256 arg0) external view returns (address); function balances(uint256 arg0) external view returns (uint256); function fee() external view returns (uint256); function admin_fee() external view returns (uint256); function previous_balances(uint256 arg0) external view returns (uint256); function block_timestamp_last() external view returns (uint256); function owner() external view returns (address); function lp_token() external view returns (address); function initial_A() external view returns (uint256); function future_A() external view returns (uint256); function initial_A_time() external view returns (uint256); function future_A_time() external view returns (uint256); function admin_actions_deadline() external view returns (uint256); function transfer_ownership_deadline() external view returns (uint256); function future_fee() external view returns (uint256); function future_admin_fee() external view returns (uint256); function future_owner() external view returns (address); } interface ILinkGauge { function decimals() external view returns (uint256); function integrate_checkpoint() external view returns (uint256); function user_checkpoint(address addr) external returns (bool); function claimable_tokens(address addr) external returns (uint256); function claimable_reward(address _addr, address _token) external returns (uint256); function claim_rewards() external; function claim_rewards(address _addr) external; function claim_historic_rewards(address[8] memory _reward_tokens) external; function claim_historic_rewards(address[8] memory _reward_tokens, address _addr) external; function kick(address addr) external; function set_approve_deposit(address addr, bool can_deposit) external; function deposit(uint256 _value) external; function deposit(uint256 _value, address _addr) external; function withdraw(uint256 _value) external; function allowance(address _owner, address _spender) external view returns (uint256); function transfer(address _to, uint256 _value) external returns (bool); function transferFrom( address _from, address _to, uint256 _value ) external returns (bool); function approve(address _spender, uint256 _value) external returns (bool); function increaseAllowance(address _spender, uint256 _added_value) external returns (bool); function decreaseAllowance(address _spender, uint256 _subtracted_value) external returns (bool); function set_rewards( address _reward_contract, bytes32 _sigs, address[8] memory _reward_tokens ) external; function set_killed(bool _is_killed) external; function commit_transfer_ownership(address addr) external; function accept_transfer_ownership() external; function minter() external view returns (address); function crv_token() external view returns (address); function lp_token() external view returns (address); function controller() external view returns (address); function voting_escrow() external view returns (address); function future_epoch_time() external view returns (uint256); function balanceOf(address arg0) external view returns (uint256); function totalSupply() external view returns (uint256); function name() external view returns (string memory); function symbol() external view returns (string memory); function approved_to_deposit(address arg0, address arg1) external view returns (bool); function working_balances(address arg0) external view returns (uint256); function working_supply() external view returns (uint256); function period() external view returns (int128); function period_timestamp(uint256 arg0) external view returns (uint256); function integrate_inv_supply(uint256 arg0) external view returns (uint256); function integrate_inv_supply_of(address arg0) external view returns (uint256); function integrate_checkpoint_of(address arg0) external view returns (uint256); function integrate_fraction(address arg0) external view returns (uint256); function inflation_rate() external view returns (uint256); function reward_contract() external view returns (address); function reward_tokens(uint256 arg0) external view returns (address); function reward_integral(address arg0) external view returns (uint256); function reward_integral_for(address arg0, address arg1) external view returns (uint256); function admin() external view returns (address); function future_admin() external view returns (address); function is_killed() external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface ICurveZapSimple { function add_liquidity(uint256[3] memory _deposit_amounts, uint256 _min_mint_amount) external; function add_liquidity( uint256[3] memory _deposit_amounts, uint256 _min_mint_amount, bool use_underlying ) external; function add_liquidity(uint256[4] memory _deposit_amounts, uint256 _min_mint_amount) external; function add_liquidity( address _pool, uint256[4] memory _deposit_amounts, uint256 _min_mint_amount ) external returns (uint256); function add_liquidity( address _pool, uint256[4] memory _deposit_amounts, uint256 _min_mint_amount, address _receiver ) external returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount, bool _donate_dust ) external; function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount ) external; function remove_liquidity_one_coin( address pool, uint256 _token_amount, int128 i, uint256 min_amount, address _receiver ) external returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount, address _receiver ) external returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function calc_withdraw_one_coin( uint256 _token_amount, int128 i, bool use_underlying ) external view returns (uint256); function calc_withdraw_one_coin( address pool, uint256 _token_amount, int128 i ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface ILendingPoolV2 { function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint256); function LENDINGPOOL_REVISION() external view returns (uint256); function MAX_NUMBER_RESERVES() external view returns (uint256); function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; function flashLoan( address receiverAddress, address[] memory assets, uint256[] memory amounts, uint256[] memory modes, address onBehalfOf, bytes memory params, uint16 referralCode ) external; function getAddressesProvider() external view returns (address); function getConfiguration(address asset) external view returns (uint256); function getReserveData(address asset) external view returns ( uint256, uint128, uint128, uint128, uint128, uint128, uint40, address, address, address, address, uint8 ); function getReserveNormalizedIncome(address asset) external view returns (uint256); function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); function getReservesList() external view returns (address[] memory); function getUserAccountData(address user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); function initReserve( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function initialize(address provider) external; function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; function paused() external view returns (bool); function rebalanceStableBorrowRate(address asset, address user) external; function repay( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external returns (uint256); function setConfiguration(address asset, uint256 configuration) external; function setPause(bool val) external; function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) external; function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; function swapBorrowRateMode(address asset, uint256 rateMode) external; function withdraw( address asset, uint256 amount, address to ) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; interface IYearn { function initialize( address token, address governance, address rewards, string memory nameOverride, string memory symbolOverride ) external; function initialize( address token, address governance, address rewards, string memory nameOverride, string memory symbolOverride, address guardian ) external; function apiVersion() external pure returns (string memory); function setName(string memory name) external; function setSymbol(string memory symbol) external; function setGovernance(address governance) external; function acceptGovernance() external; function setManagement(address management) external; function setGuestList(address guestList) external; function setRewards(address rewards) external; function setLockedProfitDegration(uint256 degration) external; function setDepositLimit(uint256 limit) external; function setPerformanceFee(uint256 fee) external; function setManagementFee(uint256 fee) external; function setGuardian(address guardian) external; function setEmergencyShutdown(bool active) external; function setWithdrawalQueue(address[20] memory queue) external; function transfer(address receiver, uint256 amount) external returns (bool); function transferFrom( address sender, address receiver, uint256 amount ) external returns (bool); function approve(address spender, uint256 amount) external returns (bool); function increaseAllowance(address spender, uint256 amount) external returns (bool); function decreaseAllowance(address spender, uint256 amount) external returns (bool); function permit( address owner, address spender, uint256 amount, uint256 expiry, bytes memory signature ) external returns (bool); function totalAssets() external view returns (uint256); function deposit() external returns (uint256); function deposit(uint256 _amount) external returns (uint256); function deposit(uint256 _amount, address recipient) external returns (uint256); function maxAvailableShares() external view returns (uint256); function withdraw() external returns (uint256); function withdraw(uint256 maxShares) external returns (uint256); function withdraw(uint256 maxShares, address recipient) external returns (uint256); function withdraw( uint256 maxShares, address recipient, uint256 maxLoss ) external returns (uint256); function pricePerShare() external view returns (uint256); function addStrategy( address strategy, uint256 debtRatio, uint256 minDebtPerHarvest, uint256 maxDebtPerHarvest, uint256 performanceFee ) external; function updateStrategyDebtRatio(address strategy, uint256 debtRatio) external; function updateStrategyMinDebtPerHarvest(address strategy, uint256 minDebtPerHarvest) external; function updateStrategyMaxDebtPerHarvest(address strategy, uint256 maxDebtPerHarvest) external; function updateStrategyPerformanceFee(address strategy, uint256 performanceFee) external; function migrateStrategy(address oldVersion, address newVersion) external; function revokeStrategy() external; function revokeStrategy(address strategy) external; function addStrategyToQueue(address strategy) external; function removeStrategyFromQueue(address strategy) external; function debtOutstanding() external view returns (uint256); function debtOutstanding(address strategy) external view returns (uint256); function creditAvailable() external view returns (uint256); function creditAvailable(address strategy) external view returns (uint256); function availableDepositLimit() external view returns (uint256); function expectedReturn() external view returns (uint256); function expectedReturn(address strategy) external view returns (uint256); function report( uint256 gain, uint256 loss, uint256 _debtPayment ) external returns (uint256); function sweep(address token) external; function sweep(address token, uint256 amount) external; function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint256); function precisionFactor() external view returns (uint256); function balanceOf(address arg0) external view returns (uint256); function allowance(address arg0, address arg1) external view returns (uint256); function totalSupply() external view returns (uint256); function token() external view returns (address); function governance() external view returns (address); function management() external view returns (address); function guardian() external view returns (address); function guestList() external view returns (address); function strategies(address arg0) external view returns ( uint256 performanceFee, uint256 activation, uint256 debtRatio, uint256 minDebtPerHarvest, uint256 maxDebtPerHarvest, uint256 lastReport, uint256 totalDebt, uint256 totalGain, uint256 totalLoss ); function withdrawalQueue(uint256 arg0) external view returns (address); function emergencyShutdown() external view returns (bool); function depositLimit() external view returns (uint256); function debtRatio() external view returns (uint256); function totalDebt() external view returns (uint256); function lastReport() external view returns (uint256); function activation() external view returns (uint256); function lockedProfit() external view returns (uint256); function lockedProfitDegration() external view returns (uint256); function rewards() external view returns (address); function managementFee() external view returns (uint256); function performanceFee() external view returns (uint256); function nonces(address arg0) external view returns (uint256); function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "./SafeMath.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ 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. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "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"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minRecv","type":"uint256"}],"name":"burnBMIToUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calcUSDCEquilavent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_derivative","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getUnderlyingAmount","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"recoverERC20s","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_fromUnderlying","type":"address"},{"internalType":"uint256","name":"_fromUnderlyingAmount","type":"uint256"},{"internalType":"uint256","name":"_minBMIRecv","type":"uint256"},{"internalType":"address[]","name":"_bmiConstituents","type":"address[]"},{"internalType":"uint256[]","name":"_bmiConstituentsWeightings","type":"uint256[]"},{"internalType":"address","name":"_aggregator","type":"address"},{"internalType":"bytes","name":"_aggregatorData","type":"bytes"},{"internalType":"bool","name":"refundDust","type":"bool"}],"name":"zapToBMI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060006200001e6200006e565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000072565b3390565b61470a80620000826000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80638da5cb5b116100665780638da5cb5b146101525780639e8c708e14610176578063a063c0421461019c578063a7a580d514610383578063f2fde38b1461042457610093565b806331bceb48146100985780636331f17f146100d6578063715018a6146101255780637a991e121461012f575b600080fd5b6100c4600480360360408110156100ae57600080fd5b506001600160a01b03813516906020013561044a565b60408051918252519081900360200190f35b610102600480360360408110156100ec57600080fd5b506001600160a01b038135169060200135610a77565b604080516001600160a01b03909316835260208301919091528051918290030190f35b61012d610ec1565b005b6100c46004803603604081101561014557600080fd5b5080359060200135610f6d565b61015a611348565b604080516001600160a01b039092168252519081900360200190f35b61012d6004803603602081101561018c57600080fd5b50356001600160a01b0316611357565b6100c460048036036101408110156101b357600080fd5b6001600160a01b03823581169260208101359260408201359092169160608201359160808101359181019060c0810160a0820135600160201b8111156101f857600080fd5b82018360208201111561020a57600080fd5b803590602001918460208302840111600160201b8311171561022b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561027a57600080fd5b82018360208201111561028c57600080fd5b803590602001918460208302840111600160201b831117156102ad57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092956001600160a01b03853516959094909350604081019250602001359050600160201b81111561030d57600080fd5b82018360208201111561031f57600080fd5b803590602001918460018302840111600160201b8311171561034057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505050351515905061144a565b61012d6004803603602081101561039957600080fd5b810190602081018135600160201b8111156103b357600080fd5b8201836020820111156103c557600080fd5b803590602001918460208302840111600160201b831117156103e657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611b81945050505050565b61012d6004803603602081101561043a57600080fd5b50356001600160a01b0316611cb9565b600061045583611dbb565b15610545576104db670de0b6b3a76400006104d5856001600160a01b03166399530b066040518163ffffffff1660e01b815260040160206040518083038186803b1580156104a257600080fd5b505afa1580156104b6573d6000803e3d6000fd5b505050506040513d60208110156104cc57600080fd5b50518590611fdd565b9061203d565b9150826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561051657600080fd5b505afa15801561052a573d6000803e3d6000fd5b505050506040513d602081101561054057600080fd5b505192505b6001600160a01b03831673df5e0e81dff6faf3a7e52ba697820c5e32d806a8148061058c57506001600160a01b03831673c25a3a3b969415c80451098fa907ec722572917f145b806105b357506001600160a01b038316736c3f90f043a72fa612cbac8115ee7e52bde6e490145b806105da57506001600160a01b038316733b3ac5386837dc563660fb6a0937dfaa5924333b145b156107325773bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b03841673c25a3a3b969415c80451098fa907ec722572917f1415610634575073fcba3e75865d2d561be8d220616520c171f128516106b0565b6001600160a01b038416736c3f90f043a72fa612cbac8115ee7e52bde6e4901415610674575073bebc44782c7db0a1a60cb6fe97d0b483032ff1c76106b0565b6001600160a01b038416733b3ac5386837dc563660fb6a0937dfaa5924333b14156106b0575073b6c057591e073249f2d9d88ba59a46cfc9b59edb5b806001600160a01b031663cc2b27d78460016040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156106fd57600080fd5b505afa158015610711573d6000803e3d6000fd5b505050506040513d602081101561072757600080fd5b50519150610a719050565b6001600160a01b038316734f3e8f405cf5afc05d68142f3783bdfe13811522148061077957506001600160a01b038316737eb40e450b9655f4b3cc4259bcc731c63ff55ae6145b806107a057506001600160a01b038316733a664ab939fd8482048609f652f9a0b0677337b9145b806107c757506001600160a01b038316731aef73d49dedc4b1778d0706583995958dc862e6145b806107ee57506001600160a01b0383167394e131324b6054c0d789b190b2dac504e4361b53145b156109515773094d12e5b541784701fd8d65f11fc0598fbc63326001600160a01b038416737eb40e450b9655f4b3cc4259bcc731c63ff55ae614156108485750733c8caee4e09296800f8d29a68fa3837e2dae4940610904565b6001600160a01b038416733a664ab939fd8482048609f652f9a0b0677337b9141561088857507361e10659fe3aa93d036d099405224e4ac24996d0610904565b6001600160a01b038416731aef73d49dedc4b1778d0706583995958dc862e614156108c8575073803a2b40c5a9bb2b86dd630b274fa2a9202874c2610904565b6001600160a01b0384167394e131324b6054c0d789b190b2dac504e4361b531415610904575073b0a0716841f2fc03fba72a891b8bb13584f52f2d5b806001600160a01b031663cc2b27d78460026040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156106fd57600080fd5b6001600160a01b038316735282a4ef67d9c33135340fb3289cc1711c13638c1415610a09576040805163314ca9dd60e21b81526004810184905260016024820181905260448201529051732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf9163c532a774916064808301926020929190829003018186803b1580156109d657600080fd5b505afa1580156109ea573d6000803e3d6000fd5b505050506040513d6020811015610a0057600080fd5b50519050610a71565b604080516341b028f360e01b81526001600160a01b03851660048201526024810184905260026044820152905173a79828df1850e8a3a3064576f380d90aecdd3359916341b028f3916064808301926020929190829003018186803b1580156109d657600080fd5b92915050565b600080610a83846120a4565b15610af757836001600160a01b031663b16a19de6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac157600080fd5b505afa158015610ad5573d6000803e3d6000fd5b505050506040513d6020811015610aeb57600080fd5b50519150829050610eba565b610b0084612164565b15610c9a576000846001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4057600080fd5b505afa158015610b54573d6000803e3d6000fd5b505050506040513d6020811015610b6a57600080fd5b505160408051636f307dc360e01b815290519192506000916001600160a01b03881691636f307dc3916004808301926020929190829003018186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d6020811015610bdc57600080fd5b50516040805163313ce56760e01b815290519192506000916001600160a01b0384169163313ce567916004808301926020929190829003018186803b158015610c2457600080fd5b505afa158015610c38573d6000803e3d6000fd5b505050506040513d6020811015610c4e57600080fd5b505160ff169050600a80820190600090610c779083900a6104d587670de0b6b3a7640000611fdd565b905083610c8c6305f5e1006104d58b85611fdd565b965096505050505050610eba565b610ca3846121fd565b80610cb25750610cb284611dbb565b15610cdf5773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48610cd6858561044a565b91509150610eba565b610ce88461241c565b15610eb457610d68670de0b6b3a76400006104d5866001600160a01b03166399530b066040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3557600080fd5b505afa158015610d49573d6000803e3d6000fd5b505050506040513d6020811015610d5f57600080fd5b50518690611fdd565b92506001600160a01b0384167319d3364a399d251e894ac732651be8b0e4e850011415610dad5750736b175474e89094c44da98b954eedeac495271d0f905081610eba565b6001600160a01b038416735f18c75abdae578b483e5f43f12a39cf75b973a91415610df0575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48905081610eba565b6001600160a01b038416737da96a3891add058ada2e826306d812c638d87a71415610e33575073dac17f958d2ee523a2206206994597c13d831ec7905081610eba565b6001600160a01b0384167337d19d1c4e1fa9dc47bd1ea12f742a0887eda74a1415610e7157506e085d4780b73119b644ae5ecd22b376905081610eba565b6001600160a01b03841673a5ca62d95d24a4a350983d5b8ac4eb86388873961415610eb457507357ab1ec28d129707052df4df418d58a2d46d5f51905081610eba565b50829050815b9250929050565b610ec96124dc565b6001600160a01b0316610eda611348565b6001600160a01b031614610f23576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610f8f730ac00355f80e289f53bf368c9bdb70f5c114c44b3330866124e0565b6060730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b031663db5792576040518163ffffffff1660e01b815260040160006040518083038186803b158015610fde57600080fd5b505afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561101b57600080fd5b8101908080516040519392919084600160201b82111561103a57600080fd5b90830190602082018581111561104f57600080fd5b82518660208202830111600160201b8211171561106b57600080fd5b82525081516020918201928201910280838360005b83811015611098578181015183820152602001611080565b5050505090500160405260200180516040519392919084600160201b8211156110c057600080fd5b9083019060208201858111156110d557600080fd5b82518660208202830111600160201b821117156110f157600080fd5b82525081516020918201928201910280838360005b8381101561111e578181015183820152602001611106565b50505050905001604052505050509050730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b03166342966c68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561118857600080fd5b505af115801561119c573d6000803e3d6000fd5b5050505060005b815181101561125c576112548282815181106111bb57fe5b60200260200101518383815181106111cf57fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561122357600080fd5b505afa158015611237573d6000803e3d6000fd5b505050506040513d602081101561124d57600080fd5b5051612540565b6001016111a3565b50604080516370a0823160e01b8152306004820152905160009173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916370a0823191602480820192602092909190829003018186803b1580156112b257600080fd5b505afa1580156112c6573d6000803e3d6000fd5b505050506040513d60208110156112dc57600080fd5b5051905083811015611321576040805162461bcd60e51b8152602060048201526009602482015268216d696e2d7573646360b81b604482015290519081900360640190fd5b61134073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb483383612613565b949350505050565b6000546001600160a01b031690565b61135f6124dc565b6001600160a01b0316611370611348565b6001600160a01b0316146113b9576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b61144733826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561140a57600080fd5b505afa15801561141e573d6000803e3d6000fd5b505050506040513d602081101561143457600080fd5b50516001600160a01b0384169190612613565b50565b600080805b86518110156114885761147e87828151811061146757fe5b60200260200101518361266a90919063ffffffff16565b915060010161144f565b50670de0b6b3a764000081111561149b57fe5b670ddd2935029d80008110156114ad57fe5b6114c26001600160a01b038d1633308e6124e0565b6114cb8c6126c4565b156114e3576114de8c8c89898989612869565b6119b1565b6114ec8c61241c565b15611567578b6001600160a01b0316633ccfd60b6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561152c57600080fd5b505af1158015611540573d6000803e3d6000fd5b505050506040513d602081101561155657600080fd5b506114de90508a8a89898989612869565b6115708c611dbb565b15611770578b6001600160a01b0316633ccfd60b6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156115b057600080fd5b505af11580156115c4573d6000803e3d6000fd5b505050506040513d60208110156115da57600080fd5b505060408051637e062a3560e11b815290516000916001600160a01b038f169163fc0c546a91600480820192602092909190829003018186803b15801561162057600080fd5b505afa158015611634573d6000803e3d6000fd5b505050506040513d602081101561164a57600080fd5b5051604080516370a0823160e01b815230600482015290519192506116cd9183916001600160a01b038316916370a0823191602480820192602092909190829003018186803b15801561169c57600080fd5b505afa1580156116b0573d6000803e3d6000fd5b505050506040513d60208110156116c657600080fd5b5051612c5a565b604080516370a0823160e01b8152306004820152905161176a9173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489182916370a08231916024808301926020929190829003018186803b15801561172457600080fd5b505afa158015611738573d6000803e3d6000fd5b505050506040513d602081101561174e57600080fd5b5051604080516020810190915260008082528c918c9190612869565b506119b1565b6117798c612164565b15611841578b6001600160a01b031663db006a758c6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156117c457600080fd5b505af11580156117d8573d6000803e3d6000fd5b505050506040513d60208110156117ee57600080fd5b505115611833576040805162461bcd60e51b815260206004820152600e60248201526d2163746f6b656e2d72656465656d60901b604482015290519081900360640190fd5b6114de8a8a89898989612869565b61184a8c6120a4565b1561190a576118786001600160a01b038d16737d2768de32b0b80b7a3454c06bdac94a69ddc7a960006132f8565b6118a06001600160a01b038d16737d2768de32b0b80b7a3454c06bdac94a69ddc7a98d6132f8565b60408051631a4ca37b60e21b81526001600160a01b038c16600482015260001960248201523060448201529051737d2768de32b0b80b7a3454c06bdac94a69ddc7a9916369328dec9160648083019260209291908290030181600087803b15801561152c57600080fd5b6119148c8c612c5a565b604080516370a0823160e01b815230600482015290516119b19173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489182916370a08231916024808301926020929190829003018186803b15801561196b57600080fd5b505afa15801561197f573d6000803e3d6000fd5b505050506040513d602081101561199557600080fd5b5051604080516020810190915260008082528b918b9190612869565b604080516370a0823160e01b81523060048201529051600091730ac00355f80e289f53bf368c9bdb70f5c114c44b916370a0823191602480820192602092909190829003018186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b5051905088811015611a75576040805162461bcd60e51b8152602060048201526009602482015268085b5a5b8b5b5a5b9d60ba1b604482015290519081900360640190fd5b611a94730ac00355f80e289f53bf368c9bdb70f5c114c44b3383612613565b8315611b715760005b8851811015611ad157611ac9898281518110611ab557fe5b60200260200101518a83815181106111cf57fe5b600101611a9d565b50604080516370a0823160e01b81523060048201529051611b7191339173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916370a08231916024808301926020929190829003018186803b158015611b2957600080fd5b505afa158015611b3d573d6000803e3d6000fd5b505050506040513d6020811015611b5357600080fd5b505173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489190612613565b9c9b505050505050505050505050565b611b896124dc565b6001600160a01b0316611b9a611348565b6001600160a01b031614611be3576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b60005b8151811015611cb557611cad33838381518110611bff57fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611c5357600080fd5b505afa158015611c67573d6000803e3d6000fd5b505050506040513d6020811015611c7d57600080fd5b50518451859085908110611c8d57fe5b60200260200101516001600160a01b03166126139092919063ffffffff16565b600101611be6565b5050565b611cc16124dc565b6001600160a01b0316611cd2611348565b6001600160a01b031614611d1b576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b6001600160a01b038116611d605760405162461bcd60e51b815260040180806020018281038252602681526020018061460e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038216734b5bfd52124784745c1071dcb244c6688d2533d31480611e0457506001600160a01b038216735a770dbd3ee6baf2802d29a901ef11501c44797a145b80611e2b57506001600160a01b038216738ee57c05741aa9db947a744e713c15d4d19d8822145b80611e5257506001600160a01b038216736ede7f19df5df6ef23bd5b9cedb651580bdf56ca145b80611e7957506001600160a01b03821673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417145b80611ea057506001600160a01b03821673b4ada607b9d6b2c9ee07a275e9616b84ac560139145b80611ec757506001600160a01b03821673a74d4b67b3368e83797a35382afb776baae4f5c8145b80611eee57506001600160a01b038216735fa5b62c8af877cb37031e0a3b2f34a78e3c56a6145b80611f1557506001600160a01b038216733b96d491f067912d18563d56858ba7d6ec67a6fa145b80611f3c57506001600160a01b0382167384e13785b5a27879921d6f685f041421c7f482da145b80611f6357506001600160a01b0382167327b7b1ad7288079a66d12350c828d3c00a6f07d7145b80611f8a57506001600160a01b038216738cc94ccd0f3841a468184aca3cc478d2148e1757145b80611fb157506001600160a01b038216731c6a9783f812b3af3abbf7de64c3cd7cc7d1af44145b80610a7157506001600160a01b0382167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c1492915050565b600082611fec57506000610a71565b82820282848281611ff957fe5b04146120365760405162461bcd60e51b81526004018080602001828103825260218152602001806146346021913960400191505060405180910390fd5b9392505050565b6000808211612093576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161209c57fe5b049392505050565b60006001600160a01b03821673028171bca77440897b824ca71d1c56cac55b68a314806120ed57506001600160a01b03821673bcca60bb61934080951369a648fb03df4f96263c145b8061211457506001600160a01b038216733ed3b47dd13ec9a98b44e6204a523e766b225811145b8061213b57506001600160a01b03821673101cc05f4a51c0319f570d5e146a8c625198e636145b80610a715750506001600160a01b0316736c5024cd4f8a59110119c56f8933403a539555eb1490565b60006001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314806121ad57506001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e7563145b806121d457506001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc9145b80610a715750506001600160a01b03167312392f67bdf24fae0af363c24ac620a2f67dad861490565b60006001600160a01b03821673df5e0e81dff6faf3a7e52ba697820c5e32d806a8148061224657506001600160a01b03821673c25a3a3b969415c80451098fa907ec722572917f145b8061226d57506001600160a01b038216733b3ac5386837dc563660fb6a0937dfaa5924333b145b8061229457506001600160a01b038216734807862aa8b2bf68830e4c8dc86d0e9a998e085a145b806122bb57506001600160a01b038216737eb40e450b9655f4b3cc4259bcc731c63ff55ae6145b806122e257506001600160a01b03821673d632f22692fac7611d2aa1c0d552930d43caed3b145b8061230957506001600160a01b0382167343b4fdfd4ff969587185cdb6f0bd875c5fc83f8c145b8061233057506001600160a01b03821673ed279fdd11ca84beef15af5d39bb4d4bee23f0ca145b8061235757506001600160a01b038216736c3f90f043a72fa612cbac8115ee7e52bde6e490145b8061237e57506001600160a01b038216734f3e8f405cf5afc05d68142f3783bdfe13811522145b806123a557506001600160a01b038216733a664ab939fd8482048609f652f9a0b0677337b9145b806123cc57506001600160a01b038216731aef73d49dedc4b1778d0706583995958dc862e6145b806123f357506001600160a01b0382167394e131324b6054c0d789b190b2dac504e4361b53145b80610a715750506001600160a01b0316735282a4ef67d9c33135340fb3289cc1711c13638c1490565b60006001600160a01b0382167319d3364a399d251e894ac732651be8b0e4e85001148061246557506001600160a01b038216735f18c75abdae578b483e5f43f12a39cf75b973a9145b8061248c57506001600160a01b038216737da96a3891add058ada2e826306d812c638d87a7145b806124b357506001600160a01b0382167337d19d1c4e1fa9dc47bd1ea12f742a0887eda74a145b80610a715750506001600160a01b031673a5ca62d95d24a4a350983d5b8ac4eb86388873961490565b3390565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261253a908590613407565b50505050565b61254982611dbb565b15611cb557611cb5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561258a57600080fd5b505afa15801561259e573d6000803e3d6000fd5b505050506040513d60208110156125b457600080fd5b505160408051632e1a7d4d60e01b81526004810185905290516001600160a01b03861691632e1a7d4d9160248083019260209291908290030181600087803b1580156125ff57600080fd5b505af11580156116b0573d6000803e3d6000fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612665908490613407565b505050565b600082820183811015612036576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006001600160a01b038216736b175474e89094c44da98b954eedeac495271d0f148061270d57506001600160a01b03821673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48145b8061273457506001600160a01b03821673dac17f958d2ee523a2206206994597c13d831ec7145b8061275657506001600160a01b0382166e085d4780b73119b644ae5ecd22b376145b8061277d57506001600160a01b0382167357ab1ec28d129707052df4df418d58a2d46d5f51145b806127a457506001600160a01b038216734fabb145d64652a948d72533023f6e7a623c7c53145b806127cb57506001600160a01b038216731456688345527be1f37e9e627da0837d6f08c925145b806127f257506001600160a01b03821673853d955acef822db058eb8505911ed77f175b99e145b8061281957506001600160a01b03821673bc6da0fe9ad5f3b0d58160288917aa56653660e9145b8061284057506001600160a01b038216735f98805a4e8be255a32880fdec7f6728c6568ba0145b80610a715750506001600160a01b031673674c6ad92fd080e4004b2312b45f796a192d27a01490565b60006001600160a01b038716736b175474e89094c44da98b954eedeac495271d0f148015906128b557506001600160a01b03871673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814155b80156128de57506001600160a01b03871673dac17f958d2ee523a2206206994597c13d831ec714155b15612a06576128f86001600160a01b0388168460006132f8565b61290c6001600160a01b03881684886132f8565b6000836001600160a01b0316836040518082805190602001908083835b602083106129485780518252601f199092019160209182019101612929565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146129aa576040519150601f19603f3d011682016040523d82523d6000602084013e6129af565b606091505b50509050806129ed576040805162461bcd60e51b8152602060048201526005602482015264021737761760dc1b604482015290519081900360640190fd5b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489750505b6001600160a01b03871673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415612a3357506001612a5c565b6001600160a01b03871673dac17f958d2ee523a2206206994597c13d831ec71415612a5c575060025b600080730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612aac57600080fd5b505afa158015612ac0573d6000803e3d6000fd5b505050506040513d6020811015612ad657600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038c16916370a08231916024808301926020929190829003018186803b158015612b2457600080fd5b505afa158015612b38573d6000803e3d6000fd5b505050506040513d6020811015612b4e57600080fd5b505190506000805b8951811015612bda57612b91670de0b6b3a76400006104d58b8481518110612b7a57fe5b602002602001015186611fdd90919063ffffffff16565b9150612bb28c8b8381518110612ba357fe5b602002602001015184896134b8565b612bd0848b8381518110612bc257fe5b60200260200101518761425b565b9450600101612b56565b50730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b031663a0712d68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015612c3557600080fd5b505af1158015612c49573d6000803e3d6000fd5b505050505050505050505050505050565b6001600160a01b03821673df5e0e81dff6faf3a7e52ba697820c5e32d806a81480612ca157506001600160a01b03821673c25a3a3b969415c80451098fa907ec722572917f145b80612cc857506001600160a01b038216733b3ac5386837dc563660fb6a0937dfaa5924333b145b15612e005773bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b03831673c25a3a3b969415c80451098fa907ec722572917f1415612d22575073fcba3e75865d2d561be8d220616520c171f12851612d5e565b6001600160a01b038316733b3ac5386837dc563660fb6a0937dfaa5924333b1415612d5e575073b6c057591e073249f2d9d88ba59a46cfc9b59edb5b612d736001600160a01b0384168260006132f8565b612d876001600160a01b03841682846132f8565b6040805163517a55a360e01b815260048101849052600160248201526000604482018190526064820181905291516001600160a01b0384169263517a55a3926084808201939182900301818387803b158015612de257600080fd5b505af1158015612df6573d6000803e3d6000fd5b5050505050611cb5565b6001600160a01b038216737eb40e450b9655f4b3cc4259bcc731c63ff55ae61480612e4757506001600160a01b038216734f3e8f405cf5afc05d68142f3783bdfe13811522145b80612e6e57506001600160a01b038216733a664ab939fd8482048609f652f9a0b0677337b9145b80612e9557506001600160a01b038216731aef73d49dedc4b1778d0706583995958dc862e6145b80612ebc57506001600160a01b0382167394e131324b6054c0d789b190b2dac504e4361b53145b1561304f5773094d12e5b541784701fd8d65f11fc0598fbc63326001600160a01b038316737eb40e450b9655f4b3cc4259bcc731c63ff55ae61415612f165750733c8caee4e09296800f8d29a68fa3837e2dae4940612fd2565b6001600160a01b038316733a664ab939fd8482048609f652f9a0b0677337b91415612f5657507361e10659fe3aa93d036d099405224e4ac24996d0612fd2565b6001600160a01b038316731aef73d49dedc4b1778d0706583995958dc862e61415612f96575073803a2b40c5a9bb2b86dd630b274fa2a9202874c2612fd2565b6001600160a01b0383167394e131324b6054c0d789b190b2dac504e4361b531415612fd2575073b0a0716841f2fc03fba72a891b8bb13584f52f2d5b612fe76001600160a01b0384168260006132f8565b612ffb6001600160a01b03841682846132f8565b60408051630d2680e960e11b8152600481018490526002602482015260006044820181905291516001600160a01b03841692631a4d01d2926064808201939182900301818387803b158015612de257600080fd5b6001600160a01b038216735282a4ef67d9c33135340fb3289cc1711c13638c141561314b5761309d6001600160a01b038316732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf60006132f8565b6130c56001600160a01b038316732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf836132f8565b6040805163517a55a360e01b81526004810183905260016024820181905260006044830181905260648301919091529151732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf9263517a55a3926084808201939182900301818387803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b50505050611cb5565b6001600160a01b038216736c3f90f043a72fa612cbac8115ee7e52bde6e49014156132025773bebc44782c7db0a1a60cb6fe97d0b483032ff1c761319a6001600160a01b0384168260006132f8565b6131ae6001600160a01b03841682846132f8565b60408051630d2680e960e11b8152600481018490526001602482015260006044820181905291516001600160a01b03841692631a4d01d2926064808201939182900301818387803b158015612de257600080fd5b61322b6001600160a01b03831673a79828df1850e8a3a3064576f380d90aecdd335960006132f8565b6132536001600160a01b03831673a79828df1850e8a3a3064576f380d90aecdd3359836132f8565b60408051631e700cbb60e01b81526001600160a01b03841660048201526024810183905260026044820152600060648201819052306084830152915173a79828df1850e8a3a3064576f380d90aecdd335992631e700cbb9260a480820193602093909283900390910190829087803b1580156132ce57600080fd5b505af11580156132e2573d6000803e3d6000fd5b505050506040513d602081101561253a57600080fd5b80158061337e575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561335057600080fd5b505afa158015613364573d6000803e3d6000fd5b505050506040513d602081101561337a57600080fd5b5051155b6133b95760405162461bcd60e51b815260040180806020018281038252603681526020018061469f6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526126659084905b606061345c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166144019092919063ffffffff16565b8051909150156126655780806020019051602081101561347b57600080fd5b50516126655760405162461bcd60e51b815260040180806020018281038252602a815260200180614675602a913960400191505060405180910390fd5b60006134c26145d1565b60405180608001604052806000815260200160008152602001600081526020016000815250905073a5ca62d95d24a4a350983d5b8ac4eb86388873966001600160a01b0316856001600160a01b031614156136d4576135406001600160a01b03871673a5407eae9ba41422680e2e00537571bcc53efbfd60006132f8565b6135686001600160a01b03871673a5407eae9ba41422680e2e00537571bcc53efbfd866132f8565b60408051630f7c084960e21b8152600f85900b60048201526003602482015260448101869052600060648201819052915173a5407eae9ba41422680e2e00537571bcc53efbfd92633df02124926084808201939182900301818387803b1580156135d157600080fd5b505af11580156135e5573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290517357ab1ec28d129707052df4df418d58a2d46d5f5193506370a0823192506024808301926020929190829003018186803b15801561363a57600080fd5b505afa15801561364e573d6000803e3d6000fd5b505050506040513d602081101561366457600080fd5b5051915061369c7357ab1ec28d129707052df4df418d58a2d46d5f5173a5ca62d95d24a4a350983d5b8ac4eb863888739660006132f8565b6136cf7357ab1ec28d129707052df4df418d58a2d46d5f5173a5ca62d95d24a4a350983d5b8ac4eb8638887396846132f8565b6141ec565b6001600160a01b038516734b5bfd52124784745c1071dcb244c6688d2533d3148061371b57506001600160a01b038516735a770dbd3ee6baf2802d29a901ef11501c44797a145b8061374257506001600160a01b038516738ee57c05741aa9db947a744e713c15d4d19d8822145b8061376957506001600160a01b038516733b96d491f067912d18563d56858ba7d6ec67a6fa145b8061379057506001600160a01b03851673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417145b806137b757506001600160a01b0385167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c145b806137de57506001600160a01b038516738cc94ccd0f3841a468184aca3cc478d2148e1757145b8061380557506001600160a01b038516731c6a9783f812b3af3abbf7de64c3cd7cc7d1af44145b15613bcf576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561384557600080fd5b505afa158015613859573d6000803e3d6000fd5b505050506040513d602081101561386f57600080fd5b5051905073bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b038716735a770dbd3ee6baf2802d29a901ef11501c44797a14156138c8575073fcba3e75865d2d561be8d220616520c171f12851613a67565b6001600160a01b038716738ee57c05741aa9db947a744e713c15d4d19d88221415613908575073b6c057591e073249f2d9d88ba59a46cfc9b59edb613a67565b6001600160a01b038716733b96d491f067912d18563d56858ba7d6ec67a6fa141561394f5773094d12e5b541784701fd8d65f11fc0598fbc63329050600185019450613a67565b6001600160a01b03871673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417141561399657733c8caee4e09296800f8d29a68fa3837e2dae49409050600185019450613a67565b6001600160a01b0387167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c14156139dd577361e10659fe3aa93d036d099405224e4ac24996d09050600185019450613a67565b6001600160a01b038716738cc94ccd0f3841a468184aca3cc478d2148e17571415613a245773803a2b40c5a9bb2b86dd630b274fa2a9202874c29050600185019450613a67565b6001600160a01b038716731c6a9783f812b3af3abbf7de64c3cd7cc7d1af441415613a675773b0a0716841f2fc03fba72a891b8bb13584f52f2d90506001850194505b85838660048110613a7457fe5b6020020152613a8e6001600160a01b0389168260006132f8565b613aa26001600160a01b03891682886132f8565b60405162a6cbcd60e21b81526001600160a01b0382169063029b2f3490859060009060040180836080808383875b83811015613ae8578181015183820152602001613ad0565b5050505090500182815260200192505050600060405180830381600087803b158015613b1357600080fd5b505af1158015613b27573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516001600160a01b03861693506370a0823192506024808301926020929190829003018186803b158015613b7157600080fd5b505afa158015613b85573d6000803e3d6000fd5b505050506040513d6020811015613b9b57600080fd5b50519350613bb46001600160a01b0383168860006132f8565b613bc86001600160a01b03831688866132f8565b50506141ec565b6001600160a01b0385167384e13785b5a27879921d6f685f041421c7f482da1480613c1657506001600160a01b0385167327b7b1ad7288079a66d12350c828d3c00a6f07d7145b15613f28576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c5657600080fd5b505afa158015613c6a573d6000803e3d6000fd5b505050506040513d6020811015613c8057600080fd5b50519050613c8c6145ef565b604051806060016040528060008152602001600081526020016000815250905085818660038110613cb957fe5b602002015273bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b0388167327b7b1ad7288079a66d12350c828d3c00a6f07d71415613d0f5750732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf5b613d246001600160a01b038a168260006132f8565b613d386001600160a01b038a1682896132f8565b6001600160a01b0388167384e13785b5a27879921d6f685f041421c7f482da1415613dec57604051634515cef360e01b81526001600160a01b03821690634515cef390849060009060040180836060808383875b83811015613da4578181015183820152602001613d8c565b5050505090500182815260200192505050600060405180830381600087803b158015613dcf57600080fd5b505af1158015613de3573d6000803e3d6000fd5b50505050613e83565b6040516315b74c9d60e11b81526001600160a01b03821690632b6e993a90849060009060019060040180846060808383885b83811015613e36578181015183820152602001613e1e565b5050505090500183815260200182151581526020019350505050600060405180830381600087803b158015613e6a57600080fd5b505af1158015613e7e573d6000803e3d6000fd5b505050505b604080516370a0823160e01b815230600482015290516001600160a01b038516916370a08231916024808301926020929190829003018186803b158015613ec957600080fd5b505afa158015613edd573d6000803e3d6000fd5b505050506040513d6020811015613ef357600080fd5b50519450613f0c6001600160a01b0384168960006132f8565b613f206001600160a01b03841689876132f8565b5050506141ec565b6001600160a01b038516736ede7f19df5df6ef23bd5b9cedb651580bdf56ca1480613f6f57506001600160a01b03851673b4ada607b9d6b2c9ee07a275e9616b84ac560139145b80613f9657506001600160a01b03851673a74d4b67b3368e83797a35382afb776baae4f5c8145b80613fbd57506001600160a01b038516735fa5b62c8af877cb37031e0a3b2f34a78e3c56a6145b156141ec576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ffd57600080fd5b505afa158015614011573d6000803e3d6000fd5b505050506040513d602081101561402757600080fd5b505190508482600186016004811061403b57fe5b60200201526140696001600160a01b03881673a79828df1850e8a3a3064576f380d90aecdd335960006132f8565b6140916001600160a01b03881673a79828df1850e8a3a3064576f380d90aecdd3359876132f8565b60405163384e03db60e01b81526001600160a01b0382166004820190815273a79828df1850e8a3a3064576f380d90aecdd33599163384e03db9184918691600091602401836080808383875b838110156140f55781810151838201526020016140dd565b505050509050018281526020019350505050602060405180830381600087803b15801561412157600080fd5b505af1158015614135573d6000803e3d6000fd5b505050506040513d602081101561414b57600080fd5b5050604080516370a0823160e01b815230600482015290516001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561419357600080fd5b505afa1580156141a7573d6000803e3d6000fd5b505050506040513d60208110156141bd57600080fd5b505192506141d66001600160a01b0382168760006132f8565b6141ea6001600160a01b03821687856132f8565b505b846001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561422757600080fd5b505af115801561423b573d6000803e3d6000fd5b505050506040513d602081101561425157600080fd5b5050505050505050565b600080836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156142ab57600080fd5b505afa1580156142bf573d6000803e3d6000fd5b505050506040513d60208110156142d557600080fd5b5051604080516370a0823160e01b8152730ac00355f80e289f53bf368c9bdb70f5c114c44b600482015290519192506000916001600160a01b038716916370a08231916024808301926020929190829003018186803b15801561433757600080fd5b505afa15801561434b573d6000803e3d6000fd5b505050506040513d602081101561436157600080fd5b5051905061438e6001600160a01b038616730ac00355f80e289f53bf368c9bdb70f5c114c44b60006132f8565b6143b66001600160a01b038616730ac00355f80e289f53bf368c9bdb70f5c114c44b846132f8565b836143d2576143c9816104d58885611fdd565b92505050612036565b60006143e2826104d58986611fdd565b9050848110156143f6579250612036915050565b509295945050505050565b606061134084846000858561441585614527565b614466576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106144a55780518252601f199092019160209182019101614486565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614507576040519150601f19603f3d011682016040523d82523d6000602084013e61450c565b606091505b509150915061451c82828661452d565b979650505050505050565b3b151590565b6060831561453c575081612036565b82511561454c5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561459657818101518382015260200161457e565b50505050905090810190601f1680156145c35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60405180608001604052806004906020820280368337509192915050565b6040518060600160405280600390602082028036833750919291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a264697066735822122033743fb3c2c81f206225ae17c7a957755ba167cd8c6bbf0f2897e84d1c4b0dcd64736f6c63430007030033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c80638da5cb5b116100665780638da5cb5b146101525780639e8c708e14610176578063a063c0421461019c578063a7a580d514610383578063f2fde38b1461042457610093565b806331bceb48146100985780636331f17f146100d6578063715018a6146101255780637a991e121461012f575b600080fd5b6100c4600480360360408110156100ae57600080fd5b506001600160a01b03813516906020013561044a565b60408051918252519081900360200190f35b610102600480360360408110156100ec57600080fd5b506001600160a01b038135169060200135610a77565b604080516001600160a01b03909316835260208301919091528051918290030190f35b61012d610ec1565b005b6100c46004803603604081101561014557600080fd5b5080359060200135610f6d565b61015a611348565b604080516001600160a01b039092168252519081900360200190f35b61012d6004803603602081101561018c57600080fd5b50356001600160a01b0316611357565b6100c460048036036101408110156101b357600080fd5b6001600160a01b03823581169260208101359260408201359092169160608201359160808101359181019060c0810160a0820135600160201b8111156101f857600080fd5b82018360208201111561020a57600080fd5b803590602001918460208302840111600160201b8311171561022b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561027a57600080fd5b82018360208201111561028c57600080fd5b803590602001918460208302840111600160201b831117156102ad57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092956001600160a01b03853516959094909350604081019250602001359050600160201b81111561030d57600080fd5b82018360208201111561031f57600080fd5b803590602001918460018302840111600160201b8311171561034057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505050351515905061144a565b61012d6004803603602081101561039957600080fd5b810190602081018135600160201b8111156103b357600080fd5b8201836020820111156103c557600080fd5b803590602001918460208302840111600160201b831117156103e657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611b81945050505050565b61012d6004803603602081101561043a57600080fd5b50356001600160a01b0316611cb9565b600061045583611dbb565b15610545576104db670de0b6b3a76400006104d5856001600160a01b03166399530b066040518163ffffffff1660e01b815260040160206040518083038186803b1580156104a257600080fd5b505afa1580156104b6573d6000803e3d6000fd5b505050506040513d60208110156104cc57600080fd5b50518590611fdd565b9061203d565b9150826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561051657600080fd5b505afa15801561052a573d6000803e3d6000fd5b505050506040513d602081101561054057600080fd5b505192505b6001600160a01b03831673df5e0e81dff6faf3a7e52ba697820c5e32d806a8148061058c57506001600160a01b03831673c25a3a3b969415c80451098fa907ec722572917f145b806105b357506001600160a01b038316736c3f90f043a72fa612cbac8115ee7e52bde6e490145b806105da57506001600160a01b038316733b3ac5386837dc563660fb6a0937dfaa5924333b145b156107325773bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b03841673c25a3a3b969415c80451098fa907ec722572917f1415610634575073fcba3e75865d2d561be8d220616520c171f128516106b0565b6001600160a01b038416736c3f90f043a72fa612cbac8115ee7e52bde6e4901415610674575073bebc44782c7db0a1a60cb6fe97d0b483032ff1c76106b0565b6001600160a01b038416733b3ac5386837dc563660fb6a0937dfaa5924333b14156106b0575073b6c057591e073249f2d9d88ba59a46cfc9b59edb5b806001600160a01b031663cc2b27d78460016040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156106fd57600080fd5b505afa158015610711573d6000803e3d6000fd5b505050506040513d602081101561072757600080fd5b50519150610a719050565b6001600160a01b038316734f3e8f405cf5afc05d68142f3783bdfe13811522148061077957506001600160a01b038316737eb40e450b9655f4b3cc4259bcc731c63ff55ae6145b806107a057506001600160a01b038316733a664ab939fd8482048609f652f9a0b0677337b9145b806107c757506001600160a01b038316731aef73d49dedc4b1778d0706583995958dc862e6145b806107ee57506001600160a01b0383167394e131324b6054c0d789b190b2dac504e4361b53145b156109515773094d12e5b541784701fd8d65f11fc0598fbc63326001600160a01b038416737eb40e450b9655f4b3cc4259bcc731c63ff55ae614156108485750733c8caee4e09296800f8d29a68fa3837e2dae4940610904565b6001600160a01b038416733a664ab939fd8482048609f652f9a0b0677337b9141561088857507361e10659fe3aa93d036d099405224e4ac24996d0610904565b6001600160a01b038416731aef73d49dedc4b1778d0706583995958dc862e614156108c8575073803a2b40c5a9bb2b86dd630b274fa2a9202874c2610904565b6001600160a01b0384167394e131324b6054c0d789b190b2dac504e4361b531415610904575073b0a0716841f2fc03fba72a891b8bb13584f52f2d5b806001600160a01b031663cc2b27d78460026040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156106fd57600080fd5b6001600160a01b038316735282a4ef67d9c33135340fb3289cc1711c13638c1415610a09576040805163314ca9dd60e21b81526004810184905260016024820181905260448201529051732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf9163c532a774916064808301926020929190829003018186803b1580156109d657600080fd5b505afa1580156109ea573d6000803e3d6000fd5b505050506040513d6020811015610a0057600080fd5b50519050610a71565b604080516341b028f360e01b81526001600160a01b03851660048201526024810184905260026044820152905173a79828df1850e8a3a3064576f380d90aecdd3359916341b028f3916064808301926020929190829003018186803b1580156109d657600080fd5b92915050565b600080610a83846120a4565b15610af757836001600160a01b031663b16a19de6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac157600080fd5b505afa158015610ad5573d6000803e3d6000fd5b505050506040513d6020811015610aeb57600080fd5b50519150829050610eba565b610b0084612164565b15610c9a576000846001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4057600080fd5b505afa158015610b54573d6000803e3d6000fd5b505050506040513d6020811015610b6a57600080fd5b505160408051636f307dc360e01b815290519192506000916001600160a01b03881691636f307dc3916004808301926020929190829003018186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d6020811015610bdc57600080fd5b50516040805163313ce56760e01b815290519192506000916001600160a01b0384169163313ce567916004808301926020929190829003018186803b158015610c2457600080fd5b505afa158015610c38573d6000803e3d6000fd5b505050506040513d6020811015610c4e57600080fd5b505160ff169050600a80820190600090610c779083900a6104d587670de0b6b3a7640000611fdd565b905083610c8c6305f5e1006104d58b85611fdd565b965096505050505050610eba565b610ca3846121fd565b80610cb25750610cb284611dbb565b15610cdf5773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48610cd6858561044a565b91509150610eba565b610ce88461241c565b15610eb457610d68670de0b6b3a76400006104d5866001600160a01b03166399530b066040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3557600080fd5b505afa158015610d49573d6000803e3d6000fd5b505050506040513d6020811015610d5f57600080fd5b50518690611fdd565b92506001600160a01b0384167319d3364a399d251e894ac732651be8b0e4e850011415610dad5750736b175474e89094c44da98b954eedeac495271d0f905081610eba565b6001600160a01b038416735f18c75abdae578b483e5f43f12a39cf75b973a91415610df0575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48905081610eba565b6001600160a01b038416737da96a3891add058ada2e826306d812c638d87a71415610e33575073dac17f958d2ee523a2206206994597c13d831ec7905081610eba565b6001600160a01b0384167337d19d1c4e1fa9dc47bd1ea12f742a0887eda74a1415610e7157506e085d4780b73119b644ae5ecd22b376905081610eba565b6001600160a01b03841673a5ca62d95d24a4a350983d5b8ac4eb86388873961415610eb457507357ab1ec28d129707052df4df418d58a2d46d5f51905081610eba565b50829050815b9250929050565b610ec96124dc565b6001600160a01b0316610eda611348565b6001600160a01b031614610f23576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610f8f730ac00355f80e289f53bf368c9bdb70f5c114c44b3330866124e0565b6060730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b031663db5792576040518163ffffffff1660e01b815260040160006040518083038186803b158015610fde57600080fd5b505afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561101b57600080fd5b8101908080516040519392919084600160201b82111561103a57600080fd5b90830190602082018581111561104f57600080fd5b82518660208202830111600160201b8211171561106b57600080fd5b82525081516020918201928201910280838360005b83811015611098578181015183820152602001611080565b5050505090500160405260200180516040519392919084600160201b8211156110c057600080fd5b9083019060208201858111156110d557600080fd5b82518660208202830111600160201b821117156110f157600080fd5b82525081516020918201928201910280838360005b8381101561111e578181015183820152602001611106565b50505050905001604052505050509050730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b03166342966c68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561118857600080fd5b505af115801561119c573d6000803e3d6000fd5b5050505060005b815181101561125c576112548282815181106111bb57fe5b60200260200101518383815181106111cf57fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561122357600080fd5b505afa158015611237573d6000803e3d6000fd5b505050506040513d602081101561124d57600080fd5b5051612540565b6001016111a3565b50604080516370a0823160e01b8152306004820152905160009173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916370a0823191602480820192602092909190829003018186803b1580156112b257600080fd5b505afa1580156112c6573d6000803e3d6000fd5b505050506040513d60208110156112dc57600080fd5b5051905083811015611321576040805162461bcd60e51b8152602060048201526009602482015268216d696e2d7573646360b81b604482015290519081900360640190fd5b61134073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb483383612613565b949350505050565b6000546001600160a01b031690565b61135f6124dc565b6001600160a01b0316611370611348565b6001600160a01b0316146113b9576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b61144733826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561140a57600080fd5b505afa15801561141e573d6000803e3d6000fd5b505050506040513d602081101561143457600080fd5b50516001600160a01b0384169190612613565b50565b600080805b86518110156114885761147e87828151811061146757fe5b60200260200101518361266a90919063ffffffff16565b915060010161144f565b50670de0b6b3a764000081111561149b57fe5b670ddd2935029d80008110156114ad57fe5b6114c26001600160a01b038d1633308e6124e0565b6114cb8c6126c4565b156114e3576114de8c8c89898989612869565b6119b1565b6114ec8c61241c565b15611567578b6001600160a01b0316633ccfd60b6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561152c57600080fd5b505af1158015611540573d6000803e3d6000fd5b505050506040513d602081101561155657600080fd5b506114de90508a8a89898989612869565b6115708c611dbb565b15611770578b6001600160a01b0316633ccfd60b6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156115b057600080fd5b505af11580156115c4573d6000803e3d6000fd5b505050506040513d60208110156115da57600080fd5b505060408051637e062a3560e11b815290516000916001600160a01b038f169163fc0c546a91600480820192602092909190829003018186803b15801561162057600080fd5b505afa158015611634573d6000803e3d6000fd5b505050506040513d602081101561164a57600080fd5b5051604080516370a0823160e01b815230600482015290519192506116cd9183916001600160a01b038316916370a0823191602480820192602092909190829003018186803b15801561169c57600080fd5b505afa1580156116b0573d6000803e3d6000fd5b505050506040513d60208110156116c657600080fd5b5051612c5a565b604080516370a0823160e01b8152306004820152905161176a9173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489182916370a08231916024808301926020929190829003018186803b15801561172457600080fd5b505afa158015611738573d6000803e3d6000fd5b505050506040513d602081101561174e57600080fd5b5051604080516020810190915260008082528c918c9190612869565b506119b1565b6117798c612164565b15611841578b6001600160a01b031663db006a758c6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156117c457600080fd5b505af11580156117d8573d6000803e3d6000fd5b505050506040513d60208110156117ee57600080fd5b505115611833576040805162461bcd60e51b815260206004820152600e60248201526d2163746f6b656e2d72656465656d60901b604482015290519081900360640190fd5b6114de8a8a89898989612869565b61184a8c6120a4565b1561190a576118786001600160a01b038d16737d2768de32b0b80b7a3454c06bdac94a69ddc7a960006132f8565b6118a06001600160a01b038d16737d2768de32b0b80b7a3454c06bdac94a69ddc7a98d6132f8565b60408051631a4ca37b60e21b81526001600160a01b038c16600482015260001960248201523060448201529051737d2768de32b0b80b7a3454c06bdac94a69ddc7a9916369328dec9160648083019260209291908290030181600087803b15801561152c57600080fd5b6119148c8c612c5a565b604080516370a0823160e01b815230600482015290516119b19173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489182916370a08231916024808301926020929190829003018186803b15801561196b57600080fd5b505afa15801561197f573d6000803e3d6000fd5b505050506040513d602081101561199557600080fd5b5051604080516020810190915260008082528b918b9190612869565b604080516370a0823160e01b81523060048201529051600091730ac00355f80e289f53bf368c9bdb70f5c114c44b916370a0823191602480820192602092909190829003018186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b5051905088811015611a75576040805162461bcd60e51b8152602060048201526009602482015268085b5a5b8b5b5a5b9d60ba1b604482015290519081900360640190fd5b611a94730ac00355f80e289f53bf368c9bdb70f5c114c44b3383612613565b8315611b715760005b8851811015611ad157611ac9898281518110611ab557fe5b60200260200101518a83815181106111cf57fe5b600101611a9d565b50604080516370a0823160e01b81523060048201529051611b7191339173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916370a08231916024808301926020929190829003018186803b158015611b2957600080fd5b505afa158015611b3d573d6000803e3d6000fd5b505050506040513d6020811015611b5357600080fd5b505173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489190612613565b9c9b505050505050505050505050565b611b896124dc565b6001600160a01b0316611b9a611348565b6001600160a01b031614611be3576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b60005b8151811015611cb557611cad33838381518110611bff57fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611c5357600080fd5b505afa158015611c67573d6000803e3d6000fd5b505050506040513d6020811015611c7d57600080fd5b50518451859085908110611c8d57fe5b60200260200101516001600160a01b03166126139092919063ffffffff16565b600101611be6565b5050565b611cc16124dc565b6001600160a01b0316611cd2611348565b6001600160a01b031614611d1b576040805162461bcd60e51b81526020600482018190526024820152600080516020614655833981519152604482015290519081900360640190fd5b6001600160a01b038116611d605760405162461bcd60e51b815260040180806020018281038252602681526020018061460e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038216734b5bfd52124784745c1071dcb244c6688d2533d31480611e0457506001600160a01b038216735a770dbd3ee6baf2802d29a901ef11501c44797a145b80611e2b57506001600160a01b038216738ee57c05741aa9db947a744e713c15d4d19d8822145b80611e5257506001600160a01b038216736ede7f19df5df6ef23bd5b9cedb651580bdf56ca145b80611e7957506001600160a01b03821673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417145b80611ea057506001600160a01b03821673b4ada607b9d6b2c9ee07a275e9616b84ac560139145b80611ec757506001600160a01b03821673a74d4b67b3368e83797a35382afb776baae4f5c8145b80611eee57506001600160a01b038216735fa5b62c8af877cb37031e0a3b2f34a78e3c56a6145b80611f1557506001600160a01b038216733b96d491f067912d18563d56858ba7d6ec67a6fa145b80611f3c57506001600160a01b0382167384e13785b5a27879921d6f685f041421c7f482da145b80611f6357506001600160a01b0382167327b7b1ad7288079a66d12350c828d3c00a6f07d7145b80611f8a57506001600160a01b038216738cc94ccd0f3841a468184aca3cc478d2148e1757145b80611fb157506001600160a01b038216731c6a9783f812b3af3abbf7de64c3cd7cc7d1af44145b80610a7157506001600160a01b0382167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c1492915050565b600082611fec57506000610a71565b82820282848281611ff957fe5b04146120365760405162461bcd60e51b81526004018080602001828103825260218152602001806146346021913960400191505060405180910390fd5b9392505050565b6000808211612093576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161209c57fe5b049392505050565b60006001600160a01b03821673028171bca77440897b824ca71d1c56cac55b68a314806120ed57506001600160a01b03821673bcca60bb61934080951369a648fb03df4f96263c145b8061211457506001600160a01b038216733ed3b47dd13ec9a98b44e6204a523e766b225811145b8061213b57506001600160a01b03821673101cc05f4a51c0319f570d5e146a8c625198e636145b80610a715750506001600160a01b0316736c5024cd4f8a59110119c56f8933403a539555eb1490565b60006001600160a01b038216735d3a536e4d6dbd6114cc1ead35777bab948e364314806121ad57506001600160a01b0382167339aa39c021dfbae8fac545936693ac917d5e7563145b806121d457506001600160a01b03821673f650c3d88d12db855b8bf7d11be6c55a4e07dcc9145b80610a715750506001600160a01b03167312392f67bdf24fae0af363c24ac620a2f67dad861490565b60006001600160a01b03821673df5e0e81dff6faf3a7e52ba697820c5e32d806a8148061224657506001600160a01b03821673c25a3a3b969415c80451098fa907ec722572917f145b8061226d57506001600160a01b038216733b3ac5386837dc563660fb6a0937dfaa5924333b145b8061229457506001600160a01b038216734807862aa8b2bf68830e4c8dc86d0e9a998e085a145b806122bb57506001600160a01b038216737eb40e450b9655f4b3cc4259bcc731c63ff55ae6145b806122e257506001600160a01b03821673d632f22692fac7611d2aa1c0d552930d43caed3b145b8061230957506001600160a01b0382167343b4fdfd4ff969587185cdb6f0bd875c5fc83f8c145b8061233057506001600160a01b03821673ed279fdd11ca84beef15af5d39bb4d4bee23f0ca145b8061235757506001600160a01b038216736c3f90f043a72fa612cbac8115ee7e52bde6e490145b8061237e57506001600160a01b038216734f3e8f405cf5afc05d68142f3783bdfe13811522145b806123a557506001600160a01b038216733a664ab939fd8482048609f652f9a0b0677337b9145b806123cc57506001600160a01b038216731aef73d49dedc4b1778d0706583995958dc862e6145b806123f357506001600160a01b0382167394e131324b6054c0d789b190b2dac504e4361b53145b80610a715750506001600160a01b0316735282a4ef67d9c33135340fb3289cc1711c13638c1490565b60006001600160a01b0382167319d3364a399d251e894ac732651be8b0e4e85001148061246557506001600160a01b038216735f18c75abdae578b483e5f43f12a39cf75b973a9145b8061248c57506001600160a01b038216737da96a3891add058ada2e826306d812c638d87a7145b806124b357506001600160a01b0382167337d19d1c4e1fa9dc47bd1ea12f742a0887eda74a145b80610a715750506001600160a01b031673a5ca62d95d24a4a350983d5b8ac4eb86388873961490565b3390565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261253a908590613407565b50505050565b61254982611dbb565b15611cb557611cb5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561258a57600080fd5b505afa15801561259e573d6000803e3d6000fd5b505050506040513d60208110156125b457600080fd5b505160408051632e1a7d4d60e01b81526004810185905290516001600160a01b03861691632e1a7d4d9160248083019260209291908290030181600087803b1580156125ff57600080fd5b505af11580156116b0573d6000803e3d6000fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612665908490613407565b505050565b600082820183811015612036576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006001600160a01b038216736b175474e89094c44da98b954eedeac495271d0f148061270d57506001600160a01b03821673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48145b8061273457506001600160a01b03821673dac17f958d2ee523a2206206994597c13d831ec7145b8061275657506001600160a01b0382166e085d4780b73119b644ae5ecd22b376145b8061277d57506001600160a01b0382167357ab1ec28d129707052df4df418d58a2d46d5f51145b806127a457506001600160a01b038216734fabb145d64652a948d72533023f6e7a623c7c53145b806127cb57506001600160a01b038216731456688345527be1f37e9e627da0837d6f08c925145b806127f257506001600160a01b03821673853d955acef822db058eb8505911ed77f175b99e145b8061281957506001600160a01b03821673bc6da0fe9ad5f3b0d58160288917aa56653660e9145b8061284057506001600160a01b038216735f98805a4e8be255a32880fdec7f6728c6568ba0145b80610a715750506001600160a01b031673674c6ad92fd080e4004b2312b45f796a192d27a01490565b60006001600160a01b038716736b175474e89094c44da98b954eedeac495271d0f148015906128b557506001600160a01b03871673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814155b80156128de57506001600160a01b03871673dac17f958d2ee523a2206206994597c13d831ec714155b15612a06576128f86001600160a01b0388168460006132f8565b61290c6001600160a01b03881684886132f8565b6000836001600160a01b0316836040518082805190602001908083835b602083106129485780518252601f199092019160209182019101612929565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146129aa576040519150601f19603f3d011682016040523d82523d6000602084013e6129af565b606091505b50509050806129ed576040805162461bcd60e51b8152602060048201526005602482015264021737761760dc1b604482015290519081900360640190fd5b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489750505b6001600160a01b03871673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415612a3357506001612a5c565b6001600160a01b03871673dac17f958d2ee523a2206206994597c13d831ec71415612a5c575060025b600080730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612aac57600080fd5b505afa158015612ac0573d6000803e3d6000fd5b505050506040513d6020811015612ad657600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038c16916370a08231916024808301926020929190829003018186803b158015612b2457600080fd5b505afa158015612b38573d6000803e3d6000fd5b505050506040513d6020811015612b4e57600080fd5b505190506000805b8951811015612bda57612b91670de0b6b3a76400006104d58b8481518110612b7a57fe5b602002602001015186611fdd90919063ffffffff16565b9150612bb28c8b8381518110612ba357fe5b602002602001015184896134b8565b612bd0848b8381518110612bc257fe5b60200260200101518761425b565b9450600101612b56565b50730ac00355f80e289f53bf368c9bdb70f5c114c44b6001600160a01b031663a0712d68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015612c3557600080fd5b505af1158015612c49573d6000803e3d6000fd5b505050505050505050505050505050565b6001600160a01b03821673df5e0e81dff6faf3a7e52ba697820c5e32d806a81480612ca157506001600160a01b03821673c25a3a3b969415c80451098fa907ec722572917f145b80612cc857506001600160a01b038216733b3ac5386837dc563660fb6a0937dfaa5924333b145b15612e005773bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b03831673c25a3a3b969415c80451098fa907ec722572917f1415612d22575073fcba3e75865d2d561be8d220616520c171f12851612d5e565b6001600160a01b038316733b3ac5386837dc563660fb6a0937dfaa5924333b1415612d5e575073b6c057591e073249f2d9d88ba59a46cfc9b59edb5b612d736001600160a01b0384168260006132f8565b612d876001600160a01b03841682846132f8565b6040805163517a55a360e01b815260048101849052600160248201526000604482018190526064820181905291516001600160a01b0384169263517a55a3926084808201939182900301818387803b158015612de257600080fd5b505af1158015612df6573d6000803e3d6000fd5b5050505050611cb5565b6001600160a01b038216737eb40e450b9655f4b3cc4259bcc731c63ff55ae61480612e4757506001600160a01b038216734f3e8f405cf5afc05d68142f3783bdfe13811522145b80612e6e57506001600160a01b038216733a664ab939fd8482048609f652f9a0b0677337b9145b80612e9557506001600160a01b038216731aef73d49dedc4b1778d0706583995958dc862e6145b80612ebc57506001600160a01b0382167394e131324b6054c0d789b190b2dac504e4361b53145b1561304f5773094d12e5b541784701fd8d65f11fc0598fbc63326001600160a01b038316737eb40e450b9655f4b3cc4259bcc731c63ff55ae61415612f165750733c8caee4e09296800f8d29a68fa3837e2dae4940612fd2565b6001600160a01b038316733a664ab939fd8482048609f652f9a0b0677337b91415612f5657507361e10659fe3aa93d036d099405224e4ac24996d0612fd2565b6001600160a01b038316731aef73d49dedc4b1778d0706583995958dc862e61415612f96575073803a2b40c5a9bb2b86dd630b274fa2a9202874c2612fd2565b6001600160a01b0383167394e131324b6054c0d789b190b2dac504e4361b531415612fd2575073b0a0716841f2fc03fba72a891b8bb13584f52f2d5b612fe76001600160a01b0384168260006132f8565b612ffb6001600160a01b03841682846132f8565b60408051630d2680e960e11b8152600481018490526002602482015260006044820181905291516001600160a01b03841692631a4d01d2926064808201939182900301818387803b158015612de257600080fd5b6001600160a01b038216735282a4ef67d9c33135340fb3289cc1711c13638c141561314b5761309d6001600160a01b038316732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf60006132f8565b6130c56001600160a01b038316732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf836132f8565b6040805163517a55a360e01b81526004810183905260016024820181905260006044830181905260648301919091529151732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf9263517a55a3926084808201939182900301818387803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b50505050611cb5565b6001600160a01b038216736c3f90f043a72fa612cbac8115ee7e52bde6e49014156132025773bebc44782c7db0a1a60cb6fe97d0b483032ff1c761319a6001600160a01b0384168260006132f8565b6131ae6001600160a01b03841682846132f8565b60408051630d2680e960e11b8152600481018490526001602482015260006044820181905291516001600160a01b03841692631a4d01d2926064808201939182900301818387803b158015612de257600080fd5b61322b6001600160a01b03831673a79828df1850e8a3a3064576f380d90aecdd335960006132f8565b6132536001600160a01b03831673a79828df1850e8a3a3064576f380d90aecdd3359836132f8565b60408051631e700cbb60e01b81526001600160a01b03841660048201526024810183905260026044820152600060648201819052306084830152915173a79828df1850e8a3a3064576f380d90aecdd335992631e700cbb9260a480820193602093909283900390910190829087803b1580156132ce57600080fd5b505af11580156132e2573d6000803e3d6000fd5b505050506040513d602081101561253a57600080fd5b80158061337e575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561335057600080fd5b505afa158015613364573d6000803e3d6000fd5b505050506040513d602081101561337a57600080fd5b5051155b6133b95760405162461bcd60e51b815260040180806020018281038252603681526020018061469f6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526126659084905b606061345c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166144019092919063ffffffff16565b8051909150156126655780806020019051602081101561347b57600080fd5b50516126655760405162461bcd60e51b815260040180806020018281038252602a815260200180614675602a913960400191505060405180910390fd5b60006134c26145d1565b60405180608001604052806000815260200160008152602001600081526020016000815250905073a5ca62d95d24a4a350983d5b8ac4eb86388873966001600160a01b0316856001600160a01b031614156136d4576135406001600160a01b03871673a5407eae9ba41422680e2e00537571bcc53efbfd60006132f8565b6135686001600160a01b03871673a5407eae9ba41422680e2e00537571bcc53efbfd866132f8565b60408051630f7c084960e21b8152600f85900b60048201526003602482015260448101869052600060648201819052915173a5407eae9ba41422680e2e00537571bcc53efbfd92633df02124926084808201939182900301818387803b1580156135d157600080fd5b505af11580156135e5573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290517357ab1ec28d129707052df4df418d58a2d46d5f5193506370a0823192506024808301926020929190829003018186803b15801561363a57600080fd5b505afa15801561364e573d6000803e3d6000fd5b505050506040513d602081101561366457600080fd5b5051915061369c7357ab1ec28d129707052df4df418d58a2d46d5f5173a5ca62d95d24a4a350983d5b8ac4eb863888739660006132f8565b6136cf7357ab1ec28d129707052df4df418d58a2d46d5f5173a5ca62d95d24a4a350983d5b8ac4eb8638887396846132f8565b6141ec565b6001600160a01b038516734b5bfd52124784745c1071dcb244c6688d2533d3148061371b57506001600160a01b038516735a770dbd3ee6baf2802d29a901ef11501c44797a145b8061374257506001600160a01b038516738ee57c05741aa9db947a744e713c15d4d19d8822145b8061376957506001600160a01b038516733b96d491f067912d18563d56858ba7d6ec67a6fa145b8061379057506001600160a01b03851673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417145b806137b757506001600160a01b0385167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c145b806137de57506001600160a01b038516738cc94ccd0f3841a468184aca3cc478d2148e1757145b8061380557506001600160a01b038516731c6a9783f812b3af3abbf7de64c3cd7cc7d1af44145b15613bcf576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561384557600080fd5b505afa158015613859573d6000803e3d6000fd5b505050506040513d602081101561386f57600080fd5b5051905073bbc81d23ea2c3ec7e56d39296f0cbb648873a5d36001600160a01b038716735a770dbd3ee6baf2802d29a901ef11501c44797a14156138c8575073fcba3e75865d2d561be8d220616520c171f12851613a67565b6001600160a01b038716738ee57c05741aa9db947a744e713c15d4d19d88221415613908575073b6c057591e073249f2d9d88ba59a46cfc9b59edb613a67565b6001600160a01b038716733b96d491f067912d18563d56858ba7d6ec67a6fa141561394f5773094d12e5b541784701fd8d65f11fc0598fbc63329050600185019450613a67565b6001600160a01b03871673c4daf3b5e2a9e93861c3fbdd25f1e943b8d87417141561399657733c8caee4e09296800f8d29a68fa3837e2dae49409050600185019450613a67565b6001600160a01b0387167330fcf7c6cdfc46ec237783d94fc78553e79d4e9c14156139dd577361e10659fe3aa93d036d099405224e4ac24996d09050600185019450613a67565b6001600160a01b038716738cc94ccd0f3841a468184aca3cc478d2148e17571415613a245773803a2b40c5a9bb2b86dd630b274fa2a9202874c29050600185019450613a67565b6001600160a01b038716731c6a9783f812b3af3abbf7de64c3cd7cc7d1af441415613a675773b0a0716841f2fc03fba72a891b8bb13584f52f2d90506001850194505b85838660048110613a7457fe5b6020020152613a8e6001600160a01b0389168260006132f8565b613aa26001600160a01b03891682886132f8565b60405162a6cbcd60e21b81526001600160a01b0382169063029b2f3490859060009060040180836080808383875b83811015613ae8578181015183820152602001613ad0565b5050505090500182815260200192505050600060405180830381600087803b158015613b1357600080fd5b505af1158015613b27573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516001600160a01b03861693506370a0823192506024808301926020929190829003018186803b158015613b7157600080fd5b505afa158015613b85573d6000803e3d6000fd5b505050506040513d6020811015613b9b57600080fd5b50519350613bb46001600160a01b0383168860006132f8565b613bc86001600160a01b03831688866132f8565b50506141ec565b6001600160a01b0385167384e13785b5a27879921d6f685f041421c7f482da1480613c1657506001600160a01b0385167327b7b1ad7288079a66d12350c828d3c00a6f07d7145b15613f28576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c5657600080fd5b505afa158015613c6a573d6000803e3d6000fd5b505050506040513d6020811015613c8057600080fd5b50519050613c8c6145ef565b604051806060016040528060008152602001600081526020016000815250905085818660038110613cb957fe5b602002015273bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b0388167327b7b1ad7288079a66d12350c828d3c00a6f07d71415613d0f5750732dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf5b613d246001600160a01b038a168260006132f8565b613d386001600160a01b038a1682896132f8565b6001600160a01b0388167384e13785b5a27879921d6f685f041421c7f482da1415613dec57604051634515cef360e01b81526001600160a01b03821690634515cef390849060009060040180836060808383875b83811015613da4578181015183820152602001613d8c565b5050505090500182815260200192505050600060405180830381600087803b158015613dcf57600080fd5b505af1158015613de3573d6000803e3d6000fd5b50505050613e83565b6040516315b74c9d60e11b81526001600160a01b03821690632b6e993a90849060009060019060040180846060808383885b83811015613e36578181015183820152602001613e1e565b5050505090500183815260200182151581526020019350505050600060405180830381600087803b158015613e6a57600080fd5b505af1158015613e7e573d6000803e3d6000fd5b505050505b604080516370a0823160e01b815230600482015290516001600160a01b038516916370a08231916024808301926020929190829003018186803b158015613ec957600080fd5b505afa158015613edd573d6000803e3d6000fd5b505050506040513d6020811015613ef357600080fd5b50519450613f0c6001600160a01b0384168960006132f8565b613f206001600160a01b03841689876132f8565b5050506141ec565b6001600160a01b038516736ede7f19df5df6ef23bd5b9cedb651580bdf56ca1480613f6f57506001600160a01b03851673b4ada607b9d6b2c9ee07a275e9616b84ac560139145b80613f9657506001600160a01b03851673a74d4b67b3368e83797a35382afb776baae4f5c8145b80613fbd57506001600160a01b038516735fa5b62c8af877cb37031e0a3b2f34a78e3c56a6145b156141ec576000856001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ffd57600080fd5b505afa158015614011573d6000803e3d6000fd5b505050506040513d602081101561402757600080fd5b505190508482600186016004811061403b57fe5b60200201526140696001600160a01b03881673a79828df1850e8a3a3064576f380d90aecdd335960006132f8565b6140916001600160a01b03881673a79828df1850e8a3a3064576f380d90aecdd3359876132f8565b60405163384e03db60e01b81526001600160a01b0382166004820190815273a79828df1850e8a3a3064576f380d90aecdd33599163384e03db9184918691600091602401836080808383875b838110156140f55781810151838201526020016140dd565b505050509050018281526020019350505050602060405180830381600087803b15801561412157600080fd5b505af1158015614135573d6000803e3d6000fd5b505050506040513d602081101561414b57600080fd5b5050604080516370a0823160e01b815230600482015290516001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561419357600080fd5b505afa1580156141a7573d6000803e3d6000fd5b505050506040513d60208110156141bd57600080fd5b505192506141d66001600160a01b0382168760006132f8565b6141ea6001600160a01b03821687856132f8565b505b846001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561422757600080fd5b505af115801561423b573d6000803e3d6000fd5b505050506040513d602081101561425157600080fd5b5050505050505050565b600080836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156142ab57600080fd5b505afa1580156142bf573d6000803e3d6000fd5b505050506040513d60208110156142d557600080fd5b5051604080516370a0823160e01b8152730ac00355f80e289f53bf368c9bdb70f5c114c44b600482015290519192506000916001600160a01b038716916370a08231916024808301926020929190829003018186803b15801561433757600080fd5b505afa15801561434b573d6000803e3d6000fd5b505050506040513d602081101561436157600080fd5b5051905061438e6001600160a01b038616730ac00355f80e289f53bf368c9bdb70f5c114c44b60006132f8565b6143b66001600160a01b038616730ac00355f80e289f53bf368c9bdb70f5c114c44b846132f8565b836143d2576143c9816104d58885611fdd565b92505050612036565b60006143e2826104d58986611fdd565b9050848110156143f6579250612036915050565b509295945050505050565b606061134084846000858561441585614527565b614466576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106144a55780518252601f199092019160209182019101614486565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614507576040519150601f19603f3d011682016040523d82523d6000602084013e61450c565b606091505b509150915061451c82828661452d565b979650505050505050565b3b151590565b6060831561453c575081612036565b82511561454c5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561459657818101518382015260200161457e565b50505050905090810190601f1680156145c35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60405180608001604052806004906020820280368337509192915050565b6040518060600160405280600390602082028036833750919291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a264697066735822122033743fb3c2c81f206225ae17c7a957755ba167cd8c6bbf0f2897e84d1c4b0dcd64736f6c63430007030033
Deployed Bytecode Sourcemap
110:797:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6841:1545:3;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6841:1545:3;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;8392:1546;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8392:1546:3;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;8392:1546:3;;;;;;;;;;;;;;;;;;;;;1710:145:14;;;:::i;:::-;;203:702:2;;;;;;;;;;;;;;;;-1:-1:-1;203:702:2;;;;;;;:::i;1078:85:14:-;;;:::i;:::-;;;;-1:-1:-1;;;;;1078:85:14;;;;;;;;;;;;;;6335:152:3;;;;;;;;;;;;;;;;-1:-1:-1;6335:152:3;-1:-1:-1;;;;;6335:152:3;;:::i;9981:3736::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9981:3736:3;;;;;;;;-1:-1:-1;9981:3736:3;;-1:-1:-1;;;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9981:3736:3;;-1:-1:-1;;;;;9981:3736:3;;;;;;;;-1:-1:-1;9981:3736:3;;;;-1:-1:-1;9981:3736:3;;;;-1:-1:-1;;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9981:3736:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9981:3736:3;;-1:-1:-1;;;;9981:3736:3;;;;-1:-1:-1;9981:3736:3;:::i;6493:240::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;6493:240:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;6493:240:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6493:240:3;;-1:-1:-1;6493:240:3;;-1:-1:-1;;;;;6493:240:3:i;2004::14:-;;;;;;;;;;;;;;;;-1:-1:-1;2004:240:14;-1:-1:-1;;;;;2004:240:14;;:::i;6841:1545:3:-;6922:7;6945:18;6957:5;6945:11;:18::i;:::-;6941:154;;;6989:52;7036:4;6989:42;7008:5;-1:-1:-1;;;;;7001:27:3;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7001:29:3;6989:7;;:11;:42::i;:::-;:46;;:52::i;:::-;6979:62;;7070:5;-1:-1:-1;;;;;7063:19:3;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7063:21:3;;-1:-1:-1;6941:154:3;-1:-1:-1;;;;;7109:13:3;;3760:42;7109:13;;:33;;-1:-1:-1;;;;;;7126:16:3;;3987:42;7126:16;7109:33;:54;;;-1:-1:-1;;;;;;7146:17:3;;4457:42;7146:17;7109:54;:75;;;-1:-1:-1;;;;;;7167:17:3;;4221:42;7167:17;7109:75;7105:1275;;;3911:42;-1:-1:-1;;;;;7240:16:3;;3987:42;7240:16;7236:230;;;-1:-1:-1;4144:42:3;7236:230;;;-1:-1:-1;;;;;7317:17:3;;4457:42;7317:17;7313:153;;;-1:-1:-1;4537:42:3;7313:153;;;-1:-1:-1;;;;;7397:17:3;;4221:42;7397:17;7393:73;;;-1:-1:-1;4380:42:3;7393:73;7503:3;-1:-1:-1;;;;;7487:43:3;;7531:7;7540:1;7487:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7487:55:3;;-1:-1:-1;7480:62:3;;-1:-1:-1;7480:62:3;7105:1275;-1:-1:-1;;;;;7563:16:3;;5542:42;7563:16;;:36;;-1:-1:-1;;;;;;7583:16:3;;4613:42;7583:16;7563:36;:56;;;-1:-1:-1;;;;;;7603:16:3;;4846:42;7603:16;7563:56;:76;;;-1:-1:-1;;;;;;7623:16:3;;5079:42;7623:16;7563:76;:95;;;-1:-1:-1;;;;;;7643:15:3;;5311:42;7643:15;7563:95;7559:821;;;5699:42;-1:-1:-1;;;;;7717:16:3;;4613:42;7717:16;7713:300;;;-1:-1:-1;4770:42:3;7713:300;;;-1:-1:-1;;;;;7794:16:3;;4846:42;7794:16;7790:223;;;-1:-1:-1;5003:42:3;7790:223;;;-1:-1:-1;;;;;7871:16:3;;5079:42;7871:16;7867:146;;;-1:-1:-1;5236:42:3;7867:146;;;-1:-1:-1;;;;;7948:15:3;;5311:42;7948:15;7944:69;;;-1:-1:-1;5466:42:3;7944:69;8050:3;-1:-1:-1;;;;;8034:43:3;;8078:7;8087:1;8034:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7559:821;-1:-1:-1;;;;;8110:14:3;;5773:42;8110:14;8106:274;;;8147:67;;;-1:-1:-1;;;8147:67:3;;;;;;;;8206:1;8147:67;;;;;;;;;;;;5850:42;;8147:49;;:67;;;;;;;;;;;;;;5850:42;8147:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8147:67:3;;-1:-1:-1;8140:74:3;;8106:274;8297:72;;;-1:-1:-1;;;8297:72:3;;-1:-1:-1;;;;;8297:72:3;;;;;;;;;;;;8367:1;8297:72;;;;;;6234:42;;8297:53;;:72;;;;;;;;;;;;;;6234:42;8297:72;;;;;;;;;;8106:274;6841:1545;;;;:::o;8392:1546::-;8480:7;8489;8512:20;8520:11;8512:7;:20::i;:::-;8508:118;;;8566:11;-1:-1:-1;;;;;8556:47:3;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8556:49:3;;-1:-1:-1;8607:7:3;;-1:-1:-1;8548:67:3;;8508:118;8640:24;8652:11;8640;:24::i;:::-;8636:466;;;8680:12;8703:11;-1:-1:-1;;;;;8695:39:3;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8695:41:3;8771:33;;;-1:-1:-1;;;8771:33:3;;;;8695:41;;-1:-1:-1;8750:18:3;;-1:-1:-1;;;;;8771:31:3;;;;;:33;;;;;8695:41;;8771:33;;;;;;;:31;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8771:33:3;8847:28;;;-1:-1:-1;;;8847:28:3;;;;8771:33;;-1:-1:-1;8818:26:3;;-1:-1:-1;;;;;8847:26:3;;;;;:28;;;;;8771:33;;8847:28;;;;;;;:26;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8847:28:3;8818:57;;;-1:-1:-1;8908:27:3;;;;;8889:16;;8981:32;;9000:12;;;8981:14;:4;8990;8981:8;:14::i;:32::-;8949:64;-1:-1:-1;9035:10:3;9047:43;9086:3;9047:34;:7;8949:64;9047:11;:34::i;:43::-;9027:64;;;;;;;;;;;8636:466;9160:19;9167:11;9160:6;:19::i;:::-;:47;;;;9183:24;9195:11;9183;:24::i;:::-;9156:133;;;874:42;9237:40;9256:11;9269:7;9237:18;:40::i;:::-;9223:55;;;;;;9156:133;9303:21;9312:11;9303:8;:21::i;:::-;9299:593;;;9350:58;9403:4;9350:48;9369:11;-1:-1:-1;;;;;9362:33:3;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9362:35:3;9350:7;;:11;:48::i;:58::-;9340:68;-1:-1:-1;;;;;;9427:19:3;;1609:42;9427:19;9423:79;;;-1:-1:-1;802:42:3;;-1:-1:-1;9479:7:3;9466:21;;9423:79;-1:-1:-1;;;;;9520:20:3;;1682:42;9520:20;9516:81;;;-1:-1:-1;874:42:3;;-1:-1:-1;9574:7:3;9560:22;;9516:81;-1:-1:-1;;;;;9615:20:3;;1755:42;9615:20;9611:81;;;-1:-1:-1;946:42:3;;-1:-1:-1;9669:7:3;9655:22;;9611:81;-1:-1:-1;;;;;9710:20:3;;1828:42;9710:20;9706:81;;;-1:-1:-1;1018:42:3;;-1:-1:-1;9764:7:3;9750:22;;9706:81;-1:-1:-1;;;;;9805:20:3;;1901:42;9805:20;9801:81;;;-1:-1:-1;1090:42:3;;-1:-1:-1;9859:7:3;9845:22;;9801:81;-1:-1:-1;9910:11:3;;-1:-1:-1;9923:7:3;8392:1546;;;;;;:::o;1710:145:14:-;1301:12;:10;:12::i;:::-;-1:-1:-1;;;;;1290:23:14;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1290:23:14;;1282:68;;;;;-1:-1:-1;;;1282:68:14;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1282:68:14;;;;;;;;;;;;;;;1816:1:::1;1800:6:::0;;1779:40:::1;::::0;-1:-1:-1;;;;;1800:6:14;;::::1;::::0;1779:40:::1;::::0;1816:1;;1779:40:::1;1846:1;1829:19:::0;;-1:-1:-1;;;;;;1829:19:14::1;::::0;;1710:145::o;203:702:2:-;277:7;316:64;718:42:3;345:10:2;365:4;372:7;316:28;:64::i;:::-;391:30;718:42:3;-1:-1:-1;;;;;427:33:2;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;427:35:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;427:35:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;427:35:2;;;;;;;;;;;;-1:-1:-1;427:35:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;427:35:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;427:35:2;;;;;;;;;;;;-1:-1:-1;427:35:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;390:72;;;718:42:3;-1:-1:-1;;;;;472:17:2;;490:7;472:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:9;532:170;556:13;:20;552:1;:24;532:170;;;597:94;623:13;637:1;623:16;;;;;;;;;;;;;;648:13;662:1;648:16;;;;;;;;;;;;;;-1:-1:-1;;;;;641:34:2;;684:4;641:49;;;;;;;;;;;;;-1:-1:-1;;;;;641:49:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;641:49:2;597:25;:94::i;:::-;578:3;;532:170;;;-1:-1:-1;729:37:2;;;-1:-1:-1;;;729:37:2;;760:4;729:37;;;;;;711:15;;874:42:3;;729:22:2;;:37;;;;;;;;;;;;;;;874:42:3;729:37:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;729:37:2;;-1:-1:-1;784:19:2;;;;776:41;;;;;-1:-1:-1;;;776:41:2;;;;;;;;;;;;-1:-1:-1;;;776:41:2;;;;;;;;;;;;;;;827:46;874:42:3;853:10:2;865:7;827:25;:46::i;:::-;891:7;203:702;-1:-1:-1;;;;203:702:2:o;1078:85:14:-;1124:7;1150:6;-1:-1:-1;;;;;1150:6:14;1078:85;:::o;6335:152:3:-;1301:12:14;:10;:12::i;:::-;-1:-1:-1;;;;;1290:23:14;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1290:23:14;;1282:68;;;;;-1:-1:-1;;;1282:68:14;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1282:68:14;;;;;;;;;;;;;;;6400:80:3::1;6428:10;6447:6;-1:-1:-1::0;;;;;6440:24:3::1;;6473:4;6440:39;;;;;;;;;;;;;-1:-1:-1::0;;;;;6440:39:3::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;6440:39:3;-1:-1:-1;;;;;6400:27:3;::::1;::::0;:80;:27:::1;:80::i;:::-;6335:152:::0;:::o;9981:3736::-;10358:7;;;10402:133;10426:26;:33;10422:1;:37;10402:133;;;10486:38;10494:26;10521:1;10494:29;;;;;;;;;;;;;;10486:3;:7;;:38;;;;:::i;:::-;10480:44;-1:-1:-1;10461:3:3;;10402:133;;;;10608:4;10601:3;:11;;10594:19;;;;10637:6;10630:3;:13;;10623:21;;;;10687:66;-1:-1:-1;;;;;10687:30:3;;10718:10;10738:4;10745:7;10687:30;:66::i;:::-;10789:14;10797:5;10789:7;:14::i;:::-;10785:2312;;;10819:107;10835:5;10842:7;10851:16;10869:26;10897:11;10910:15;10819;:107::i;:::-;10785:2312;;;10984:15;10993:5;10984:8;:15::i;:::-;10980:2117;;;11022:5;-1:-1:-1;;;;;11015:22:3;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11053:241:3;;-1:-1:-1;11086:15:3;11119:21;11158:16;11192:26;11236:11;11265:15;11053;:241::i;10980:2117::-;11352:18;11364:5;11352:11;:18::i;:::-;11348:1749;;;11393:5;-1:-1:-1;;;;;11386:22:3;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11443:21:3;;;-1:-1:-1;;;11443:21:3;;;;11424:16;;-1:-1:-1;;;;;11443:19:3;;;;;:21;;;;;11386:24;;11443:21;;;;;;;;:19;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11443:21:3;11504:41;;;-1:-1:-1;;;11504:41:3;;11539:4;11504:41;;;;;;11443:21;;-1:-1:-1;11478:68:3;;11443:21;;-1:-1:-1;;;;;11504:26:3;;;;;:41;;;;;11443:21;;11504:41;;;;;;;;:26;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11504:41:3;11478:15;:68::i;:::-;11615:37;;;-1:-1:-1;;;11615:37:3;;11646:4;11615:37;;;;;;11560:232;;874:42;;;;11615:22;;:37;;;;;;;;;;;;;;874:42;11615:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11615:37:3;11560:232;;;11615:37;11560:232;;;;;11756:1;11560:232;;;11670:16;;11704:26;;11756:1;11560:15;:232::i;:::-;11348:1749;;;;11841:18;11853:5;11841:11;:18::i;:::-;11837:1260;;;11891:5;-1:-1:-1;;;;;11883:21:3;;11905:7;11883:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11883:30:3;:35;11875:62;;;;;-1:-1:-1;;;11875:62:3;;;;;;;;;;;;-1:-1:-1;;;11875:62:3;;;;;;;;;;;;;;;11951:241;11984:15;12017:21;12056:16;12090:26;12134:11;12163:15;11951;:241::i;11837:1260::-;12237:14;12245:5;12237:7;:14::i;:::-;12233:864;;;12267:50;-1:-1:-1;;;;;12267:25:3;;620:42;12315:1;12267:25;:50::i;:::-;12331:56;-1:-1:-1;;;;;12331:25:3;;620:42;12379:7;12331:25;:56::i;:::-;12401:96;;;-1:-1:-1;;;12401:96:3;;-1:-1:-1;;;;;12401:96:3;;;;;;-1:-1:-1;;12401:96:3;;;;12491:4;12401:96;;;;;;620:42;;12401:45;;:96;;;;;;;;;;;;;;-1:-1:-1;620:42:3;12401:96;;;;;;;;;;12233:864;12809:31;12825:5;12832:7;12809:15;:31::i;:::-;12909:37;;;-1:-1:-1;;;12909:37:3;;12940:4;12909:37;;;;;;12854:232;;874:42;;;;12909:22;;:37;;;;;;;;;;;;;;874:42;12909:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12909:37:3;12854:232;;;12909:37;12854:232;;;;;13050:1;12854:232;;;12964:16;;12998:26;;13050:1;12854:15;:232::i;:::-;13143:36;;;-1:-1:-1;;;13143:36:3;;13173:4;13143:36;;;;;;13125:15;;718:42;;13143:21;;:36;;;;;;;;;;;;;;;718:42;13143:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13143:36:3;;-1:-1:-1;13197:22:3;;;;13189:44;;;;;-1:-1:-1;;;13189:44:3;;;;;;;;;;;;-1:-1:-1;;;13189:44:3;;;;;;;;;;;;;;;13243:45;718:42;13268:10;13280:7;13243:24;:45::i;:::-;13373:10;13369:317;;;13404:9;13399:187;13423:16;:23;13419:1;:27;13399:187;;;13471:100;13497:16;13514:1;13497:19;;;;;;;;;;;;;;13525:16;13542:1;13525:19;;;;;;;13471:100;13448:3;;13399:187;;;-1:-1:-1;13637:37:3;;;-1:-1:-1;;;13637:37:3;;13668:4;13637:37;;;;;;13599:76;;13625:10;;874:42;;13637:22;;:37;;;;;;;;;;;;;;874:42;13637:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13637:37:3;874:42;;13599:76;:25;:76::i;:::-;13703:7;9981:3736;-1:-1:-1;;;;;;;;;;;;9981:3736:3:o;6493:240::-;1301:12:14;:10;:12::i;:::-;-1:-1:-1;;;;;1290:23:14;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1290:23:14;;1282:68;;;;;-1:-1:-1;;;1282:68:14;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1282:68:14;;;;;;;;;;;;;;;6574:9:3::1;6569:158;6593:7;:14;6589:1;:18;6569:158;;;6628:88;6660:10;6679:7;6687:1;6679:10;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6672:28:3::1;;6709:4;6672:43;;;;;;;;;;;;;-1:-1:-1::0;;;;;6672:43:3::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;6672:43:3;6635:10;;:7;;6643:1;;6635:10;::::1;;;;;;;;;;;-1:-1:-1::0;;;;;6628:31:3::1;;;:88;;;;;:::i;:::-;6609:3;;6569:158;;;;6493:240:::0;:::o;2004::14:-;1301:12;:10;:12::i;:::-;-1:-1:-1;;;;;1290:23:14;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1290:23:14;;1282:68;;;;;-1:-1:-1;;;1282:68:14;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1282:68:14;;;;;;;;;;;;;;;-1:-1:-1;;;;;2092:22:14;::::1;2084:73;;;;-1:-1:-1::0;;;2084:73:14::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2193:6;::::0;;2172:38:::1;::::0;-1:-1:-1;;;;;2172:38:14;;::::1;::::0;2193:6;::::1;::::0;2172:38:::1;::::0;::::1;2220:6;:17:::0;;-1:-1:-1;;;;;;2220:17:14::1;-1:-1:-1::0;;;;;2220:17:14;;;::::1;::::0;;;::::1;::::0;;2004:240::o;22956:548:3:-;23016:4;-1:-1:-1;;;;;23040:14:3;;1991:42;23040:14;;:48;;-1:-1:-1;;;;;;23070:18:3;;2077:42;23070:18;23040:48;:83;;;-1:-1:-1;;;;;;23104:19:3;;2154:42;23104:19;23040:83;:117;;;-1:-1:-1;;;;;;23139:18:3;;2230:42;23139:18;23040:117;:151;;;-1:-1:-1;;;;;;23173:18:3;;2306:42;23173:18;23040:151;:185;;;-1:-1:-1;;;;;;23207:18:3;;2382:42;23207:18;23040:185;:220;;;-1:-1:-1;;;;;;23241:19:3;;2459:42;23241:19;23040:220;:254;;;-1:-1:-1;;;;;;23276:18:3;;2535:42;23276:18;23040:254;:288;;;-1:-1:-1;;;;;;23310:18:3;;2611:42;23310:18;23040:288;:323;;;-1:-1:-1;;;;;;23344:19:3;;2762:42;23344:19;23040:323;:355;;;-1:-1:-1;;;;;;23379:16:3;;2685:42;23379:16;23040:355;:389;;;-1:-1:-1;;;;;;23411:18:3;;2914:42;23411:18;23040:389;:422;;;-1:-1:-1;;;;;;23445:17:3;;2989:42;23445:17;23040:422;:456;;;-1:-1:-1;;;;;;23478:18:3;;2838:42;23478:18;23032:465;22956:548;-1:-1:-1;;22956:548:3:o;3538:215:16:-;3596:7;3619:6;3615:20;;-1:-1:-1;3634:1:16;3627:8;;3615:20;3657:5;;;3661:1;3657;:5;:1;3680:5;;;;;:10;3672:56;;;;-1:-1:-1;;;3672:56:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3745:1;3538:215;-1:-1:-1;;;3538:215:16:o;4217:150::-;4275:7;4306:1;4302;:5;4294:44;;;;;-1:-1:-1;;;4294:44:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;4359:1;4355;:5;;;;;;;4217:150;-1:-1:-1;;;4217:150:16:o;24215:178:3:-;24271:4;-1:-1:-1;;;;;24295:14:3;;3074:42;24295:14;;:33;;-1:-1:-1;;;;;;24313:15:3;;3147:42;24313:15;24295:33;:52;;;-1:-1:-1;;;;;;24332:15:3;;3220:42;24332:15;24295:52;:71;;;-1:-1:-1;;;;;;24351:15:3;;3293:42;24351:15;24295:71;:90;;;-1:-1:-1;;;;;;;24370:15:3;3366:42;24370:15;;24215:178::o;24046:163::-;24106:4;-1:-1:-1;;;;;24130:14:3;;3455:42;24130:14;;:33;;-1:-1:-1;;;;;;24148:15:3;;3528:42;24148:15;24130:33;:52;;;-1:-1:-1;;;;;;24167:15:3;;3601:42;24167:15;24130:52;:71;;;-1:-1:-1;;;;;;;24186:15:3;3674:42;24186:15;;24046:163::o;23510:530::-;23565:4;-1:-1:-1;;;;;23589:14:3;;3760:42;23589:14;;:47;;-1:-1:-1;;;;;;23619:17:3;;3987:42;23619:17;23589:47;:81;;;-1:-1:-1;;;;;;23652:18:3;;4221:42;23652:18;23589:81;:114;;;-1:-1:-1;;;;;;23686:17:3;;5926:42;23686:17;23589:114;:147;;;-1:-1:-1;;;;;;23719:17:3;;4613:42;23719:17;23589:147;:180;;;-1:-1:-1;;;;;;23752:17:3;;6001:42;23752:17;23589:180;:214;;;-1:-1:-1;;;;;;23785:18:3;;6077:42;23785:18;23589:214;:247;;;-1:-1:-1;;;;;;23819:17:3;;6152:42;23819:17;23589:247;:281;;;-1:-1:-1;;;;;;23852:18:3;;4457:42;23852:18;23589:281;:314;;;-1:-1:-1;;;;;;23886:17:3;;5542:42;23886:17;23589:314;:347;;;-1:-1:-1;;;;;;23919:17:3;;4846:42;23919:17;23589:347;:380;;;-1:-1:-1;;;;;;23952:17:3;;5079:42;23952:17;23589:380;:412;;;-1:-1:-1;;;;;;23985:16:3;;5311:42;23985:16;23589:412;:443;;;-1:-1:-1;;;;;;;24017:15:3;5773:42;24017:15;;23510:530::o;22771:179::-;22828:4;-1:-1:-1;;;;;22852:14:3;;1609:42;22852:14;;:33;;-1:-1:-1;;;;;;22870:15:3;;1682:42;22870:15;22852:33;:52;;;-1:-1:-1;;;;;;22889:15:3;;1755:42;22889:15;22852:52;:71;;;-1:-1:-1;;;;;;22908:15:3;;1828:42;22908:15;22852:71;:90;;;-1:-1:-1;;;;;;;22927:15:3;1901:42;22927:15;;22771:179::o;598:104:4:-;685:10;598:104;:::o;866:203:15:-;993:68;;;-1:-1:-1;;;;;993:68:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;993:68:15;-1:-1:-1;;;993:68:15;;;966:96;;986:5;;966:19;:96::i;:::-;866:203;;;;:::o;22125:232:3:-;22220:23;22232:10;22220:11;:23::i;:::-;22216:135;;;22259:81;22282:10;-1:-1:-1;;;;;22275:24:3;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22275:26:3;22303:36;;;-1:-1:-1;;;22303:36:3;;;;;;;;;;-1:-1:-1;;;;;22303:27:3;;;;;:36;;;;;22275:26;;22303:36;;;;;;;-1:-1:-1;22303:27:3;:36;;;;;;;;;;;;;;;;;;;;;;;;;;685:175:15;794:58;;;-1:-1:-1;;;;;794:58:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;794:58:15;-1:-1:-1;;;794:58:15;;;767:86;;787:5;;767:19;:86::i;:::-;685:175;;;:::o;2690::16:-;2748:7;2779:5;;;2802:6;;;;2794:46;;;;;-1:-1:-1;;;2794:46:16;;;;;;;;;;;;;;;;;;;;;;;;;;;22363:402:3;22419:4;-1:-1:-1;;;;;22443:13:3;;802:42;22443:13;;:43;;-1:-1:-1;;;;;;22472:14:3;;874:42;22472:14;22443:43;:73;;;-1:-1:-1;;;;;;22502:14:3;;946:42;22502:14;22443:73;:103;;;-1:-1:-1;;;;;;22532:14:3;;1018:42;22532:14;22443:103;:133;;;-1:-1:-1;;;;;;22562:14:3;;1090:42;22562:14;22443:133;:163;;;-1:-1:-1;;;;;;22592:14:3;;1162:42;22592:14;22443:163;:193;;;-1:-1:-1;;;;;;22622:14:3;;1234:42;22622:14;22443:193;:223;;;-1:-1:-1;;;;;;22652:14:3;;1306:42;22652:14;22443:223;:254;;;-1:-1:-1;;;;;;22682:15:3;;1379:42;22682:15;22443:254;:284;;;-1:-1:-1;;;;;;22713:14:3;;1451:42;22713:14;22443:284;:314;;;-1:-1:-1;;;;;;;22743:14:3;1523:42;22743:14;;22363:402::o;15760:1613::-;16069:14;-1:-1:-1;;;;;16153:13:3;;802:42;16153:13;;;;:31;;-1:-1:-1;;;;;;16170:14:3;;874:42;16170:14;;16153:31;:49;;;;-1:-1:-1;;;;;;16188:14:3;;946:42;16188:14;;16153:49;16149:383;;;16218:42;-1:-1:-1;;;;;16218:26:3;;16245:11;16258:1;16218:26;:42::i;:::-;16274:48;-1:-1:-1;;;;;16274:26:3;;16301:11;16314:7;16274:26;:48::i;:::-;16338:12;16356:11;-1:-1:-1;;;;;16356:16:3;16373:15;16356:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16356:33:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16337:52;;;16411:7;16403:25;;;;;-1:-1:-1;;;16403:25:3;;;;;;;;;;;;-1:-1:-1;;;16403:25:3;;;;;;;;;;;;;;;874:42;16508:13;;16149:383;;-1:-1:-1;;;;;16546:14:3;;874:42;16546:14;16542:116;;;-1:-1:-1;16585:1:3;16542:116;;;-1:-1:-1;;;;;16607:14:3;;946:42;16607:14;16603:55;;;-1:-1:-1;16646:1:3;16603:55;16694:20;16724:17;718:42;-1:-1:-1;;;;;16744:23:3;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16744:25:3;16799:39;;;-1:-1:-1;;;16799:39:3;;16832:4;16799:39;;;;;;16744:25;;-1:-1:-1;16780:16:3;;-1:-1:-1;;;;;16799:24:3;;;;;:39;;;;;16744:25;;16799:39;;;;;;;:24;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16799:39:3;;-1:-1:-1;16848:19:3;;16877:427;16901:16;:23;16897:1;:27;16877:427;;;17018:53;17066:4;17018:43;17031:26;17058:1;17031:29;;;;;;;;;;;;;;17018:8;:12;;:43;;;;:::i;:53::-;17004:67;;17085;17103:6;17111:16;17128:1;17111:19;;;;;;;;;;;;;;17132:11;17145:6;17085:17;:67::i;:::-;17216:77;17248:9;17259:16;17276:1;17259:19;;;;;;;;;;;;;;17280:12;17216:31;:77::i;:::-;17201:92;-1:-1:-1;16926:3:3;;16877:427;;;;718:42;-1:-1:-1;;;;;17335:17:3;;17353:12;17335:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15760:1613;;;;;;;;;;;:::o;13758:1996::-;-1:-1:-1;;;;;13872:13:3;;3760:42;13872:13;;:33;;-1:-1:-1;;;;;;13889:16:3;;3987:42;13889:16;13872:33;:54;;;-1:-1:-1;;;;;;13909:17:3;;4221:42;13909:17;13872:54;13868:1880;;;3911:42;-1:-1:-1;;;;;13982:16:3;;3987:42;13982:16;13978:150;;;-1:-1:-1;4144:42:3;13978:150;;;-1:-1:-1;;;;;14059:17:3;;4221:42;14059:17;14055:73;;;-1:-1:-1;4380:42:3;14055:73;14142:33;-1:-1:-1;;;;;14142:25:3;;14168:3;14173:1;14142:25;:33::i;:::-;14189:39;-1:-1:-1;;;;;14189:25:3;;14215:3;14220:7;14189:25;:39::i;:::-;14242:68;;;-1:-1:-1;;;14242:68:3;;;;;;;;14298:1;14242:68;;;;14301:1;14242:68;;;;;;;;;;;;;;-1:-1:-1;;;;;14242:46:3;;;;;:68;;;;;;;;;;;14301:1;14242:46;:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13868:1880;;;;-1:-1:-1;;;;;14331:16:3;;4613:42;14331:16;;:36;;-1:-1:-1;;;;;;14351:16:3;;5542:42;14351:16;14331:36;:56;;;-1:-1:-1;;;;;;14371:16:3;;4846:42;14371:16;14331:56;:76;;;-1:-1:-1;;;;;;14391:16:3;;5079:42;14391:16;14331:76;:95;;;-1:-1:-1;;;;;;14411:15:3;;5311:42;14411:15;14331:95;14327:1421;;;5699:42;-1:-1:-1;;;;;14485:16:3;;4613:42;14485:16;14481:300;;;-1:-1:-1;4770:42:3;14481:300;;;-1:-1:-1;;;;;14562:16:3;;4846:42;14562:16;14558:223;;;-1:-1:-1;5003:42:3;14558:223;;;-1:-1:-1;;;;;14639:16:3;;5079:42;14639:16;14635:146;;;-1:-1:-1;5236:42:3;14635:146;;;-1:-1:-1;;;;;14716:15:3;;5311:42;14716:15;14712:69;;;-1:-1:-1;5466:42:3;14712:69;14795:33;-1:-1:-1;;;;;14795:25:3;;14821:3;14826:1;14795:25;:33::i;:::-;14842:39;-1:-1:-1;;;;;14842:25:3;;14868:3;14873:7;14842:25;:39::i;:::-;14895:61;;;-1:-1:-1;;;14895:61:3;;;;;;;;14951:1;14895:61;;;;14954:1;14895:61;;;;;;;;-1:-1:-1;;;;;14895:46:3;;;;;:61;;;;;;;;;;;14954:1;14895:46;:61;;;;;;;;;;14327:1421;-1:-1:-1;;;;;14977:14:3;;5773:42;14977:14;14973:775;;;15007:39;-1:-1:-1;;;;;15007:25:3;;5850:42;15044:1;15007:25;:39::i;:::-;15060:45;-1:-1:-1;;;;;15060:25:3;;5850:42;15097:7;15060:25;:45::i;:::-;15119:73;;;-1:-1:-1;;;15119:73:3;;;;;;;;15181:1;15119:73;;;;;;15184:1;15119:73;;;;;;;;;;;;;;;5850:42;;15119:52;;:73;;;;;;;;;;;15184:1;5850:42;15119:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14973:775;;;-1:-1:-1;;;;;15213:17:3;;4457:42;15213:17;15209:539;;;4537:42;15287:33;-1:-1:-1;;;;;15287:25:3;;4537:42;15246:11;15287:25;:33::i;:::-;15334:39;-1:-1:-1;;;;;15334:25:3;;15360:3;15365:7;15334:25;:39::i;:::-;15387:61;;;-1:-1:-1;;;15387:61:3;;;;;;;;15443:1;15387:61;;;;15446:1;15387:61;;;;;;;;-1:-1:-1;;;;;15387:46:3;;;;;:61;;;;;;;;;;;15446:1;15387:46;:61;;;;;;;;;;15209:539;15524:43;-1:-1:-1;;;;;15524:25:3;;6234:42;15565:1;15524:25;:43::i;:::-;15581:49;-1:-1:-1;;;;;15581:25:3;;6234:42;15622:7;15581:25;:49::i;:::-;15644:93;;;-1:-1:-1;;;15644:93:3;;-1:-1:-1;;;;;15644:93:3;;;;;;;;;;;;15717:1;15644:93;;;;15720:1;15644:93;;;;;;15731:4;15644:93;;;;;;6234:42;;15644:56;;:93;;;;;;;;;;;;;;;;;;6234:42;15644:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1329:613:15;1694:10;;;1693:62;;-1:-1:-1;1710:39:15;;;-1:-1:-1;;;1710:39:15;;1734:4;1710:39;;;;-1:-1:-1;;;;;1710:39:15;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1710:39:15;:44;1693:62;1685:150;;;;-1:-1:-1;;;1685:150:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:62;;;-1:-1:-1;;;;;1872:62:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1872:62:15;-1:-1:-1;;;1872:62:15;;;1845:90;;1865:5;;2948:751;3367:23;3393:69;3421:4;3393:69;;;;;;;;;;;;;;;;;3401:5;-1:-1:-1;;;;;3393:27:15;;;:69;;;;;:::i;:::-;3476:17;;3367:95;;-1:-1:-1;3476:21:15;3472:221;;3616:10;3605:30;;;;;;;;;;;;;;;-1:-1:-1;3605:30:15;3597:85;;;;-1:-1:-1;;;3597:85:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18216:3903:3;18377:11;18398:33;;:::i;:::-;:84;;;;;;;;18443:1;18398:84;;;;18455:1;18398:84;;;;18467:1;18398:84;;;;18479:1;18398:84;;;;;1901:42;-1:-1:-1;;;;;18497:17:3;:8;-1:-1:-1;;;;;18497:17:3;;18493:3583;;;18530:46;-1:-1:-1;;;;;18530:30:3;;4066:42;18574:1;18530:30;:46::i;:::-;18590:52;-1:-1:-1;;;;;18590:30:3;;4066:42;18634:7;18590:30;:52::i;:::-;18657:69;;;-1:-1:-1;;;18657:69:3;;;;;;;;;;18712:1;18657:69;;;;;;;;;;18724:1;18657:69;;;;;;;;4066:42;;18657:32;;:69;;;;;;;;;;;18724:1;4066:42;18657:69;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;18747:37:3;;;-1:-1:-1;;;18747:37:3;;18778:4;18747:37;;;;;;1090:42;;-1:-1:-1;18747:22:3;;-1:-1:-1;18747:37:3;;;;;;;;;;;;;;1090:42;18747:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18747:37:3;;-1:-1:-1;18798:34:3;1090:42;1901;18830:1;18798:24;:34::i;:::-;18846:36;1090:42;1901;18878:3;18846:24;:36::i;:::-;18493:3583;;;-1:-1:-1;;;;;18947:16:3;;1991:42;18947:16;;:52;;-1:-1:-1;;;;;;18979:20:3;;2077:42;18979:20;18947:52;:89;;;-1:-1:-1;;;;;;19015:21:3;;2154:42;19015:21;18947:89;:125;;;-1:-1:-1;;;;;;19052:20:3;;2611:42;19052:20;18947:125;:161;;;-1:-1:-1;;;;;;19088:20:3;;2306:42;19088:20;18947:161;:197;;;-1:-1:-1;;;;;;19124:20:3;;2838:42;19124:20;18947:197;:233;;;-1:-1:-1;;;;;;19160:20:3;;2914:42;19160:20;18947:233;:268;;;-1:-1:-1;;;;;;19196:19:3;;2989:42;19196:19;18947:268;18930:3146;;;19240:16;19266:8;-1:-1:-1;;;;;19259:22:3;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19259:24:3;;-1:-1:-1;3911:42:3;-1:-1:-1;;;;;19337:20:3;;2077:42;19337:20;19333:736;;;-1:-1:-1;4144:42:3;19333:736;;;-1:-1:-1;;;;;19418:21:3;;2154:42;19418:21;19414:655;;;-1:-1:-1;4380:42:3;19414:655;;;-1:-1:-1;;;;;19501:20:3;;2611:42;19501:20;19497:572;;;5699:42;19541:16;;19591:1;19575:17;;;;19497:572;;;-1:-1:-1;;;;;19617:20:3;;2306:42;19617:20;19613:456;;;4770:42;19657:16;;19707:1;19691:17;;;;19613:456;;;-1:-1:-1;;;;;19733:20:3;;2838:42;19733:20;19729:340;;;5003:42;19773:16;;19823:1;19807:17;;;;19729:340;;;-1:-1:-1;;;;;19849:20:3;;2914:42;19849:20;19845:224;;;5236:42;19889:16;;19939:1;19923:17;;;;19845:224;;;-1:-1:-1;;;;;19965:19:3;;2989:42;19965:19;19961:108;;;5466:42;20004:15;;20053:1;20037:17;;;;19961:108;20115:7;20083:15;20099:12;20083:29;;;;;;;;;;:39;20136:38;-1:-1:-1;;;;;20136:30:3;;20167:3;20172:1;20136:30;:38::i;:::-;20188:44;-1:-1:-1;;;;;20188:30:3;;20219:3;20224:7;20188:30;:44::i;:::-;20246:54;;-1:-1:-1;;;20246:54:3;;-1:-1:-1;;;;;20246:34:3;;;;;20281:15;;20298:1;;20246:54;;;20281:15;20246:54;;;20281:15;20298:1;20246:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20321:41:3;;;-1:-1:-1;;;20321:41:3;;20356:4;20321:41;;;;;;-1:-1:-1;;;;;20321:26:3;;;-1:-1:-1;20321:26:3;;-1:-1:-1;20321:41:3;;;;;;;;;;;;;;:26;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20321:41:3;;-1:-1:-1;20376:41:3;-1:-1:-1;;;;;20376:28:3;;20405:8;20415:1;20376:28;:41::i;:::-;20431:43;-1:-1:-1;;;;;20431:28:3;;20460:8;20470:3;20431:28;:43::i;:::-;18930:3146;;;;;-1:-1:-1;;;;;20495:21:3;;2762:42;20495:21;;:43;;-1:-1:-1;;;;;;20520:18:3;;2685:42;20520:18;20495:43;20491:1585;;;20554:16;20580:8;-1:-1:-1;;;;;20573:22:3;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20573:24:3;;-1:-1:-1;20612:33:3;;:::i;:::-;:72;;;;;;;;20657:1;20612:72;;;;20669:1;20612:72;;;;20681:1;20612:72;;;;;20730:7;20698:15;20714:12;20698:29;;;;;;;;;;:39;4537:42;-1:-1:-1;;;;;20796:18:3;;2685:42;20796:18;20792:72;;;-1:-1:-1;5850:42:3;20792:72;20878:38;-1:-1:-1;;;;;20878:30:3;;20909:3;20914:1;20878:30;:38::i;:::-;20930:44;-1:-1:-1;;;;;20930:30:3;;20961:3;20966:7;20930:30;:44::i;:::-;-1:-1:-1;;;;;20993:21:3;;2762:42;20993:21;20989:213;;;21034:54;;-1:-1:-1;;;21034:54:3;;-1:-1:-1;;;;;21034:34:3;;;;;21069:15;;21086:1;;21034:54;;;21069:15;21034:54;;;21069:15;21086:1;21034:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20989:213;;;21127:60;;-1:-1:-1;;;21127:60:3;;-1:-1:-1;;;;;21127:34:3;;;;;21162:15;;21179:1;;21182:4;;21127:60;;;21162:15;21127:60;;;21162:15;21179:1;21127:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20989:213;21222:41;;;-1:-1:-1;;;21222:41:3;;21257:4;21222:41;;;;;;-1:-1:-1;;;;;21222:26:3;;;;;:41;;;;;;;;;;;;;;:26;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21222:41:3;;-1:-1:-1;21277:41:3;-1:-1:-1;;;;;21277:28:3;;21306:8;21316:1;21277:28;:41::i;:::-;21332:43;-1:-1:-1;;;;;21332:28:3;;21361:8;21371:3;21332:28;:43::i;:::-;20491:1585;;;;;;-1:-1:-1;;;;;21426:20:3;;2230:42;21426:20;;:44;;-1:-1:-1;;;;;;21450:20:3;;2382:42;21450:20;21426:44;:69;;;-1:-1:-1;;;;;;21474:21:3;;2459:42;21474:21;21426:69;:93;;;-1:-1:-1;;;;;;21499:20:3;;2535:42;21499:20;21426:93;21422:654;;;21571:16;21597:8;-1:-1:-1;;;;;21590:22:3;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21590:24:3;;-1:-1:-1;21665:7:3;21629:15;21660:1;21645:16;;21629:33;;;;;;;;;;:43;21686:48;-1:-1:-1;;;;;21686:30:3;;6234:42;21732:1;21686:30;:48::i;:::-;21748:54;-1:-1:-1;;;;;21748:30:3;;6234:42;21794:7;21748:30;:54::i;:::-;21817:74;;-1:-1:-1;;;21817:74:3;;-1:-1:-1;;;;;21817:74:3;;;;;;;;6234:42;;21817:44;;21862:8;;21872:15;;21889:1;;21817:74;;21872:15;21817:74;;;21872:15;21889:1;21817:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;21912:41:3;;;-1:-1:-1;;;21912:41:3;;21947:4;21912:41;;;;;;-1:-1:-1;;;;;21912:26:3;;;;;:41;;;;;21817:74;;21912:41;;;;;;;:26;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21912:41:3;;-1:-1:-1;21967:41:3;-1:-1:-1;;;;;21967:28:3;;21996:8;22006:1;21967:28;:41::i;:::-;22022:43;-1:-1:-1;;;;;22022:28:3;;22051:8;22061:3;22022:28;:43::i;:::-;21422:654;;22093:8;-1:-1:-1;;;;;22086:24:3;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;18216:3903:3:o;17379:831::-;17543:7;17562:11;17583:16;-1:-1:-1;;;;;17576:34:3;;17619:4;17576:49;;;;;;;;;;;;;-1:-1:-1;;;;;17576:49:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17576:49:3;17652:39;;;-1:-1:-1;;;17652:39:3;;718:42;17652:39;;;;;;17576:49;;-1:-1:-1;17635:14:3;;-1:-1:-1;;;;;17652:34:3;;;;;:39;;;;;17576:49;;17652:39;;;;;;;:34;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17652:39:3;;-1:-1:-1;17702:44:3;-1:-1:-1;;;;;17702:36:3;;718:42;17744:1;17702:36;:44::i;:::-;17756:46;-1:-1:-1;;;;;17756:36:3;;718:42;17798:3;17756:36;:46::i;:::-;17949:19;17945:93;;17991:36;18020:6;17991:24;:15;18011:3;17991:19;:24::i;:36::-;17984:43;;;;;;17945:93;18048:12;18063:36;18092:6;18063:24;:15;18083:3;18063:19;:24::i;:36::-;18048:51;;18120:14;18113:4;:21;18109:63;;;18157:4;-1:-1:-1;18150:11:3;;-1:-1:-1;;18150:11:3;18109:63;-1:-1:-1;18189:14:3;;17379:831;-1:-1:-1;;;;;17379:831:3:o;3581:193:1:-;3684:12;3715:52;3737:6;3745:4;3751:1;3754:12;3684;4858:18;4869:6;4858:10;:18::i;:::-;4850:60;;;;;-1:-1:-1;;;4850:60:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;4981:12;4995:23;5022:6;-1:-1:-1;;;;;5022:11:1;5042:5;5050:4;5022:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5022:33:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4980:75;;;;5072:52;5090:7;5099:10;5111:12;5072:17;:52::i;:::-;5065:59;4608:523;-1:-1:-1;;;;;;;4608:523:1:o;726:413::-;1086:20;1124:8;;;726:413::o;7091:725::-;7206:12;7234:7;7230:580;;;-1:-1:-1;7264:10:1;7257:17;;7230:580;7375:17;;:21;7371:429;;7633:10;7627:17;7693:15;7680:10;7676:2;7672:19;7665:44;7582:145;7772:12;7765:20;;-1:-1:-1;;;7765:20:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://33743fb3c2c81f206225ae17c7a957755ba167cd8c6bbf0f2897e84d1c4b0dcd
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.996715 | 10 | $9.97 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.