Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 212 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 13865231 | 1052 days ago | IN | 0.001 ETH | 0.00477469 | ||||
Transfer | 13491662 | 1111 days ago | IN | 0.05 ETH | 0.00483745 | ||||
Transfer | 13485421 | 1112 days ago | IN | 0.001 ETH | 0.00360841 | ||||
Transfer | 13385027 | 1127 days ago | IN | 0.001 ETH | 0.0043887 | ||||
Transfer | 13247317 | 1149 days ago | IN | 0.01 ETH | 0.0019263 | ||||
Transfer | 13237017 | 1150 days ago | IN | 0.0002 ETH | 0.00349196 | ||||
Transfer | 13230855 | 1151 days ago | IN | 0.001 ETH | 0.00456673 | ||||
Transfer | 13230306 | 1152 days ago | IN | 0.2 ETH | 0.00219362 | ||||
Transfer | 13230210 | 1152 days ago | IN | 0.001 ETH | 0.0027159 | ||||
Transfer | 13229942 | 1152 days ago | IN | 0.01 ETH | 0.00271965 | ||||
Transfer | 13209885 | 1155 days ago | IN | 0.01 ETH | 0.0036198 | ||||
Transfer | 13074345 | 1176 days ago | IN | 0.005 ETH | 0.00128694 | ||||
Transfer | 12869459 | 1208 days ago | IN | 0.001 ETH | 0.00059395 | ||||
Transfer | 12765143 | 1224 days ago | IN | 0.001 ETH | 0.00053996 | ||||
Transfer | 12747221 | 1227 days ago | IN | 0.002 ETH | 0.00059414 | ||||
Transfer | 12747206 | 1227 days ago | IN | 0.002 ETH | 0.00054013 | ||||
Transfer | 12747184 | 1227 days ago | IN | 0.002 ETH | 0.00054013 | ||||
Transfer | 12747174 | 1227 days ago | IN | 0.0024 ETH | 0.00054027 | ||||
Transfer | 12747161 | 1227 days ago | IN | 0.0025 ETH | 0.00054027 | ||||
Transfer | 12747139 | 1227 days ago | IN | 0.0025 ETH | 0.00054027 | ||||
Transfer | 12747112 | 1227 days ago | IN | 0.01 ETH | 0.00064832 | ||||
Transfer | 12730108 | 1229 days ago | IN | 0.0234 ETH | 0.00140514 | ||||
Transfer | 12721099 | 1231 days ago | IN | 0.06 ETH | 0.00059463 | ||||
Transfer | 12693890 | 1235 days ago | IN | 0.002 ETH | 0.00054013 | ||||
Transfer | 12685960 | 1236 days ago | IN | 0.001 ETH | 0.00086393 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13865231 | 1052 days ago | 0.001 ETH | ||||
13794942 | 1063 days ago | 0.00685251 ETH | ||||
13794942 | 1063 days ago | 0.00685251 ETH | ||||
13600515 | 1094 days ago | 0.04287854 ETH | ||||
13600515 | 1094 days ago | 0.04287854 ETH | ||||
13491662 | 1111 days ago | 0.05 ETH | ||||
13485421 | 1112 days ago | 0.001 ETH | ||||
13385027 | 1127 days ago | 0.001 ETH | ||||
13247317 | 1149 days ago | 0.01 ETH | ||||
13237017 | 1150 days ago | 0.0002 ETH | ||||
13230855 | 1151 days ago | 0.001 ETH | ||||
13230306 | 1152 days ago | 0.2 ETH | ||||
13230210 | 1152 days ago | 0.001 ETH | ||||
13229942 | 1152 days ago | 0.01 ETH | ||||
13209885 | 1155 days ago | 0.01 ETH | ||||
13074345 | 1176 days ago | 0.005 ETH | ||||
12869459 | 1208 days ago | 0.001 ETH | ||||
12765143 | 1224 days ago | 0.001 ETH | ||||
12747221 | 1227 days ago | 0.002 ETH | ||||
12747206 | 1227 days ago | 0.002 ETH | ||||
12747184 | 1227 days ago | 0.002 ETH | ||||
12747174 | 1227 days ago | 0.0024 ETH | ||||
12747161 | 1227 days ago | 0.0025 ETH | ||||
12747139 | 1227 days ago | 0.0025 ETH | ||||
12747112 | 1227 days ago | 0.01 ETH |
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x53E7daA8...BaDa17064 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
UnmanagedGrant
Compiler Version
v0.7.0+commit.9e61f92b
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-12-15 */ /** *Submitted for verification at Etherscan.io on 2020-12-03 */ // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol // SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: contracts/shared/libraries/abdk-libraries/ABDKMathQuad.sol /* * ABDK Math Quad Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.7.0; /** * Smart contract library of mathematical functions operating with IEEE 754 * quadruple-precision binary floating-point numbers (quadruple precision * numbers). As long as quadruple precision numbers are 16-bytes long, they are * represented by bytes16 type. */ library ABDKMathQuad { /* * 0. */ bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000; /* * -0. */ bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000; /* * +Infinity. */ bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000; /* * -Infinity. */ bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000; /* * Canonical NaN value. */ bytes16 private constant NaN = 0x7FFF8000000000000000000000000000; /** * Convert signed 256-bit integer number into quadruple precision number. * * @param x signed 256-bit integer number * @return quadruple precision number */ function fromInt (int256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 256-bit integer number * rounding towards zero. Revert on overflow. * * @param x quadruple precision number * @return signed 256-bit integer number */ function toInt (bytes16 x) internal pure returns (int256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16638); // Overflow if (exponent < 16383) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } /** * Convert unsigned 256-bit integer number into quadruple precision number. * * @param x unsigned 256-bit integer number * @return quadruple precision number */ function fromUInt (uint256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { uint256 result = x; uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into unsigned 256-bit integer number * rounding towards zero. Revert on underflow. Note, that negative floating * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer * without error, because they are rounded to zero. * * @param x quadruple precision number * @return unsigned 256-bit integer number */ function toUInt (bytes16 x) internal pure returns (uint256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; if (exponent < 16383) return 0; // Underflow require (uint128 (x) < 0x80000000000000000000000000000000); // Negative require (exponent <= 16638); // Overflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; return result; } /** * Convert signed 128.128 bit fixed point number into quadruple precision * number. * * @param x signed 128.128 bit fixed point number * @return quadruple precision number */ function from128x128 (int256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 128.128 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 128.128 bit fixed point number */ function to128x128 (bytes16 x) internal pure returns (int256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16510); // Overflow if (exponent < 16255) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16367) result >>= 16367 - exponent; else if (exponent > 16367) result <<= exponent - 16367; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } /** * Convert signed 64.64 bit fixed point number into quadruple precision * number. * * @param x signed 64.64 bit fixed point number * @return quadruple precision number */ function from64x64 (int128 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint128 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 64.64 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 64.64 bit fixed point number */ function to64x64 (bytes16 x) internal pure returns (int128) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16446); // Overflow if (exponent < 16319) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16431) result >>= 16431 - exponent; else if (exponent > 16431) result <<= exponent - 16431; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x80000000000000000000000000000000); return -int128 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (result); } } /** * Convert octuple precision number into quadruple precision number. * * @param x octuple precision number * @return quadruple precision number */ function fromOctuple (bytes32 x) internal pure returns (bytes16) { bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; uint256 exponent = uint256 (x) >> 236 & 0x7FFFF; uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFFF) { if (significand > 0) return NaN; else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } if (exponent > 278526) return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else if (exponent < 245649) return negative ? NEGATIVE_ZERO : POSITIVE_ZERO; else if (exponent < 245761) { significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent; exponent = 0; } else { significand >>= 124; exponent -= 245760; } uint128 result = uint128 (significand | exponent << 112); if (negative) result |= 0x80000000000000000000000000000000; return bytes16 (result); } /** * Convert quadruple precision number into octuple precision number. * * @param x quadruple precision number * @return octuple precision number */ function toOctuple (bytes16 x) internal pure returns (bytes32) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = msb (result); result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 245649 + msb; } } else { result <<= 124; exponent += 245760; } result |= exponent << 236; if (uint128 (x) >= 0x80000000000000000000000000000000) result |= 0x8000000000000000000000000000000000000000000000000000000000000000; return bytes32 (result); } /** * Convert double precision number into quadruple precision number. * * @param x double precision number * @return quadruple precision number */ function fromDouble (bytes8 x) internal pure returns (bytes16) { uint256 exponent = uint64 (x) >> 52 & 0x7FF; uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF; if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = msb (result); result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 15309 + msb; } } else { result <<= 60; exponent += 15360; } result |= exponent << 112; if (x & 0x8000000000000000 > 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } /** * Convert quadruple precision number into double precision number. * * @param x quadruple precision number * @return double precision number */ function toDouble (bytes16 x) internal pure returns (bytes8) { bool negative = uint128 (x) >= 0x80000000000000000000000000000000; uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { if (significand > 0) return 0x7FF8000000000000; // NaN else return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity } if (exponent > 17406) return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity else if (exponent < 15309) return negative ? bytes8 (0x8000000000000000) : // -0 bytes8 (0x0000000000000000); // 0 else if (exponent < 15361) { significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent; exponent = 0; } else { significand >>= 60; exponent -= 15360; } uint64 result = uint64 (significand | exponent << 52); if (negative) result |= 0x8000000000000000; return bytes8 (result); } /** * Test whether given quadruple precision number is NaN. * * @param x quadruple precision number * @return true if x is NaN, false otherwise */ function isNaN (bytes16 x) internal pure returns (bool) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0x7FFF0000000000000000000000000000; } /** * Test whether given quadruple precision number is positive or negative * infinity. * * @param x quadruple precision number * @return true if x is positive or negative infinity, false otherwise */ function isInfinity (bytes16 x) internal pure returns (bool) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x7FFF0000000000000000000000000000; } /** * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x * is positive. Note that sign (-0) is zero. Revert if x is NaN. * * @param x quadruple precision number * @return sign of x */ function sign (bytes16 x) internal pure returns (int8) { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN if (absoluteX == 0) return 0; else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1; else return 1; } /** * Calculate sign (x - y). Revert if either argument is NaN, or both * arguments are infinities of the same sign. * * @param x quadruple precision number * @param y quadruple precision number * @return sign (x - y) */ function cmp (bytes16 x, bytes16 y) internal pure returns (int8) { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN // Not infinities of the same sign require (x != y || absoluteX < 0x7FFF0000000000000000000000000000); if (x == y) return 0; else { bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000; bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000; if (negativeX) { if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1); else return -1; } else { if (negativeY) return 1; else return absoluteX > absoluteY ? int8 (1) : -1; } } } /** * Test whether x equals y. NaN, infinity, and -infinity are not equal to * anything. * * @param x quadruple precision number * @param y quadruple precision number * @return true if x equals to y, false otherwise */ function eq (bytes16 x, bytes16 y) internal pure returns (bool) { if (x == y) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF < 0x7FFF0000000000000000000000000000; } else return false; } /** * Calculate x + y. Special values behave in the following way: * * NaN + x = NaN for any x. * Infinity + x = Infinity for any finite x. * -Infinity + x = -Infinity for any finite x. * Infinity + Infinity = Infinity. * -Infinity + -Infinity = -Infinity. * Infinity + -Infinity = -Infinity + Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function add (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x; else return NaN; } else return x; } else if (yExponent == 0x7FFF) return y; else { bool xSign = uint128 (x) >= 0x80000000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; bool ySign = uint128 (y) >= 0x80000000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y; else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x; else { int256 delta = int256 (xExponent) - int256 (yExponent); if (xSign == ySign) { if (delta > 112) return x; else if (delta > 0) ySignifier >>= uint256 (delta); else if (delta < -112) return y; else if (delta < 0) { xSignifier >>= uint256 (-delta); xExponent = yExponent; } xSignifier += ySignifier; if (xSignifier >= 0x20000000000000000000000000000) { xSignifier >>= 1; xExponent += 1; } if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else { if (xSignifier < 0x10000000000000000000000000000) xExponent = 0; else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } else { if (delta > 0) { xSignifier <<= 1; xExponent -= 1; } else if (delta < 0) { ySignifier <<= 1; xExponent = yExponent - 1; } if (delta > 112) ySignifier = 1; else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1; else if (delta < -112) xSignifier = 1; else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1; if (xSignifier >= ySignifier) xSignifier -= ySignifier; else { xSignifier = ySignifier - xSignifier; xSign = ySign; } if (xSignifier == 0) return POSITIVE_ZERO; uint256 msb = msb (xSignifier); if (msb == 113) { xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent += 1; } else if (msb < 112) { uint256 shift = 112 - msb; if (xExponent > shift) { xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent -= shift; } else { xSignifier <<= xExponent - 1; xExponent = 0; } } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } } } /** * Calculate x - y. Special values behave in the following way: * * NaN - x = NaN for any x. * Infinity - x = Infinity for any finite x. * -Infinity - x = -Infinity for any finite x. * Infinity - -Infinity = Infinity. * -Infinity - Infinity = -Infinity. * Infinity - Infinity = -Infinity - -Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) { return add (x, y ^ 0x80000000000000000000000000000000); } /** * Calculate x * y. Special values behave in the following way: * * NaN * x = NaN for any x. * Infinity * x = Infinity for any finite positive x. * Infinity * x = -Infinity for any finite negative x. * -Infinity * x = -Infinity for any finite positive x. * -Infinity * x = Infinity for any finite negative x. * Infinity * 0 = NaN. * -Infinity * 0 = NaN. * Infinity * Infinity = Infinity. * Infinity * -Infinity = -Infinity. * -Infinity * Infinity = -Infinity. * -Infinity * -Infinity = Infinity. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x ^ y & 0x80000000000000000000000000000000; else if (x ^ y == 0x80000000000000000000000000000000) return x | y; else return NaN; } else { if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } } else if (yExponent == 0x7FFF) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return y ^ x & 0x80000000000000000000000000000000; } else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; xSignifier *= ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; xExponent += yExponent; uint256 msb = xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 : xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 : msb (xSignifier); if (xExponent + msb < 16496) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb < 16608) { // Subnormal if (xExponent < 16496) xSignifier >>= 16496 - xExponent; else if (xExponent > 16496) xSignifier <<= xExponent - 16496; xExponent = 0; } else if (xExponent + msb > 49373) { xExponent = 0x7FFF; xSignifier = 0; } else { if (msb > 112) xSignifier >>= msb - 112; else if (msb < 112) xSignifier <<= 112 - msb; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb - 16607; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } /** * Calculate x / y. Special values behave in the following way: * * NaN / x = NaN for any x. * x / NaN = NaN for any x. * Infinity / x = Infinity for any finite non-negative x. * Infinity / x = -Infinity for any finite negative x including -0. * -Infinity / x = -Infinity for any finite non-negative x. * -Infinity / x = Infinity for any finite negative x including -0. * x / Infinity = 0 for any finite non-negative x. * x / -Infinity = -0 for any finite non-negative x. * x / Infinity = -0 for any finite non-negative x including -0. * x / -Infinity = 0 for any finite non-negative x including -0. * * Infinity / Infinity = NaN. * Infinity / -Infinity = -NaN. * -Infinity / Infinity = -NaN. * -Infinity / -Infinity = NaN. * * Division by zero behaves in the following way: * * x / 0 = Infinity for any finite positive x. * x / -0 = -Infinity for any finite positive x. * x / 0 = -Infinity for any finite negative x. * x / -0 = Infinity for any finite negative x. * 0 / 0 = NaN. * 0 / -0 = NaN. * -0 / 0 = NaN. * -0 / -0 = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function div (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } else if (yExponent == 0x7FFF) { if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN; else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000; } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000; } else { uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) { if (xSignifier != 0) { uint shift = 226 - msb (xSignifier); xSignifier <<= shift; xExponent = 1; yExponent += shift - 114; } } else { xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114; } xSignifier = xSignifier / ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; assert (xSignifier >= 0x1000000000000000000000000000); uint256 msb = xSignifier >= 0x80000000000000000000000000000 ? msb (xSignifier) : xSignifier >= 0x40000000000000000000000000000 ? 114 : xSignifier >= 0x20000000000000000000000000000 ? 113 : 112; if (xExponent + msb > yExponent + 16497) { // Overflow xExponent = 0x7FFF; xSignifier = 0; } else if (xExponent + msb + 16380 < yExponent) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb + 16268 < yExponent) { // Subnormal if (xExponent + 16380 > yExponent) xSignifier <<= xExponent + 16380 - yExponent; else if (xExponent + 16380 < yExponent) xSignifier >>= yExponent - xExponent - 16380; xExponent = 0; } else { // Normal if (msb > 112) xSignifier >>= msb - 112; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb + 16269 - yExponent; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } /** * Calculate -x. * * @param x quadruple precision number * @return quadruple precision number */ function neg (bytes16 x) internal pure returns (bytes16) { return x ^ 0x80000000000000000000000000000000; } /** * Calculate |x|. * * @param x quadruple precision number * @return quadruple precision number */ function abs (bytes16 x) internal pure returns (bytes16) { return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } /** * Calculate square root of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function sqrt (bytes16 x) internal pure returns (bytes16) { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return POSITIVE_ZERO; bool oddExponent = xExponent & 0x1 == 0; xExponent = xExponent + 16383 >> 1; if (oddExponent) { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 113; else { uint256 msb = msb (xSignifier); uint256 shift = (226 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } else { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 112; else { uint256 msb = msb (xSignifier); uint256 shift = (225 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } uint256 r = 0x10000000000000000000000000000; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; // Seven iterations should be enough uint256 r1 = xSignifier / r; if (r1 < r) r = r1; return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } /** * Calculate binary logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function log_2 (bytes16 x) internal pure returns (bytes16) { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return NEGATIVE_INFINITY; bool resultNegative; uint256 resultExponent = 16495; uint256 resultSignifier; if (xExponent >= 0x3FFF) { resultNegative = false; resultSignifier = xExponent - 0x3FFF; xSignifier <<= 15; } else { resultNegative = true; if (xSignifier >= 0x10000000000000000000000000000) { resultSignifier = 0x3FFE - xExponent; xSignifier <<= 15; } else { uint256 msb = msb (xSignifier); resultSignifier = 16493 - msb; xSignifier <<= 127 - msb; } } if (xSignifier == 0x80000000000000000000000000000000) { if (resultNegative) resultSignifier += 1; uint256 shift = 112 - msb (resultSignifier); resultSignifier <<= shift; resultExponent -= shift; } else { uint256 bb = resultNegative ? 1 : 0; while (resultSignifier < 0x10000000000000000000000000000) { resultSignifier <<= 1; resultExponent -= 1; xSignifier *= xSignifier; uint256 b = xSignifier >> 255; resultSignifier += b ^ bb; xSignifier >>= 127 + b; } } return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) | resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } /** * Calculate natural logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function ln (bytes16 x) internal pure returns (bytes16) { return mul (log_2 (x), 0x3FFE62E42FEFA39EF35793C7673007E5); } /** * Calculate 2^x. * * @param x quadruple precision number * @return quadruple precision number */ function pow_2 (bytes16 x) internal pure returns (bytes16) { bool xNegative = uint128 (x) > 0x80000000000000000000000000000000; uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF && xSignifier != 0) return NaN; else if (xExponent > 16397) return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY; else if (xExponent < 16255) return 0x3FFF0000000000000000000000000000; else { if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xExponent > 16367) xSignifier <<= xExponent - 16367; else if (xExponent < 16367) xSignifier >>= 16367 - xExponent; if (xNegative && xSignifier > 0x406E00000000000000000000000000000000) return POSITIVE_ZERO; if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) return POSITIVE_INFINITY; uint256 resultExponent = xSignifier >> 128; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xNegative && xSignifier != 0) { xSignifier = ~xSignifier; resultExponent += 1; } uint256 resultSignifier = 0x80000000000000000000000000000000; if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128; if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128; if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128; if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128; if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128; if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128; if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128; if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128; if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128; if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128; if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128; if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128; if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128; if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128; if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128; if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128; if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128; if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128; if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128; if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128; if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128; if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128; if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128; if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128; if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128; if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128; if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128; if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128; if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128; if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128; if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128; if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128; if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128; if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128; if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128; if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128; if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128; if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128; if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128; if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128; if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128; if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128; if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128; if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128; if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128; if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128; if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128; if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128; if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128; if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128; if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128; if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128; if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128; if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128; if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128; if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128; if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128; if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128; if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128; if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128; if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128; if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128; if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128; if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128; if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128; if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128; if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128; if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128; if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128; if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128; if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128; if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128; if (!xNegative) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent += 0x3FFF; } else if (resultExponent <= 0x3FFE) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent = 0x3FFF - resultExponent; } else { resultSignifier = resultSignifier >> resultExponent - 16367; resultExponent = 0; } return bytes16 (uint128 (resultExponent << 112 | resultSignifier)); } } /** * Calculate e^x. * * @param x quadruple precision number * @return quadruple precision number */ function exp (bytes16 x) internal pure returns (bytes16) { return pow_2 (mul (x, 0x3FFF71547652B82FE1777D0FFDA0D23A)); } /** * Get index of the most significant non-zero bit in binary representation of * x. Reverts if x is zero. * * @return index of the most significant non-zero bit in binary representation * of x */ function msb (uint256 x) private pure returns (uint256) { require (x > 0); uint256 result = 0; if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; } if (x >= 0x10000000000000000) { x >>= 64; result += 64; } if (x >= 0x100000000) { x >>= 32; result += 32; } if (x >= 0x10000) { x >>= 16; result += 16; } if (x >= 0x100) { x >>= 8; result += 8; } if (x >= 0x10) { x >>= 4; result += 4; } if (x >= 0x4) { x >>= 2; result += 2; } if (x >= 0x2) result += 1; // No need to shift x anymore return result; } } // File: contracts/shared/libraries/Percentages.sol pragma solidity ^0.7.0; /** * @title Percentage Helpers for Grant Contracts. * @dev Used to offer pro-rata refunds and proportionate payment splitting among grantees * without loss of precision when handling tokens with large supply. * @author @NoahMarconi */ library Percentages { /** * @dev Calculate quad point percentage from two uint256 values. * @param numerator division numerator. * @param denominator division denominator. */ function percentage(uint256 numerator, uint256 denominator) internal pure returns (bytes16) { bytes16 num = ABDKMathQuad.fromUInt(numerator); bytes16 den = ABDKMathQuad.fromUInt(denominator); return ABDKMathQuad.div(num, den); } /** * @dev Multiply a quad point percentage by a uint256 value. * @param percent percent of total. * @param total total to get percent value from. */ function percentTimesTotal(bytes16 percent, uint256 total) internal pure returns (uint256) { bytes16 tot = ABDKMathQuad.fromUInt(total); bytes16 res = ABDKMathQuad.mul(tot, percent); return ABDKMathQuad.toUInt(res); } /** * @dev Determine the maxiumum allocation for a Donor or Grantee. * @param contribution their contribution to total. * @param totalPool total pool to derive percentage owed from. * @param remainingPool remaining pool to split between Donors or Grantees. */ function maxAllocation(uint256 contribution, uint256 totalPool, uint256 remainingPool) internal pure returns (uint256) { bytes16 contributionPercent = Percentages.percentage( contribution, totalPool ); uint256 contributionMaxAllocation = Percentages.percentTimesTotal( contributionPercent, remainingPool ); return contributionMaxAllocation; } } // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/shared/interfaces/IGrantee.sol pragma solidity ^0.7.0; /** * @title Grants Spec Abstract Contract. * @dev Grant request, funding, and management. * @author @NoahMarconi */ interface IGrantee { /*---------- Global Variable Getters ----------*/ /** * @dev Overall funding target for all grantees combined. */ function getCumulativeTargetFunding() external view returns(uint256); /** * @dev Grantee amounts are percentage based (if true) or fixed (if false). */ function getPercentageBased() external view returns(bool); /*---------- Shared Getters ----------*/ /** * @dev Get number of grantees. * @return number of grantees. */ function getGranteeReferenceLength() external view returns(uint256); /** * @dev Get grantee address by index. * @param index index of grantee to get. * @return grantee address. */ function getGranteeReference(uint256 index) external view returns(address); /** * @dev Get grantee target funding by address. * @param grantee address of grantee to set. * @return target funding. */ function getGranteeTargetFunding(address grantee) external view returns(uint256); /** * @dev Get grantee total amount paid by address. * @param grantee address of grantee to set. * @return total paid. */ function getGranteeTotalPaid(address grantee) external view returns(uint256); /** * @dev Get grantee payout approved paid by address. * @param grantee address of grantee to set. * @return payout approved. */ function getGranteePayoutApproved(address grantee) external view returns(uint256); } // File: contracts/shared/storage/Grantee.sol pragma solidity ^0.7.0; /** * @title Grantee State Management Contract. * @dev State, getters, and setters for Grantees. * @author @NoahMarconi @ameensol @JFickel @ArnaudBrousseau */ abstract contract Grantee is IGrantee { /*---------- Globals ----------*/ mapping(address => uint256) private granteeTargetFunding; // Funding amount targeted for Grantee. mapping(address => uint256) private granteeTotalPaid; // Cumulative funding received by Grantee. mapping(address => uint256) private granteePayoutApproved; // Pending payout approved by Manager. address[] private granteeReference; // Reference to grantee addresses to allow for iterating over grantees. uint256 private cumulativeTargetFunding; // Denominator for calculating grantee's percentage. bool private percentageBased = false; // Grantee amounts are percentage based (if true) or fixed (if false). /*---------- Global Variable Getters ----------*/ /** * @dev Overall funding target for all grantees combined. */ function getCumulativeTargetFunding() public view override returns(uint256) { return cumulativeTargetFunding; } /** * @dev Grantee amounts are percentage based (if true) or fixed (if false). */ function getPercentageBased() public view override returns(bool) { return percentageBased; } /*---------- Global Variable Setters ----------*/ /** * @dev Overall funding target for all grantees combined. * @param value cumulative target funding to set. */ function setPercentageBased(bool value) internal { percentageBased = value; } /** * @dev Set grantee targets as either fixed or percentage based. * @param value cumulative target funding to set. */ function setCumulativeTargetFunding(uint256 value) internal { cumulativeTargetFunding = value; } /*---------- Grantee Getters ----------*/ /** * @dev Get number of grantees. * @return number of grantees. */ function getGranteeReferenceLength() public override view returns(uint256) { return granteeReference.length; } /** * @dev Get grantee address by index. * @param index index of grantee to get. * @return grantee address. */ function getGranteeReference(uint256 index) public override view returns(address) { return granteeReference[index]; } /** * @dev Get grantee target funding by address. * @param grantee address of grantee to set. * @return target funding. */ function getGranteeTargetFunding(address grantee) public override view returns(uint256) { return granteeTargetFunding[grantee]; } /** * @dev Get grantee total amount paid by address. * @param grantee address of grantee to set. * @return total paid. */ function getGranteeTotalPaid(address grantee) public override view returns(uint256) { return granteeTotalPaid[grantee]; } /** * @dev Get grantee payout approved paid by address. * @param grantee address of grantee to set. * @return payout approved. */ function getGranteePayoutApproved(address grantee) public override view returns(uint256) { return granteePayoutApproved[grantee]; } /*---------- Grantee Setters ----------*/ /** * @dev Add grantee address to reference array. * @param grantee grantee address to add. */ function addGranteeReference(address grantee) internal { return granteeReference.push(grantee); } /** * @dev Set grantee target funding by address. * @param grantee address of grantee to set. * @param value target funding to set. */ function setGranteeTargetFunding(address grantee, uint256 value) internal { granteeTargetFunding[grantee] = value; } /** * @dev Set grantee total amount paid by address. * @param grantee address of grantee to set. * @param value total paid to set. */ function setGranteeTotalPaid(address grantee, uint256 value) internal { granteeTotalPaid[grantee] = value; } /** * @dev Set grantee payout approved paid by address. * @param grantee address of grantee to set. * @param value payout approved to set. */ function setGranteePayoutApproved(address grantee, uint256 value) internal { granteePayoutApproved[grantee] = value; } } // File: contracts/shared/modules/GranteeConstructor.sol pragma solidity ^0.7.0; contract GranteeConstructor is Grantee { using SafeMath for uint256; /*---------- Constructor ----------*/ /** * @dev Grant creation function. May be called by donors, grantees, or any other relevant party. * @param _grantees Sorted recipients of donated funds. * @param _amounts Respective allocations for each Grantee (must follow sort order of _grantees). * @param _percentageBased Grantee amounts are percentage based (if true) or fixed (if false). */ constructor( address[] memory _grantees, uint256[] memory _amounts, bool _percentageBased ) { require( _grantees.length > 0, "constructor::Invalid Argument. Must have one or more grantees." ); require( _grantees.length == _amounts.length, "constructor::Invalid Argument. _grantees.length must equal _amounts.length" ); // Initialize Grantees. address lastAddress = address(0); uint256 _cumulativeTargetFunding = 0; for (uint256 i = 0; i < _grantees.length; i++) { address currentGrantee = _grantees[i]; uint256 currentAmount = _amounts[i]; require( currentAmount > 0, "constructor::Invalid Argument. currentAmount must be greater than 0." ); require( currentGrantee != address(0), "constructor::Invalid Argument. grantee address cannot be a ADDRESS_ZERO." ); require( currentGrantee > lastAddress, "constructor::Invalid Argument. Duplicate or out of order _grantees." ); lastAddress = currentGrantee; setGranteeTargetFunding(currentGrantee, currentAmount); _cumulativeTargetFunding = _cumulativeTargetFunding.add(currentAmount); // Store address as reference. addGranteeReference(currentGrantee); } setCumulativeTargetFunding(_cumulativeTargetFunding); setPercentageBased(_percentageBased); } } // File: contracts/shared/interfaces/IFunding.sol pragma solidity ^0.7.0; /** * @title Grants Spec Abstract Contract. * @dev Grant request, funding, and management. * @author @NoahMarconi */ interface IFunding { /*---------- Events ----------*/ /** * @dev Funding target reached event. */ event LogFundingComplete(); /** * @dev Grant received funding. * @param donor Address funding the grant. * @param value Amount in WEI or ATOMIC_UNITS funded. */ event LogFunding(address indexed donor, uint256 value); /*---------- Shared Getters ----------*/ /** * @dev Cumulative funding donated by donors. */ function getTotalFunding() external view returns(uint256); } // File: contracts/shared/storage/Funding.sol pragma solidity ^0.7.0; /** * @title Total Funding. * @dev Handles state for tracking contract total amount funded. * @author @NoahMarconi @ameensol @JFickel @ArnaudBrousseau */ abstract contract Funding is IFunding { using SafeMath for uint256; /*---------- Globals ----------*/ /* solhint-disable max-line-length */ uint256 private totalFunding; // Cumulative funding donated by donors. /* solhint-enable max-line-length */ /*---------- Shared Getters ----------*/ /** * @dev Cumulative funding donated by donors. */ function getTotalFunding() public override view returns(uint256) { return totalFunding; } /*---------- Shared Setters ----------*/ /** * @dev Increase cumulative funding donated by donors. * @param value amount to increase total funding by. */ function increaseTotalFundingBy(uint256 value) internal { totalFunding = totalFunding.add(value); } function setTotalFunding(uint256 value) internal { totalFunding = value; } } // File: contracts/shared/interfaces/IBaseGrant.sol pragma solidity ^0.7.0; /** * @title Grants Spec Abstract Contract. * @dev Grant request, funding, and management. * @author @NoahMarconi */ interface IBaseGrant { /*---------- Events ----------*/ /** * @dev Funding target reached event. * implemented in IFunding * event LogFundingComplete(); */ /** * @dev Grant received funding. * implemented in IFunding * @param donor Address funding the grant. * @param value Amount in WEI or ATOMIC_UNITS funded. * event LogFunding(address indexed donor, uint256 value); */ /** * @dev Grant paying grantee. * @param grantee Address receiving payment. * @param value Amount in WEI or ATOMIC_UNITS paid. */ event LogPayment(address indexed grantee, uint256 value); /*---------- Shared Getters ----------*/ /** * @dev URI for additional (off-chain) grant details such as description, milestones, etc. */ function getUri() external view returns(bytes32); /** * @dev If null, amount is in wei, otherwise address of ERC20-compliant contract. */ function getCurrency() external view returns(address); /** * @dev Funding threshold required to begin releasing funds. */ function getTargetFunding() external view returns(uint256); /** * @dev Cumulative funding paid to grantees. */ function getTotalPaid() external view returns(uint256); /** * @dev Date after which signal OR funds cannot be sent. */ function getFundingDeadline() external view returns(uint256); /** * @dev Date after which payouts must be complete or anyone can trigger refunds. */ function getContractExpiration() external view returns(uint256); /** * @dev Flag to indicate when grant is cancelled. */ function getGrantCancelled() external view returns(bool); } // File: contracts/shared/storage/BaseGrant.sol pragma solidity ^0.7.0; /** * @title Base Grant State Management Contract. * @dev State, getters, and setters for BaseGrant. * @author @NoahMarconi @ameensol @JFickel @ArnaudBrousseau */ abstract contract BaseGrant is IBaseGrant { /*---------- Globals ----------*/ /* solhint-disable max-line-length */ bytes32 private uri; // URI for additional (off-chain) grant details such as description, milestones, etc. address private currency; // (Optional) If null, amount is in wei, otherwise address of ERC20-compliant contract. uint256 private targetFunding; // (Optional) Funding threshold required to begin releasing funds. uint256 private totalPaid; // Cumulative funding paid to grantees. uint256 private fundingDeadline; // (Optional) Date after which signal OR funds cannot be sent. uint256 private contractExpiration; // (Optional) Date after which payouts must be complete or anyone can trigger refunds. bool private grantCancelled; // Flag to indicate when grant is cancelled. /* solhint-enable max-line-length */ /*---------- Shared Getters ----------*/ function getUri() public override view returns(bytes32) { return uri; } function getContractExpiration() public override view returns(uint256) { return contractExpiration; } function getFundingDeadline() public override view returns(uint256) { return fundingDeadline; } function getTargetFunding() public override view returns(uint256) { return targetFunding; } function getTotalPaid() public override view returns(uint256) { return totalPaid; } function getGrantCancelled() public override view returns(bool) { return grantCancelled; } function getCurrency() public override view returns(address) { return currency; } /*---------- Shared Setters ----------*/ function setTotalPaid(uint256 value) internal { totalPaid = value; } function setUri(bytes32 value) internal { uri = value; } function setGrantCancelled(bool value) internal { grantCancelled = value; } } // File: contracts/UnmanagedGrant.sol pragma solidity ^0.7.0; /** * @title Grant for Eth2. * @dev Managed (n) * Funding Deadline (n) * Contract expiry (n) * With Token (n) * Percentage based allocation (y) * Withdraw (pull payment) (n) * This is a simplified grant which behaves as a simple payment splitter. * No refunds or managers; payment are immediately pushed. * WARNING: vulnerable to sending to Gas Token generating addresses. Trust in grantees not doing so is required. * @author @NoahMarconi */ contract UnmanagedGrant is ReentrancyGuard, BaseGrant, GranteeConstructor, Funding { /*---------- Constructor ----------*/ /** * @dev Grant creation function. May be called by grantors, grantees, or any other relevant party. * @param _grantees Sorted recipients of unlocked funds. * @param _amounts Respective allocations for each Grantee (must follow sort order of _grantees). * @param _uri URI for additional (off-chain) grant details such as description, milestones, etc. */ constructor( address[] memory _grantees, uint256[] memory _amounts, bytes32 _uri ) GranteeConstructor(_grantees, _amounts, true) { // Initialize globals. setUri(_uri); } /*---------- Fallback ----------*/ receive() external payable nonReentrant { require( msg.value > 0, "fallback::Invalid Value. msg.value must be greater than 0." ); uint256 numGrantees = getGranteeReferenceLength(); address lastGrantee = payable(getGranteeReference(numGrantees - 1)); for (uint256 i = 0; i < numGrantees; i++) { address payable currentGrantee = payable(getGranteeReference(i)); uint256 eligiblePortion = Percentages.maxAllocation( getGranteeTargetFunding(currentGrantee), getCumulativeTargetFunding(), msg.value ); if (currentGrantee == lastGrantee) { // Handle rounding of a few wei. // @audit question for auditor, should we enforce this is within expected threshold? eligiblePortion = address(this).balance; } if (eligiblePortion > 0) { (bool success, ) = currentGrantee.call{ value: eligiblePortion}(""); require( success, "fallback::Transfer Error. Unable to send eligiblePortion to Grantee." ); emit LogPayment(currentGrantee, eligiblePortion); } } increaseTotalFundingBy(msg.value); emit LogFunding(msg.sender, msg.value); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"_grantees","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes32","name":"_uri","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"donor","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogFunding","type":"event"},{"anonymous":false,"inputs":[],"name":"LogFundingComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogPayment","type":"event"},{"inputs":[],"name":"getContractExpiration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCumulativeTargetFunding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundingDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGrantCancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"grantee","type":"address"}],"name":"getGranteePayoutApproved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getGranteeReference","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGranteeReferenceLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"grantee","type":"address"}],"name":"getGranteeTargetFunding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"grantee","type":"address"}],"name":"getGranteeTotalPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPercentageBased","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTargetFunding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFunding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUri","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Deployed Bytecode
0x6080604052600436106100ec5760003560e01c80638025220e1161008a578063c569c96811610059578063c569c96814610612578063d6b3798a14610677578063fa7e64e9146106a2578063fedc58e314610707576103e0565b80638025220e1461052a578063b1039e2814610557578063b6e3a3ff14610582578063c2750f99146105e7576103e0565b806356b6491a116100c657806356b6491a146104685780636133c27c146104935780636793141f146104be5780636945c1fd146104e9576103e0565b80630f5a89c8146103e557806337e44469146104125780634e16fc8b1461043d576103e0565b366103e0576002600054141561016a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550600034116101cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180611652603a913960400191505060405180910390fd5b60006101d561076c565b905060006101e560018303610779565b905060005b8281101561037c5760006101fd82610779565b9050600061021b61020d836107ba565b610215610803565b3461080d565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610255574790505b600081111561036d5760008273ffffffffffffffffffffffffffffffffffffffff168260405180600001905060006040518083038185875af1925050503d80600081146102be576040519150601f19603f3d011682016040523d82523d6000602084013e6102c3565b606091505b505090508061031d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604481526020018061160e6044913960600191505060405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff167f27a391d95d67e3626574fb5fbe3532bb7366e9254957b1f0e840953c248b2aa8836040518082815260200191505060405180910390a2505b505080806001019150506101ea565b5061038634610836565b3373ffffffffffffffffffffffffffffffffffffffff167f9f1a5e1a5d3381f9af1a62f8d61e4ae71444e28af488786cb10c8b2b457632ae346040518082815260200191505060405180910390a250506001600081905550005b600080fd5b3480156103f157600080fd5b506103fa610854565b60405180821515815260200191505060405180910390f35b34801561041e57600080fd5b5061042761076c565b6040518082815260200191505060405180910390f35b34801561044957600080fd5b5061045261086b565b6040518082815260200191505060405180910390f35b34801561047457600080fd5b5061047d610875565b6040518082815260200191505060405180910390f35b34801561049f57600080fd5b506104a8610803565b6040518082815260200191505060405180910390f35b3480156104ca57600080fd5b506104d361087f565b6040518082815260200191505060405180910390f35b3480156104f557600080fd5b506104fe610889565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053657600080fd5b5061053f6108b3565b60405180821515815260200191505060405180910390f35b34801561056357600080fd5b5061056c6108ca565b6040518082815260200191505060405180910390f35b34801561058e57600080fd5b506105bb600480360360208110156105a557600080fd5b8101908080359060200190929190505050610779565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156105f357600080fd5b506105fc6108d4565b6040518082815260200191505060405180910390f35b34801561061e57600080fd5b506106616004803603602081101561063557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108de565b6040518082815260200191505060405180910390f35b34801561068357600080fd5b5061068c610927565b6040518082815260200191505060405180910390f35b3480156106ae57600080fd5b506106f1600480360360208110156106c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610931565b6040518082815260200191505060405180910390f35b34801561071357600080fd5b506107566004803603602081101561072a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506107ba565b6040518082815260200191505060405180910390f35b6000600b80549050905090565b6000600b828154811061078857fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600c54905090565b60008061081a8585610a02565b905060006108288285610a31565b905080925050509392505050565b61084b81600e5461097a90919063ffffffff16565b600e8190555050565b6000600d60009054906101000a900460ff16905090565b6000600154905090565b6000600554905090565b6000600454905090565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600760009054906101000a900460ff16905090565b6000600654905090565b6000600e54905090565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600354905090565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000808284019050838110156109f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080610a0e84610a60565b90506000610a1b84610a60565b9050610a278282610ade565b9250505092915050565b600080610a3d83610a60565b90506000610a4b8286610f99565b9050610a568161142e565b9250505092915050565b600080821415610a7657600060801b9050610ad9565b60008290506000610a868261152c565b90506070811015610a9f578060700382901b9150610ab3565b6070811115610ab2576070810382901c91505b5b607081613fff01901b6dffffffffffffffffffffffffffff83161791508160801b925050505b919050565b600080617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff1690506000617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050617fff821415610b9957617fff811415610b78576f7fff800000000000000000000000000060801b92505050610f93565b6f8000000000000000000000000000000060801b8416851892505050610f93565b617fff811415610c1857600060801b6dffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff191614610bf1576f7fff800000000000000000000000000060801b92505050610f93565b6f8000000000000000000000000000000060801b84861816600060801b1792505050610f93565b600060801b6f7fffffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff19161415610cd357600060801b6f7fffffffffffffffffffffffffffffff60801b86166fffffffffffffffffffffffffffffffff19161415610c9d576f7fff800000000000000000000000000060801b92505050610f93565b6f8000000000000000000000000000000060801b848618166f7fff000000000000000000000000000060801b1792505050610f93565b60006dffffffffffffffffffffffffffff8560801c166fffffffffffffffffffffffffffffffff1690506000821415610d0f5760019150610d24565b6e010000000000000000000000000000811790505b60006dffffffffffffffffffffffffffff8760801c166fffffffffffffffffffffffffffffffff1690506000841415610d885760008114610d83576000610d6a8261152c565b60e20390508082901b9150600194506072810384019350505b610da1565b60726e0100000000000000000000000000008217901b90505b818181610daa57fe5b0490506000811415610e1557600060801b6f8000000000000000000000000000000060801b878918166fffffffffffffffffffffffffffffffff191611610df557600060801b610e0a565b6f8000000000000000000000000000000060801b5b945050505050610f93565b6d1000000000000000000000000000811015610e2d57fe5b60006e080000000000000000000000000000821015610e8e576e040000000000000000000000000000821015610e83576e020000000000000000000000000000821015610e7b576070610e7e565b60715b610e86565b60725b60ff16610e98565b610e978261152c565b5b905061407184018186011115610eb657617fff945060009150610f53565b83613ffc828701011015610ed1576000945060009150610f52565b83613f8c828701011015610f1f5783613ffc86011115610efc5783613ffc86010382901b9150610f16565b83613ffc86011015610f1557613ffc8585030382901c91505b5b60009450610f51565b6070811115610f32576070810382901c91505b6dffffffffffffffffffffffffffff8216915083613f8d828701010394505b5b5b81607086901b6f8000000000000000000000000000000060801b898b181660801c6fffffffffffffffffffffffffffffffff16171760801b955050505050505b92915050565b600080617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff1690506000617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050617fff82141561113057617fff8114156110be57836fffffffffffffffffffffffffffffffff1916856fffffffffffffffffffffffffffffffff19161415611065576f8000000000000000000000000000000060801b8416851892505050611428565b6f8000000000000000000000000000000060801b8486186fffffffffffffffffffffffffffffffff191614156110a15783851792505050611428565b6f7fff800000000000000000000000000060801b92505050611428565b600060801b6f7fffffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff1916141561110f576f7fff800000000000000000000000000060801b92505050611428565b6f8000000000000000000000000000000060801b8416851892505050611428565b617fff8114156111ac57600060801b6f7fffffffffffffffffffffffffffffff60801b86166fffffffffffffffffffffffffffffffff1916141561118b576f7fff800000000000000000000000000060801b92505050611428565b6f8000000000000000000000000000000060801b8516841892505050611428565b60006dffffffffffffffffffffffffffff8660801c166fffffffffffffffffffffffffffffffff16905060008314156111e857600192506111fd565b6e010000000000000000000000000000811790505b60006dffffffffffffffffffffffffffff8660801c166fffffffffffffffffffffffffffffffff1690506000831415611239576001925061124e565b6e010000000000000000000000000000811790505b808202915060008214156112bb57600060801b6f8000000000000000000000000000000060801b878918166fffffffffffffffffffffffffffffffff19161161129b57600060801b6112b0565b6f8000000000000000000000000000000060801b5b945050505050611428565b828401935060007c0200000000000000000000000000000000000000000000000000000000831015611322577c010000000000000000000000000000000000000000000000000000000083101561131a576113158361152c565b61131d565b60e05b611325565b60e15b905061407081860110156113405760009450600092506113e8565b6140e081860110156113845761407085101561136557846140700383901c925061137b565b61407085111561137a57614070850383901b92505b5b600094506113e7565b61c0dd818601111561139e57617fff9450600092506113e6565b60708111156113b5576070810383901c92506113c9565b60708110156113c8578060700383901b92505b5b6dffffffffffffffffffffffffffff831692506140df8186010394505b5b5b82607086901b6f8000000000000000000000000000000060801b898b181660801c6fffffffffffffffffffffffffffffffff16171760801b955050505050505b92915050565b600080617fff60708460801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050613fff811015611477576000915050611527565b6f800000000000000000000000000000008360801c6fffffffffffffffffffffffffffffffff16106114a857600080fd5b6140fe8111156114b757600080fd5b60006e0100000000000000000000000000006dffffffffffffffffffffffffffff8560801c6fffffffffffffffffffffffffffffffff161617905061406f82101561150b578161406f0381901c9050611521565b61406f8211156115205761406f820381901b90505b5b80925050505b919050565b600080821161153a57600080fd5b6000700100000000000000000000000000000000831061156257608083901c92506080810190505b68010000000000000000831061158057604083901c92506040810190505b640100000000831061159a57602083901c92506020810190505b6201000083106115b257601083901c92506010810190505b61010083106115c957600883901c92506008810190505b601083106115df57600483901c92506004810190505b600483106115f557600283901c92506002810190505b60028310611604576001810190505b8091505091905056fe66616c6c6261636b3a3a5472616e73666572204572726f722e20556e61626c6520746f2073656e6420656c696769626c65506f7274696f6e20746f204772616e7465652e66616c6c6261636b3a3a496e76616c69642056616c75652e206d73672e76616c7565206d7573742062652067726561746572207468616e20302ea26469706673582212201e359ce3af9b33be3973cdf8fcde49672f5e67bec1c2ad411774b420daf62ef964736f6c63430007000033
Deployed Bytecode Sourcemap
79017:2301:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1837:1;2434:7;;:19;;2426:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1837:1;2567:7;:18;;;;79963:1:::1;79951:9;:13;79929:121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80063:19;80085:27;:25;:27::i;:::-;80063:49;;80123:19;80153:36;80187:1;80173:11;:15;80153:19;:36::i;:::-;80123:67;;80206:9;80201:1006;80225:11;80221:1;:15;80201:1006;;;80258:30;80299:22;80319:1;80299:19;:22::i;:::-;80258:64;;80339:23;80365:173;80409:39;80433:14;80409:23;:39::i;:::-;80467:28;:26;:28::i;:::-;80514:9;80365:25;:173::i;:::-;80339:199;;80577:11;80559:29;;:14;:29;;;80555:261;;;80779:21;80761:39;;80555:261;80854:1;80836:15;:19;80832:362;;;80877:12;80895:14;:19;;80923:15;80895:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80876:67;;;80992:7;80962:149;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81146:14;81135:43;;;81162:15;81135:43;;;;;;;;;;;;;;;;;;80832:362;;80201:1006;;80238:3;;;;;;;80201:1006;;;;81219:33;81242:9;81219:22;:33::i;:::-;81281:10;81270:33;;;81293:9;81270:33;;;;;;;;;;;;;;;;;;2598:1;;1793::::0;2746:7;:22;;;;79017:2301;;;;;65413:147;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66297:165;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;76968:126;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;77266:150;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;65139:166;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;77578:138;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;77877:136;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;77724:145;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;77102:156;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66610:172;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;72843:144;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67628:186;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;77424:146;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67285:176;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66942:184;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66297:165;66399:7;66431:16;:23;;;;66424:30;;66297:165;:::o;66610:172::-;66719:7;66751:16;66768:5;66751:23;;;;;;;;;;;;;;;;;;;;;;;;;66744:30;;66610:172;;;:::o;66942:184::-;67057:7;67089:20;:29;67110:7;67089:29;;;;;;;;;;;;;;;;67082:36;;66942:184;;;:::o;65139:166::-;65242:7;65274:23;;65267:30;;65139:166;:::o;56110:480::-;56247:7;56272:27;56302:84;56339:12;56366:9;56302:22;:84::i;:::-;56272:114;;56399:33;56435:102;56479:19;56513:13;56435:29;:102::i;:::-;56399:138;;56557:25;56550:32;;;;56110:480;;;;;:::o;73183:127::-;73279:23;73296:5;73279:12;;:16;;:23;;;;:::i;:::-;73264:12;:38;;;;73183:127;:::o;65413:147::-;65508:4;65537:15;;;;;;;;;;;65530:22;;65413:147;:::o;76968:126::-;77051:7;77083:3;;77076:10;;76968:126;:::o;77266:150::-;77361:7;77393:15;;77386:22;;77266:150;:::o;77578:138::-;77667:7;77699:9;;77692:16;;77578:138;:::o;77877:136::-;77965:7;77997:8;;;;;;;;;;;77990:15;;77877:136;:::o;77724:145::-;77818:4;77847:14;;;;;;;;;;;77840:21;;77724:145;:::o;77102:156::-;77200:7;77232:18;;77225:25;;77102:156;:::o;72843:144::-;72935:7;72967:12;;72960:19;;72843:144;:::o;67628:186::-;67744:7;67776:21;:30;67798:7;67776:30;;;;;;;;;;;;;;;;67769:37;;67628:186;;;:::o;77424:146::-;77517:7;77549:13;;77542:20;;77424:146;:::o;67285:176::-;67396:7;67428:16;:25;67445:7;67428:25;;;;;;;;;;;;;;;;67421:32;;67285:176;;;:::o;57518:181::-;57576:7;57596:9;57612:1;57608;:5;57596:17;;57637:1;57632;:6;;57624:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57690:1;57683:8;;;57518:181;;;;:::o;55043:294::-;55153:7;55178:11;55192:32;55214:9;55192:21;:32::i;:::-;55178:46;;55235:11;55249:34;55271:11;55249:21;:34::i;:::-;55235:48;;55303:26;55320:3;55325;55303:16;:26::i;:::-;55296:33;;;;55043:294;;;;:::o;55524:283::-;55633:7;55658:11;55672:28;55694:5;55672:21;:28::i;:::-;55658:42;;55711:11;55725:30;55742:3;55747:7;55725:16;:30::i;:::-;55711:44;;55775:24;55795:3;55775:19;:24::i;:::-;55768:31;;;;55524:283;;;;:::o;5880:405::-;5933:7;5958:1;5953;:6;5949:331;;;5977:1;5968:11;;5961:18;;;;5949:331;6000:14;6017:1;6000:18;;6029:11;6043:12;6048:6;6043:3;:12::i;:::-;6029:26;;6074:3;6068;:9;6064:84;;;6096:3;6090;:9;6079:20;;;;;6064:84;;;6123:3;6117;:9;6113:35;;;6145:3;6139;:9;6128:20;;;;;6113:35;6064:84;6225:3;6218;6210:5;:11;:18;;6177:30;6168:6;:39;:60;6159:69;;6264:6;6246:26;;6239:33;;;;5880:405;;;;:::o;27500:2698::-;27559:7;27575:17;27616:6;27610:3;27604:1;27595:11;;:18;;;;:27;27575:47;;;;27629:17;27670:6;27664:3;27658:1;27649:11;;:18;;;;:27;27629:47;;;;27702:6;27689:9;:19;27685:2508;;;27736:6;27723:9;:19;27719:98;;;3849:34;27751:3;;27744:10;;;;;;27719:98;27783:34;27779:38;;:1;:38;27775:1;:42;27768:49;;;;;;27685:2508;27848:6;27835:9;:19;27831:2362;;;27911:1;27869:43;;27873:34;27869:38;;:1;:38;:43;;;;27865:140;;3849:34;27921:3;;27914:10;;;;;;27865:140;27971:34;27961:44;;27966:1;27962;:5;27961:44;3400:34;27945:13;;:60;27938:67;;;;;;27831:2362;28065:1;28023:43;;28027:34;28023:38;;:1;:38;:43;;;;28019:2174;;;28123:1;28081:43;;28085:34;28081:38;;:1;:38;:43;;;;28077:144;;;3849:34;28133:3;;28126:10;;;;;;28077:144;28187:34;28177:44;;28182:1;28178;:5;28177:44;3621:34;28157:17;;:64;28150:71;;;;;;28019:2174;28244:18;28279:30;28274:1;28265:11;;:44;28244:65;;;;28335:1;28322:9;:14;28318:92;;;28350:1;28338:13;;28318:92;;;28379:31;28365:45;;;;28318:92;28421:18;28456:30;28451:1;28442:11;;:44;28421:65;;;;28512:1;28499:9;:14;28495:321;;;28544:1;28530:10;:15;28526:181;;28560:10;28579:16;28584:10;28579:3;:16::i;:::-;28573:3;:22;28560:35;;28625:5;28610:20;;;;;28657:1;28645:13;;28692:3;28684:5;:11;28671:24;;;;28526:181;;28495:321;;;28803:3;28767:31;28754:10;:44;28753:53;;28740:66;;28495:321;28852:10;28839;:23;;;;;;28826:36;;28889:1;28875:10;:15;28871:130;;;28955:1;28908:48;;28918:34;28908:44;;28913:1;28909;:5;28908:44;:48;;;;:93;;3400:34;28988:13;;28908:93;;;3505:34;28972:13;;28908:93;28901:100;;;;;;;;28871:130;29034:30;29020:10;:44;;29012:53;;;;29076:11;29113:31;29099:10;:45;;:196;;29189:31;29175:10;:45;;:120;;29252:31;29238:10;:45;;:57;;29292:3;29238:57;;;29286:3;29238:57;29175:120;;;29223:3;29175:120;29099:196;;;;;29147:16;29152:10;29147:3;:16::i;:::-;29099:196;29076:219;;29340:5;29328:9;:17;29322:3;29310:9;:15;:35;29306:745;;;29382:6;29370:18;;29412:1;29399:14;;29306:745;;;29460:9;29451:5;29445:3;29433:9;:15;:23;:36;29429:622;;;29507:1;29495:13;;29532:1;29519:14;;29429:622;;;29580:9;29571:5;29565:3;29553:9;:15;:23;:36;29549:502;;;29639:9;29631:5;29619:9;:17;:29;29615:196;;;29696:9;29688:5;29676:9;:17;:29;29661:44;;;;;29615:196;;;29745:9;29737:5;29725:9;:17;:29;29721:90;;;29806:5;29794:9;29782;:21;:29;29767:44;;;;;29721:90;29615:196;29836:1;29824:13;;29549:502;;;29884:3;29878;:9;29874:50;;;29921:3;29915;:9;29900:24;;;;;29874:50;29951:30;29937:44;;;;30032:9;30024:5;30018:3;30006:9;:15;:23;:35;29994:47;;29549:502;29429:622;29306:745;30173:10;30167:3;30154:9;:16;;30105:34;30095:44;;30100:1;30096;:5;30095:44;30086:54;;:84;;;:97;30068:117;;30061:124;;;;;;;27500:2698;;;;;:::o;23802:2405::-;23861:7;23877:17;23918:6;23912:3;23906:1;23897:11;;:18;;;;:27;23877:47;;;;23931:17;23972:6;23966:3;23960:1;23951:11;;:18;;;;:27;23931:47;;;;24004:6;23991:9;:19;23987:2215;;;24038:6;24025:9;:19;24021:361;;;24066:1;24061:6;;;:1;:6;;;;24057:164;;;24084:34;24080:38;;:1;:38;24076:1;:42;24069:49;;;;;;24057:164;24147:34;24138:43;;24142:1;24138;:5;:43;;;;24134:87;;;24194:1;24190;:5;24183:12;;;;;;24134:87;3849:34;24218:3;;24211:10;;;;;;24021:361;24294:1;24252:43;;24256:34;24252:38;;:1;:38;:43;;;;24248:124;;;3849:34;24304:3;;24297:10;;;;;;24248:124;24338:34;24334:38;;:1;:38;24330:1;:42;24323:49;;;;;;23987:2215;24412:6;24399:9;:19;24395:1807;;;24477:1;24435:43;;24439:34;24435:38;;:1;:38;:43;;;;24431:124;;;3849:34;24487:3;;24480:10;;;;;;24431:124;24521:34;24517:38;;:1;:38;24513:1;:42;24506:49;;;;;;24395:1807;24578:18;24613:30;24608:1;24599:11;;:44;24578:65;;;;24669:1;24656:9;:14;24652:92;;;24684:1;24672:13;;24652:92;;;24713:31;24699:45;;;;24652:92;24755:18;24790:30;24785:1;24776:11;;:44;24755:65;;;;24846:1;24833:9;:14;24829:92;;;24861:1;24849:13;;24829:92;;;24890:31;24876:45;;;;24829:92;24946:10;24932:24;;;;24983:1;24969:10;:15;24965:130;;;25049:1;25002:48;;25012:34;25002:44;;25007:1;25003;:5;25002:44;:48;;;;:93;;3400:34;25082:13;;25002:93;;;3505:34;25066:13;;25002:93;24995:100;;;;;;;;24965:130;25119:9;25106:22;;;;25139:11;25176:59;25162:10;:73;;:198;;25267:59;25253:10;:73;;:107;;25344:16;25349:10;25344:3;:16::i;:::-;25253:107;;;25329:3;25253:107;25162:198;;;25238:3;25162:198;25139:221;;25393:5;25387:3;25375:9;:15;:23;25371:689;;;25436:1;25424:13;;25461:1;25448:14;;25371:689;;;25500:5;25494:3;25482:9;:15;:23;25478:582;;;25547:5;25535:9;:17;25531:148;;;25588:9;25580:5;:17;25565:32;;;;;25531:148;;;25629:5;25617:9;:17;25613:66;;;25674:5;25662:9;:17;25647:32;;;;;25613:66;25531:148;25702:1;25690:13;;25478:582;;;25741:5;25735:3;25723:9;:15;:23;25719:341;;;25771:6;25759:18;;25801:1;25788:14;;25719:341;;;25839:3;25833;:9;25829:116;;;25876:3;25870;:9;25855:24;;;;;25829:116;;;25905:3;25899;:9;25895:50;;;25942:3;25936;:9;25921:24;;;;;25895:50;25829:116;25972:30;25958:44;;;;26045:5;26039:3;26027:9;:15;:23;26015:35;;25719:341;25478:582;25371:689;26182:10;26176:3;26163:9;:16;;26114:34;26104:44;;26109:1;26105;:5;26104:44;26095:54;;:84;;;:97;26077:117;;26070:124;;;;;;;23802:2405;;;;;:::o;6693:558::-;6744:7;6760:16;6800:6;6794:3;6788:1;6779:11;;:18;;;;:27;6760:46;;;;6830:5;6819:8;:16;6815:30;;;6844:1;6837:8;;;;;6815:30;6890:34;6885:1;6876:11;;:48;;;6867:58;;;;;;6967:5;6955:8;:17;;6946:27;;;;;;6992:14;7073:31;7033:30;7027:1;7018:11;;7009:21;;:54;:95;6992:112;;7128:5;7117:8;:16;7113:110;;;7154:8;7146:5;:16;7135:27;;;;;7113:110;;;7189:5;7178:8;:16;7174:49;;;7218:5;7207:8;:16;7196:27;;;;;7174:49;7113:110;7239:6;7232:13;;;;6693:558;;;;:::o;53900:585::-;53947:7;53976:1;53972;:5;53963:15;;;;;;53987:14;54023:35;54018:1;:40;54014:75;;54068:3;54062:9;;;;;54083:3;54073:13;;;;54014:75;54104:19;54099:1;:24;54095:57;;54133:2;54127:8;;;;;54147:2;54137:12;;;;54095:57;54167:11;54162:1;:16;54158:49;;54188:2;54182:8;;;;;54202:2;54192:12;;;;54158:49;54222:7;54217:1;:12;54213:45;;54239:2;54233:8;;;;;54253:2;54243:12;;;;54213:45;54273:5;54268:1;:10;54264:41;;54288:1;54282:7;;;;;54301:1;54291:11;;;;54264:41;54320:4;54315:1;:9;54311:40;;54334:1;54328:7;;;;;54347:1;54337:11;;;;54311:40;54366:3;54361:1;:8;54357:39;;54379:1;54373:7;;;;;54392:1;54382:11;;;;54357:39;54411:3;54406:1;:8;54402:25;;54426:1;54416:11;;;;54402:25;54473:6;54466:13;;;53900:585;;;:::o
Swarm Source
ipfs://1e359ce3af9b33be3973cdf8fcde49672f5e67bec1c2ad411774b420daf62ef9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.