Source Code
Overview
S Balance
More Info
ContractCreator
Loading...
Loading
Contract Name:
BancorFormula
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Bancor LICENSE pragma solidity ^0.8.20; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "./Power.sol"; /* Note From https://github.com/bancorprotocol/contracts-solidity/blob/master/solidity/contracts/converter/BancorFormula.sol with some minor alterations */ contract BancorFormula is Power { using SafeMath for uint256; uint32 private constant MAX_WEIGHT = 1000000; /** * @dev given a token supply, reserve balance, weight and an amount (in the main token), * calculates the amount of reserve tokens required for purchasing the given amount of pool tokens * * Formula: * return = _reserveBalance * ((_amount / _supply + 1) ^ (1000000 / _reserveWeight) - 1) * * @param _supply liquid token supply * @param _reserveBalance reserve balance * @param _reserveWeight reserve weight, represented in ppm (1-1000000) * @param _amount requested amount of pool tokens * * @return reserve token amount */ function purchaseCost( uint256 _supply, uint256 _reserveBalance, uint32 _reserveWeight, uint256 _amount ) public view virtual returns (uint256) { // validate input require(_supply > 0, "ERR_INVALID_SUPPLY"); require(_reserveBalance > 0, "ERR_INVALID_RESERVE_BALANCE"); require(_reserveWeight > 0 && _reserveWeight <= MAX_WEIGHT, "ERR_INVALID_RESERVE_RATIO"); // special case for 0 amount if (_amount == 0) return 0; // special case if the reserve weight = 100% if (_reserveWeight == MAX_WEIGHT) return (_amount.mul(_reserveBalance) - 1) / _supply + 1; uint256 result; uint8 precision; uint256 baseN = _supply.add(_amount); (result, precision) = power(baseN, _supply, MAX_WEIGHT, _reserveWeight); uint256 temp = (_reserveBalance.mul(result) - 1) >> precision; return temp - _reserveBalance; } /** * @dev given a token supply, reserve balance, weight and a deposit amount (in the reserve token), * calculates the target amount for a given conversion (in the main token) * * Formula: * return = _supply * ((1 + _amount / _reserveBalance) ^ (_reserveWeight / 1000000) - 1) * * @param _supply liquid token supply * @param _reserveBalance reserve balance * @param _reserveWeight reserve weight, represented in ppm (1-1000000) * @param _amount amount of reserve tokens to get the target amount for * * @return target */ function purchaseTargetAmount( uint256 _supply, uint256 _reserveBalance, uint32 _reserveWeight, uint256 _amount ) public view virtual returns (uint256) { // validate input require(_supply > 0, "ERR_INVALID_SUPPLY"); require(_reserveBalance > 0, "ERR_INVALID_RESERVE_BALANCE"); require(_reserveWeight > 0 && _reserveWeight <= MAX_WEIGHT, "ERR_INVALID_RESERVE_WEIGHT"); // special case for 0 deposit amount if (_amount == 0) return 0; // special case if the weight = 100% if (_reserveWeight == MAX_WEIGHT) return _supply.mul(_amount) / _reserveBalance; uint256 result; uint8 precision; uint256 baseN = _amount.add(_reserveBalance); (result, precision) = power(baseN, _reserveBalance, _reserveWeight, MAX_WEIGHT); uint256 temp = (_supply.mul(result) >> precision) + 1; return temp - _supply; } /** * @dev given a token supply, reserve balance, weight and a sell amount (in the main token), * calculates the target amount for a given conversion (in the reserve token) * * Formula: * return = _reserveBalance * (1 - (1 - _amount / _supply) ^ (1000000 / _reserveWeight)) * * @param _supply liquid token supply * @param _reserveBalance reserve balance * @param _reserveWeight reserve weight, represented in ppm (1-1000000) * @param _amount amount of liquid tokens to get the target amount for * * @return reserve token amount */ function saleTargetAmount( uint256 _supply, uint256 _reserveBalance, uint32 _reserveWeight, uint256 _amount ) public view virtual returns (uint256) { // validate input require(_supply > 0, "ERR_INVALID_SUPPLY"); require(_reserveBalance > 0, "ERR_INVALID_RESERVE_BALANCE"); require(_reserveWeight > 0 && _reserveWeight <= MAX_WEIGHT, "ERR_INVALID_RESERVE_WEIGHT"); require(_amount <= _supply, "ERR_INVALID_AMOUNT"); // special case for 0 sell amount if (_amount == 0) return 0; // special case for selling the entire supply if (_amount == _supply) return _reserveBalance; // special case if the weight = 100% if (_reserveWeight == MAX_WEIGHT) return _reserveBalance.mul(_amount) / _supply; uint256 result; uint8 precision; uint256 baseD = _supply - _amount; (result, precision) = power(_supply, baseD, MAX_WEIGHT, _reserveWeight); uint256 temp1 = _reserveBalance.mul(result); uint256 temp2 = _reserveBalance << precision; return (temp1 - temp2) / result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ 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) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { 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) { unchecked { // 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) { unchecked { 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) { unchecked { 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) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return 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) { return a * b; } /** * @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. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { 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) { 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) { unchecked { 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. * * 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) { unchecked { 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) { unchecked { require(b > 0, errorMessage); return a % b; } } }
//SPDX-License-Identifier: Bancor LICENSE pragma solidity ^0.8.20; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; /// @notice For calculating fractional exponents /// Note from https://github.com/bancorprotocol/contracts-solidity/blob/master/solidity/contracts/converter/BancorFormula.sol contract Power { using SafeMath for uint256; uint256 private constant ONE = 1; uint32 private constant MAX_WEIGHT = 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 'PrintMaxExpArray.py' uint256[128] private maxExpArray; function initMaxExpArray() private { // 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 should be executed after construction (too large for the constructor) */ function init() public virtual { initMaxExpArray(); } /** * @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". * Since we rely on unsigned-integer arithmetic and "base < 1" ==> "log(base) < 0", this function does not support "_baseN < _baseD". */ 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; // revert if no return require(false); } /** * @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 <= OPT_LOG_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; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_reserveBalance","type":"uint256"},{"internalType":"uint32","name":"_reserveWeight","type":"uint32"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"purchaseCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_reserveBalance","type":"uint256"},{"internalType":"uint32","name":"_reserveWeight","type":"uint32"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"purchaseTargetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_reserveBalance","type":"uint256"},{"internalType":"uint32","name":"_reserveWeight","type":"uint32"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"saleTargetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506123be806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80635f28fdfc1461005157806376cf0b5614610076578063e1c7392a14610089578063f3250fe214610093575b600080fd5b61006461005f3660046121c5565b6100a6565b60405190815260200160405180910390f35b6100646100843660046121c5565b61020c565b61009161039d565b005b6100646100a13660046121c5565b610b74565b60008085116100d05760405162461bcd60e51b81526004016100c79061220d565b60405180910390fd5b600084116100f05760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff1611801561010f5750620f424063ffffffff841611155b61015b5760405162461bcd60e51b815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f524154494f0000000000000060448201526064016100c7565b8160000361016b57506000610204565b620f423f1963ffffffff8416016101af578460016101898487610c98565b6101939190612286565b61019d91906122af565b6101a89060016122c3565b9050610204565b600080806101bd8886610cad565b90506101ce8189620f424089610cb9565b9093509150600060ff831660016101e58a87610c98565b6101ef9190612286565b901c90506101fd8882612286565b9450505050505b949350505050565b600080851161022d5760405162461bcd60e51b81526004016100c79061220d565b6000841161024d5760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff1611801561026c5750620f424063ffffffff841611155b6102b85760405162461bcd60e51b815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f57454947485400000000000060448201526064016100c7565b848211156102fd5760405162461bcd60e51b815260206004820152601260248201527111549497d253959053125117d05353d5539560721b60448201526064016100c7565b8160000361030d57506000610204565b84820361031b575082610204565b620f423f1963ffffffff84160161034157846103378584610c98565b6101a891906122af565b6000808061034f8589612286565b90506103608882620f424089610cb9565b909350915060006103718885610c98565b905060ff831688901b846103858284612286565b61038f91906122af565b9a9950505050505050505050565b610b72701c35fedd14ffffffffffffffffffffffff602055701b0ce43b323fffffffffffffffffffffff6021557019f0028ec1ffffffffffffffffffffffff6022557018ded91f0e7fffffffffffffffffffffff6023557017d8ec7f0417ffffffffffffffffffffff6024557016ddc6556cdbffffffffffffffffffffff6025557015ecf52776a1ffffffffffffffffffffff6026557015060c256cb2ffffffffffffffffffffff602755701428a2f98d72ffffffffffffffffffffff6028557013545598e5c23fffffffffffffffffffff602955701288c4161ce1dfffffffffffffffffffff602a557011c592761c666fffffffffffffffffffff602b5570110a688680a757ffffffffffffffffffff602c55701056f1b5bedf77ffffffffffffffffffff602d55700faadceceeff8bffffffffffffffffffff602e55700f05dc6b27edadffffffffffffffffffff602f55700e67a5a25da4107fffffffffffffffffff603055700dcff115b14eedffffffffffffffffffff603155700d3e7a392431239fffffffffffffffffff603255700cb2ff529eb71e4fffffffffffffffffff603355700c2d415c3db974afffffffffffffffffff603455700bad03e7d883f69bffffffffffffffffff603555700b320d03b2c343d5ffffffffffffffffff603655700abc25204e02828dffffffffffffffffff603755700a4b16f74ee4bb207fffffffffffffffff6038557009deaf736ac1f569ffffffffffffffffff603955700976bd9952c7aa957fffffffffffffffff603a557009131271922eaa606fffffffffffffffff603b557008b380f3558668c46fffffffffffffffff603c55700857ddf0117efa215bffffffffffffffff603d557007ffffffffffffffffffffffffffffffff603e557007abbf6f6abb9d087fffffffffffffffff603f5570075af62cbac95f7dfa7fffffffffffffff60405570070d7fb7452e187ac13fffffffffffffff6041557006c3390ecc8af379295fffffffffffffff60425570067c00a3b07ffc01fd6fffffffffffffff604355700637b647c39cbb9d3d27ffffffffffffff6044557005f63b1fc104dbd39587ffffffffffffff6045557005b771955b36e12f7235ffffffffffffff60465570057b3d49dda84556d6f6ffffffffffffff60475570054183095b2c8ececf30ffffffffffffff60485570050a28be635ca2b888f77fffffffffffff6049557004d5156639708c9db33c3fffffffffffff604a557004a23105873875bd52dfdfffffffffffff604b55700471649d87199aa990756fffffffffffff604c557004429a21a029d4c1457cfbffffffffffff604d55700415bc6d6fb7dd71af2cb3ffffffffffff604e557003eab73b3bbfe282243ce1ffffffffffff604f557003c1771ac9fb6b4c18e229ffffffffffff605055700399e96897690418f785257fffffffffff605155700373fc456c53bb779bf0ea9fffffffffff60525570034f9e8e490c48e67e6ab8bfffffffffff60535570032cbfd4a7adc790560b3337ffffffffff60545570030b50570f6e5d2acca94613ffffffffff6055557002eb40f9f620fda6b56c2861ffffffffff6056557002cc8340ecb0d0f520a6af58ffffffffff6057557002af09481380a0a35cf1ba02ffffffffff605855700292c5bdd3b92ec810287b1b3fffffffff605955700277abdcdab07d5a77ac6d6b9fffffffff605a5570025daf6654b1eaa55fd64df5efffffffff605b55700244c49c648baa98192dce88b7ffffffff605c5570022ce03cd5619a311b2471268bffffffff605d55700215f77c045fbe885654a44a0fffffffff605e557001ffffffffffffffffffffffffffffffff605f557001eaefdbdaaee7421fc4d3ede5ffffffff6060557001d6bd8b2eb257df7e8ca57b09bfffffff6061557001c35fedd14b861eb0443f7f133fffffff6062557001b0ce43b322bcde4a56e8ada5afffffff60635570019f0028ec1fff007f5a195a39dfffffff60645570018ded91f0e72ee74f49b15ba527ffffff60655570017d8ec7f04136f4e5615fd41a63ffffff60665570016ddc6556cdb84bdc8d12d22e6fffffff60675570015ecf52776a1155b5bd8395814f7fffff60685570015060c256cb23b3b3cc3754cf40ffffff6069557001428a2f98d728ae223ddab715be3fffff606a5570013545598e5c23276ccf0ede68034fffff606b557001288c4161ce1d6f54b7f61081194fffff606c5570011c592761c666aa641d5a01a40f17ffff606d55700110a688680a7530515f3e6e6cfdcdffff606e557001056f1b5bedf75c6bcb2ce8aed428ffff606f556ffaadceceeff8a0890f3875f008277fff6070556ff05dc6b27edad306388a600f6ba0bfff6071556fe67a5a25da41063de1495d5b18cdbfff6072556fdcff115b14eedde6fc3aa5353f2e4fff6073556fd3e7a3924312399f9aae2e0f868f8fff6074556fcb2ff529eb71e41582cccd5a1ee26fff6075556fc2d415c3db974ab32a51840c0b67edff6076556fbad03e7d883f69ad5b0a186184e06bff6077556fb320d03b2c343d4829abd6075f0cc5ff6078556fabc25204e02828d73c6e80bcdb1a95bf6079556fa4b16f74ee4bb2040a1ec6c15fbbf2df607a556f9deaf736ac1f569deb1b5ae3f36c130f607b556f976bd9952c7aa957f5937d790ef65037607c556f9131271922eaa6064b73a22d0bd4f2bf607d556f8b380f3558668c46c91c49a2f8e967b9607e556f857ddf0117efa215952912839f6473e6607f55565b565b6000808511610b955760405162461bcd60e51b81526004016100c79061220d565b60008411610bb55760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff16118015610bd45750620f424063ffffffff841611155b610c205760405162461bcd60e51b815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f57454947485400000000000060448201526064016100c7565b81600003610c3057506000610204565b620f423f1963ffffffff841601610c4c57836103378684610c98565b60008080610c5a8588610cad565b9050610c6b818888620f4240610cb9565b9093509150600060ff8316610c808a86610c98565b610c8c911c60016122c3565b90506101fd8982612286565b6000610ca482846122d6565b90505b92915050565b6000610ca482846122c3565b600080600160811b8610610ccc57600080fd5b60008086610cde6001607f1b8a6122d6565b610ce891906122af565b905070015bf0a8b1457695355fb8ac404e7a79e3811015610d1357610d0c81610da6565b9150610d1f565b610d1c8161131f565b91505b60008563ffffffff168763ffffffff1684610d3a91906122d6565b610d4491906122af565b9050600160831b811015610d6957610d5b81611414565b607f94509450505050610d9d565b6000610d7482611a3f565b9050610d90610d8482607f6122ed565b60ff1683901c82611af2565b95509350610d9d92505050565b94509492505050565b6000808080806fd3094c70f034de4b96ff7d5b6f99fcd88610610dff57610dd16001607e1b856122c3565b93506fd3094c70f034de4b96ff7d5b6f99fcd8610df26001607f1b886122d6565b610dfc91906122af565b95505b6fa45af1e1f40c333b3de1db4dd55f29a78610610e5257610e246001607d1b856122c3565b93506fa45af1e1f40c333b3de1db4dd55f29a7610e456001607f1b886122d6565b610e4f91906122af565b95505b6f910b022db7ae67ce76b441c27035c6a18610610ea557610e776001607c1b856122c3565b93506f910b022db7ae67ce76b441c27035c6a1610e986001607f1b886122d6565b610ea291906122af565b95505b6f88415abbe9a76bead8d00cf112e4d4a88610610ef857610eca6001607b1b856122c3565b93506f88415abbe9a76bead8d00cf112e4d4a8610eeb6001607f1b886122d6565b610ef591906122af565b95505b6f84102b00893f64c705e841d5d4064bd38610610f4b57610f1d6001607a1b856122c3565b93506f84102b00893f64c705e841d5d4064bd3610f3e6001607f1b886122d6565b610f4891906122af565b95505b6f8204055aaef1c8bd5c3259f4822735a28610610f9e57610f70600160791b856122c3565b93506f8204055aaef1c8bd5c3259f4822735a2610f916001607f1b886122d6565b610f9b91906122af565b95505b6f810100ab00222d861931c15e39b44e998610610ff157610fc3600160781b856122c3565b93506f810100ab00222d861931c15e39b44e99610fe46001607f1b886122d6565b610fee91906122af565b95505b6f808040155aabbbe9451521693554f733861061104457611016600160771b856122c3565b93506f808040155aabbbe9451521693554f7336110376001607f1b886122d6565b61104191906122af565b95505b6110526001607f1b87612286565b92508291506001607f1b61106683806122d6565b61107091906122af565b9050600160801b6110818482612286565b61108b90846122d6565b61109591906122af565b61109f90856122c3565b93506001607f1b6110b082846122d6565b6110ba91906122af565b9150600160811b6110db846faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa612286565b6110e590846122d6565b6110ef91906122af565b6110f990856122c3565b93506001607f1b61110a82846122d6565b61111491906122af565b9150600360801b611135846f99999999999999999999999999999999612286565b61113f90846122d6565b61114991906122af565b61115390856122c3565b93506001607f1b61116482846122d6565b61116e91906122af565b9150600160821b61118f846f92492492492492492492492492492492612286565b61119990846122d6565b6111a391906122af565b6111ad90856122c3565b93506001607f1b6111be82846122d6565b6111c891906122af565b9150600560801b6111e9846f8e38e38e38e38e38e38e38e38e38e38e612286565b6111f390846122d6565b6111fd91906122af565b61120790856122c3565b93506001607f1b61121882846122d6565b61122291906122af565b9150600360811b611243846f8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b612286565b61124d90846122d6565b61125791906122af565b61126190856122c3565b93506001607f1b61127282846122d6565b61127c91906122af565b9150600760801b61129d846f89d89d89d89d89d89d89d89d89d89d89612286565b6112a790846122d6565b6112b191906122af565b6112bb90856122c3565b93506001607f1b6112cc82846122d6565b6112d691906122af565b9150600160831b6112f7846f88888888888888888888888888888888612286565b61130190846122d6565b61130b91906122af565b61131590856122c3565b9695505050505050565b600080600160801b83106113635760006113456113406001607f1b866122af565b612159565b60ff811694851c9490915061135f906001607f1b906122d6565b9150505b6001607f1b8311156113d857607f5b60ff8116156113d6576001607f1b61138a85806122d6565b61139491906122af565b9350600160801b84106113c657600193841c936113b190826122ed565b60ff166001901b826113c391906122c3565b91505b6113cf8161231c565b9050611372565b505b6f05b9de1d10bf4103d647b0955897ba806114036f03f80fe03f80fe03f80fe03f80fe03f8836122d6565b61140d91906122af565b9392505050565b60008080806114276001607c1b86612339565b91508190506001607f1b61143b82806122d6565b61144591906122af565b9050611459816710e1b3be415a00006122d6565b61146390846122c3565b92506001607f1b61147483836122d6565b61147e91906122af565b9050611492816705a0913f6b1e00006122d6565b61149c90846122c3565b92506001607f1b6114ad83836122d6565b6114b791906122af565b90506114cb81670168244fdac780006122d6565b6114d590846122c3565b92506001607f1b6114e683836122d6565b6114f091906122af565b905061150381664807432bc180006122d6565b61150d90846122c3565b92506001607f1b61151e83836122d6565b61152891906122af565b905061153b81660c0135dca040006122d6565b61154590846122c3565b92506001607f1b61155683836122d6565b61156091906122af565b9050611573816601b707b1cdc0006122d6565b61157d90846122c3565b92506001607f1b61158e83836122d6565b61159891906122af565b90506115aa816536e0f639b8006122d6565b6115b490846122c3565b92506001607f1b6115c583836122d6565b6115cf91906122af565b90506115e181650618fee9f8006122d6565b6115eb90846122c3565b92506001607f1b6115fc83836122d6565b61160691906122af565b905061161781649c197dcc006122d6565b61162190846122c3565b92506001607f1b61163283836122d6565b61163c91906122af565b905061164d81640e30dce4006122d6565b61165790846122c3565b92506001607f1b61166883836122d6565b61167291906122af565b90506116838164012ebd13006122d6565b61168d90846122c3565b92506001607f1b61169e83836122d6565b6116a891906122af565b90506116b8816317499f006122d6565b6116c290846122c3565b92506001607f1b6116d383836122d6565b6116dd91906122af565b90506116ed816301a9d4806122d6565b6116f790846122c3565b92506001607f1b61170883836122d6565b61171291906122af565b905061172181621c63806122d6565b61172b90846122c3565b92506001607f1b61173c83836122d6565b61174691906122af565b9050611755816201c6386122d6565b61175f90846122c3565b92506001607f1b61177083836122d6565b61177a91906122af565b905061178881611ab86122d6565b61179290846122c3565b92506001607f1b6117a383836122d6565b6117ad91906122af565b90506117bb8161017c6122d6565b6117c590846122c3565b92506001607f1b6117d683836122d6565b6117e091906122af565b90506117ed8160146122d6565b6117f790846122c3565b92506001607f1b61180883836122d6565b61181291906122af565b905061181f8160016122d6565b61182990846122c3565b92506001607f1b826118436721c3677c82b40000866122af565b61184d91906122c3565b61185791906122c3565b92506001607c1b85161561189f5770018ebef9eac820ae8682b9793ac6d1e776611892847001c3d6a24ed82218787d624d3e5eba95f96122d6565b61189c91906122af565b92505b6001607d1b8516156118e5577001368b2fc6f9609fe7aceb46aa619baed46118d88470018ebef9eac820ae8682b9793ac6d1e7786122d6565b6118e291906122af565b92505b6001607e1b85161561192a576fbc5ab1b16779be3575bd8f0520a9f21f61191d847001368b2fc6f9609fe7aceb46aa619baed56122d6565b61192791906122af565b92505b6001607f1b85161561196e576f454aaa8efe072e7f6ddbab84b40a55c9611961846fbc5ab1b16779be3575bd8f0520a9f21e6122d6565b61196b91906122af565b92505b600160801b8516156119b2576f0960aadc109e7a3bf4578099615711ea6119a5846f454aaa8efe072e7f6ddbab84b40a55c56122d6565b6119af91906122af565b92505b600160811b8516156119f5576e2bf84208204f5977f9a8cf01fdce3d6119e8846f0960aadc109e7a3bf4578099615711d76122d6565b6119f291906122af565b92505b600160821b851615611a36576d03c6ab775dd0b95b4cbee7e65d11611a29846e2bf84208204f5977f9a8cf01fdc3076122d6565b611a3391906122af565b92505b50909392505050565b60006020607f5b60ff8116611a5583600161234d565b60ff161015611aa85760006002611a6c838561234d565b611a769190612366565b90508460008260ff1660808110611a8f57611a8f612306565b015410611a9e57809250611aa2565b8091505b50611a46565b8360008260ff1660808110611abf57611abf612306565b015410611acd579392505050565b8360008360ff1660808110611ae457611ae4612306565b01541061004c575092915050565b6000828160ff8416611b0483806122d6565b901c9150611b22826f03442c4e6074a82f1797f72ac00000006122d6565b611b2c90826122c3565b905060ff8416611b3c86846122d6565b901c9150611b5a826f0116b96f757c380fb287fd0e400000006122d6565b611b6490826122c3565b905060ff8416611b7486846122d6565b901c9150611b91826e45ae5bdd5f0e03eca1ff43900000006122d6565b611b9b90826122c3565b905060ff8416611bab86846122d6565b901c9150611bc8826e0defabf91302cd95b9ffda500000006122d6565b611bd290826122c3565b905060ff8416611be286846122d6565b901c9150611bff826e02529ca9832b22439efff9b80000006122d6565b611c0990826122c3565b905060ff8416611c1986846122d6565b901c9150611c35826d54f1cf12bd04e516b6da880000006122d6565b611c3f90826122c3565b905060ff8416611c4f86846122d6565b901c9150611c6b826d0a9e39e257a09ca2d6db510000006122d6565b611c7590826122c3565b905060ff8416611c8586846122d6565b901c9150611ca1826d012e066e7b839fa050c3090000006122d6565b611cab90826122c3565b905060ff8416611cbb86846122d6565b901c9150611cd6826c1e33d7d926c329a1ad1a8000006122d6565b611ce090826122c3565b905060ff8416611cf086846122d6565b901c9150611d0b826c02bee513bdb4a6b19b5f8000006122d6565b611d1590826122c3565b905060ff8416611d2586846122d6565b901c9150611d3f826b3a9316fa79b88eccf2a000006122d6565b611d4990826122c3565b905060ff8416611d5986846122d6565b901c9150611d73826b048177ebe1fa8123752000006122d6565b611d7d90826122c3565b905060ff8416611d8d86846122d6565b901c9150611da6826a5263fe90242dcbacf000006122d6565b611db090826122c3565b905060ff8416611dc086846122d6565b901c9150611dd9826a057e22099c030d941000006122d6565b611de390826122c3565b905060ff8416611df386846122d6565b901c9150611e0b826957e22099c030d94100006122d6565b611e1590826122c3565b905060ff8416611e2586846122d6565b901c9150611e3d8269052b6b545699763100006122d6565b611e4790826122c3565b905060ff8416611e5786846122d6565b901c9150611e6e82684985f67696bf7480006122d6565b611e7890826122c3565b905060ff8416611e8886846122d6565b901c9150611e9f826803dea12ea99e4980006122d6565b611ea990826122c3565b905060ff8416611eb986846122d6565b901c9150611ecf826731880f2214b6e0006122d6565b611ed990826122c3565b905060ff8416611ee986846122d6565b901c9150611eff8267025bcff56eb360006122d6565b611f0990826122c3565b905060ff8416611f1986846122d6565b901c9150611f2e82661b722e10ab10006122d6565b611f3890826122c3565b905060ff8416611f4886846122d6565b901c9150611f5d826601317c700770006122d6565b611f6790826122c3565b905060ff8416611f7786846122d6565b901c9150611f8b82650cba84aafa006122d6565b611f9590826122c3565b905060ff8416611fa586846122d6565b901c9150611fb8826482573a0a006122d6565b611fc290826122c3565b905060ff8416611fd286846122d6565b901c9150611fe5826405035ad9006122d6565b611fef90826122c3565b905060ff8416611fff86846122d6565b901c915061201182632f881b006122d6565b61201b90826122c3565b905060ff841661202b86846122d6565b901c915061203d826301b293406122d6565b61204790826122c3565b905060ff841661205786846122d6565b901c915061206882620efc406122d6565b61207290826122c3565b905060ff841661208286846122d6565b901c915061209282617fe06122d6565b61209c90826122c3565b905060ff84166120ac86846122d6565b901c91506120bc826104206122d6565b6120c690826122c3565b905060ff84166120d686846122d6565b901c91506120e58260216122d6565b6120ef90826122c3565b905060ff84166120ff86846122d6565b901c915061210e8260016122d6565b61211890826122c3565b9050600160ff85161b8561213c6f0688589cc0e9505e2f2fee5580000000846122af565b61214691906122c3565b61215091906122c3565b95945050505050565b60008061010083101561218c575b600183111561218757600192831c92612180908261234d565b9050612167565b610ca7565b60805b60ff8116156121be57600160ff82161b84106121b35760ff81169390931c92908117905b60011c607f1661218f565b5092915050565b600080600080608085870312156121db57600080fd5b8435935060208501359250604085013563ffffffff811681146121fd57600080fd5b9396929550929360600135925050565b6020808252601290820152714552525f494e56414c49445f535550504c5960701b604082015260600190565b6020808252601b908201527f4552525f494e56414c49445f524553455256455f42414c414e43450000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ca757610ca7612270565b634e487b7160e01b600052601260045260246000fd5b6000826122be576122be612299565b500490565b80820180821115610ca757610ca7612270565b8082028115828204841417610ca757610ca7612270565b60ff8281168282160390811115610ca757610ca7612270565b634e487b7160e01b600052603260045260246000fd5b600060ff82168061232f5761232f612270565b6000190192915050565b60008261234857612348612299565b500690565b60ff8181168382160190811115610ca757610ca7612270565b600060ff83168061237957612379612299565b8060ff8416049150509291505056fea26469706673582212206932604338533472b147269d641806aebbe0d0d44642e42e9f1a037ab0a6a83364736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80635f28fdfc1461005157806376cf0b5614610076578063e1c7392a14610089578063f3250fe214610093575b600080fd5b61006461005f3660046121c5565b6100a6565b60405190815260200160405180910390f35b6100646100843660046121c5565b61020c565b61009161039d565b005b6100646100a13660046121c5565b610b74565b60008085116100d05760405162461bcd60e51b81526004016100c79061220d565b60405180910390fd5b600084116100f05760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff1611801561010f5750620f424063ffffffff841611155b61015b5760405162461bcd60e51b815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f524154494f0000000000000060448201526064016100c7565b8160000361016b57506000610204565b620f423f1963ffffffff8416016101af578460016101898487610c98565b6101939190612286565b61019d91906122af565b6101a89060016122c3565b9050610204565b600080806101bd8886610cad565b90506101ce8189620f424089610cb9565b9093509150600060ff831660016101e58a87610c98565b6101ef9190612286565b901c90506101fd8882612286565b9450505050505b949350505050565b600080851161022d5760405162461bcd60e51b81526004016100c79061220d565b6000841161024d5760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff1611801561026c5750620f424063ffffffff841611155b6102b85760405162461bcd60e51b815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f57454947485400000000000060448201526064016100c7565b848211156102fd5760405162461bcd60e51b815260206004820152601260248201527111549497d253959053125117d05353d5539560721b60448201526064016100c7565b8160000361030d57506000610204565b84820361031b575082610204565b620f423f1963ffffffff84160161034157846103378584610c98565b6101a891906122af565b6000808061034f8589612286565b90506103608882620f424089610cb9565b909350915060006103718885610c98565b905060ff831688901b846103858284612286565b61038f91906122af565b9a9950505050505050505050565b610b72701c35fedd14ffffffffffffffffffffffff602055701b0ce43b323fffffffffffffffffffffff6021557019f0028ec1ffffffffffffffffffffffff6022557018ded91f0e7fffffffffffffffffffffff6023557017d8ec7f0417ffffffffffffffffffffff6024557016ddc6556cdbffffffffffffffffffffff6025557015ecf52776a1ffffffffffffffffffffff6026557015060c256cb2ffffffffffffffffffffff602755701428a2f98d72ffffffffffffffffffffff6028557013545598e5c23fffffffffffffffffffff602955701288c4161ce1dfffffffffffffffffffff602a557011c592761c666fffffffffffffffffffff602b5570110a688680a757ffffffffffffffffffff602c55701056f1b5bedf77ffffffffffffffffffff602d55700faadceceeff8bffffffffffffffffffff602e55700f05dc6b27edadffffffffffffffffffff602f55700e67a5a25da4107fffffffffffffffffff603055700dcff115b14eedffffffffffffffffffff603155700d3e7a392431239fffffffffffffffffff603255700cb2ff529eb71e4fffffffffffffffffff603355700c2d415c3db974afffffffffffffffffff603455700bad03e7d883f69bffffffffffffffffff603555700b320d03b2c343d5ffffffffffffffffff603655700abc25204e02828dffffffffffffffffff603755700a4b16f74ee4bb207fffffffffffffffff6038557009deaf736ac1f569ffffffffffffffffff603955700976bd9952c7aa957fffffffffffffffff603a557009131271922eaa606fffffffffffffffff603b557008b380f3558668c46fffffffffffffffff603c55700857ddf0117efa215bffffffffffffffff603d557007ffffffffffffffffffffffffffffffff603e557007abbf6f6abb9d087fffffffffffffffff603f5570075af62cbac95f7dfa7fffffffffffffff60405570070d7fb7452e187ac13fffffffffffffff6041557006c3390ecc8af379295fffffffffffffff60425570067c00a3b07ffc01fd6fffffffffffffff604355700637b647c39cbb9d3d27ffffffffffffff6044557005f63b1fc104dbd39587ffffffffffffff6045557005b771955b36e12f7235ffffffffffffff60465570057b3d49dda84556d6f6ffffffffffffff60475570054183095b2c8ececf30ffffffffffffff60485570050a28be635ca2b888f77fffffffffffff6049557004d5156639708c9db33c3fffffffffffff604a557004a23105873875bd52dfdfffffffffffff604b55700471649d87199aa990756fffffffffffff604c557004429a21a029d4c1457cfbffffffffffff604d55700415bc6d6fb7dd71af2cb3ffffffffffff604e557003eab73b3bbfe282243ce1ffffffffffff604f557003c1771ac9fb6b4c18e229ffffffffffff605055700399e96897690418f785257fffffffffff605155700373fc456c53bb779bf0ea9fffffffffff60525570034f9e8e490c48e67e6ab8bfffffffffff60535570032cbfd4a7adc790560b3337ffffffffff60545570030b50570f6e5d2acca94613ffffffffff6055557002eb40f9f620fda6b56c2861ffffffffff6056557002cc8340ecb0d0f520a6af58ffffffffff6057557002af09481380a0a35cf1ba02ffffffffff605855700292c5bdd3b92ec810287b1b3fffffffff605955700277abdcdab07d5a77ac6d6b9fffffffff605a5570025daf6654b1eaa55fd64df5efffffffff605b55700244c49c648baa98192dce88b7ffffffff605c5570022ce03cd5619a311b2471268bffffffff605d55700215f77c045fbe885654a44a0fffffffff605e557001ffffffffffffffffffffffffffffffff605f557001eaefdbdaaee7421fc4d3ede5ffffffff6060557001d6bd8b2eb257df7e8ca57b09bfffffff6061557001c35fedd14b861eb0443f7f133fffffff6062557001b0ce43b322bcde4a56e8ada5afffffff60635570019f0028ec1fff007f5a195a39dfffffff60645570018ded91f0e72ee74f49b15ba527ffffff60655570017d8ec7f04136f4e5615fd41a63ffffff60665570016ddc6556cdb84bdc8d12d22e6fffffff60675570015ecf52776a1155b5bd8395814f7fffff60685570015060c256cb23b3b3cc3754cf40ffffff6069557001428a2f98d728ae223ddab715be3fffff606a5570013545598e5c23276ccf0ede68034fffff606b557001288c4161ce1d6f54b7f61081194fffff606c5570011c592761c666aa641d5a01a40f17ffff606d55700110a688680a7530515f3e6e6cfdcdffff606e557001056f1b5bedf75c6bcb2ce8aed428ffff606f556ffaadceceeff8a0890f3875f008277fff6070556ff05dc6b27edad306388a600f6ba0bfff6071556fe67a5a25da41063de1495d5b18cdbfff6072556fdcff115b14eedde6fc3aa5353f2e4fff6073556fd3e7a3924312399f9aae2e0f868f8fff6074556fcb2ff529eb71e41582cccd5a1ee26fff6075556fc2d415c3db974ab32a51840c0b67edff6076556fbad03e7d883f69ad5b0a186184e06bff6077556fb320d03b2c343d4829abd6075f0cc5ff6078556fabc25204e02828d73c6e80bcdb1a95bf6079556fa4b16f74ee4bb2040a1ec6c15fbbf2df607a556f9deaf736ac1f569deb1b5ae3f36c130f607b556f976bd9952c7aa957f5937d790ef65037607c556f9131271922eaa6064b73a22d0bd4f2bf607d556f8b380f3558668c46c91c49a2f8e967b9607e556f857ddf0117efa215952912839f6473e6607f55565b565b6000808511610b955760405162461bcd60e51b81526004016100c79061220d565b60008411610bb55760405162461bcd60e51b81526004016100c790612239565b60008363ffffffff16118015610bd45750620f424063ffffffff841611155b610c205760405162461bcd60e51b815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f57454947485400000000000060448201526064016100c7565b81600003610c3057506000610204565b620f423f1963ffffffff841601610c4c57836103378684610c98565b60008080610c5a8588610cad565b9050610c6b818888620f4240610cb9565b9093509150600060ff8316610c808a86610c98565b610c8c911c60016122c3565b90506101fd8982612286565b6000610ca482846122d6565b90505b92915050565b6000610ca482846122c3565b600080600160811b8610610ccc57600080fd5b60008086610cde6001607f1b8a6122d6565b610ce891906122af565b905070015bf0a8b1457695355fb8ac404e7a79e3811015610d1357610d0c81610da6565b9150610d1f565b610d1c8161131f565b91505b60008563ffffffff168763ffffffff1684610d3a91906122d6565b610d4491906122af565b9050600160831b811015610d6957610d5b81611414565b607f94509450505050610d9d565b6000610d7482611a3f565b9050610d90610d8482607f6122ed565b60ff1683901c82611af2565b95509350610d9d92505050565b94509492505050565b6000808080806fd3094c70f034de4b96ff7d5b6f99fcd88610610dff57610dd16001607e1b856122c3565b93506fd3094c70f034de4b96ff7d5b6f99fcd8610df26001607f1b886122d6565b610dfc91906122af565b95505b6fa45af1e1f40c333b3de1db4dd55f29a78610610e5257610e246001607d1b856122c3565b93506fa45af1e1f40c333b3de1db4dd55f29a7610e456001607f1b886122d6565b610e4f91906122af565b95505b6f910b022db7ae67ce76b441c27035c6a18610610ea557610e776001607c1b856122c3565b93506f910b022db7ae67ce76b441c27035c6a1610e986001607f1b886122d6565b610ea291906122af565b95505b6f88415abbe9a76bead8d00cf112e4d4a88610610ef857610eca6001607b1b856122c3565b93506f88415abbe9a76bead8d00cf112e4d4a8610eeb6001607f1b886122d6565b610ef591906122af565b95505b6f84102b00893f64c705e841d5d4064bd38610610f4b57610f1d6001607a1b856122c3565b93506f84102b00893f64c705e841d5d4064bd3610f3e6001607f1b886122d6565b610f4891906122af565b95505b6f8204055aaef1c8bd5c3259f4822735a28610610f9e57610f70600160791b856122c3565b93506f8204055aaef1c8bd5c3259f4822735a2610f916001607f1b886122d6565b610f9b91906122af565b95505b6f810100ab00222d861931c15e39b44e998610610ff157610fc3600160781b856122c3565b93506f810100ab00222d861931c15e39b44e99610fe46001607f1b886122d6565b610fee91906122af565b95505b6f808040155aabbbe9451521693554f733861061104457611016600160771b856122c3565b93506f808040155aabbbe9451521693554f7336110376001607f1b886122d6565b61104191906122af565b95505b6110526001607f1b87612286565b92508291506001607f1b61106683806122d6565b61107091906122af565b9050600160801b6110818482612286565b61108b90846122d6565b61109591906122af565b61109f90856122c3565b93506001607f1b6110b082846122d6565b6110ba91906122af565b9150600160811b6110db846faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa612286565b6110e590846122d6565b6110ef91906122af565b6110f990856122c3565b93506001607f1b61110a82846122d6565b61111491906122af565b9150600360801b611135846f99999999999999999999999999999999612286565b61113f90846122d6565b61114991906122af565b61115390856122c3565b93506001607f1b61116482846122d6565b61116e91906122af565b9150600160821b61118f846f92492492492492492492492492492492612286565b61119990846122d6565b6111a391906122af565b6111ad90856122c3565b93506001607f1b6111be82846122d6565b6111c891906122af565b9150600560801b6111e9846f8e38e38e38e38e38e38e38e38e38e38e612286565b6111f390846122d6565b6111fd91906122af565b61120790856122c3565b93506001607f1b61121882846122d6565b61122291906122af565b9150600360811b611243846f8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b612286565b61124d90846122d6565b61125791906122af565b61126190856122c3565b93506001607f1b61127282846122d6565b61127c91906122af565b9150600760801b61129d846f89d89d89d89d89d89d89d89d89d89d89612286565b6112a790846122d6565b6112b191906122af565b6112bb90856122c3565b93506001607f1b6112cc82846122d6565b6112d691906122af565b9150600160831b6112f7846f88888888888888888888888888888888612286565b61130190846122d6565b61130b91906122af565b61131590856122c3565b9695505050505050565b600080600160801b83106113635760006113456113406001607f1b866122af565b612159565b60ff811694851c9490915061135f906001607f1b906122d6565b9150505b6001607f1b8311156113d857607f5b60ff8116156113d6576001607f1b61138a85806122d6565b61139491906122af565b9350600160801b84106113c657600193841c936113b190826122ed565b60ff166001901b826113c391906122c3565b91505b6113cf8161231c565b9050611372565b505b6f05b9de1d10bf4103d647b0955897ba806114036f03f80fe03f80fe03f80fe03f80fe03f8836122d6565b61140d91906122af565b9392505050565b60008080806114276001607c1b86612339565b91508190506001607f1b61143b82806122d6565b61144591906122af565b9050611459816710e1b3be415a00006122d6565b61146390846122c3565b92506001607f1b61147483836122d6565b61147e91906122af565b9050611492816705a0913f6b1e00006122d6565b61149c90846122c3565b92506001607f1b6114ad83836122d6565b6114b791906122af565b90506114cb81670168244fdac780006122d6565b6114d590846122c3565b92506001607f1b6114e683836122d6565b6114f091906122af565b905061150381664807432bc180006122d6565b61150d90846122c3565b92506001607f1b61151e83836122d6565b61152891906122af565b905061153b81660c0135dca040006122d6565b61154590846122c3565b92506001607f1b61155683836122d6565b61156091906122af565b9050611573816601b707b1cdc0006122d6565b61157d90846122c3565b92506001607f1b61158e83836122d6565b61159891906122af565b90506115aa816536e0f639b8006122d6565b6115b490846122c3565b92506001607f1b6115c583836122d6565b6115cf91906122af565b90506115e181650618fee9f8006122d6565b6115eb90846122c3565b92506001607f1b6115fc83836122d6565b61160691906122af565b905061161781649c197dcc006122d6565b61162190846122c3565b92506001607f1b61163283836122d6565b61163c91906122af565b905061164d81640e30dce4006122d6565b61165790846122c3565b92506001607f1b61166883836122d6565b61167291906122af565b90506116838164012ebd13006122d6565b61168d90846122c3565b92506001607f1b61169e83836122d6565b6116a891906122af565b90506116b8816317499f006122d6565b6116c290846122c3565b92506001607f1b6116d383836122d6565b6116dd91906122af565b90506116ed816301a9d4806122d6565b6116f790846122c3565b92506001607f1b61170883836122d6565b61171291906122af565b905061172181621c63806122d6565b61172b90846122c3565b92506001607f1b61173c83836122d6565b61174691906122af565b9050611755816201c6386122d6565b61175f90846122c3565b92506001607f1b61177083836122d6565b61177a91906122af565b905061178881611ab86122d6565b61179290846122c3565b92506001607f1b6117a383836122d6565b6117ad91906122af565b90506117bb8161017c6122d6565b6117c590846122c3565b92506001607f1b6117d683836122d6565b6117e091906122af565b90506117ed8160146122d6565b6117f790846122c3565b92506001607f1b61180883836122d6565b61181291906122af565b905061181f8160016122d6565b61182990846122c3565b92506001607f1b826118436721c3677c82b40000866122af565b61184d91906122c3565b61185791906122c3565b92506001607c1b85161561189f5770018ebef9eac820ae8682b9793ac6d1e776611892847001c3d6a24ed82218787d624d3e5eba95f96122d6565b61189c91906122af565b92505b6001607d1b8516156118e5577001368b2fc6f9609fe7aceb46aa619baed46118d88470018ebef9eac820ae8682b9793ac6d1e7786122d6565b6118e291906122af565b92505b6001607e1b85161561192a576fbc5ab1b16779be3575bd8f0520a9f21f61191d847001368b2fc6f9609fe7aceb46aa619baed56122d6565b61192791906122af565b92505b6001607f1b85161561196e576f454aaa8efe072e7f6ddbab84b40a55c9611961846fbc5ab1b16779be3575bd8f0520a9f21e6122d6565b61196b91906122af565b92505b600160801b8516156119b2576f0960aadc109e7a3bf4578099615711ea6119a5846f454aaa8efe072e7f6ddbab84b40a55c56122d6565b6119af91906122af565b92505b600160811b8516156119f5576e2bf84208204f5977f9a8cf01fdce3d6119e8846f0960aadc109e7a3bf4578099615711d76122d6565b6119f291906122af565b92505b600160821b851615611a36576d03c6ab775dd0b95b4cbee7e65d11611a29846e2bf84208204f5977f9a8cf01fdc3076122d6565b611a3391906122af565b92505b50909392505050565b60006020607f5b60ff8116611a5583600161234d565b60ff161015611aa85760006002611a6c838561234d565b611a769190612366565b90508460008260ff1660808110611a8f57611a8f612306565b015410611a9e57809250611aa2565b8091505b50611a46565b8360008260ff1660808110611abf57611abf612306565b015410611acd579392505050565b8360008360ff1660808110611ae457611ae4612306565b01541061004c575092915050565b6000828160ff8416611b0483806122d6565b901c9150611b22826f03442c4e6074a82f1797f72ac00000006122d6565b611b2c90826122c3565b905060ff8416611b3c86846122d6565b901c9150611b5a826f0116b96f757c380fb287fd0e400000006122d6565b611b6490826122c3565b905060ff8416611b7486846122d6565b901c9150611b91826e45ae5bdd5f0e03eca1ff43900000006122d6565b611b9b90826122c3565b905060ff8416611bab86846122d6565b901c9150611bc8826e0defabf91302cd95b9ffda500000006122d6565b611bd290826122c3565b905060ff8416611be286846122d6565b901c9150611bff826e02529ca9832b22439efff9b80000006122d6565b611c0990826122c3565b905060ff8416611c1986846122d6565b901c9150611c35826d54f1cf12bd04e516b6da880000006122d6565b611c3f90826122c3565b905060ff8416611c4f86846122d6565b901c9150611c6b826d0a9e39e257a09ca2d6db510000006122d6565b611c7590826122c3565b905060ff8416611c8586846122d6565b901c9150611ca1826d012e066e7b839fa050c3090000006122d6565b611cab90826122c3565b905060ff8416611cbb86846122d6565b901c9150611cd6826c1e33d7d926c329a1ad1a8000006122d6565b611ce090826122c3565b905060ff8416611cf086846122d6565b901c9150611d0b826c02bee513bdb4a6b19b5f8000006122d6565b611d1590826122c3565b905060ff8416611d2586846122d6565b901c9150611d3f826b3a9316fa79b88eccf2a000006122d6565b611d4990826122c3565b905060ff8416611d5986846122d6565b901c9150611d73826b048177ebe1fa8123752000006122d6565b611d7d90826122c3565b905060ff8416611d8d86846122d6565b901c9150611da6826a5263fe90242dcbacf000006122d6565b611db090826122c3565b905060ff8416611dc086846122d6565b901c9150611dd9826a057e22099c030d941000006122d6565b611de390826122c3565b905060ff8416611df386846122d6565b901c9150611e0b826957e22099c030d94100006122d6565b611e1590826122c3565b905060ff8416611e2586846122d6565b901c9150611e3d8269052b6b545699763100006122d6565b611e4790826122c3565b905060ff8416611e5786846122d6565b901c9150611e6e82684985f67696bf7480006122d6565b611e7890826122c3565b905060ff8416611e8886846122d6565b901c9150611e9f826803dea12ea99e4980006122d6565b611ea990826122c3565b905060ff8416611eb986846122d6565b901c9150611ecf826731880f2214b6e0006122d6565b611ed990826122c3565b905060ff8416611ee986846122d6565b901c9150611eff8267025bcff56eb360006122d6565b611f0990826122c3565b905060ff8416611f1986846122d6565b901c9150611f2e82661b722e10ab10006122d6565b611f3890826122c3565b905060ff8416611f4886846122d6565b901c9150611f5d826601317c700770006122d6565b611f6790826122c3565b905060ff8416611f7786846122d6565b901c9150611f8b82650cba84aafa006122d6565b611f9590826122c3565b905060ff8416611fa586846122d6565b901c9150611fb8826482573a0a006122d6565b611fc290826122c3565b905060ff8416611fd286846122d6565b901c9150611fe5826405035ad9006122d6565b611fef90826122c3565b905060ff8416611fff86846122d6565b901c915061201182632f881b006122d6565b61201b90826122c3565b905060ff841661202b86846122d6565b901c915061203d826301b293406122d6565b61204790826122c3565b905060ff841661205786846122d6565b901c915061206882620efc406122d6565b61207290826122c3565b905060ff841661208286846122d6565b901c915061209282617fe06122d6565b61209c90826122c3565b905060ff84166120ac86846122d6565b901c91506120bc826104206122d6565b6120c690826122c3565b905060ff84166120d686846122d6565b901c91506120e58260216122d6565b6120ef90826122c3565b905060ff84166120ff86846122d6565b901c915061210e8260016122d6565b61211890826122c3565b9050600160ff85161b8561213c6f0688589cc0e9505e2f2fee5580000000846122af565b61214691906122c3565b61215091906122c3565b95945050505050565b60008061010083101561218c575b600183111561218757600192831c92612180908261234d565b9050612167565b610ca7565b60805b60ff8116156121be57600160ff82161b84106121b35760ff81169390931c92908117905b60011c607f1661218f565b5092915050565b600080600080608085870312156121db57600080fd5b8435935060208501359250604085013563ffffffff811681146121fd57600080fd5b9396929550929360600135925050565b6020808252601290820152714552525f494e56414c49445f535550504c5960701b604082015260600190565b6020808252601b908201527f4552525f494e56414c49445f524553455256455f42414c414e43450000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ca757610ca7612270565b634e487b7160e01b600052601260045260246000fd5b6000826122be576122be612299565b500490565b80820180821115610ca757610ca7612270565b8082028115828204841417610ca757610ca7612270565b60ff8281168282160390811115610ca757610ca7612270565b634e487b7160e01b600052603260045260246000fd5b600060ff82168061232f5761232f612270565b6000190192915050565b60008261234857612348612299565b500690565b60ff8181168382160190811115610ca757610ca7612270565b600060ff83168061237957612379612299565b8060ff8416049150509291505056fea26469706673582212206932604338533472b147269d641806aebbe0d0d44642e42e9f1a037ab0a6a83364736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.