More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
BancorFormula
Compiler Version
v0.4.26+commit.4563c3fc
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-12-12 */ // File: contracts/converter/interfaces/IBancorFormula.sol pragma solidity 0.4.26; /* Bancor Formula interface */ contract IBancorFormula { function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _depositAmount) public view returns (uint256); function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _sellAmount) public view returns (uint256); function calculateCrossReserveReturn(uint256 _fromReserveBalance, uint32 _fromReserveRatio, uint256 _toReserveBalance, uint32 _toReserveRatio, uint256 _amount) public view returns (uint256); function calculateFundCost(uint256 _supply, uint256 _reserveBalance, uint32 _totalRatio, uint256 _amount) public view returns (uint256); function calculateLiquidateReturn(uint256 _supply, uint256 _reserveBalance, uint32 _totalRatio, uint256 _amount) public view returns (uint256); // deprecated, backward compatibility function calculateCrossConnectorReturn(uint256 _fromConnectorBalance, uint32 _fromConnectorWeight, uint256 _toConnectorBalance, uint32 _toConnectorWeight, uint256 _amount) public view returns (uint256); } // File: contracts/utility/SafeMath.sol pragma solidity 0.4.26; /** * @dev Library for basic math operations with overflow/underflow protection */ library SafeMath { /** * @dev returns the sum of _x and _y, reverts if the calculation overflows * * @param _x value 1 * @param _y value 2 * * @return sum */ function add(uint256 _x, uint256 _y) internal pure returns (uint256) { uint256 z = _x + _y; require(z >= _x); return z; } /** * @dev returns the difference of _x minus _y, reverts if the calculation underflows * * @param _x minuend * @param _y subtrahend * * @return difference */ function sub(uint256 _x, uint256 _y) internal pure returns (uint256) { require(_x >= _y); return _x - _y; } /** * @dev returns the product of multiplying _x by _y, reverts if the calculation overflows * * @param _x factor 1 * @param _y factor 2 * * @return product */ function mul(uint256 _x, uint256 _y) internal pure returns (uint256) { // gas optimization if (_x == 0) return 0; uint256 z = _x * _y; require(z / _x == _y); return z; } /** * ev Integer division of two numbers truncating the quotient, reverts on division by zero. * * aram _x dividend * aram _y divisor * * eturn quotient */ function div(uint256 _x, uint256 _y) internal pure returns (uint256) { require(_y > 0); uint256 c = _x / _y; return c; } } // File: contracts/utility/Utils.sol pragma solidity 0.4.26; /** * @dev Utilities & Common Modifiers */ contract Utils { /** * constructor */ constructor() public { } // verifies that an amount is greater than zero modifier greaterThanZero(uint256 _amount) { require(_amount > 0); _; } // validates an address - currently only checks that it isn't null modifier validAddress(address _address) { require(_address != address(0)); _; } // verifies that the address is different than this contract address modifier notThis(address _address) { require(_address != address(this)); _; } } // File: contracts/converter/BancorFormula.sol pragma solidity 0.4.26; contract BancorFormula is IBancorFormula, Utils { using SafeMath for uint256; uint16 public version = 5; uint256 private constant ONE = 1; uint32 private constant MAX_RATIO = 1000000; uint8 private constant MIN_PRECISION = 32; uint8 private constant MAX_PRECISION = 127; /** * Auto-generated via 'PrintIntScalingFactors.py' */ uint256 private constant FIXED_1 = 0x080000000000000000000000000000000; uint256 private constant FIXED_2 = 0x100000000000000000000000000000000; uint256 private constant MAX_NUM = 0x200000000000000000000000000000000; /** * Auto-generated via 'PrintLn2ScalingFactors.py' */ uint256 private constant LN2_NUMERATOR = 0x3f80fe03f80fe03f80fe03f80fe03f8; uint256 private constant LN2_DENOMINATOR = 0x5b9de1d10bf4103d647b0955897ba80; /** * Auto-generated via 'PrintFunctionOptimalLog.py' and 'PrintFunctionOptimalExp.py' */ uint256 private constant OPT_LOG_MAX_VAL = 0x15bf0a8b1457695355fb8ac404e7a79e3; uint256 private constant OPT_EXP_MAX_VAL = 0x800000000000000000000000000000000; /** * Auto-generated via 'PrintFunctionConstructor.py' */ uint256[128] private maxExpArray; constructor() public { // maxExpArray[ 0] = 0x6bffffffffffffffffffffffffffffffff; // maxExpArray[ 1] = 0x67ffffffffffffffffffffffffffffffff; // maxExpArray[ 2] = 0x637fffffffffffffffffffffffffffffff; // maxExpArray[ 3] = 0x5f6fffffffffffffffffffffffffffffff; // maxExpArray[ 4] = 0x5b77ffffffffffffffffffffffffffffff; // maxExpArray[ 5] = 0x57b3ffffffffffffffffffffffffffffff; // maxExpArray[ 6] = 0x5419ffffffffffffffffffffffffffffff; // maxExpArray[ 7] = 0x50a2ffffffffffffffffffffffffffffff; // maxExpArray[ 8] = 0x4d517fffffffffffffffffffffffffffff; // maxExpArray[ 9] = 0x4a233fffffffffffffffffffffffffffff; // maxExpArray[ 10] = 0x47165fffffffffffffffffffffffffffff; // maxExpArray[ 11] = 0x4429afffffffffffffffffffffffffffff; // maxExpArray[ 12] = 0x415bc7ffffffffffffffffffffffffffff; // maxExpArray[ 13] = 0x3eab73ffffffffffffffffffffffffffff; // maxExpArray[ 14] = 0x3c1771ffffffffffffffffffffffffffff; // maxExpArray[ 15] = 0x399e96ffffffffffffffffffffffffffff; // maxExpArray[ 16] = 0x373fc47fffffffffffffffffffffffffff; // maxExpArray[ 17] = 0x34f9e8ffffffffffffffffffffffffffff; // maxExpArray[ 18] = 0x32cbfd5fffffffffffffffffffffffffff; // maxExpArray[ 19] = 0x30b5057fffffffffffffffffffffffffff; // maxExpArray[ 20] = 0x2eb40f9fffffffffffffffffffffffffff; // maxExpArray[ 21] = 0x2cc8340fffffffffffffffffffffffffff; // maxExpArray[ 22] = 0x2af09481ffffffffffffffffffffffffff; // maxExpArray[ 23] = 0x292c5bddffffffffffffffffffffffffff; // maxExpArray[ 24] = 0x277abdcdffffffffffffffffffffffffff; // maxExpArray[ 25] = 0x25daf6657fffffffffffffffffffffffff; // maxExpArray[ 26] = 0x244c49c65fffffffffffffffffffffffff; // maxExpArray[ 27] = 0x22ce03cd5fffffffffffffffffffffffff; // maxExpArray[ 28] = 0x215f77c047ffffffffffffffffffffffff; // maxExpArray[ 29] = 0x1fffffffffffffffffffffffffffffffff; // maxExpArray[ 30] = 0x1eaefdbdabffffffffffffffffffffffff; // maxExpArray[ 31] = 0x1d6bd8b2ebffffffffffffffffffffffff; maxExpArray[ 32] = 0x1c35fedd14ffffffffffffffffffffffff; maxExpArray[ 33] = 0x1b0ce43b323fffffffffffffffffffffff; maxExpArray[ 34] = 0x19f0028ec1ffffffffffffffffffffffff; maxExpArray[ 35] = 0x18ded91f0e7fffffffffffffffffffffff; maxExpArray[ 36] = 0x17d8ec7f0417ffffffffffffffffffffff; maxExpArray[ 37] = 0x16ddc6556cdbffffffffffffffffffffff; maxExpArray[ 38] = 0x15ecf52776a1ffffffffffffffffffffff; maxExpArray[ 39] = 0x15060c256cb2ffffffffffffffffffffff; maxExpArray[ 40] = 0x1428a2f98d72ffffffffffffffffffffff; maxExpArray[ 41] = 0x13545598e5c23fffffffffffffffffffff; maxExpArray[ 42] = 0x1288c4161ce1dfffffffffffffffffffff; maxExpArray[ 43] = 0x11c592761c666fffffffffffffffffffff; maxExpArray[ 44] = 0x110a688680a757ffffffffffffffffffff; maxExpArray[ 45] = 0x1056f1b5bedf77ffffffffffffffffffff; maxExpArray[ 46] = 0x0faadceceeff8bffffffffffffffffffff; maxExpArray[ 47] = 0x0f05dc6b27edadffffffffffffffffffff; maxExpArray[ 48] = 0x0e67a5a25da4107fffffffffffffffffff; maxExpArray[ 49] = 0x0dcff115b14eedffffffffffffffffffff; maxExpArray[ 50] = 0x0d3e7a392431239fffffffffffffffffff; maxExpArray[ 51] = 0x0cb2ff529eb71e4fffffffffffffffffff; maxExpArray[ 52] = 0x0c2d415c3db974afffffffffffffffffff; maxExpArray[ 53] = 0x0bad03e7d883f69bffffffffffffffffff; maxExpArray[ 54] = 0x0b320d03b2c343d5ffffffffffffffffff; maxExpArray[ 55] = 0x0abc25204e02828dffffffffffffffffff; maxExpArray[ 56] = 0x0a4b16f74ee4bb207fffffffffffffffff; maxExpArray[ 57] = 0x09deaf736ac1f569ffffffffffffffffff; maxExpArray[ 58] = 0x0976bd9952c7aa957fffffffffffffffff; maxExpArray[ 59] = 0x09131271922eaa606fffffffffffffffff; maxExpArray[ 60] = 0x08b380f3558668c46fffffffffffffffff; maxExpArray[ 61] = 0x0857ddf0117efa215bffffffffffffffff; maxExpArray[ 62] = 0x07ffffffffffffffffffffffffffffffff; maxExpArray[ 63] = 0x07abbf6f6abb9d087fffffffffffffffff; maxExpArray[ 64] = 0x075af62cbac95f7dfa7fffffffffffffff; maxExpArray[ 65] = 0x070d7fb7452e187ac13fffffffffffffff; maxExpArray[ 66] = 0x06c3390ecc8af379295fffffffffffffff; maxExpArray[ 67] = 0x067c00a3b07ffc01fd6fffffffffffffff; maxExpArray[ 68] = 0x0637b647c39cbb9d3d27ffffffffffffff; maxExpArray[ 69] = 0x05f63b1fc104dbd39587ffffffffffffff; maxExpArray[ 70] = 0x05b771955b36e12f7235ffffffffffffff; maxExpArray[ 71] = 0x057b3d49dda84556d6f6ffffffffffffff; maxExpArray[ 72] = 0x054183095b2c8ececf30ffffffffffffff; maxExpArray[ 73] = 0x050a28be635ca2b888f77fffffffffffff; maxExpArray[ 74] = 0x04d5156639708c9db33c3fffffffffffff; maxExpArray[ 75] = 0x04a23105873875bd52dfdfffffffffffff; maxExpArray[ 76] = 0x0471649d87199aa990756fffffffffffff; maxExpArray[ 77] = 0x04429a21a029d4c1457cfbffffffffffff; maxExpArray[ 78] = 0x0415bc6d6fb7dd71af2cb3ffffffffffff; maxExpArray[ 79] = 0x03eab73b3bbfe282243ce1ffffffffffff; maxExpArray[ 80] = 0x03c1771ac9fb6b4c18e229ffffffffffff; maxExpArray[ 81] = 0x0399e96897690418f785257fffffffffff; maxExpArray[ 82] = 0x0373fc456c53bb779bf0ea9fffffffffff; maxExpArray[ 83] = 0x034f9e8e490c48e67e6ab8bfffffffffff; maxExpArray[ 84] = 0x032cbfd4a7adc790560b3337ffffffffff; maxExpArray[ 85] = 0x030b50570f6e5d2acca94613ffffffffff; maxExpArray[ 86] = 0x02eb40f9f620fda6b56c2861ffffffffff; maxExpArray[ 87] = 0x02cc8340ecb0d0f520a6af58ffffffffff; maxExpArray[ 88] = 0x02af09481380a0a35cf1ba02ffffffffff; maxExpArray[ 89] = 0x0292c5bdd3b92ec810287b1b3fffffffff; maxExpArray[ 90] = 0x0277abdcdab07d5a77ac6d6b9fffffffff; maxExpArray[ 91] = 0x025daf6654b1eaa55fd64df5efffffffff; maxExpArray[ 92] = 0x0244c49c648baa98192dce88b7ffffffff; maxExpArray[ 93] = 0x022ce03cd5619a311b2471268bffffffff; maxExpArray[ 94] = 0x0215f77c045fbe885654a44a0fffffffff; maxExpArray[ 95] = 0x01ffffffffffffffffffffffffffffffff; maxExpArray[ 96] = 0x01eaefdbdaaee7421fc4d3ede5ffffffff; maxExpArray[ 97] = 0x01d6bd8b2eb257df7e8ca57b09bfffffff; maxExpArray[ 98] = 0x01c35fedd14b861eb0443f7f133fffffff; maxExpArray[ 99] = 0x01b0ce43b322bcde4a56e8ada5afffffff; maxExpArray[100] = 0x019f0028ec1fff007f5a195a39dfffffff; maxExpArray[101] = 0x018ded91f0e72ee74f49b15ba527ffffff; maxExpArray[102] = 0x017d8ec7f04136f4e5615fd41a63ffffff; maxExpArray[103] = 0x016ddc6556cdb84bdc8d12d22e6fffffff; maxExpArray[104] = 0x015ecf52776a1155b5bd8395814f7fffff; maxExpArray[105] = 0x015060c256cb23b3b3cc3754cf40ffffff; maxExpArray[106] = 0x01428a2f98d728ae223ddab715be3fffff; maxExpArray[107] = 0x013545598e5c23276ccf0ede68034fffff; maxExpArray[108] = 0x01288c4161ce1d6f54b7f61081194fffff; maxExpArray[109] = 0x011c592761c666aa641d5a01a40f17ffff; maxExpArray[110] = 0x0110a688680a7530515f3e6e6cfdcdffff; maxExpArray[111] = 0x01056f1b5bedf75c6bcb2ce8aed428ffff; maxExpArray[112] = 0x00faadceceeff8a0890f3875f008277fff; maxExpArray[113] = 0x00f05dc6b27edad306388a600f6ba0bfff; maxExpArray[114] = 0x00e67a5a25da41063de1495d5b18cdbfff; maxExpArray[115] = 0x00dcff115b14eedde6fc3aa5353f2e4fff; maxExpArray[116] = 0x00d3e7a3924312399f9aae2e0f868f8fff; maxExpArray[117] = 0x00cb2ff529eb71e41582cccd5a1ee26fff; maxExpArray[118] = 0x00c2d415c3db974ab32a51840c0b67edff; maxExpArray[119] = 0x00bad03e7d883f69ad5b0a186184e06bff; maxExpArray[120] = 0x00b320d03b2c343d4829abd6075f0cc5ff; maxExpArray[121] = 0x00abc25204e02828d73c6e80bcdb1a95bf; maxExpArray[122] = 0x00a4b16f74ee4bb2040a1ec6c15fbbf2df; maxExpArray[123] = 0x009deaf736ac1f569deb1b5ae3f36c130f; maxExpArray[124] = 0x00976bd9952c7aa957f5937d790ef65037; maxExpArray[125] = 0x009131271922eaa6064b73a22d0bd4f2bf; maxExpArray[126] = 0x008b380f3558668c46c91c49a2f8e967b9; maxExpArray[127] = 0x00857ddf0117efa215952912839f6473e6; } /** * @dev given a token supply, reserve balance, ratio and a deposit amount (in the reserve token), * calculates the return for a given conversion (in the main token) * * Formula: * Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 1000000) - 1) * * @param _supply token total supply * @param _reserveBalance total reserve balance * @param _reserveRatio reserve ratio, represented in ppm, 1-1000000 * @param _depositAmount deposit amount, in reserve token * * @return purchase return amount */ function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _depositAmount) public view returns (uint256) { // validate input require(_supply > 0 && _reserveBalance > 0 && _reserveRatio > 0 && _reserveRatio <= MAX_RATIO); // special case for 0 deposit amount if (_depositAmount == 0) return 0; // special case if the ratio = 100% if (_reserveRatio == MAX_RATIO) return _supply.mul(_depositAmount) / _reserveBalance; uint256 result; uint8 precision; uint256 baseN = _depositAmount.add(_reserveBalance); (result, precision) = power(baseN, _reserveBalance, _reserveRatio, MAX_RATIO); uint256 temp = _supply.mul(result) >> precision; return temp - _supply; } /** * @dev given a token supply, reserve balance, ratio and a sell amount (in the main token), * calculates the return for a given conversion (in the reserve token) * * Formula: * Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / 1000000))) * * @param _supply token total supply * @param _reserveBalance total reserve * @param _reserveRatio constant reserve Ratio, represented in ppm, 1-1000000 * @param _sellAmount sell amount, in the token itself * * @return sale return amount */ function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _sellAmount) public view returns (uint256) { // validate input require(_supply > 0 && _reserveBalance > 0 && _reserveRatio > 0 && _reserveRatio <= MAX_RATIO && _sellAmount <= _supply); // special case for 0 sell amount if (_sellAmount == 0) return 0; // special case for selling the entire supply if (_sellAmount == _supply) return _reserveBalance; // special case if the ratio = 100% if (_reserveRatio == MAX_RATIO) return _reserveBalance.mul(_sellAmount) / _supply; uint256 result; uint8 precision; uint256 baseD = _supply - _sellAmount; (result, precision) = power(_supply, baseD, MAX_RATIO, _reserveRatio); uint256 temp1 = _reserveBalance.mul(result); uint256 temp2 = _reserveBalance << precision; return (temp1 - temp2) / result; } /** * @dev given two reserve balances/ratios and a sell amount (in the first reserve token), * calculates the return for a conversion from the first reserve token to the second reserve token (in the second reserve token) * note that prior to version 4, you should use 'calculateCrossConnectorReturn' instead * * Formula: * Return = _toReserveBalance * (1 - (_fromReserveBalance / (_fromReserveBalance + _amount)) ^ (_fromReserveRatio / _toReserveRatio)) * * @param _fromReserveBalance input reserve balance * @param _fromReserveRatio input reserve ratio, represented in ppm, 1-1000000 * @param _toReserveBalance output reserve balance * @param _toReserveRatio output reserve ratio, represented in ppm, 1-1000000 * @param _amount input reserve amount * * @return second reserve amount */ function calculateCrossReserveReturn(uint256 _fromReserveBalance, uint32 _fromReserveRatio, uint256 _toReserveBalance, uint32 _toReserveRatio, uint256 _amount) public view returns (uint256) { // validate input require(_fromReserveBalance > 0 && _fromReserveRatio > 0 && _fromReserveRatio <= MAX_RATIO && _toReserveBalance > 0 && _toReserveRatio > 0 && _toReserveRatio <= MAX_RATIO); // special case for equal ratios if (_fromReserveRatio == _toReserveRatio) return _toReserveBalance.mul(_amount) / _fromReserveBalance.add(_amount); uint256 result; uint8 precision; uint256 baseN = _fromReserveBalance.add(_amount); (result, precision) = power(baseN, _fromReserveBalance, _fromReserveRatio, _toReserveRatio); uint256 temp1 = _toReserveBalance.mul(result); uint256 temp2 = _toReserveBalance << precision; return (temp1 - temp2) / result; } /** * @dev given a smart token supply, reserve balance, total ratio and an amount of requested smart tokens, * calculates the amount of reserve tokens required for purchasing the given amount of smart tokens * * Formula: * Return = _reserveBalance * (((_supply + _amount) / _supply) ^ (MAX_RATIO / _totalRatio) - 1) * * @param _supply smart token supply * @param _reserveBalance reserve token balance * @param _totalRatio total ratio, represented in ppm, 2-2000000 * @param _amount requested amount of smart tokens * * @return amount of reserve tokens */ function calculateFundCost(uint256 _supply, uint256 _reserveBalance, uint32 _totalRatio, uint256 _amount) public view returns (uint256) { // validate input require(_supply > 0 && _reserveBalance > 0 && _totalRatio > 1 && _totalRatio <= MAX_RATIO * 2); // special case for 0 amount if (_amount == 0) return 0; // special case if the total ratio = 100% if (_totalRatio == MAX_RATIO) return (_amount.mul(_reserveBalance) - 1) / _supply + 1; uint256 result; uint8 precision; uint256 baseN = _supply.add(_amount); (result, precision) = power(baseN, _supply, MAX_RATIO, _totalRatio); uint256 temp = ((_reserveBalance.mul(result) - 1) >> precision) + 1; return temp - _reserveBalance; } /** * @dev given a smart token supply, reserve balance, total ratio and an amount of smart tokens to liquidate, * calculates the amount of reserve tokens received for selling the given amount of smart tokens * * Formula: * Return = _reserveBalance * ((_supply / (_supply - _amount)) ^ (MAX_RATIO / _totalRatio) - 1) * * @param _supply smart token supply * @param _reserveBalance reserve token balance * @param _totalRatio total ratio, represented in ppm, 2-2000000 * @param _amount amount of smart tokens to liquidate * * @return amount of reserve tokens */ function calculateLiquidateReturn(uint256 _supply, uint256 _reserveBalance, uint32 _totalRatio, uint256 _amount) public view returns (uint256) { // validate input require(_supply > 0 && _reserveBalance > 0 && _totalRatio > 1 && _totalRatio <= MAX_RATIO * 2 && _amount <= _supply); // special case for 0 amount if (_amount == 0) return 0; // special case if the total ratio = 100% if (_totalRatio == MAX_RATIO) return _amount.mul(_reserveBalance) / _supply; uint256 result; uint8 precision; uint256 baseD = _supply - _amount; (result, precision) = power(_supply, baseD, MAX_RATIO, _totalRatio); uint256 temp = _reserveBalance.mul(result) >> precision; return temp - _reserveBalance; } /** * @dev General Description: * Determine a value of precision. * Calculate an integer approximation of (_baseN / _baseD) ^ (_expN / _expD) * 2 ^ precision. * Return the result along with the precision used. * * Detailed Description: * Instead of calculating "base ^ exp", we calculate "e ^ (log(base) * exp)". * The value of "log(base)" is represented with an integer slightly smaller than "log(base) * 2 ^ precision". * The larger "precision" is, the more accurately this value represents the real value. * However, the larger "precision" is, the more bits are required in order to store this value. * And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x"). * This maximum exponent depends on the "precision" used, and it is given by "maxExpArray[precision] >> (MAX_PRECISION - precision)". * Hence we need to determine the highest precision which can be used for the given input, before calling the exponentiation function. * This allows us to compute "base ^ exp" with maximum accuracy and without exceeding 256 bits in any of the intermediate computations. * This functions assumes that "_expN < 2 ^ 256 / log(MAX_NUM - 1)", otherwise the multiplication should be replaced with a "safeMul". */ function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) internal view returns (uint256, uint8) { require(_baseN < MAX_NUM); uint256 baseLog; uint256 base = _baseN * FIXED_1 / _baseD; if (base < OPT_LOG_MAX_VAL) { baseLog = optimalLog(base); } else { baseLog = generalLog(base); } uint256 baseLogTimesExp = baseLog * _expN / _expD; if (baseLogTimesExp < OPT_EXP_MAX_VAL) { return (optimalExp(baseLogTimesExp), MAX_PRECISION); } else { uint8 precision = findPositionInMaxExpArray(baseLogTimesExp); return (generalExp(baseLogTimesExp >> (MAX_PRECISION - precision), precision), precision); } } /** * @dev computes log(x / FIXED_1) * FIXED_1. * This functions assumes that "x >= FIXED_1", because the output would be negative otherwise. */ function generalLog(uint256 x) internal pure returns (uint256) { uint256 res = 0; // If x >= 2, then we compute the integer part of log2(x), which is larger than 0. if (x >= FIXED_2) { uint8 count = floorLog2(x / FIXED_1); x >>= count; // now x < 2 res = count * FIXED_1; } // If x > 1, then we compute the fraction part of log2(x), which is larger than 0. if (x > FIXED_1) { for (uint8 i = MAX_PRECISION; i > 0; --i) { x = (x * x) / FIXED_1; // now 1 < x < 4 if (x >= FIXED_2) { x >>= 1; // now 1 < x < 2 res += ONE << (i - 1); } } } return res * LN2_NUMERATOR / LN2_DENOMINATOR; } /** * @dev computes the largest integer smaller than or equal to the binary logarithm of the input. */ function floorLog2(uint256 _n) internal pure returns (uint8) { uint8 res = 0; if (_n < 256) { // At most 8 iterations while (_n > 1) { _n >>= 1; res += 1; } } else { // Exactly 8 iterations for (uint8 s = 128; s > 0; s >>= 1) { if (_n >= (ONE << s)) { _n >>= s; res |= s; } } } return res; } /** * @dev the global "maxExpArray" is sorted in descending order, and therefore the following statements are equivalent: * - This function finds the position of [the smallest value in "maxExpArray" larger than or equal to "x"] * - This function finds the highest position of [a value in "maxExpArray" larger than or equal to "x"] */ function findPositionInMaxExpArray(uint256 _x) internal view returns (uint8) { uint8 lo = MIN_PRECISION; uint8 hi = MAX_PRECISION; while (lo + 1 < hi) { uint8 mid = (lo + hi) / 2; if (maxExpArray[mid] >= _x) lo = mid; else hi = mid; } if (maxExpArray[hi] >= _x) return hi; if (maxExpArray[lo] >= _x) return lo; require(false); return 0; } /** * @dev this function can be auto-generated by the script 'PrintFunctionGeneralExp.py'. * it approximates "e ^ x" via maclaurin summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!". * it returns "e ^ (x / 2 ^ precision) * 2 ^ precision", that is, the result is upshifted for accuracy. * the global "maxExpArray" maps each "precision" to "((maximumExponent + 1) << (MAX_PRECISION - precision)) - 1". * the maximum permitted value for "x" is therefore given by "maxExpArray[precision] >> (MAX_PRECISION - precision)". */ function generalExp(uint256 _x, uint8 _precision) internal pure returns (uint256) { uint256 xi = _x; uint256 res = 0; xi = (xi * _x) >> _precision; res += xi * 0x3442c4e6074a82f1797f72ac0000000; // add x^02 * (33! / 02!) xi = (xi * _x) >> _precision; res += xi * 0x116b96f757c380fb287fd0e40000000; // add x^03 * (33! / 03!) xi = (xi * _x) >> _precision; res += xi * 0x045ae5bdd5f0e03eca1ff4390000000; // add x^04 * (33! / 04!) xi = (xi * _x) >> _precision; res += xi * 0x00defabf91302cd95b9ffda50000000; // add x^05 * (33! / 05!) xi = (xi * _x) >> _precision; res += xi * 0x002529ca9832b22439efff9b8000000; // add x^06 * (33! / 06!) xi = (xi * _x) >> _precision; res += xi * 0x00054f1cf12bd04e516b6da88000000; // add x^07 * (33! / 07!) xi = (xi * _x) >> _precision; res += xi * 0x0000a9e39e257a09ca2d6db51000000; // add x^08 * (33! / 08!) xi = (xi * _x) >> _precision; res += xi * 0x000012e066e7b839fa050c309000000; // add x^09 * (33! / 09!) xi = (xi * _x) >> _precision; res += xi * 0x000001e33d7d926c329a1ad1a800000; // add x^10 * (33! / 10!) xi = (xi * _x) >> _precision; res += xi * 0x0000002bee513bdb4a6b19b5f800000; // add x^11 * (33! / 11!) xi = (xi * _x) >> _precision; res += xi * 0x00000003a9316fa79b88eccf2a00000; // add x^12 * (33! / 12!) xi = (xi * _x) >> _precision; res += xi * 0x0000000048177ebe1fa812375200000; // add x^13 * (33! / 13!) xi = (xi * _x) >> _precision; res += xi * 0x0000000005263fe90242dcbacf00000; // add x^14 * (33! / 14!) xi = (xi * _x) >> _precision; res += xi * 0x000000000057e22099c030d94100000; // add x^15 * (33! / 15!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000057e22099c030d9410000; // add x^16 * (33! / 16!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000052b6b54569976310000; // add x^17 * (33! / 17!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000004985f67696bf748000; // add x^18 * (33! / 18!) xi = (xi * _x) >> _precision; res += xi * 0x000000000000003dea12ea99e498000; // add x^19 * (33! / 19!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000000031880f2214b6e000; // add x^20 * (33! / 20!) xi = (xi * _x) >> _precision; res += xi * 0x000000000000000025bcff56eb36000; // add x^21 * (33! / 21!) xi = (xi * _x) >> _precision; res += xi * 0x000000000000000001b722e10ab1000; // add x^22 * (33! / 22!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000001317c70077000; // add x^23 * (33! / 23!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000cba84aafa00; // add x^24 * (33! / 24!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000082573a0a00; // add x^25 * (33! / 25!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000005035ad900; // add x^26 * (33! / 26!) xi = (xi * _x) >> _precision; res += xi * 0x000000000000000000000002f881b00; // add x^27 * (33! / 27!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000001b29340; // add x^28 * (33! / 28!) xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000000000efc40; // add x^29 * (33! / 29!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000007fe0; // add x^30 * (33! / 30!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000420; // add x^31 * (33! / 31!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000021; // add x^32 * (33! / 32!) xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000001; // add x^33 * (33! / 33!) return res / 0x688589cc0e9505e2f2fee5580000000 + _x + (ONE << _precision); // divide by 33! and then add x^1 / 1! + x^0 / 0! } /** * @dev computes log(x / FIXED_1) * FIXED_1 * Input range: FIXED_1 <= x <= LOG_EXP_MAX_VAL - 1 * Auto-generated via 'PrintFunctionOptimalLog.py' * Detailed description: * - Rewrite the input as a product of natural exponents and a single residual r, such that 1 < r < 2 * - The natural logarithm of each (pre-calculated) exponent is the degree of the exponent * - The natural logarithm of r is calculated via Taylor series for log(1 + x), where x = r - 1 * - The natural logarithm of the input is calculated by summing up the intermediate results above * - For example: log(250) = log(e^4 * e^1 * e^0.5 * 1.021692859) = 4 + 1 + 0.5 + log(1 + 0.021692859) */ function optimalLog(uint256 x) internal pure returns (uint256) { uint256 res = 0; uint256 y; uint256 z; uint256 w; if (x >= 0xd3094c70f034de4b96ff7d5b6f99fcd8) {res += 0x40000000000000000000000000000000; x = x * FIXED_1 / 0xd3094c70f034de4b96ff7d5b6f99fcd8;} // add 1 / 2^1 if (x >= 0xa45af1e1f40c333b3de1db4dd55f29a7) {res += 0x20000000000000000000000000000000; x = x * FIXED_1 / 0xa45af1e1f40c333b3de1db4dd55f29a7;} // add 1 / 2^2 if (x >= 0x910b022db7ae67ce76b441c27035c6a1) {res += 0x10000000000000000000000000000000; x = x * FIXED_1 / 0x910b022db7ae67ce76b441c27035c6a1;} // add 1 / 2^3 if (x >= 0x88415abbe9a76bead8d00cf112e4d4a8) {res += 0x08000000000000000000000000000000; x = x * FIXED_1 / 0x88415abbe9a76bead8d00cf112e4d4a8;} // add 1 / 2^4 if (x >= 0x84102b00893f64c705e841d5d4064bd3) {res += 0x04000000000000000000000000000000; x = x * FIXED_1 / 0x84102b00893f64c705e841d5d4064bd3;} // add 1 / 2^5 if (x >= 0x8204055aaef1c8bd5c3259f4822735a2) {res += 0x02000000000000000000000000000000; x = x * FIXED_1 / 0x8204055aaef1c8bd5c3259f4822735a2;} // add 1 / 2^6 if (x >= 0x810100ab00222d861931c15e39b44e99) {res += 0x01000000000000000000000000000000; x = x * FIXED_1 / 0x810100ab00222d861931c15e39b44e99;} // add 1 / 2^7 if (x >= 0x808040155aabbbe9451521693554f733) {res += 0x00800000000000000000000000000000; x = x * FIXED_1 / 0x808040155aabbbe9451521693554f733;} // add 1 / 2^8 z = y = x - FIXED_1; w = y * y / FIXED_1; res += z * (0x100000000000000000000000000000000 - y) / 0x100000000000000000000000000000000; z = z * w / FIXED_1; // add y^01 / 01 - y^02 / 02 res += z * (0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - y) / 0x200000000000000000000000000000000; z = z * w / FIXED_1; // add y^03 / 03 - y^04 / 04 res += z * (0x099999999999999999999999999999999 - y) / 0x300000000000000000000000000000000; z = z * w / FIXED_1; // add y^05 / 05 - y^06 / 06 res += z * (0x092492492492492492492492492492492 - y) / 0x400000000000000000000000000000000; z = z * w / FIXED_1; // add y^07 / 07 - y^08 / 08 res += z * (0x08e38e38e38e38e38e38e38e38e38e38e - y) / 0x500000000000000000000000000000000; z = z * w / FIXED_1; // add y^09 / 09 - y^10 / 10 res += z * (0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b - y) / 0x600000000000000000000000000000000; z = z * w / FIXED_1; // add y^11 / 11 - y^12 / 12 res += z * (0x089d89d89d89d89d89d89d89d89d89d89 - y) / 0x700000000000000000000000000000000; z = z * w / FIXED_1; // add y^13 / 13 - y^14 / 14 res += z * (0x088888888888888888888888888888888 - y) / 0x800000000000000000000000000000000; // add y^15 / 15 - y^16 / 16 return res; } /** * @dev computes e ^ (x / FIXED_1) * FIXED_1 * input range: 0 <= x <= OPT_EXP_MAX_VAL - 1 * auto-generated via 'PrintFunctionOptimalExp.py' * Detailed description: * - Rewrite the input as a sum of binary exponents and a single residual r, as small as possible * - The exponentiation of each binary exponent is given (pre-calculated) * - The exponentiation of r is calculated via Taylor series for e^x, where x = r * - The exponentiation of the input is calculated by multiplying the intermediate results above * - For example: e^5.521692859 = e^(4 + 1 + 0.5 + 0.021692859) = e^4 * e^1 * e^0.5 * e^0.021692859 */ function optimalExp(uint256 x) internal pure returns (uint256) { uint256 res = 0; uint256 y; uint256 z; z = y = x % 0x10000000000000000000000000000000; // get the input modulo 2^(-3) z = z * y / FIXED_1; res += z * 0x10e1b3be415a0000; // add y^02 * (20! / 02!) z = z * y / FIXED_1; res += z * 0x05a0913f6b1e0000; // add y^03 * (20! / 03!) z = z * y / FIXED_1; res += z * 0x0168244fdac78000; // add y^04 * (20! / 04!) z = z * y / FIXED_1; res += z * 0x004807432bc18000; // add y^05 * (20! / 05!) z = z * y / FIXED_1; res += z * 0x000c0135dca04000; // add y^06 * (20! / 06!) z = z * y / FIXED_1; res += z * 0x0001b707b1cdc000; // add y^07 * (20! / 07!) z = z * y / FIXED_1; res += z * 0x000036e0f639b800; // add y^08 * (20! / 08!) z = z * y / FIXED_1; res += z * 0x00000618fee9f800; // add y^09 * (20! / 09!) z = z * y / FIXED_1; res += z * 0x0000009c197dcc00; // add y^10 * (20! / 10!) z = z * y / FIXED_1; res += z * 0x0000000e30dce400; // add y^11 * (20! / 11!) z = z * y / FIXED_1; res += z * 0x000000012ebd1300; // add y^12 * (20! / 12!) z = z * y / FIXED_1; res += z * 0x0000000017499f00; // add y^13 * (20! / 13!) z = z * y / FIXED_1; res += z * 0x0000000001a9d480; // add y^14 * (20! / 14!) z = z * y / FIXED_1; res += z * 0x00000000001c6380; // add y^15 * (20! / 15!) z = z * y / FIXED_1; res += z * 0x000000000001c638; // add y^16 * (20! / 16!) z = z * y / FIXED_1; res += z * 0x0000000000001ab8; // add y^17 * (20! / 17!) z = z * y / FIXED_1; res += z * 0x000000000000017c; // add y^18 * (20! / 18!) z = z * y / FIXED_1; res += z * 0x0000000000000014; // add y^19 * (20! / 19!) z = z * y / FIXED_1; res += z * 0x0000000000000001; // add y^20 * (20! / 20!) res = res / 0x21c3677c82b40000 + y + FIXED_1; // divide by 20! and then add y^1 / 1! + y^0 / 0! if ((x & 0x010000000000000000000000000000000) != 0) res = res * 0x1c3d6a24ed82218787d624d3e5eba95f9 / 0x18ebef9eac820ae8682b9793ac6d1e776; // multiply by e^2^(-3) if ((x & 0x020000000000000000000000000000000) != 0) res = res * 0x18ebef9eac820ae8682b9793ac6d1e778 / 0x1368b2fc6f9609fe7aceb46aa619baed4; // multiply by e^2^(-2) if ((x & 0x040000000000000000000000000000000) != 0) res = res * 0x1368b2fc6f9609fe7aceb46aa619baed5 / 0x0bc5ab1b16779be3575bd8f0520a9f21f; // multiply by e^2^(-1) if ((x & 0x080000000000000000000000000000000) != 0) res = res * 0x0bc5ab1b16779be3575bd8f0520a9f21e / 0x0454aaa8efe072e7f6ddbab84b40a55c9; // multiply by e^2^(+0) if ((x & 0x100000000000000000000000000000000) != 0) res = res * 0x0454aaa8efe072e7f6ddbab84b40a55c5 / 0x00960aadc109e7a3bf4578099615711ea; // multiply by e^2^(+1) if ((x & 0x200000000000000000000000000000000) != 0) res = res * 0x00960aadc109e7a3bf4578099615711d7 / 0x0002bf84208204f5977f9a8cf01fdce3d; // multiply by e^2^(+2) if ((x & 0x400000000000000000000000000000000) != 0) res = res * 0x0002bf84208204f5977f9a8cf01fdc307 / 0x0000003c6ab775dd0b95b4cbee7e65d11; // multiply by e^2^(+3) return res; } /** * @dev deprecated, backward compatibility */ function calculateCrossConnectorReturn(uint256 _fromConnectorBalance, uint32 _fromConnectorWeight, uint256 _toConnectorBalance, uint32 _toConnectorWeight, uint256 _amount) public view returns (uint256) { return calculateCrossReserveReturn(_fromConnectorBalance, _fromConnectorWeight, _toConnectorBalance, _toConnectorWeight, _amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"_supply","type":"uint256"},{"name":"_reserveBalance","type":"uint256"},{"name":"_totalRatio","type":"uint32"},{"name":"_amount","type":"uint256"}],"name":"calculateFundCost","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_supply","type":"uint256"},{"name":"_reserveBalance","type":"uint256"},{"name":"_reserveRatio","type":"uint32"},{"name":"_depositAmount","type":"uint256"}],"name":"calculatePurchaseReturn","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_supply","type":"uint256"},{"name":"_reserveBalance","type":"uint256"},{"name":"_reserveRatio","type":"uint32"},{"name":"_sellAmount","type":"uint256"}],"name":"calculateSaleReturn","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_fromConnectorBalance","type":"uint256"},{"name":"_fromConnectorWeight","type":"uint32"},{"name":"_toConnectorBalance","type":"uint256"},{"name":"_toConnectorWeight","type":"uint32"},{"name":"_amount","type":"uint256"}],"name":"calculateCrossConnectorReturn","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_fromReserveBalance","type":"uint256"},{"name":"_fromReserveRatio","type":"uint32"},{"name":"_toReserveBalance","type":"uint256"},{"name":"_toReserveRatio","type":"uint32"},{"name":"_amount","type":"uint256"}],"name":"calculateCrossReserveReturn","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_supply","type":"uint256"},{"name":"_reserveBalance","type":"uint256"},{"name":"_totalRatio","type":"uint32"},{"name":"_amount","type":"uint256"}],"name":"calculateLiquidateReturn","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]
Contract Creation Code
60806040526000805461ffff1916600517905534801561001e57600080fd5b506001606060020a641c35fedd1502036021556001605e60020a646c3390ecc902036022556001606160020a640cf801476102036023556001605f60020a6431bdb23e1d02036024556001605b60020a6502fb1d8fe08302036025556001605a60020a6505b771955b3702036026556001605960020a650af67a93bb5102036027556001605860020a6515060c256cb302036028556001605860020a651428a2f98d7302036029556001605660020a654d51566397090203602a556001605560020a65944620b0e70f0203602b557011c592761c666fffffffffffffffffffff602c5570110a688680a757ffffffffffffffffffff602d55701056f1b5bedf77ffffffffffffffffffff602e55700faadceceeff8bffffffffffffffffffff602f55700f05dc6b27edadffffffffffffffffffff603055700e67a5a25da4107fffffffffffffffffff603155700dcff115b14eedffffffffffffffffffff603255700d3e7a392431239fffffffffffffffffff603355700cb2ff529eb71e4fffffffffffffffffff603455700c2d415c3db974afffffffffffffffffff603555700bad03e7d883f69bffffffffffffffffff603655700b320d03b2c343d5ffffffffffffffffff603755700abc25204e02828dffffffffffffffffff603855700a4b16f74ee4bb207fffffffffffffffff6039557009deaf736ac1f569ffffffffffffffffff603a55700976bd9952c7aa957fffffffffffffffff603b557009131271922eaa606fffffffffffffffff603c557008b380f3558668c46fffffffffffffffff603d55700857ddf0117efa215bffffffffffffffff603e556001608360020a03603f557007abbf6f6abb9d087fffffffffffffffff60405570075af62cbac95f7dfa7fffffffffffffff60415570070d7fb7452e187ac13fffffffffffffff6042557006c3390ecc8af379295fffffffffffffff60435570067c00a3b07ffc01fd6fffffffffffffff604455700637b647c39cbb9d3d27ffffffffffffff6045557005f63b1fc104dbd39587ffffffffffffff6046557005b771955b36e12f7235ffffffffffffff60475570057b3d49dda84556d6f6ffffffffffffff60485570054183095b2c8ececf30ffffffffffffff60495570050a28be635ca2b888f77fffffffffffff604a557004d5156639708c9db33c3fffffffffffff604b557004a23105873875bd52dfdfffffffffffff604c55700471649d87199aa990756fffffffffffff604d557004429a21a029d4c1457cfbffffffffffff604e55700415bc6d6fb7dd71af2cb3ffffffffffff604f557003eab73b3bbfe282243ce1ffffffffffff6050557003c1771ac9fb6b4c18e229ffffffffffff605155700399e96897690418f785257fffffffffff605255700373fc456c53bb779bf0ea9fffffffffff60535570034f9e8e490c48e67e6ab8bfffffffffff60545570032cbfd4a7adc790560b3337ffffffffff60555570030b50570f6e5d2acca94613ffffffffff6056557002eb40f9f620fda6b56c2861ffffffffff6057557002cc8340ecb0d0f520a6af58ffffffffff6058557002af09481380a0a35cf1ba02ffffffffff605955700292c5bdd3b92ec810287b1b3fffffffff605a55700277abdcdab07d5a77ac6d6b9fffffffff605b5570025daf6654b1eaa55fd64df5efffffffff605c55700244c49c648baa98192dce88b7ffffffff605d5570022ce03cd5619a311b2471268bffffffff605e55700215f77c045fbe885654a44a0fffffffff605f556001608160020a036060557001eaefdbdaaee7421fc4d3ede5ffffffff6061557001d6bd8b2eb257df7e8ca57b09bfffffff6062557001c35fedd14b861eb0443f7f133fffffff6063557001b0ce43b322bcde4a56e8ada5afffffff60645570019f0028ec1fff007f5a195a39dfffffff60655570018ded91f0e72ee74f49b15ba527ffffff60665570017d8ec7f04136f4e5615fd41a63ffffff60675570016ddc6556cdb84bdc8d12d22e6fffffff60685570015ecf52776a1155b5bd8395814f7fffff60695570015060c256cb23b3b3cc3754cf40ffffff606a557001428a2f98d728ae223ddab715be3fffff606b5570013545598e5c23276ccf0ede68034fffff606c557001288c4161ce1d6f54b7f61081194fffff606d5570011c592761c666aa641d5a01a40f17ffff606e55700110a688680a7530515f3e6e6cfdcdffff606f557001056f1b5bedf75c6bcb2ce8aed428ffff6070556ffaadceceeff8a0890f3875f008277fff6071556ff05dc6b27edad306388a600f6ba0bfff6072556fe67a5a25da41063de1495d5b18cdbfff6073556fdcff115b14eedde6fc3aa5353f2e4fff6074556fd3e7a3924312399f9aae2e0f868f8fff6075556fcb2ff529eb71e41582cccd5a1ee26fff6076556fc2d415c3db974ab32a51840c0b67edff6077556fbad03e7d883f69ad5b0a186184e06bff6078556fb320d03b2c343d4829abd6075f0cc5ff6079556fabc25204e02828d73c6e80bcdb1a95bf607a556fa4b16f74ee4bb2040a1ec6c15fbbf2df607b556f9deaf736ac1f569deb1b5ae3f36c130f607c556f976bd9952c7aa957f5937d790ef65037607d556f9131271922eaa6064b73a22d0bd4f2bf607e556f8b380f3558668c46c91c49a2f8e967b9607f556f857ddf0117efa215952912839f6473e6608055611826806107d06000396000f3006080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631da6bbfb811461008757806329a00e7c146100c057806349f9b0f7146100e757806354fd4d501461010e57806365098bb31461013a57806379c1b45014610168578063abfd231d14610196575b600080fd5b34801561009357600080fd5b506100ae60043560243563ffffffff604435166064356101bd565b60408051918252519081900360200190f35b3480156100cc57600080fd5b506100ae60043560243563ffffffff604435166064356102a9565b3480156100f357600080fd5b506100ae60043560243563ffffffff60443516606435610387565b34801561011a57600080fd5b50610123610484565b6040805161ffff9092168252519081900360200190f35b34801561014657600080fd5b506100ae60043563ffffffff602435811690604435906064351660843561048e565b34801561017457600080fd5b506100ae60043563ffffffff60243581169060443590606435166084356104a7565b3480156101a257600080fd5b506100ae60043560243563ffffffff604435166064356105bc565b600080600080600080891180156101d45750600088115b80156101e6575060018763ffffffff16115b80156101fb5750621e848063ffffffff881611155b151561020657600080fd5b851515610216576000945061029d565b63ffffffff8716620f4240141561024f5788600161023a888b63ffffffff61068816565b0381151561024457fe5b04600101945061029d565b61025f898763ffffffff6106c116565b9150610270828a620f42408a6106d3565b909450925060ff8316600161028b8a8763ffffffff61068816565b039060020a9004600101905087810394505b50505050949350505050565b600080600080600080891180156102c05750600088115b80156102d2575060008763ffffffff16115b80156102e75750620f424063ffffffff881611155b15156102f257600080fd5b851515610302576000945061029d565b63ffffffff8716620f4240141561033557876103248a8863ffffffff61068816565b81151561032d57fe5b04945061029d565b610345868963ffffffff6106c116565b9150610356828989620f42406106d3565b909450925060ff831661036f8a8663ffffffff61068816565b60029190910a90049890980398975050505050505050565b60008060008060008060008a1180156103a05750600089115b80156103b2575060008863ffffffff16115b80156103c75750620f424063ffffffff891611155b80156103d35750898711155b15156103de57600080fd5b8615156103ee5760009550610477565b898714156103fe57889550610477565b63ffffffff8816620f4240141561043157896104208a8963ffffffff61068816565b81151561042957fe5b049550610477565b868a0392506104458a84620f42408b6106d3565b909550935061045a898663ffffffff61068816565b91505060ff831660020a88028481830381151561047357fe5b0495505b5050505050949350505050565b60005461ffff1681565b600061049d86868686866104a7565b9695505050505050565b60008060008060008060008b1180156104c6575060008a63ffffffff16115b80156104db5750620f424063ffffffff8b1611155b80156104e75750600089115b80156104f9575060008863ffffffff16115b801561050e5750620f424063ffffffff891611155b151561051957600080fd5b8763ffffffff168a63ffffffff16141561055e5761053d8b8863ffffffff6106c116565b61054d8a8963ffffffff61068816565b81151561055657fe5b0495506105ae565b61056e8b8863ffffffff6106c116565b925061057c838c8c8b6106d3565b9095509350610591898663ffffffff61068816565b91505060ff831660020a8802848183038115156105aa57fe5b0495505b505050505095945050505050565b600080600080600080891180156105d35750600088115b80156105e5575060018763ffffffff16115b80156105fa5750621e848063ffffffff881611155b80156106065750888611155b151561061157600080fd5b851515610621576000945061029d565b63ffffffff8716620f424014156106435788610324878a63ffffffff61068816565b85890391506106578983620f42408a6106d3565b909450925060ff8316610670898663ffffffff61068816565b60029190910a90049790970398975050505050505050565b60008083151561069b57600091506106ba565b508282028284828115156106ab57fe5b04146106b657600080fd5b8091505b5092915050565b6000828201838110156106b657600080fd5b600080808080807002000000000000000000000000000000008a106106f757600080fd5b886f800000000000000000000000000000008b0281151561071457fe5b04925070015bf0a8b1457695355fb8ac404e7a79e383101561074057610739836107c9565b935061074c565b61074983610cbd565b93505b8663ffffffff168863ffffffff16850281151561076557fe5b0491507008000000000000000000000000000000008210156107955761078a82610dfc565b607f955095506107bc565b61079e826112e1565b90506107b660ff607f8390031660020a83048261136e565b81955095505b5050505094509492505050565b6000808080806fd3094c70f034de4b96ff7d5b6f99fcd88610610824576f4000000000000000000000000000000093909301926fd3094c70f034de4b96ff7d5b6f99fcd86f8000000000000000000000000000000087020495505b6fa45af1e1f40c333b3de1db4dd55f29a78610610879576f2000000000000000000000000000000093909301926fa45af1e1f40c333b3de1db4dd55f29a76f8000000000000000000000000000000087020495505b6f910b022db7ae67ce76b441c27035c6a186106108ce576f1000000000000000000000000000000093909301926f910b022db7ae67ce76b441c27035c6a16f8000000000000000000000000000000087020495505b6f88415abbe9a76bead8d00cf112e4d4a88610610923576f0800000000000000000000000000000093909301926f88415abbe9a76bead8d00cf112e4d4a86f8000000000000000000000000000000087020495505b6f84102b00893f64c705e841d5d4064bd38610610978576f0400000000000000000000000000000093909301926f84102b00893f64c705e841d5d4064bd36f8000000000000000000000000000000087020495505b6f8204055aaef1c8bd5c3259f4822735a286106109cd576f0200000000000000000000000000000093909301926f8204055aaef1c8bd5c3259f4822735a26f8000000000000000000000000000000087020495505b6f810100ab00222d861931c15e39b44e998610610a22576f0100000000000000000000000000000093909301926f810100ab00222d861931c15e39b44e996f8000000000000000000000000000000087020495505b6f808040155aabbbe9451521693554f7338610610a76576e80000000000000000000000000000093909301926f808040155aabbbe9451521693554f7336f8000000000000000000000000000000087020495505b7fffffffffffffffffffffffffffffffff80000000000000000000000000000000860192508291506f8000000000000000000000000000000082800204905070010000000000000000000000000000000083810383020493909301926f800000000000000000000000000000008282020491507002000000000000000000000000000000006faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84900383020493909301926f800000000000000000000000000000008282020491507003000000000000000000000000000000006f9999999999999999999999999999999984900383020493909301926f800000000000000000000000000000008282020491507004000000000000000000000000000000006f9249249249249249249249249249249284900383020493909301926f800000000000000000000000000000008282020491507005000000000000000000000000000000006f8e38e38e38e38e38e38e38e38e38e38e84900383020493909301926f800000000000000000000000000000008282020491507006000000000000000000000000000000006f8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b84900383020493909301926f800000000000000000000000000000008282020491507007000000000000000000000000000000006f89d89d89d89d89d89d89d89d89d89d8984900383020493909301926f800000000000000000000000000000008282020491507008000000000000000000000000000000006f888888888888888888888888888888888490038302049390930195945050505050565b60008080807001000000000000000000000000000000008510610d1957610cf56f800000000000000000000000000000008604611791565b60ff8116600281900a909604956f8000000000000000000000000000000002935091505b6f80000000000000000000000000000000851115610dcc5750607f5b60008160ff161115610dcc576f800000000000000000000000000000008580020494507001000000000000000000000000000000008510610da5576002948590049460ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830116900a92909201915b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610d35565b6f05b9de1d10bf4103d647b0955897ba806f03f80fe03f80fe03f80fe03f80fe03f884020493505b505050919050565b6000670168244fdac780006f800000000000000000000000000000006f0fffffffffffffffffffffffffffffff84168080028290048082028390048083028490049485026710e1b3be415a00009092026705a0913f6b1e000091909102010192909181830204905080664807432bc1800002830192506f80000000000000000000000000000000828202811515610e8f57fe5b04905080660c0135dca0400002830192506f80000000000000000000000000000000828202811515610ebd57fe5b049050806601b707b1cdc00002830192506f80000000000000000000000000000000828202811515610eeb57fe5b049050806536e0f639b80002830192506f80000000000000000000000000000000828202811515610f1857fe5b04905080650618fee9f80002830192506f80000000000000000000000000000000828202811515610f4557fe5b04905080649c197dcc0002830192506f80000000000000000000000000000000828202811515610f7157fe5b04905080640e30dce40002830192506f80000000000000000000000000000000828202811515610f9d57fe5b0490508064012ebd130002830192506f80000000000000000000000000000000828202811515610fc957fe5b049050806317499f0002830192506f80000000000000000000000000000000828202811515610ff457fe5b049050806301a9d48002830192506f8000000000000000000000000000000082820281151561101f57fe5b04905080621c638002830192506f8000000000000000000000000000000082820281151561104957fe5b049050806201c63802830192506f8000000000000000000000000000000082820281151561107357fe5b04905080611ab802830192506f8000000000000000000000000000000082820281151561109c57fe5b0490508061017c02830192506f800000000000000000000000000000008282028115156110c557fe5b04905080601402830192506f800000000000000000000000000000008282028115156110ed57fe5b6721c3677c82b400009190049384010482016f80000000000000000000000000000000019290506f100000000000000000000000000000008516156111565770018ebef9eac820ae8682b9793ac6d1e7767001c3d6a24ed82218787d624d3e5eba95f984020492505b6f20000000000000000000000000000000851615611198577001368b2fc6f9609fe7aceb46aa619baed470018ebef9eac820ae8682b9793ac6d1e77884020492505b6f400000000000000000000000000000008516156111d9576fbc5ab1b16779be3575bd8f0520a9f21f7001368b2fc6f9609fe7aceb46aa619baed584020492505b6f80000000000000000000000000000000851615611219576f454aaa8efe072e7f6ddbab84b40a55c96fbc5ab1b16779be3575bd8f0520a9f21e84020492505b70010000000000000000000000000000000085161561125a576f0960aadc109e7a3bf4578099615711ea6f454aaa8efe072e7f6ddbab84b40a55c584020492505b70020000000000000000000000000000000085161561129a576e2bf84208204f5977f9a8cf01fdce3d6f0960aadc109e7a3bf4578099615711d784020492505b7004000000000000000000000000000000008516156112d8576d03c6ab775dd0b95b4cbee7e65d116e2bf84208204f5977f9a8cf01fdc30784020492505b50909392505050565b60006020607f825b8160ff168360010160ff16101561132e57600260ff8484011604905084600160ff83166080811061131657fe5b01541061132557809250611329565b8091505b6112e9565b84600160ff84166080811061133f57fe5b01541061134e57819350610df4565b84600160ff85166080811061135f57fe5b01541061008257829350610df4565b6000806000849150600090508360ff168583029060020a90049150816f03442c4e6074a82f1797f72ac000000002810190508360ff168583029060020a90049150816f0116b96f757c380fb287fd0e4000000002810190508360ff168583029060020a90049150816e45ae5bdd5f0e03eca1ff439000000002810190508360ff168583029060020a90049150816e0defabf91302cd95b9ffda5000000002810190508360ff168583029060020a90049150816e02529ca9832b22439efff9b800000002810190508360ff168583029060020a90049150816d54f1cf12bd04e516b6da8800000002810190508360ff168583029060020a90049150816d0a9e39e257a09ca2d6db5100000002810190508360ff168583029060020a90049150816d012e066e7b839fa050c30900000002810190508360ff168583029060020a90049150816c1e33d7d926c329a1ad1a80000002810190508360ff168583029060020a90049150816c02bee513bdb4a6b19b5f80000002810190508360ff168583029060020a90049150816b3a9316fa79b88eccf2a0000002810190508360ff168583029060020a90049150816b048177ebe1fa81237520000002810190508360ff168583029060020a90049150816a5263fe90242dcbacf0000002810190508360ff168583029060020a90049150816a057e22099c030d9410000002810190508360ff168583029060020a90049150816957e22099c030d941000002810190508360ff168583029060020a900491508169052b6b5456997631000002810190508360ff168583029060020a9004915081684985f67696bf74800002810190508360ff168583029060020a90049150816803dea12ea99e49800002810190508360ff168583029060020a90049150816731880f2214b6e00002810190508360ff168583029060020a900491508167025bcff56eb3600002810190508360ff168583029060020a9004915081661b722e10ab100002810190508360ff168583029060020a90049150816601317c7007700002810190508360ff168583029060020a9004915081650cba84aafa0002810190508360ff168583029060020a90049150816482573a0a0002810190508360ff168583029060020a90049150816405035ad90002810190508360ff168583029060020a9004915081632f881b0002810190508360ff168583029060020a90049150816301b2934002810190508360ff168583029060020a9004915081620efc4002810190508360ff168583029060020a9004915081617fe002810190508360ff168583029060020a900491508161042002810190508360ff168583029060020a9004915081602102810190508360ff168583029060020a9004915081600102810190508360ff1660019060020a02856f0688589cc0e9505e2f2fee55800000008381151561178557fe5b04010195945050505050565b600080806101008410156117c0575b60018411156117bb57600290930492600191909101906117a0565b6106ba565b5060805b60008160ff1611156106ba5760ff811660020a84106117ed5760ff811660020a90930492908117905b600260ff909116046117c45600a165627a7a7230582009ca39062ddc0cf02c6f411710c864ade25761adca76207a72cf8c868ec9b2bc0029
Deployed Bytecode
0x6080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631da6bbfb811461008757806329a00e7c146100c057806349f9b0f7146100e757806354fd4d501461010e57806365098bb31461013a57806379c1b45014610168578063abfd231d14610196575b600080fd5b34801561009357600080fd5b506100ae60043560243563ffffffff604435166064356101bd565b60408051918252519081900360200190f35b3480156100cc57600080fd5b506100ae60043560243563ffffffff604435166064356102a9565b3480156100f357600080fd5b506100ae60043560243563ffffffff60443516606435610387565b34801561011a57600080fd5b50610123610484565b6040805161ffff9092168252519081900360200190f35b34801561014657600080fd5b506100ae60043563ffffffff602435811690604435906064351660843561048e565b34801561017457600080fd5b506100ae60043563ffffffff60243581169060443590606435166084356104a7565b3480156101a257600080fd5b506100ae60043560243563ffffffff604435166064356105bc565b600080600080600080891180156101d45750600088115b80156101e6575060018763ffffffff16115b80156101fb5750621e848063ffffffff881611155b151561020657600080fd5b851515610216576000945061029d565b63ffffffff8716620f4240141561024f5788600161023a888b63ffffffff61068816565b0381151561024457fe5b04600101945061029d565b61025f898763ffffffff6106c116565b9150610270828a620f42408a6106d3565b909450925060ff8316600161028b8a8763ffffffff61068816565b039060020a9004600101905087810394505b50505050949350505050565b600080600080600080891180156102c05750600088115b80156102d2575060008763ffffffff16115b80156102e75750620f424063ffffffff881611155b15156102f257600080fd5b851515610302576000945061029d565b63ffffffff8716620f4240141561033557876103248a8863ffffffff61068816565b81151561032d57fe5b04945061029d565b610345868963ffffffff6106c116565b9150610356828989620f42406106d3565b909450925060ff831661036f8a8663ffffffff61068816565b60029190910a90049890980398975050505050505050565b60008060008060008060008a1180156103a05750600089115b80156103b2575060008863ffffffff16115b80156103c75750620f424063ffffffff891611155b80156103d35750898711155b15156103de57600080fd5b8615156103ee5760009550610477565b898714156103fe57889550610477565b63ffffffff8816620f4240141561043157896104208a8963ffffffff61068816565b81151561042957fe5b049550610477565b868a0392506104458a84620f42408b6106d3565b909550935061045a898663ffffffff61068816565b91505060ff831660020a88028481830381151561047357fe5b0495505b5050505050949350505050565b60005461ffff1681565b600061049d86868686866104a7565b9695505050505050565b60008060008060008060008b1180156104c6575060008a63ffffffff16115b80156104db5750620f424063ffffffff8b1611155b80156104e75750600089115b80156104f9575060008863ffffffff16115b801561050e5750620f424063ffffffff891611155b151561051957600080fd5b8763ffffffff168a63ffffffff16141561055e5761053d8b8863ffffffff6106c116565b61054d8a8963ffffffff61068816565b81151561055657fe5b0495506105ae565b61056e8b8863ffffffff6106c116565b925061057c838c8c8b6106d3565b9095509350610591898663ffffffff61068816565b91505060ff831660020a8802848183038115156105aa57fe5b0495505b505050505095945050505050565b600080600080600080891180156105d35750600088115b80156105e5575060018763ffffffff16115b80156105fa5750621e848063ffffffff881611155b80156106065750888611155b151561061157600080fd5b851515610621576000945061029d565b63ffffffff8716620f424014156106435788610324878a63ffffffff61068816565b85890391506106578983620f42408a6106d3565b909450925060ff8316610670898663ffffffff61068816565b60029190910a90049790970398975050505050505050565b60008083151561069b57600091506106ba565b508282028284828115156106ab57fe5b04146106b657600080fd5b8091505b5092915050565b6000828201838110156106b657600080fd5b600080808080807002000000000000000000000000000000008a106106f757600080fd5b886f800000000000000000000000000000008b0281151561071457fe5b04925070015bf0a8b1457695355fb8ac404e7a79e383101561074057610739836107c9565b935061074c565b61074983610cbd565b93505b8663ffffffff168863ffffffff16850281151561076557fe5b0491507008000000000000000000000000000000008210156107955761078a82610dfc565b607f955095506107bc565b61079e826112e1565b90506107b660ff607f8390031660020a83048261136e565b81955095505b5050505094509492505050565b6000808080806fd3094c70f034de4b96ff7d5b6f99fcd88610610824576f4000000000000000000000000000000093909301926fd3094c70f034de4b96ff7d5b6f99fcd86f8000000000000000000000000000000087020495505b6fa45af1e1f40c333b3de1db4dd55f29a78610610879576f2000000000000000000000000000000093909301926fa45af1e1f40c333b3de1db4dd55f29a76f8000000000000000000000000000000087020495505b6f910b022db7ae67ce76b441c27035c6a186106108ce576f1000000000000000000000000000000093909301926f910b022db7ae67ce76b441c27035c6a16f8000000000000000000000000000000087020495505b6f88415abbe9a76bead8d00cf112e4d4a88610610923576f0800000000000000000000000000000093909301926f88415abbe9a76bead8d00cf112e4d4a86f8000000000000000000000000000000087020495505b6f84102b00893f64c705e841d5d4064bd38610610978576f0400000000000000000000000000000093909301926f84102b00893f64c705e841d5d4064bd36f8000000000000000000000000000000087020495505b6f8204055aaef1c8bd5c3259f4822735a286106109cd576f0200000000000000000000000000000093909301926f8204055aaef1c8bd5c3259f4822735a26f8000000000000000000000000000000087020495505b6f810100ab00222d861931c15e39b44e998610610a22576f0100000000000000000000000000000093909301926f810100ab00222d861931c15e39b44e996f8000000000000000000000000000000087020495505b6f808040155aabbbe9451521693554f7338610610a76576e80000000000000000000000000000093909301926f808040155aabbbe9451521693554f7336f8000000000000000000000000000000087020495505b7fffffffffffffffffffffffffffffffff80000000000000000000000000000000860192508291506f8000000000000000000000000000000082800204905070010000000000000000000000000000000083810383020493909301926f800000000000000000000000000000008282020491507002000000000000000000000000000000006faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84900383020493909301926f800000000000000000000000000000008282020491507003000000000000000000000000000000006f9999999999999999999999999999999984900383020493909301926f800000000000000000000000000000008282020491507004000000000000000000000000000000006f9249249249249249249249249249249284900383020493909301926f800000000000000000000000000000008282020491507005000000000000000000000000000000006f8e38e38e38e38e38e38e38e38e38e38e84900383020493909301926f800000000000000000000000000000008282020491507006000000000000000000000000000000006f8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b84900383020493909301926f800000000000000000000000000000008282020491507007000000000000000000000000000000006f89d89d89d89d89d89d89d89d89d89d8984900383020493909301926f800000000000000000000000000000008282020491507008000000000000000000000000000000006f888888888888888888888888888888888490038302049390930195945050505050565b60008080807001000000000000000000000000000000008510610d1957610cf56f800000000000000000000000000000008604611791565b60ff8116600281900a909604956f8000000000000000000000000000000002935091505b6f80000000000000000000000000000000851115610dcc5750607f5b60008160ff161115610dcc576f800000000000000000000000000000008580020494507001000000000000000000000000000000008510610da5576002948590049460ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830116900a92909201915b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610d35565b6f05b9de1d10bf4103d647b0955897ba806f03f80fe03f80fe03f80fe03f80fe03f884020493505b505050919050565b6000670168244fdac780006f800000000000000000000000000000006f0fffffffffffffffffffffffffffffff84168080028290048082028390048083028490049485026710e1b3be415a00009092026705a0913f6b1e000091909102010192909181830204905080664807432bc1800002830192506f80000000000000000000000000000000828202811515610e8f57fe5b04905080660c0135dca0400002830192506f80000000000000000000000000000000828202811515610ebd57fe5b049050806601b707b1cdc00002830192506f80000000000000000000000000000000828202811515610eeb57fe5b049050806536e0f639b80002830192506f80000000000000000000000000000000828202811515610f1857fe5b04905080650618fee9f80002830192506f80000000000000000000000000000000828202811515610f4557fe5b04905080649c197dcc0002830192506f80000000000000000000000000000000828202811515610f7157fe5b04905080640e30dce40002830192506f80000000000000000000000000000000828202811515610f9d57fe5b0490508064012ebd130002830192506f80000000000000000000000000000000828202811515610fc957fe5b049050806317499f0002830192506f80000000000000000000000000000000828202811515610ff457fe5b049050806301a9d48002830192506f8000000000000000000000000000000082820281151561101f57fe5b04905080621c638002830192506f8000000000000000000000000000000082820281151561104957fe5b049050806201c63802830192506f8000000000000000000000000000000082820281151561107357fe5b04905080611ab802830192506f8000000000000000000000000000000082820281151561109c57fe5b0490508061017c02830192506f800000000000000000000000000000008282028115156110c557fe5b04905080601402830192506f800000000000000000000000000000008282028115156110ed57fe5b6721c3677c82b400009190049384010482016f80000000000000000000000000000000019290506f100000000000000000000000000000008516156111565770018ebef9eac820ae8682b9793ac6d1e7767001c3d6a24ed82218787d624d3e5eba95f984020492505b6f20000000000000000000000000000000851615611198577001368b2fc6f9609fe7aceb46aa619baed470018ebef9eac820ae8682b9793ac6d1e77884020492505b6f400000000000000000000000000000008516156111d9576fbc5ab1b16779be3575bd8f0520a9f21f7001368b2fc6f9609fe7aceb46aa619baed584020492505b6f80000000000000000000000000000000851615611219576f454aaa8efe072e7f6ddbab84b40a55c96fbc5ab1b16779be3575bd8f0520a9f21e84020492505b70010000000000000000000000000000000085161561125a576f0960aadc109e7a3bf4578099615711ea6f454aaa8efe072e7f6ddbab84b40a55c584020492505b70020000000000000000000000000000000085161561129a576e2bf84208204f5977f9a8cf01fdce3d6f0960aadc109e7a3bf4578099615711d784020492505b7004000000000000000000000000000000008516156112d8576d03c6ab775dd0b95b4cbee7e65d116e2bf84208204f5977f9a8cf01fdc30784020492505b50909392505050565b60006020607f825b8160ff168360010160ff16101561132e57600260ff8484011604905084600160ff83166080811061131657fe5b01541061132557809250611329565b8091505b6112e9565b84600160ff84166080811061133f57fe5b01541061134e57819350610df4565b84600160ff85166080811061135f57fe5b01541061008257829350610df4565b6000806000849150600090508360ff168583029060020a90049150816f03442c4e6074a82f1797f72ac000000002810190508360ff168583029060020a90049150816f0116b96f757c380fb287fd0e4000000002810190508360ff168583029060020a90049150816e45ae5bdd5f0e03eca1ff439000000002810190508360ff168583029060020a90049150816e0defabf91302cd95b9ffda5000000002810190508360ff168583029060020a90049150816e02529ca9832b22439efff9b800000002810190508360ff168583029060020a90049150816d54f1cf12bd04e516b6da8800000002810190508360ff168583029060020a90049150816d0a9e39e257a09ca2d6db5100000002810190508360ff168583029060020a90049150816d012e066e7b839fa050c30900000002810190508360ff168583029060020a90049150816c1e33d7d926c329a1ad1a80000002810190508360ff168583029060020a90049150816c02bee513bdb4a6b19b5f80000002810190508360ff168583029060020a90049150816b3a9316fa79b88eccf2a0000002810190508360ff168583029060020a90049150816b048177ebe1fa81237520000002810190508360ff168583029060020a90049150816a5263fe90242dcbacf0000002810190508360ff168583029060020a90049150816a057e22099c030d9410000002810190508360ff168583029060020a90049150816957e22099c030d941000002810190508360ff168583029060020a900491508169052b6b5456997631000002810190508360ff168583029060020a9004915081684985f67696bf74800002810190508360ff168583029060020a90049150816803dea12ea99e49800002810190508360ff168583029060020a90049150816731880f2214b6e00002810190508360ff168583029060020a900491508167025bcff56eb3600002810190508360ff168583029060020a9004915081661b722e10ab100002810190508360ff168583029060020a90049150816601317c7007700002810190508360ff168583029060020a9004915081650cba84aafa0002810190508360ff168583029060020a90049150816482573a0a0002810190508360ff168583029060020a90049150816405035ad90002810190508360ff168583029060020a9004915081632f881b0002810190508360ff168583029060020a90049150816301b2934002810190508360ff168583029060020a9004915081620efc4002810190508360ff168583029060020a9004915081617fe002810190508360ff168583029060020a900491508161042002810190508360ff168583029060020a9004915081602102810190508360ff168583029060020a9004915081600102810190508360ff1660019060020a02856f0688589cc0e9505e2f2fee55800000008381151561178557fe5b04010195945050505050565b600080806101008410156117c0575b60018411156117bb57600290930492600191909101906117a0565b6106ba565b5060805b60008160ff1611156106ba5760ff811660020a84106117ed5760ff811660020a90930492908117905b600260ff909116046117c45600a165627a7a7230582009ca39062ddc0cf02c6f411710c864ade25761adca76207a72cf8c868ec9b2bc0029
Deployed Bytecode Sourcemap
3762:34993:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19283:824;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;19283:824:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14150:844;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14150:844:0;;;;;;;;;;;;;15650:1024;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15650:1024:0;;;;;;;;;;;;;3852:25;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3852:25:0;;;;;;;;;;;;;;;;;;;;;;;38402:350;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38402:350:0;;;;;;;;;;;;;;;;;;;17625:958;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;17625:958:0;;;;;;;;;;;;;;;;;;;20810:828;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;20810:828:0;;;;;;;;;;;;;19283:824;19410:7;19816:14;19841:15;19867:13;19992:12;19475:1;19465:7;:11;:34;;;;;19498:1;19480:15;:19;19465:34;:53;;;;;19517:1;19503:11;:15;;;19465:53;:85;;;;-1:-1:-1;19537:13:0;19522:28;;;;;19465:85;19457:94;;;;;;;;19606:12;;19602:39;;;19640:1;19633:8;;;;19602:39;19709:24;;;3961:7;19709:24;19705:98;;;19792:7;19787:1;19756:28;:7;19768:15;19756:28;:11;:28;:::i;:::-;:32;19755:44;;;;;;;;19802:1;19755:48;19748:55;;;;19705:98;19883:20;:7;19895;19883:20;:11;:20;:::i;:::-;19867:36;;19936:45;19942:5;19949:7;3961;19969:11;19936:5;:45::i;:::-;19914:67;;-1:-1:-1;19914:67:0;-1:-1:-1;20008:46:0;;;20039:1;20009:27;:15;19914:67;20009:27;:19;:27;:::i;:::-;:31;20008:46;;;;;20058:1;20007:52;19992:67;;20084:15;20077:4;:22;20070:29;;19283:824;;;;;;;;;;;:::o;14150:844::-;14292:7;14706:14;14731:15;14757:13;14907:12;14357:1;14347:7;:11;:34;;;;;14380:1;14362:15;:19;14347:34;:55;;;;;14401:1;14385:13;:17;;;14347:55;:85;;;;-1:-1:-1;3961:7:0;14406:26;;;;;14347:85;14339:94;;;;;;;;14496:19;;14492:46;;;14537:1;14530:8;;;;14492:46;14600:26;;;3961:7;14600:26;14596:97;;;14678:15;14648:27;:7;14660:14;14648:27;:11;:27;:::i;:::-;:45;;;;;;;;14641:52;;;;14596:97;14773:35;:14;14792:15;14773:35;:18;:35;:::i;:::-;14757:51;;14841:55;14847:5;14854:15;14871:13;3961:7;14841:5;:55::i;:::-;14819:77;;-1:-1:-1;14819:77:0;-1:-1:-1;14922:32:0;;;:19;:7;14819:77;14922:19;:11;:19;:::i;:::-;:32;;;;;;;14972:14;;;;;14150:844;-1:-1:-1;;;;;;;;14150:844:0:o;15650:1024::-;15785:7;16347:14;16372:15;16398:13;16526;16580;15850:1;15840:7;:11;:34;;;;;15873:1;15855:15;:19;15840:34;:55;;;;;15894:1;15878:13;:17;;;15840:55;:85;;;;-1:-1:-1;3961:7:0;15899:26;;;;;15840:85;:111;;;;;15944:7;15929:11;:22;;15840:111;15832:120;;;;;;;;16012:16;;16008:43;;;16050:1;16043:8;;;;16008:43;16138:7;16123:11;:22;16119:63;;;16167:15;16160:22;;;;16119:63;16244:26;;;3961:7;16244:26;16240:94;;;16327:7;16292:32;:15;16312:11;16292:32;:19;:32;:::i;:::-;:42;;;;;;;;16285:49;;;;16240:94;16424:11;16414:7;:21;16398:37;;16468:47;16474:7;16483:5;3961:7;16501:13;16468:5;:47::i;:::-;16446:69;;-1:-1:-1;16446:69:0;-1:-1:-1;16542:27:0;:15;16446:69;16542:27;:19;:27;:::i;:::-;16526:43;-1:-1:-1;;16596:28:0;;;;;;;16660:6;16643:13;;;16642:24;;;;;;;;16635:31;;15650:1024;;;;;;;;;;;;:::o;3852:25::-;;;;;;:::o;38402:350::-;38595:7;38622:122;38650:21;38673:20;38695:19;38716:18;38736:7;38622:27;:122::i;:::-;38615:129;38402:350;-1:-1:-1;;;;;;38402:350:0:o;17625:958::-;17806:7;18219:14;18244:15;18270:13;18431;18487;17883:1;17861:19;:23;:48;;;;;17908:1;17888:17;:21;;;17861:48;:82;;;;-1:-1:-1;3961:7:0;17913:30;;;;;17861:82;:107;;;;;17967:1;17947:17;:21;17861:107;:130;;;;;17990:1;17972:15;:19;;;17861:130;:162;;;;-1:-1:-1;3961:7:0;17995:28;;;;;17861:162;17853:171;;;;;;;;18104:15;18083:36;;:17;:36;;;18079:127;;;18174:32;:19;18198:7;18174:32;:23;:32;:::i;:::-;18141:30;:17;18163:7;18141:30;:21;:30;:::i;:::-;:65;;;;;;;;18134:72;;;;18079:127;18286:32;:19;18310:7;18286:32;:23;:32;:::i;:::-;18270:48;;18351:69;18357:5;18364:19;18385:17;18404:15;18351:5;:69::i;:::-;18329:91;;-1:-1:-1;18329:91:0;-1:-1:-1;18447:29:0;:17;18329:91;18447:29;:21;:29;:::i;:::-;18431:45;-1:-1:-1;;18503:30:0;;;;;;;18569:6;18552:13;;;18551:24;;;;;;;;18544:31;;17625:958;;;;;;;;;;;;;:::o;20810:828::-;20944:7;21362:14;21387:15;21413:13;21535:12;21009:1;20999:7;:11;:34;;;;;21032:1;21014:15;:19;20999:34;:53;;;;;21051:1;21037:11;:15;;;20999:53;:85;;;;-1:-1:-1;21071:13:0;21056:28;;;;;20999:85;:107;;;;;21099:7;21088;:18;;20999:107;20991:116;;;;;;;;21162:12;;21158:39;;;21196:1;21189:8;;;;21158:39;21265:24;;;3961:7;21265:24;21261:88;;;21342:7;21311:28;:7;21323:15;21311:28;:11;:28;:::i;21261:88::-;21439:7;21429;:17;21413:33;;21479:45;21485:7;21494:5;3961:7;21512:11;21479:5;:45::i;:::-;21457:67;;-1:-1:-1;21457:67:0;-1:-1:-1;21550:40:0;;;:27;:15;21457:67;21550:27;:19;:27;:::i;:::-;:40;;;;;;;21608:22;;;;;20810:828;-1:-1:-1;;;;;;;;20810:828:0:o;2317:234::-;2377:7;;2430;;2426:34;;;2459:1;2452:8;;;;2426:34;-1:-1:-1;2485:7:0;;;2490:2;2485;:7;2511:6;;;;;;;;:12;2503:21;;;;;;2542:1;2535:8;;2317:234;;;;;;:::o;1583:153::-;1643:7;1675;;;1701;;;;1693:16;;;;;23085:791;23183:7;;;;;;4336:35;23218:16;;23210:25;;;;;;23308:6;4182:35;23289:6;:16;:25;;;;;;;;23274:40;;4771:35;23329:4;:22;23325:149;;;23378:16;23389:4;23378:10;:16::i;:::-;23368:26;;23325:149;;;23446:16;23457:4;23446:10;:16::i;:::-;23436:26;;23325:149;23530:5;23512:23;;23522:5;23512:15;;:7;:15;:23;;;;;;;;23486:49;;4856:35;23550:15;:33;23546:323;;;23608:27;23619:15;23608:10;:27::i;:::-;4062:3;23600:51;;;;;;23546:323;23711:42;23737:15;23711:25;:42::i;:::-;23693:60;-1:-1:-1;23776:69:0;23787:46;4062:3;23807:25;;;23787:46;;;;;23693:60;23776:10;:69::i;:::-;23847:9;23768:89;;;;23546:323;23085:791;;;;;;;;;;;:::o;31617:2798::-;31671:7;;;;;31790:34;31785:39;;31781:143;;31834:34;31827:41;;;;;31888:34;4182:35;31874:11;;:48;31870:52;;31781:143;31958:34;31953:39;;31949:143;;32002:34;31995:41;;;;;32056:34;4182:35;32042:11;;:48;32038:52;;31949:143;32126:34;32121:39;;32117:143;;32170:34;32163:41;;;;;32224:34;4182:35;32210:11;;:48;32206:52;;32117:143;32294:34;32289:39;;32285:143;;32338:34;32331:41;;;;;32392:34;4182:35;32378:11;;:48;32374:52;;32285:143;32462:34;32457:39;;32453:143;;32506:34;32499:41;;;;;32560:34;4182:35;32546:11;;:48;32542:52;;32453:143;32630:34;32625:39;;32621:143;;32674:34;32667:41;;;;;32728:34;4182:35;32714:11;;:48;32710:52;;32621:143;32798:34;32793:39;;32789:143;;32842:34;32835:41;;;;;32896:34;4182:35;32882:11;;:48;32878:52;;32789:143;32966:34;32961:39;;32957:143;;33010:34;33003:41;;;;;33064:34;4182:35;33050:11;;:48;33046:52;;32957:143;33135:11;;;;-1:-1:-1;33135:11:0;;-1:-1:-1;4182:35:0;33161:5;;;:15;;-1:-1:-1;33242:35:0;33199:39;;;33194:45;;:83;33187:90;;;;;4182:35;33283:5;;;:15;;-1:-1:-1;33393:35:0;33350;:39;;;33345:45;;:83;33338:90;;;;;4182:35;33434:5;;;:15;;-1:-1:-1;33544:35:0;33501;:39;;;33496:45;;:83;33489:90;;;;;4182:35;33585:5;;;:15;;-1:-1:-1;33695:35:0;33652;:39;;;33647:45;;:83;33640:90;;;;;4182:35;33736:5;;;:15;;-1:-1:-1;33846:35:0;33803;:39;;;33798:45;;:83;33791:90;;;;;4182:35;33887:5;;;:15;;-1:-1:-1;33997:35:0;33954;:39;;;33949:45;;:83;33942:90;;;;;4182:35;34038:5;;;:15;;-1:-1:-1;34148:35:0;34105;:39;;;34100:45;;:83;34093:90;;;;;4182:35;34189:5;;;:15;;-1:-1:-1;34299:35:0;34256;:39;;;34251:45;;:83;34244:90;;;;;31617:2798;-1:-1:-1;;;;;31617:2798:0:o;24053:823::-;24107:7;;;;4259:35;24251:12;;24247:156;;24294:22;4182:35;24304:1;:11;24294:9;:22::i;:::-;24331:11;;;;;;;;;;;4182:35;24376:15;;-1:-1:-1;24280:36:0;-1:-1:-1;24247:156:0;4182:35;24511:1;:11;24507:305;;;-1:-1:-1;4062:3:0;24539:262;24573:1;24569;:5;;;24539:262;;;4182:35;24605:5;;;24604:17;;-1:-1:-1;4259:35:0;24661:12;;24657:129;;24698:7;;;;;;24752:14;24760:5;;;24752:14;;;24745:21;;;;;24657:129;24576:3;;24539:262;;;4579:33;4496;24831:19;;:37;24824:44;;24053:823;;;;;;;:::o;35112:3216::-;35166:7;35550:18;4182:35;35264:38;;;35348:5;;;:15;;;35435:5;;;:15;;;35522:5;;;:15;;;35546:22;;;35376:18;35372:22;;;35463:18;35459:22;;;;35452:29;35539;;35264:38;;35609:5;;;:15;35605:19;;35633:1;35637:18;35633:22;35626:29;;;;4182:35;35700:1;35696;:5;:15;;;;;;;;35692:19;;35720:1;35724:18;35720:22;35713:29;;;;4182:35;35787:1;35783;:5;:15;;;;;;;;35779:19;;35807:1;35811:18;35807:22;35800:29;;;;4182:35;35874:1;35870;:5;:15;;;;;;;;35866:19;;35894:1;35898:18;35894:22;35887:29;;;;4182:35;35961:1;35957;:5;:15;;;;;;;;35953:19;;35981:1;35985:18;35981:22;35974:29;;;;4182:35;36048:1;36044;:5;:15;;;;;;;;36040:19;;36068:1;36072:18;36068:22;36061:29;;;;4182:35;36135:1;36131;:5;:15;;;;;;;;36127:19;;36155:1;36159:18;36155:22;36148:29;;;;4182:35;36222:1;36218;:5;:15;;;;;;;;36214:19;;36242:1;36246:18;36242:22;36235:29;;;;4182:35;36309:1;36305;:5;:15;;;;;;;;36301:19;;36329:1;36333:18;36329:22;36322:29;;;;4182:35;36396:1;36392;:5;:15;;;;;;;;36388:19;;36416:1;36420:18;36416:22;36409:29;;;;4182:35;36483:1;36479;:5;:15;;;;;;;;36475:19;;36503:1;36507:18;36503:22;36496:29;;;;4182:35;36570:1;36566;:5;:15;;;;;;;;36562:19;;36590:1;36594:18;36590:22;36583:29;;;;4182:35;36657:1;36653;:5;:15;;;;;;;;36649:19;;36677:1;36681:18;36677:22;36670:29;;;;4182:35;36744:1;36740;:5;:15;;;;;;;;36736:19;;36764:1;36768:18;36764:22;36757:29;;;;4182:35;36831:1;36827;:5;:15;;;;;;;;36823:19;;36851:1;36855:18;36851:22;36844:29;;;;4182:35;36918:1;36914;:5;:15;;;;;;;37009:18;36914:15;;;36931:29;;;37003:24;:28;;4182:35;37003:38;;36914:15;-1:-1:-1;37113:35:0;37109:39;;37108:46;37104:137;;37206:35;37168;37162:41;;:79;37156:85;;37104:137;37285:35;37281:39;;37280:46;37276:137;;37378:35;37340;37334:41;;:79;37328:85;;37276:137;37457:35;37453:39;;37452:46;37448:137;;37550:35;37512;37506:41;;:79;37500:85;;37448:137;37629:35;37625:39;;37624:46;37620:137;;37722:35;37684;37678:41;;:79;37672:85;;37620:137;37801:35;37797:39;;37796:46;37792:137;;37894:35;37856;37850:41;;:79;37844:85;;37792:137;37973:35;37969:39;;37968:46;37964:137;;38066:35;38028;38022:41;;:79;38016:85;;37964:137;38145:35;38141:39;;38140:46;38136:137;;38238:35;38200;38194:41;;:79;38188:85;;38136:137;-1:-1:-1;38317:3:0;;35112:3216;-1:-1:-1;;;35112:3216:0:o;25919:520::-;25989:5;4014:2;4062:3;25989:5;26079:185;26095:2;26086:11;;:2;26091:1;26086:6;:11;;;26079:185;;;26138:1;26126:13;26127:7;;;26126:13;;;-1:-1:-1;26178:2:0;26158:11;:16;;;;;;;;;;;;:22;26154:98;;26204:3;26199:8;;26154:98;;;26249:3;26244:8;;26154:98;26079:185;;;26299:2;26280:11;:15;;;;;;;;;;;;:21;26276:49;;26323:2;26316:9;;;;26276:49;26359:2;26340:11;:15;;;;;;;;;;;;:21;26336:49;;26383:2;26376:9;;;;27011:3864;27084:7;27104:10;27130:11;27117:2;27104:15;;27144:1;27130:15;;27176:10;27163:23;;27169:2;27164;:7;27163:23;;;;;27158:28;;27195:2;27200:33;27195:38;27188:45;;;;27288:10;27275:23;;27281:2;27276;:7;27275:23;;;;;27270:28;;27307:2;27312:33;27307:38;27300:45;;;;27400:10;27387:23;;27393:2;27388;:7;27387:23;;;;;27382:28;;27419:2;27424:33;27419:38;27412:45;;;;27512:10;27499:23;;27505:2;27500;:7;27499:23;;;;;27494:28;;27531:2;27536:33;27531:38;27524:45;;;;27624:10;27611:23;;27617:2;27612;:7;27611:23;;;;;27606:28;;27643:2;27648:33;27643:38;27636:45;;;;27736:10;27723:23;;27729:2;27724;:7;27723:23;;;;;27718:28;;27755:2;27760:33;27755:38;27748:45;;;;27848:10;27835:23;;27841:2;27836;:7;27835:23;;;;;27830:28;;27867:2;27872:33;27867:38;27860:45;;;;27960:10;27947:23;;27953:2;27948;:7;27947:23;;;;;27942:28;;27979:2;27984:33;27979:38;27972:45;;;;28072:10;28059:23;;28065:2;28060;:7;28059:23;;;;;28054:28;;28091:2;28096:33;28091:38;28084:45;;;;28184:10;28171:23;;28177:2;28172;:7;28171:23;;;;;28166:28;;28203:2;28208:33;28203:38;28196:45;;;;28296:10;28283:23;;28289:2;28284;:7;28283:23;;;;;28278:28;;28315:2;28320:33;28315:38;28308:45;;;;28408:10;28395:23;;28401:2;28396;:7;28395:23;;;;;28390:28;;28427:2;28432:33;28427:38;28420:45;;;;28520:10;28507:23;;28513:2;28508;:7;28507:23;;;;;28502:28;;28539:2;28544:33;28539:38;28532:45;;;;28632:10;28619:23;;28625:2;28620;:7;28619:23;;;;;28614:28;;28651:2;28656:33;28651:38;28644:45;;;;28744:10;28731:23;;28737:2;28732;:7;28731:23;;;;;28726:28;;28763:2;28768:33;28763:38;28756:45;;;;28856:10;28843:23;;28849:2;28844;:7;28843:23;;;;;28838:28;;28875:2;28880:33;28875:38;28868:45;;;;28968:10;28955:23;;28961:2;28956;:7;28955:23;;;;;28950:28;;28987:2;28992:33;28987:38;28980:45;;;;29080:10;29067:23;;29073:2;29068;:7;29067:23;;;;;29062:28;;29099:2;29104:33;29099:38;29092:45;;;;29192:10;29179:23;;29185:2;29180;:7;29179:23;;;;;29174:28;;29211:2;29216:33;29211:38;29204:45;;;;29304:10;29291:23;;29297:2;29292;:7;29291:23;;;;;29286:28;;29323:2;29328:33;29323:38;29316:45;;;;29416:10;29403:23;;29409:2;29404;:7;29403:23;;;;;29398:28;;29435:2;29440:33;29435:38;29428:45;;;;29528:10;29515:23;;29521:2;29516;:7;29515:23;;;;;29510:28;;29547:2;29552:33;29547:38;29540:45;;;;29640:10;29627:23;;29633:2;29628;:7;29627:23;;;;;29622:28;;29659:2;29664:33;29659:38;29652:45;;;;29752:10;29739:23;;29745:2;29740;:7;29739:23;;;;;29734:28;;29771:2;29776:33;29771:38;29764:45;;;;29864:10;29851:23;;29857:2;29852;:7;29851:23;;;;;29846:28;;29883:2;29888:33;29883:38;29876:45;;;;29976:10;29963:23;;29969:2;29964;:7;29963:23;;;;;29958:28;;29995:2;30000:33;29995:38;29988:45;;;;30088:10;30075:23;;30081:2;30076;:7;30075:23;;;;;30070:28;;30107:2;30112:33;30107:38;30100:45;;;;30200:10;30187:23;;30193:2;30188;:7;30187:23;;;;;30182:28;;30219:2;30224:33;30219:38;30212:45;;;;30312:10;30299:23;;30305:2;30300;:7;30299:23;;;;;30294:28;;30331:2;30336:33;30331:38;30324:45;;;;30424:10;30411:23;;30417:2;30412;:7;30411:23;;;;;30406:28;;30443:2;30448:33;30443:38;30436:45;;;;30536:10;30523:23;;30529:2;30524;:7;30523:23;;;;;30518:28;;30555:2;30560:33;30555:38;30548:45;;;;30648:10;30635:23;;30641:2;30636;:7;30635:23;;;;;30630:28;;30667:2;30672:33;30667:38;30660:45;;;;30806:10;30799:17;;3917:1;30799:17;;;;30793:2;30757:33;30751:3;:39;;;;;;;;:44;:66;;27011:3864;-1:-1:-1;;;;;27011:3864:0:o;25004:542::-;25058:5;;;25111:3;25106:8;;25102:414;;;25168:85;25180:1;25175:2;:6;25168:85;;;25202:8;;;;;25209:1;25229:8;;;;;25168:85;;;25102:414;;;-1:-1:-1;25346:3:0;25331:174;25355:1;25351;:5;;;25331:174;;;25397:8;;;;;25390:16;;25386:104;;25431:8;;;;;;;;;25462;;;;25386:104;25358:7;;;;;;25331:174;
Swarm Source
bzzr://09ca39062ddc0cf02c6f411710c864ade25761adca76207a72cf8c868ec9b2bc
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.