Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
ProtocolGovernor
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-18 */ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } pragma solidity 0.8.19; /// @title SafeCast Library /// @author velodrome.finance /// @notice Safely convert unsigned and signed integers without overflow / underflow library SafeCastLibrary { error SafeCastOverflow(); error SafeCastUnderflow(); /// @dev Safely convert uint256 to int128 function toInt128(uint256 value) internal pure returns (int128) { if (value > uint128(type(int128).max)) revert SafeCastOverflow(); return int128(uint128(value)); } /// @dev Safely convert int128 to uint256 function toUint256(int128 value) internal pure returns (uint256) { if (value < 0) revert SafeCastUnderflow(); return uint256(int256(value)); } } pragma solidity 0.8.19; library ProtocolTimeLibrary { uint256 internal constant WEEK = 7 days; /// @dev Returns start of epoch based on current timestamp function epochStart(uint256 timestamp) internal pure returns (uint256) { unchecked { return timestamp - (timestamp % WEEK); } } /// @dev Returns start of next epoch / end of current epoch function epochNext(uint256 timestamp) internal pure returns (uint256) { unchecked { return timestamp - (timestamp % WEEK) + WEEK; } } /// @dev Returns start of voting window function epochVoteStart(uint256 timestamp) internal pure returns (uint256) { unchecked { return timestamp - (timestamp % WEEK) + 1 hours; } } /// @dev Returns end of voting window / beginning of unrestricted voting window function epochVoteEnd(uint256 timestamp) internal pure returns (uint256) { unchecked { return timestamp - (timestamp % WEEK) + WEEK - 1 hours; } } } pragma solidity ^0.8.0; interface IReward { error InvalidReward(); error NotAuthorized(); error NotGauge(); error NotEscrowToken(); error NotSingleToken(); error NotVotingEscrow(); error NotWhitelisted(); error ZeroAmount(); event Deposit(address indexed from, uint256 indexed tokenId, uint256 amount); event Withdraw(address indexed from, uint256 indexed tokenId, uint256 amount); event NotifyReward(address indexed from, address indexed reward, uint256 indexed epoch, uint256 amount); event ClaimRewards(address indexed from, address indexed reward, uint256 amount); /// @notice A checkpoint for marking balance struct Checkpoint { uint256 timestamp; uint256 balanceOf; } /// @notice A checkpoint for marking supply struct SupplyCheckpoint { uint256 timestamp; uint256 supply; } /// @notice Epoch duration constant (7 days) function DURATION() external view returns (uint256); /// @notice Address of Voter.sol function voter() external view returns (address); /// @notice Address of VotingEscrow.sol function ve() external view returns (address); /// @dev Address which has permission to externally call _deposit() & _withdraw() function authorized() external view returns (address); /// @notice Total amount currently deposited via _deposit() function totalSupply() external view returns (uint256); /// @notice Current amount deposited by tokenId function balanceOf(uint256 tokenId) external view returns (uint256); /// @notice Amount of tokens to reward depositors for a given epoch /// @param token Address of token to reward /// @param epochStart Startime of rewards epoch /// @return Amount of token function tokenRewardsPerEpoch(address token, uint256 epochStart) external view returns (uint256); /// @notice Most recent timestamp a veNFT has claimed their rewards /// @param token Address of token rewarded /// @param tokenId veNFT unique identifier /// @return Timestamp function lastEarn(address token, uint256 tokenId) external view returns (uint256); /// @notice True if a token is or has been an active reward token, else false function isReward(address token) external view returns (bool); /// @notice The number of checkpoints for each tokenId deposited function numCheckpoints(uint256 tokenId) external view returns (uint256); /// @notice The total number of checkpoints function supplyNumCheckpoints() external view returns (uint256); /// @notice Deposit an amount into the rewards contract to earn future rewards associated to a veNFT /// @dev Internal notation used as only callable internally by `authorized`. /// @param amount Amount deposited for the veNFT /// @param tokenId Unique identifier of the veNFT function _deposit(uint256 amount, uint256 tokenId) external; /// @notice Withdraw an amount from the rewards contract associated to a veNFT /// @dev Internal notation used as only callable internally by `authorized`. /// @param amount Amount deposited for the veNFT /// @param tokenId Unique identifier of the veNFT function _withdraw(uint256 amount, uint256 tokenId) external; /// @notice Claim the rewards earned by a veNFT staker /// @param tokenId Unique identifier of the veNFT /// @param tokens Array of tokens to claim rewards of function getReward(uint256 tokenId, address[] memory tokens) external; /// @notice Add rewards for stakers to earn /// @param token Address of token to reward /// @param amount Amount of token to transfer to rewards function notifyRewardAmount(address token, uint256 amount) external; /// @notice Determine the prior balance for an account as of a block number /// @dev Block number must be a finalized block or else this function will revert to prevent misinformation. /// @param tokenId The token of the NFT to check /// @param timestamp The timestamp to get the balance at /// @return The balance the account had as of the given block function getPriorBalanceIndex(uint256 tokenId, uint256 timestamp) external view returns (uint256); /// @notice Determine the prior index of supply staked by of a timestamp /// @dev Timestamp must be <= current timestamp /// @param timestamp The timestamp to get the index at /// @return Index of supply checkpoint function getPriorSupplyIndex(uint256 timestamp) external view returns (uint256); /// @notice Get number of rewards tokens function rewardsListLength() external view returns (uint256); /// @notice Calculate how much in rewards are earned for a specific token and veNFT /// @param token Address of token to fetch rewards of /// @param tokenId Unique identifier of the veNFT /// @return Amount of token earned in rewards function earned(address token, uint256 tokenId) external view returns (uint256); function checkpoints(uint256 tokenId, uint256 index) external view returns (uint256 timestamp, uint256 balanceOf); function supplyCheckpoints(uint256 index) external view returns (uint256 timestamp, uint256 supply); } pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } pragma solidity ^0.8.8; type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * Strings of arbitrary length can be optimized if they are short enough by * the addition of a storage variable used as fallback. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { error StringTooLong(string str); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = length(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function length(ShortString sstr) internal pure returns (uint256) { return uint256(ShortString.unwrap(sstr)) & 0xFF; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(0); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (length(value) > 0) { return toString(value); } else { return store; } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Checkpoints.sol) // This file was procedurally generated from scripts/generate/templates/Checkpoints.js. pragma solidity ^0.8.0; /** * @dev This library defines the `History` struct, for checkpointing values as they change at different points in * time, and later looking up past values by block number. See {Votes} as an example. * * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new * checkpoint for the current transaction block using the {push} function. * * _Available since v4.5._ */ library Checkpoints { struct History { Checkpoint[] _checkpoints; } struct Checkpoint { uint32 _blockNumber; uint224 _value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the * block, the requested block number must be in the past, excluding the current block. */ function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of * checkpoints. */ function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. * * Returns previous value and new value. */ function push(History storage self, uint256 value) internal returns (uint256, uint256) { return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value)); } /** * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will * be set to `op(latest, delta)`. * * Returns previous value and new value. */ function push( History storage self, function(uint256, uint256) view returns (uint256) op, uint256 delta ) internal returns (uint256, uint256) { return push(self, op(latest(self), delta)); } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(History storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint( History storage self ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._blockNumber, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(History storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._blockNumber <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._blockNumber == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint({_blockNumber: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint({_blockNumber: key, _value: value})); return (0, value); } } /** * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace224 { Checkpoint224[] _checkpoints; } struct Checkpoint224 { uint32 _key; uint224 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. */ function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace224 storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace224 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint224 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint224({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint224({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint224[] storage self, uint256 pos ) private pure returns (Checkpoint224 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace160 { Checkpoint160[] _checkpoints; } struct Checkpoint160 { uint96 _key; uint160 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. */ function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace160 storage self) internal view returns (uint160) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace160 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint160 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint160({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint160({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint160[] storage self, uint256 pos ) private pure returns (Checkpoint160 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol) pragma solidity ^0.8.4; /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ```solidity * DoubleEndedQueue.Bytes32Deque queue; * ``` * * _Available since v4.6._ */ library DoubleEndedQueue { /** * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. */ error Empty(); /** * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. */ error OutOfBounds(); /** * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at * data[end - 1]. */ struct Bytes32Deque { int128 _begin; int128 _end; mapping(int128 => bytes32) _data; } /** * @dev Inserts an item at the end of the queue. */ function pushBack(Bytes32Deque storage deque, bytes32 value) internal { int128 backIndex = deque._end; deque._data[backIndex] = value; unchecked { deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } /** * @dev Inserts an item at the beginning of the queue. */ function pushFront(Bytes32Deque storage deque, bytes32 value) internal { int128 frontIndex; unchecked { frontIndex = deque._begin - 1; } deque._data[frontIndex] = value; deque._begin = frontIndex; } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; value = deque._data[frontIndex]; delete deque._data[frontIndex]; unchecked { deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with `Empty` if the queue is empty. */ function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; return deque._data[frontIndex]; } /** * @dev Returns the item at the end of the queue. * * Reverts with `Empty` if the queue is empty. */ function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } return deque._data[backIndex]; } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with `OutOfBounds` if the index is out of bounds. */ function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { // int256(deque._begin) is a safe upcast int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index)); if (idx >= deque._end) revert OutOfBounds(); return deque._data[idx]; } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Bytes32Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Bytes32Deque storage deque) internal view returns (uint256) { // The interface preserves the invariant that begin <= end so we assume this will not overflow. // We also assume there are at most int256.max items in the queue. unchecked { return uint256(int256(deque._end) - int256(deque._begin)); } } /** * @dev Returns true if the queue is empty. */ function empty(Bytes32Deque storage deque) internal view returns (bool) { return deque._end <= deque._begin; } } // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } pragma solidity ^0.8.0; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); } // OpenZeppelin Contracts (interfaces/IERC6372.sol) pragma solidity ^0.8.0; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); } // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } pragma solidity ^0.8.0; interface IVoter { error AlreadyVotedOrDeposited(); error DistributeWindow(); error FactoryPathNotApproved(); error GaugeAlreadyKilled(); error GaugeAlreadyRevived(); error GaugeExists(); error GaugeDoesNotExist(address _pool); error GaugeNotAlive(address _gauge); error InactiveManagedNFT(); error MaximumVotingNumberTooLow(); error NonZeroVotes(); error NotAPool(); error NotApprovedOrOwner(); error NotGovernor(); error NotEmergencyCouncil(); error NotMinter(); error NotWhitelistedNFT(); error NotWhitelistedToken(); error SameValue(); error SpecialVotingWindow(); error TooManyPools(); error UnequalLengths(); error ZeroBalance(); error ZeroAddress(); event GaugeCreated( address indexed poolFactory, address indexed votingRewardsFactory, address indexed gaugeFactory, address pool, address bribeVotingReward, address feeVotingReward, address gauge, address creator ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event Abstained( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event NotifyReward(address indexed sender, address indexed reward, uint256 amount); event DistributeReward(address indexed sender, address indexed gauge, uint256 amount); event WhitelistToken(address indexed whitelister, address indexed token, bool indexed _bool); event WhitelistNFT(address indexed whitelister, uint256 indexed tokenId, bool indexed _bool); /// @notice Store trusted forwarder address to pass into factories function forwarder() external view returns (address); /// @notice The ve token that governs these contracts function ve() external view returns (address); /// @notice Factory registry for valid pool / gauge / rewards factories function factoryRegistry() external view returns (address); /// @notice Address of Minter.sol function minter() external view returns (address); /// @notice Standard OZ IGovernor using ve for vote weights. function governor() external view returns (address); /// @notice Custom Epoch Governor using ve for vote weights. function epochGovernor() external view returns (address); /// @notice credibly neutral party similar to Curve's Emergency DAO function emergencyCouncil() external view returns (address); /// @dev Total Voting Weights function totalWeight() external view returns (uint256); /// @dev Most number of pools one voter can vote for at once function maxVotingNum() external view returns (uint256); // mappings /// @dev Pool => Gauge function gauges(address pool) external view returns (address); /// @dev Gauge => Pool function poolForGauge(address gauge) external view returns (address); /// @dev Gauge => Fees Voting Reward function gaugeToFees(address gauge) external view returns (address); /// @dev Gauge => Bribes Voting Reward function gaugeToBribe(address gauge) external view returns (address); /// @dev Pool => Weights function weights(address pool) external view returns (uint256); /// @dev NFT => Pool => Votes function votes(uint256 tokenId, address pool) external view returns (uint256); /// @dev NFT => Total voting weight of NFT function usedWeights(uint256 tokenId) external view returns (uint256); /// @dev Nft => Timestamp of last vote (ensures single vote per epoch) function lastVoted(uint256 tokenId) external view returns (uint256); /// @dev Address => Gauge function isGauge(address) external view returns (bool); /// @dev Token => Whitelisted status function isWhitelistedToken(address token) external view returns (bool); /// @dev TokenId => Whitelisted status function isWhitelistedNFT(uint256 tokenId) external view returns (bool); /// @dev Gauge => Liveness status function isAlive(address gauge) external view returns (bool); /// @dev Gauge => Amount claimable function claimable(address gauge) external view returns (uint256); /// @notice Number of pools with a Gauge function length() external view returns (uint256); /// @notice Called by Minter to distribute weekly emissions rewards for disbursement amongst gauges. /// @dev Assumes totalWeight != 0 (Will never be zero as long as users are voting). /// Throws if not called by minter. /// @param _amount Amount of rewards to distribute. function notifyRewardAmount(uint256 _amount) external; /// @dev Utility to distribute to gauges of pools in range _start to _finish. /// @param _start Starting index of gauges to distribute to. /// @param _finish Ending index of gauges to distribute to. function distribute(uint256 _start, uint256 _finish) external; /// @dev Utility to distribute to gauges of pools in array. /// @param _gauges Array of gauges to distribute to. function distribute(address[] memory _gauges) external; /// @notice Called by users to update voting balances in voting rewards contracts. /// @param _tokenId Id of veNFT whose balance you wish to update. function poke(uint256 _tokenId) external; /// @notice Called by users to vote for pools. Votes distributed proportionally based on weights. /// Can only vote or deposit into a managed NFT once per epoch. /// Can only vote for gauges that have not been killed. /// @dev Weights are distributed proportional to the sum of the weights in the array. /// Throws if length of _poolVote and _weights do not match. /// @param _tokenId Id of veNFT you are voting with. /// @param _poolVote Array of pools you are voting for. /// @param _weights Weights of pools. function vote(uint256 _tokenId, address[] calldata _poolVote, uint256[] calldata _weights) external; /// @notice Called by users to reset voting state. Required if you wish to make changes to /// veNFT state (e.g. merge, split, deposit into managed etc). /// Cannot reset in the same epoch that you voted in. /// Can vote or deposit into a managed NFT again after reset. /// @param _tokenId Id of veNFT you are reseting. function reset(uint256 _tokenId) external; /// @notice Called by users to deposit into a managed NFT. /// Can only vote or deposit into a managed NFT once per epoch. /// Note that NFTs deposited into a managed NFT will be re-locked /// to the maximum lock time on withdrawal. /// @dev Throws if not approved or owner. /// Throws if managed NFT is inactive. /// Throws if depositing within privileged window (one hour prior to epoch flip). function depositManaged(uint256 _tokenId, uint256 _mTokenId) external; /// @notice Called by users to withdraw from a managed NFT. /// Cannot do it in the same epoch that you deposited into a managed NFT. /// Can vote or deposit into a managed NFT again after withdrawing. /// Note that the NFT withdrawn is re-locked to the maximum lock time. function withdrawManaged(uint256 _tokenId) external; /// @notice Claim emissions from gauges. /// @param _gauges Array of gauges to collect emissions from. function claimRewards(address[] memory _gauges) external; /// @notice Claim bribes for a given NFT. /// @dev Utility to help batch bribe claims. /// @param _bribes Array of BribeVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as bribes. /// @param _tokenId Id of veNFT that you wish to claim bribes for. function claimBribes(address[] memory _bribes, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Claim fees for a given NFT. /// @dev Utility to help batch fee claims. /// @param _fees Array of FeesVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as fees. /// @param _tokenId Id of veNFT that you wish to claim fees for. function claimFees(address[] memory _fees, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Set new governor. /// @dev Throws if not called by governor. /// @param _governor . function setGovernor(address _governor) external; /// @notice Set new epoch based governor. /// @dev Throws if not called by governor. /// @param _epochGovernor . function setEpochGovernor(address _epochGovernor) external; /// @notice Set new emergency council. /// @dev Throws if not called by emergency council. /// @param _emergencyCouncil . function setEmergencyCouncil(address _emergencyCouncil) external; /// @notice Set maximum number of gauges that can be voted for. /// @dev Throws if not called by governor. /// Throws if _maxVotingNum is too low. /// Throws if the values are the same. /// @param _maxVotingNum . function setMaxVotingNum(uint256 _maxVotingNum) external; /// @notice Whitelist (or unwhitelist) token for use in bribes. /// @dev Throws if not called by governor. /// @param _token . /// @param _bool . function whitelistToken(address _token, bool _bool) external; /// @notice Whitelist (or unwhitelist) token id for voting in last hour prior to epoch flip. /// @dev Throws if not called by governor. /// Throws if already whitelisted. /// @param _tokenId . /// @param _bool . function whitelistNFT(uint256 _tokenId, bool _bool) external; /// @notice Create a new gauge (unpermissioned). /// @dev Governor can create a new gauge for a pool with any address. /// @param _poolFactory . /// @param _pool . function createGauge(address _poolFactory, address _pool) external returns (address); /// @notice Kills a gauge. The gauge will not receive any new emissions and cannot be deposited into. /// Can still withdraw from gauge. /// @dev Throws if not called by emergency council. /// Throws if gauge already killed. /// @param _gauge . function killGauge(address _gauge) external; /// @notice Revives a killed gauge. Gauge will can receive emissions and deposits again. /// @dev Throws if not called by emergency council. /// Throws if gauge is not killed. /// @param _gauge . function reviveGauge(address _gauge) external; /// @dev Update claims to emissions for an array of gauges. /// @param _gauges Array of gauges to update emissions for. function updateFor(address[] memory _gauges) external; /// @dev Update claims to emissions for gauges based on their pool id as stored in Voter. /// @param _start Starting index of pools. /// @param _end Ending index of pools. function updateFor(uint256 _start, uint256 _end) external; /// @dev Update claims to emissions for single gauge /// @param _gauge . function updateFor(address _gauge) external; } pragma solidity ^0.8.0; /// Modified IVotes interface for tokenId based voting interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, uint256 indexed fromDelegate, uint256 indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the amount of votes that `tokenId` had at a specific moment in the past. * If the account passed in is not the owner, returns 0. */ function getPastVotes(address account, uint256 tokenId, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `tokenId` has chosen. Can never be equal to the delegator's `tokenId`. * Returns 0 if not delegated. */ function delegates(uint256 tokenId) external view returns (uint256); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(uint256 delegator, uint256 delegatee) external; /** * @dev Delegates votes from `delegator` to `delegatee`. Signer must own `delegator`. */ function delegateBySig( uint256 delegator, uint256 delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } } // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.0; interface IVotingEscrow is IVotes, IERC4906, IERC6372, IERC721Metadata { struct LockedBalance { int128 amount; uint256 end; bool isPermanent; } struct UserPoint { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block uint256 permanent; } struct GlobalPoint { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block uint256 permanentLockBalance; } /// @notice A checkpoint for recorded delegated voting weights at a certain timestamp struct Checkpoint { uint256 fromTimestamp; address owner; uint256 delegatedBalance; uint256 delegatee; } enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME } /// @dev Different types of veNFTs: /// NORMAL - typical veNFT /// LOCKED - veNFT which is locked into a MANAGED veNFT /// MANAGED - veNFT which can accept the deposit of NORMAL veNFTs enum EscrowType { NORMAL, LOCKED, MANAGED } error AlreadyVoted(); error AmountTooBig(); error ERC721ReceiverRejectedTokens(); error ERC721TransferToNonERC721ReceiverImplementer(); error InvalidNonce(); error InvalidSignature(); error InvalidSignatureS(); error InvalidManagedNFTId(); error LockDurationNotInFuture(); error LockDurationTooLong(); error LockExpired(); error LockNotExpired(); error NoLockFound(); error NonExistentToken(); error NotApprovedOrOwner(); error NotDistributor(); error NotEmergencyCouncilOrGovernor(); error NotGovernor(); error NotGovernorOrManager(); error NotManagedNFT(); error NotManagedOrNormalNFT(); error NotLockedNFT(); error NotNormalNFT(); error NotPermanentLock(); error NotOwner(); error NotTeam(); error NotVoter(); error OwnershipChange(); error PermanentLock(); error SameAddress(); error SameNFT(); error SameState(); error SplitNoOwner(); error SplitNotAllowed(); error SignatureExpired(); error TooManyTokenIDs(); error ZeroAddress(); error ZeroAmount(); error ZeroBalance(); event Deposit( address indexed provider, uint256 indexed tokenId, DepositType indexed depositType, uint256 value, uint256 locktime, uint256 ts ); event Withdraw(address indexed provider, uint256 indexed tokenId, uint256 value, uint256 ts); event LockPermanent(address indexed _owner, uint256 indexed _tokenId, uint256 amount, uint256 _ts); event UnlockPermanent(address indexed _owner, uint256 indexed _tokenId, uint256 amount, uint256 _ts); event Supply(uint256 prevSupply, uint256 supply); event Merge( address indexed _sender, uint256 indexed _from, uint256 indexed _to, uint256 _amountFrom, uint256 _amountTo, uint256 _amountFinal, uint256 _locktime, uint256 _ts ); event Split( uint256 indexed _from, uint256 indexed _tokenId1, uint256 indexed _tokenId2, address _sender, uint256 _splitAmount1, uint256 _splitAmount2, uint256 _locktime, uint256 _ts ); event CreateManaged( address indexed _to, uint256 indexed _mTokenId, address indexed _from, address _lockedManagedReward, address _freeManagedReward ); event DepositManaged( address indexed _owner, uint256 indexed _tokenId, uint256 indexed _mTokenId, uint256 _weight, uint256 _ts ); event WithdrawManaged( address indexed _owner, uint256 indexed _tokenId, uint256 indexed _mTokenId, uint256 _weight, uint256 _ts ); event SetAllowedManager(address indexed _allowedManager); // State variables /// @notice Address of Meta-tx Forwarder function forwarder() external view returns (address); /// @notice Address of FactoryRegistry.sol function factoryRegistry() external view returns (address); /// @notice Address of token (HYDRO) used to create a veNFT function token() external view returns (address); /// @notice Address of RewardsDistributor.sol function distributor() external view returns (address); /// @notice Address of Voter.sol function voter() external view returns (address); /// @notice Address of Protocol Team multisig function team() external view returns (address); /// @notice Address of art proxy used for on-chain art generation function artProxy() external view returns (address); /// @dev address which can create managed NFTs function allowedManager() external view returns (address); /// @dev Current count of token function tokenId() external view returns (uint256); /*/////////////////////////////////////////////////////////////// MANAGED NFT STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping of token id to escrow type /// Takes advantage of the fact default value is EscrowType.NORMAL function escrowType(uint256 tokenId) external view returns (EscrowType); /// @dev Mapping of token id to managed id function idToManaged(uint256 tokenId) external view returns (uint256 managedTokenId); /// @dev Mapping of user token id to managed token id to weight of token id function weights(uint256 tokenId, uint256 managedTokenId) external view returns (uint256 weight); /// @dev Mapping of managed id to deactivated state function deactivated(uint256 tokenId) external view returns (bool inactive); /// @dev Mapping from managed nft id to locked managed rewards /// `token` denominated rewards (rebases/rewards) stored in locked managed rewards contract /// to prevent co-mingling of assets function managedToLocked(uint256 tokenId) external view returns (address); /// @dev Mapping from managed nft id to free managed rewards contract /// these rewards can be freely withdrawn by users function managedToFree(uint256 tokenId) external view returns (address); /*/////////////////////////////////////////////////////////////// MANAGED NFT LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Create managed NFT (a permanent lock) for use within ecosystem. /// @dev Throws if address already owns a managed NFT. /// @return _mTokenId managed token id. function createManagedLockFor(address _to) external returns (uint256 _mTokenId); /// @notice Delegates balance to managed nft /// Note that NFTs deposited into a managed NFT will be re-locked /// to the maximum lock time on withdrawal. /// Permanent locks that are deposited will automatically unlock. /// @dev Managed nft will remain max-locked as long as there is at least one /// deposit or withdrawal per week. /// Throws if deposit nft is managed. /// Throws if recipient nft is not managed. /// Throws if deposit nft is already locked. /// Throws if not called by voter. /// @param _tokenId tokenId of NFT being deposited /// @param _mTokenId tokenId of managed NFT that will receive the deposit function depositManaged(uint256 _tokenId, uint256 _mTokenId) external; /// @notice Retrieves locked rewards and withdraws balance from managed nft. /// Note that the NFT withdrawn is re-locked to the maximum lock time. /// @dev Throws if NFT not locked. /// Throws if not called by voter. /// @param _tokenId tokenId of NFT being deposited. function withdrawManaged(uint256 _tokenId) external; /// @notice Permit one address to call createManagedLockFor() that is not Voter.governor() function setAllowedManager(address _allowedManager) external; /// @notice Set Managed NFT state. Inactive NFTs cannot be deposited into. /// @param _mTokenId managed nft state to set /// @param _state true => inactive, false => active function setManagedState(uint256 _mTokenId, bool _state) external; /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ function name() external view returns (string memory); function symbol() external view returns (string memory); function version() external view returns (string memory); function decimals() external view returns (uint8); function setTeam(address _team) external; function setArtProxy(address _proxy) external; /// @inheritdoc IERC721Metadata function tokenURI(uint256 tokenId) external view returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping from owner address to mapping of index to tokenId function ownerToNFTokenIdList(address _owner, uint256 _index) external view returns (uint256 _tokenId); /// @inheritdoc IERC721 function ownerOf(uint256 tokenId) external view returns (address owner); /// @inheritdoc IERC721 function balanceOf(address owner) external view returns (uint256 balance); /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC721 function getApproved(uint256 _tokenId) external view returns (address operator); /// @inheritdoc IERC721 function isApprovedForAll(address owner, address operator) external view returns (bool); /// @notice Check whether spender is owner or an approved user for a given veNFT /// @param _spender . /// @param _tokenId . function isApprovedOrOwner(address _spender, uint256 _tokenId) external returns (bool); /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC721 function approve(address to, uint256 tokenId) external; /// @inheritdoc IERC721 function setApprovalForAll(address operator, bool approved) external; /// @inheritdoc IERC721 function transferFrom(address from, address to, uint256 tokenId) external; /// @inheritdoc IERC721 function safeTransferFrom(address from, address to, uint256 tokenId) external; /// @inheritdoc IERC721 function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC165 function supportsInterface(bytes4 _interfaceID) external view returns (bool); /*////////////////////////////////////////////////////////////// ESCROW STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Total count of epochs witnessed since contract creation function epoch() external view returns (uint256); /// @notice Total amount of token() deposited function supply() external view returns (uint256); /// @notice Aggregate permanent locked balances function permanentLockBalance() external view returns (uint256); function userPointEpoch(uint256 _tokenId) external view returns (uint256 _epoch); /// @notice time -> signed slope change function slopeChanges(uint256 _timestamp) external view returns (int128); /// @notice account -> can split function canSplit(address _account) external view returns (bool); /// @notice Global point history at a given index function pointHistory(uint256 _loc) external view returns (GlobalPoint memory); /// @notice Get the LockedBalance (amount, end) of a _tokenId /// @param _tokenId . /// @return LockedBalance of _tokenId function locked(uint256 _tokenId) external view returns (LockedBalance memory); /// @notice User -> UserPoint[userEpoch] function userPointHistory(uint256 _tokenId, uint256 _loc) external view returns (UserPoint memory); /*////////////////////////////////////////////////////////////// ESCROW LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Record global data to checkpoint function checkpoint() external; /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock /// @dev Anyone (even a smart contract) can deposit for someone else, but /// cannot extend their locktime and deposit for a brand new user /// @param _tokenId lock NFT /// @param _value Amount to add to user's lock function depositFor(uint256 _tokenId, uint256 _value) external; /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration` /// @param _value Amount to deposit /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week) /// @return TokenId of created veNFT function createLock(uint256 _value, uint256 _lockDuration) external returns (uint256); /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration` /// @param _value Amount to deposit /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit /// @return TokenId of created veNFT function createLockFor(uint256 _value, uint256 _lockDuration, address _to) external returns (uint256); /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time /// @param _value Amount of tokens to deposit and add to the lock function increaseAmount(uint256 _tokenId, uint256 _value) external; /// @notice Extend the unlock time for `_tokenId` /// Cannot extend lock time of permanent locks /// @param _lockDuration New number of seconds until tokens unlock function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external; /// @notice Withdraw all tokens for `_tokenId` /// @dev Only possible if the lock is both expired and not permanent /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. function withdraw(uint256 _tokenId) external; /// @notice Merges `_from` into `_to`. /// @dev Cannot merge `_from` locks that are permanent or have already voted this epoch. /// Cannot merge `_to` locks that have already expired. /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. /// @param _from VeNFT to merge from. /// @param _to VeNFT to merge into. function merge(uint256 _from, uint256 _to) external; /// @notice Splits veNFT into two new veNFTS - one with oldLocked.amount - `_amount`, and the second with `_amount` /// @dev This burns the tokenId of the target veNFT /// Callable by approved or owner /// If this is called by approved, approved will not have permissions to manipulate the newly created veNFTs /// Returns the two new split veNFTs to owner /// If `from` is permanent, will automatically dedelegate. /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. /// @param _from VeNFT to split. /// @param _amount Amount to split from veNFT. /// @return _tokenId1 Return tokenId of veNFT with oldLocked.amount - `_amount`. /// @return _tokenId2 Return tokenId of veNFT with `_amount`. function split(uint256 _from, uint256 _amount) external returns (uint256 _tokenId1, uint256 _tokenId2); /// @notice Toggle split for a specific address. /// @dev Toggle split for address(0) to enable or disable for all. /// @param _account Address to toggle split permissions /// @param _bool True to allow, false to disallow function toggleSplit(address _account, bool _bool) external; /// @notice Permanently lock a veNFT. Voting power will be equal to /// `LockedBalance.amount` with no decay. Required to delegate. /// @dev Only callable by unlocked normal veNFTs. /// @param _tokenId tokenId to lock. function lockPermanent(uint256 _tokenId) external; /// @notice Unlock a permanently locked veNFT. Voting power will decay. /// Will automatically dedelegate if delegated. /// @dev Only callable by permanently locked veNFTs. /// Cannot unlock if already voted this epoch. /// @param _tokenId tokenId to unlock. function unlockPermanent(uint256 _tokenId) external; /*/////////////////////////////////////////////////////////////// GAUGE VOTING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Get the voting power for _tokenId at the current timestamp /// @dev Returns 0 if called in the same block as a transfer. /// @param _tokenId . /// @return Voting power function balanceOfNFT(uint256 _tokenId) external view returns (uint256); /// @notice Get the voting power for _tokenId at a given timestamp /// @param _tokenId . /// @param _t Timestamp to query voting power /// @return Voting power function balanceOfNFTAt(uint256 _tokenId, uint256 _t) external view returns (uint256); /// @notice Calculate total voting power at current timestamp /// @return Total voting power at current timestamp function totalSupply() external view returns (uint256); /// @notice Calculate total voting power at a given timestamp /// @param _t Timestamp to query total voting power /// @return Total voting power at given timestamp function totalSupplyAt(uint256 _t) external view returns (uint256); /*/////////////////////////////////////////////////////////////// GAUGE VOTING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice See if a queried _tokenId has actively voted /// @param _tokenId . /// @return True if voted, else false function voted(uint256 _tokenId) external view returns (bool); /// @notice Set the global state voter and distributor /// @dev This is only called once, at setup function setVoterAndDistributor(address _voter, address _distributor) external; /// @notice Set `voted` for _tokenId to true or false /// @dev Only callable by voter /// @param _tokenId . /// @param _voted . function voting(uint256 _tokenId, bool _voted) external; /*/////////////////////////////////////////////////////////////// DAO VOTING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice The number of checkpoints for each tokenId function numCheckpoints(uint256 tokenId) external view returns (uint48); /// @notice A record of states for signing / validating signatures function nonces(address account) external view returns (uint256); /// @inheritdoc IVotes function delegates(uint256 delegator) external view returns (uint256); /// @notice A record of delegated token checkpoints for each account, by index /// @param tokenId . /// @param index . /// @return Checkpoint function checkpoints(uint256 tokenId, uint48 index) external view returns (Checkpoint memory); /// @inheritdoc IVotes function getPastVotes(address account, uint256 tokenId, uint256 timestamp) external view returns (uint256); /// @inheritdoc IVotes function getPastTotalSupply(uint256 timestamp) external view returns (uint256); /*/////////////////////////////////////////////////////////////// DAO VOTING LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IVotes function delegate(uint256 delegator, uint256 delegatee) external; /// @inheritdoc IVotes function delegateBySig( uint256 delegator, uint256 delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; /*////////////////////////////////////////////////////////////// ERC6372 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC6372 function clock() external view returns (uint48); /// @inheritdoc IERC6372 function CLOCK_MODE() external view returns (string memory); } pragma solidity ^0.8.0; /** * @dev Taken from OpenZeppelin's IGovernor. * Includes support for veto-ing as mitigation against a 51% attack. */ abstract contract IVetoGovernor is IERC165, IERC6372 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Expired, Queued, // unused, required for backwards compatibility Executed, Vetoed } /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description ); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a proposal is vetoed. */ event ProposalVetoed(uint256 proposalId); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a comment is cast on a certain proposal. */ event Comment(uint256 indexed proposalId, address indexed account, uint256 indexed tokenId, string comment); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast( address indexed voter, uint256 indexed tokenId, uint256 proposalId, uint8 support, uint256 weight, string reason ); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 indexed tokenId, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the ERC712 domain separator). */ function name() public view virtual returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" */ function version() public view virtual returns (string memory); /** * @notice module:core * @dev See {IERC6372} */ function clock() public view virtual override returns (uint48); /** * @notice module:core * @dev See EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory); /// @notice Numerator used to calculate minimum voting power required to comment. function commentWeighting() external view virtual returns (uint256); /// @notice Denominator used to calculate minimum voting power required to comment. function COMMENT_DENOMINATOR() external view virtual returns (uint256); /// @notice Contract whose total supply / voting power is being used. function escrow() external view virtual returns (IVotingEscrow); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public view virtual returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash, address proposer ) public pure virtual returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) public view virtual returns (ProposalState); /** * @notice module:core * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the * following block. */ function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is * possible to cast a vote during this block. */ function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends * on the clock (see EIP-6372) this contract uses. * * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a * proposal starts. */ function votingDelay() public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay, between the vote start and vote ends. The unit this duration is expressed in depends on the clock * (see EIP-6372) this contract uses. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. */ function votingPeriod() public view virtual returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}). */ function quorum(uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `tokenId` at a specific `timepoint`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 tokenId, uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `tokenId` at a specific `timepoint` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 tokenId, uint256 timepoint, bytes memory params ) public view virtual returns (uint256); /** * @notice module:voting * @dev Returns whether `tokenId` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, uint256 tokenId) public view virtual returns (bool); /** * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a * duration specified by {IGovernor-votingPeriod}. * * Emits a {ProposalCreated} event. */ function propose( uint256 tokenId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. * * Emits a {ProposalExecuted} event. * * Note: some module can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash, address proposer ) public payable virtual returns (uint256 proposalId); /** * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. * before the vote starts. * * Emits a {ProposalCanceled} event. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256 proposalId); /** * @dev Add a comment to a proposal * * Emits a {Comment} event. */ function comment(uint256 proposalId, uint256 tokenId, string calldata message) external virtual; /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint256 tokenId, uint8 support) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason, bytes memory params ) public virtual returns (uint256 balance); /** * @dev Cast a vote using the user's cryptographic signature. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint256 tokenId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); } // OpenZeppelin Contracts (last updated v4.8.0) (governance/Governor.sol) pragma solidity ^0.8.0; /** * @dev Modified lightly from OpenZeppelin's Governor contract to support vetoing. */ abstract contract VetoGovernor is Context, ERC165, EIP712, IVetoGovernor, IERC721Receiver, IERC1155Receiver { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; using SafeCast for uint256; bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); // solhint-disable var-name-mixedcase struct ProposalCore { // --- start retyped from Timers.BlockNumber at offset 0x00 --- uint64 voteStart; address proposer; bytes4 __gap_unused0; // --- start retyped from Timers.BlockNumber at offset 0x20 --- uint64 voteEnd; bytes24 __gap_unused1; // --- Remaining fields starting at offset 0x40 --------------- bool executed; bool canceled; bool vetoed; } // solhint-enable var-name-mixedcase string private _name; uint256 public override commentWeighting = 0; uint256 public constant override COMMENT_DENOMINATOR = 1_000_000_000; IVotingEscrow public immutable override escrow; /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore) mapping(uint256 => ProposalCore) private _proposals; // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. DoubleEndedQueue.Bytes32Deque private _governanceCall; /** * @dev Restricts a function so it can only be executed through governance proposals. For example, governance * parameter setters in {GovernorSettings} are protected using this modifier. * * The governance executing address may be different from the Governor's own address, for example it could be a * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, * for example, additional timelock proposers are not able to change governance parameters without going through the * governance protocol (since v4.6). */ modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) {} } _; } /** * @dev Sets the value for {name} and {version} */ constructor(string memory name_, IVotingEscrow _ve) EIP712(name_, version()) { _name = name_; escrow = _ve; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { require(_executor() == address(this)); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { // In addition to the current interfaceId, also support previous version of the interfaceId that did not // include the castVoteWithReasonAndParams() function as standard return interfaceId == (type(IVetoGovernor).interfaceId ^ type(IERC6372).interfaceId ^ this.cancel.selector ^ this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector) || // Previous interface for backwards compatibility interfaceId == (type(IVetoGovernor).interfaceId ^ type(IERC6372).interfaceId ^ this.cancel.selector) || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IVetoGovernor-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IVetoGovernor-version}. */ function version() public view virtual override returns (string memory) { return "1"; } /** * @dev See {IVetoGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array, * the descriptionHash (bytes32 which itself is the keccak256 hash of the description string) and the `proposer` address. * This proposal id can be produced from the proposal data which is part of the {ProposalCreated} event. It can even * be computed in advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash, address proposer ) public pure virtual override returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash, proposer))); } /** * @dev See {IVetoGovernor-state}. */ function state(uint256 proposalId) public view virtual override returns (ProposalState) { ProposalCore storage proposal = _proposals[proposalId]; if (proposal.executed) { return ProposalState.Executed; } if (proposal.canceled) { return ProposalState.Canceled; } if (proposal.vetoed) { return ProposalState.Vetoed; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { return ProposalState.Succeeded; } else { return ProposalState.Defeated; } } /** * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev See {IVetoGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteStart; } /** * @dev See {IVetoGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteEnd; } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `tokenId`, owned by `account` at a specific `timepoint`, for a vote as described by `params`. */ function _getVotes( address account, uint256 tokenId, uint256 timepoint, bytes memory params ) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `tokenId` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote( uint256 proposalId, uint256 tokenId, uint8 support, uint256 weight, bytes memory params ) internal virtual; /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IVetoGovernor-propose}. */ function propose( uint256 tokenId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual override returns (uint256) { address proposer = _msgSender(); uint256 currentTimepoint = clock(); require( getVotes(proposer, tokenId, currentTimepoint - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold" ); uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)), proposer); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); require(_proposals[proposalId].proposer == address(0), "Governor: proposal already exists"); uint256 snapshot = currentTimepoint + votingDelay(); uint256 deadline = snapshot + votingPeriod(); _proposals[proposalId] = ProposalCore({ voteStart: snapshot.toUint64(), proposer: proposer, __gap_unused0: 0, voteEnd: deadline.toUint64(), __gap_unused1: 0, executed: false, canceled: false, vetoed: false }); emit ProposalCreated( proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description ); return proposalId; } /** * @dev See {IVetoGovernor-execute}. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash, address proposer ) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash, proposer); ProposalState status = state(proposalId); require(status == ProposalState.Succeeded, "Governor: proposal not successful"); _proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); return proposalId; } /** * @dev See {IVetoGovernor-cancel}. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual override returns (uint256) { address proposer = _msgSender(); uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash, proposer); require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel"); require(proposer == _proposals[proposalId].proposer, "Governor: only proposer can cancel"); return _cancel(targets, values, calldatas, descriptionHash, proposer); } /** * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism */ function _execute( uint256 /* proposalId */, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { string memory errorMessage = "Governor: call reverted without message"; uint256 _length = targets.length; for (uint256 i = 0; i < _length; ++i) { (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); Address.verifyCallResult(success, returndata, errorMessage); } } /** * @dev Hook before execution is triggered. */ function _beforeExecute( uint256 /* proposalId */, address[] memory targets, uint256[] memory /* values */, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { uint256 _length = targets.length; for (uint256 i = 0; i < _length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } } /** * @dev Hook after execution is triggered. */ function _afterExecute( uint256 /* proposalId */, address[] memory /* targets */, uint256[] memory /* values */, bytes[] memory /* calldatas */, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { if (!_governanceCall.empty()) { _governanceCall.clear(); } } } /** * @dev Internal veto mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * vetoed to allow distinguishing it from executed and canceled proposals. * * Emits a {IVetoGovernor-ProposalVetoed} event. */ function _veto(uint256 proposalId) internal returns (uint256) { ProposalState status = state(proposalId); require( status != ProposalState.Vetoed && status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, "Governor: proposal not active" ); _proposals[proposalId].vetoed = true; emit ProposalVetoed(proposalId); return proposalId; } /** * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * canceled to allow distinguishing it from executed and canceled proposals. * * Emits a {IVetoGovernor-ProposalCanceled} event. */ function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash, address proposer ) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash, proposer); ProposalState status = state(proposalId); require( status != ProposalState.Vetoed && status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, "Governor: proposal not active" ); _proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IVetoGovernor-getVotes}. */ function getVotes( address account, uint256 tokenId, uint256 timepoint ) public view virtual override returns (uint256) { return _getVotes(account, tokenId, timepoint, _defaultParams()); } /** * @dev See {IVetoGovernor-getVotesWithParams}. */ function getVotesWithParams( address account, uint256 tokenId, uint256 timepoint, bytes memory params ) public view virtual override returns (uint256) { return _getVotes(account, tokenId, timepoint, params); } /** * @dev See {IVetoGovernor-castVote}. */ function castVote(uint256 proposalId, uint256 tokenId, uint8 support) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, tokenId, support, ""); } /** * @dev See {IVetoGovernor-castVoteWithReason}. */ function castVoteWithReason( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, tokenId, support, reason); } /** * @dev See {IVetoGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason, bytes memory params ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, tokenId, support, reason, params); } /** * @dev See {IVetoGovernor-castVoteBySig}. */ function castVoteBySig( uint256 proposalId, uint256 tokenId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s ); return _castVote(proposalId, voter, tokenId, support, ""); } /** * @dev See {IVetoGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint256 tokenId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params) ) ) ), v, r, s ); return _castVote(proposalId, voter, tokenId, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IVetoGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IVetoGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint256 tokenId, uint8 support, string memory reason ) internal virtual returns (uint256) { return _castVote(proposalId, account, tokenId, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IVetoGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IVetoGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint256 tokenId, uint8 support, string memory reason, bytes memory params ) internal virtual returns (uint256) { ProposalCore storage proposal = _proposals[proposalId]; require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, tokenId, proposal.voteStart, params); _countVote(proposalId, tokenId, support, weight, params); if (params.length == 0) { emit VoteCast(account, tokenId, proposalId, support, weight, reason); } else { emit VoteCastWithParams(account, tokenId, proposalId, support, weight, reason, params); } return weight; } /** * @dev Comment mechanism for active or pending proposals. Requires a certain amount of votes. Emits a comment * containing the message. * * Emits a {IVetoGovernor-Comment} event. */ function comment(uint256 proposalId, uint256 tokenId, string calldata message) external virtual override { bytes memory params; ProposalCore storage proposal = _proposals[proposalId]; ProposalState status = state(proposalId); require(status == ProposalState.Active || status == ProposalState.Pending, "Governor: not active or pending"); uint256 startTime = proposal.voteStart; address account = _msgSender(); uint256 weight = _getVotes(account, tokenId, startTime, params); uint256 minimumWeight = (escrow.getPastTotalSupply(startTime) * commentWeighting) / 10_000; require(weight > minimumWeight, "Governor: insufficient voting power"); emit Comment(proposalId, account, tokenId, message); } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{value: value}(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. */ function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. */ function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } } // OpenZeppelin Contracts (last updated v4.8.0) (governance/extensions/GovernorCountingSimple.sol) pragma solidity ^0.8.0; /** * @dev OpenZeppelin's GovernorCountingSimple using VetoGovernor */ abstract contract VetoGovernorCountingSimple is VetoGovernor { /** * @dev Supported vote types. Matches Governor Bravo ordering. */ enum VoteType { Against, For, Abstain } struct ProposalVote { uint256 againstVotes; uint256 forVotes; uint256 abstainVotes; mapping(uint256 => bool) hasVoted; } mapping(uint256 => ProposalVote) private _proposalVotes; /** * @dev See {IGovernor-COUNTING_MODE}. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual override returns (string memory) { return "support=bravo&quorum=for,abstain"; } /** * @dev See {IGovernor-hasVoted}. */ function hasVoted(uint256 proposalId, uint256 tokenId) public view virtual override returns (bool) { return _proposalVotes[proposalId].hasVoted[tokenId]; } /** * @dev Accessor to the internal vote counts. */ function proposalVotes( uint256 proposalId ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } /** * @dev See {Governor-_quorumReached}. */ function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes; } /** * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. */ function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return proposalVote.forVotes > proposalVote.againstVotes; } /** * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). */ function _countVote( uint256 proposalId, uint256 tokenId, uint8 support, uint256 weight, bytes memory // params ) internal virtual override { ProposalVote storage proposalVote = _proposalVotes[proposalId]; require(!proposalVote.hasVoted[tokenId], "GovernorVotingSimple: vote already cast"); require(weight > 0, "GovernorVotingSimple: zero voting weight"); proposalVote.hasVoted[tokenId] = true; if (support == uint8(VoteType.Against)) { proposalVote.againstVotes += weight; } else if (support == uint8(VoteType.For)) { proposalVote.forVotes += weight; } else if (support == uint8(VoteType.Abstain)) { proposalVote.abstainVotes += weight; } else { revert("GovernorVotingSimple: invalid value for enum VoteType"); } } } pragma solidity 0.8.19; library DelegationHelperLibrary { uint256 public constant DURATION = 7 days; /// Helper function to fetch the checkpoint for the last voting checkpoint prior to a timepoint /// Adapted from DelegationLogicLibrary.sol:getPastVotesIndex(uint256 tokenId, uint256 timestamp) function getPastCheckpointIndex( IVotingEscrow ve, uint256 mTokenId, uint256 timepoint ) internal view returns (uint48) { uint48 nCheckpoints = ve.numCheckpoints(mTokenId); if (nCheckpoints == 0) return 0; // First check most recent balance if (ve.checkpoints(mTokenId, nCheckpoints - 1).fromTimestamp <= timepoint) return (nCheckpoints - 1); // Next check implicit zero balance if (ve.checkpoints(mTokenId, 0).fromTimestamp > timepoint) return 0; uint48 lower = 0; uint48 upper = nCheckpoints - 1; IVotingEscrow.Checkpoint memory cp; while (upper > lower) { uint48 center = upper - (upper - lower) / 2; // ceil, avoiding overflow cp = ve.checkpoints(mTokenId, center); if (cp.fromTimestamp == timepoint) { return center; } else if (cp.fromTimestamp < timepoint) { lower = center; } else { upper = center - 1; } } return lower; } /// Helper function to calculate the locked balance owed to a locked nft at a certain timepoint /// It calculates the rewards until the end of the current epoch. As rewards are lagged by one epoch /// This means it includes rewards that the user is projected to get in the following epoch. /// These rewards are not immediately claimable, but the user can vote as if they claimed it. /// Adapted from Reward.sol:earned(address token, uint256 tokenId) function earned( IVotingEscrow ve, uint256 mTokenId, uint256 tokenId, uint256 timepoint ) internal view returns (uint256) { IReward lmr = IReward(ve.managedToLocked(mTokenId)); if (lmr.numCheckpoints(tokenId) == 0) { return 0; } address _rewardToken = ve.token(); uint256 reward = 0; uint256 _supply = 1; uint256 _currTs = ProtocolTimeLibrary.epochStart(lmr.lastEarn(_rewardToken, tokenId)); // take epoch last claimed in as starting point uint256 _index = lmr.getPriorBalanceIndex(tokenId, _currTs); (uint256 _cpTs, uint256 _cpBalanceOf) = lmr.checkpoints(tokenId, _index); // accounts for case where lastEarn is before first checkpoint _currTs = Math.max(_currTs, ProtocolTimeLibrary.epochStart(_cpTs)); // get epochs between end of the current epoch and first checkpoint in same epoch as last claim uint256 numEpochs = (ProtocolTimeLibrary.epochNext(timepoint) - _currTs) / DURATION; uint256 _priorSupply; if (numEpochs > 0) { for (uint256 i = 0; i < numEpochs; i++) { // get index of last checkpoint in this epoch _index = lmr.getPriorBalanceIndex(tokenId, _currTs + DURATION - 1); // get checkpoint in this epoch (_cpTs, _cpBalanceOf) = lmr.checkpoints(tokenId, _index); // get supply of last checkpoint in this epoch (, _priorSupply) = lmr.supplyCheckpoints(lmr.getPriorSupplyIndex(_currTs + DURATION - 1)); _supply = Math.max(_priorSupply, 1); reward += (_cpBalanceOf * lmr.tokenRewardsPerEpoch(_rewardToken, _currTs)) / _supply; _currTs += DURATION; } } return reward; } } // OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotes.sol) pragma solidity ^0.8.0; /** * @dev OpenZeppelin's GovernorVotes using VetoGovernor */ abstract contract VetoGovernorVotes is VetoGovernor { using DelegationHelperLibrary for IVotingEscrow; IVotes public immutable token; IVotingEscrow public immutable ve; constructor(IVotes votes) { token = votes; ve = IVotingEscrow(address(votes)); } /** * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token * does not implement EIP-6372. */ function clock() public view virtual override returns (uint48) { try IERC6372(address(token)).clock() returns (uint48 timepoint) { return timepoint; } catch { return SafeCast.toUint48(block.number); } } /** * @dev Machine-readable description of the clock as specified in EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory) { try IERC6372(address(token)).CLOCK_MODE() returns (string memory clockmode) { return clockmode; } catch { return "mode=blocknumber&from=default"; } } /** * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). */ function _getVotes( address account, uint256 tokenId, uint256 timepoint, bytes memory /*params*/ ) internal view virtual override returns (uint256) { IVotingEscrow.EscrowType escrowType = ve.escrowType(tokenId); require(escrowType != IVotingEscrow.EscrowType.MANAGED, "Governor: managed nft cannot vote"); if (escrowType == IVotingEscrow.EscrowType.NORMAL) { return token.getPastVotes(account, tokenId, timepoint); } // only allow locked veNFT voting if underlying nft not delegating at timepoint uint256 mTokenId = ve.idToManaged(tokenId); uint48 index = ve.getPastCheckpointIndex(mTokenId, timepoint); uint256 delegatee = ve.checkpoints(mTokenId, index).delegatee; if (delegatee == 0) { // if mveNFT not delegating, voting balance = delegated balance + // initial contribution to mveNFT + accrued locked rewards uint256 delegatedBalance = token.getPastVotes(account, tokenId, timepoint); uint256 weight = ve.weights(tokenId, mTokenId); // initial deposit weight uint256 _earned = ve.earned(mTokenId, tokenId, timepoint); // accrued rewards return weight + _earned + delegatedBalance; } // nft locked and underlying nft delegating // balance will only be delegated balance return token.getPastVotes(account, tokenId, timepoint); } function getVotes(uint256 tokenId, uint256 timepoint) external view returns (uint256) { address account = ve.ownerOf(tokenId); return _getVotes(account, tokenId, timepoint, ""); } } // OpenZeppelin Contracts (last updated v4.8.0) (governance/extensions/GovernorVotesQuorumFraction.sol) pragma solidity ^0.8.0; /** * @dev OpenZeppelin's GovernorVotesQuorumFraction using VetoGovernor */ abstract contract VetoGovernorVotesQuorumFraction is VetoGovernorVotes { using SafeCast for *; using Checkpoints for Checkpoints.Trace224; uint256 private _quorumNumerator; // DEPRECATED in favor of _quorumNumeratorHistory /// @custom:oz-retyped-from Checkpoints.History Checkpoints.Trace224 private _quorumNumeratorHistory; event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); /** * @dev Initialize quorum as a fraction of the token's total supply. * * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be * customized by overriding {quorumDenominator}. */ constructor(uint256 quorumNumeratorValue) { _updateQuorumNumerator(quorumNumeratorValue); } /** * @dev Returns the current quorum numerator. See {quorumDenominator}. */ function quorumNumerator() public view virtual returns (uint256) { return _quorumNumeratorHistory._checkpoints.length == 0 ? _quorumNumerator : _quorumNumeratorHistory.latest(); } /** * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}. */ function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) { // If history is empty, fallback to old storage uint256 length = _quorumNumeratorHistory._checkpoints.length; if (length == 0) { return _quorumNumerator; } // Optimistic search, check the latest checkpoint Checkpoints.Checkpoint224 memory latest = _quorumNumeratorHistory._checkpoints[length - 1]; if (latest._key <= timepoint) { return latest._value; } // Otherwise, do the binary search return _quorumNumeratorHistory.upperLookupRecent(timepoint.toUint32()); } /** * @dev Returns the quorum denominator. Defaults to 100, but may be overridden. */ function quorumDenominator() public view virtual returns (uint256) { return 100; } /** * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`. */ function quorum(uint256 timepoint) public view virtual override returns (uint256) { return (token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator(); } /** * @dev Changes the quorum numerator. * * Emits a {QuorumNumeratorUpdated} event. * * Requirements: * * - Must be called through a governance proposal. * - New numerator must be smaller or equal to the denominator. */ function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance { _updateQuorumNumerator(newQuorumNumerator); } /** * @dev Changes the quorum numerator. * * Emits a {QuorumNumeratorUpdated} event. * * Requirements: * * - New numerator must be smaller or equal to the denominator. */ function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { require( newQuorumNumerator <= quorumDenominator(), "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator" ); uint256 oldQuorumNumerator = quorumNumerator(); // Make sure we keep track of the original numerator in contracts upgraded from a version without checkpoints. if (oldQuorumNumerator != 0 && _quorumNumeratorHistory._checkpoints.length == 0) { _quorumNumeratorHistory._checkpoints.push( Checkpoints.Checkpoint224({_key: 0, _value: oldQuorumNumerator.toUint224()}) ); } // Set new quorum for future proposals _quorumNumeratorHistory.push(clock().toUint32(), newQuorumNumerator.toUint224()); emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); } } pragma solidity 0.8.19; /// @title ProtocolGovernor /// @author velodrome.finance, @figs999, @pegahcarter /// @notice Protocol governance with timestamp-based voting power from VotingEscrow NFTs /// Supports vetoing of proposals as mitigation for 51% attacks /// Votes are cast and counted on a per tokenId basis contract ProtocolGovernor is VetoGovernor, VetoGovernorCountingSimple, VetoGovernorVotes, VetoGovernorVotesQuorumFraction { IVoter public immutable voter; address public team; address public pendingTeam; address public vetoer; address public pendingVetoer; uint256 public constant MAX_PROPOSAL_NUMERATOR = 500; // max 5% uint256 public constant PROPOSAL_DENOMINATOR = 10_000; uint256 public proposalNumerator = 0; // 1% error CommentWeightingTooHigh(); error NotGovernor(); error NotPendingTeam(); error NotTeam(); error NotPendingVetoer(); error NotVetoer(); error ProposalNumeratorTooHigh(); error ZeroAddress(); event AcceptTeam(address indexed newTeam); event AcceptVetoer(address indexed vetoer); event RenounceVetoer(); event SetCommentWeighting(uint256 commentWeighting); event SetProposalNumerator(uint256 indexed proposalNumerator); constructor( IVotes _ve, IVoter _voter ) VetoGovernor("Hydrometer Governor", IVotingEscrow(address(_ve))) VetoGovernorVotes(_ve) VetoGovernorVotesQuorumFraction(25) { vetoer = msg.sender; team = msg.sender; voter = _voter; } function votingDelay() public pure override(IVetoGovernor) returns (uint256) { return (2 days); } function votingPeriod() public pure override(IVetoGovernor) returns (uint256) { return (5 days); } function setProposalNumerator(uint256 numerator) external { if (msg.sender != team) revert NotTeam(); if (numerator > MAX_PROPOSAL_NUMERATOR) revert ProposalNumeratorTooHigh(); proposalNumerator = numerator; emit SetProposalNumerator(numerator); } function proposalThreshold() public view override(VetoGovernor) returns (uint256) { return (token.getPastTotalSupply(block.timestamp - 1) * proposalNumerator) / PROPOSAL_DENOMINATOR; } function setTeam(address _pendingTeam) external { if (_pendingTeam == address(0)) revert ZeroAddress(); if (msg.sender != team) revert NotTeam(); pendingTeam = _pendingTeam; } function acceptTeam() external { if (msg.sender != pendingTeam) revert NotPendingTeam(); team = pendingTeam; delete pendingTeam; emit AcceptTeam(team); } /// @dev Vetoer can be removed once the risk of a 51% attack becomes unfeasible. /// This can be done by transferring ownership of vetoer to a contract that is "bricked" /// i.e. a non-zero address contract that is immutable with no ability to call this function. function setVetoer(address _vetoer) external { if (msg.sender != vetoer) revert NotVetoer(); if (_vetoer == address(0)) revert ZeroAddress(); pendingVetoer = _vetoer; } function acceptVetoer() external { if (msg.sender != pendingVetoer) revert NotPendingVetoer(); vetoer = pendingVetoer; delete pendingVetoer; emit AcceptVetoer(vetoer); } /// @notice Support for vetoer to protect against 51% attacks function veto(uint256 _proposalId) external { if (msg.sender != vetoer) revert NotVetoer(); _veto(_proposalId); } function renounceVetoer() external { if (msg.sender != vetoer) revert NotVetoer(); delete vetoer; emit RenounceVetoer(); } /// @notice Set minimum % of total supply required to comment /// @dev Callable only by voter.governor() (i.e. this contract) /// @param _commentWeighting Weighting required for comment (note the denominator value). function setCommentWeighting(uint256 _commentWeighting) external { if (_commentWeighting > COMMENT_DENOMINATOR) revert CommentWeightingTooHigh(); if (msg.sender != voter.governor()) revert NotGovernor(); commentWeighting = _commentWeighting; emit SetCommentWeighting(_commentWeighting); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IVotes","name":"_ve","type":"address"},{"internalType":"contract IVoter","name":"_voter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CommentWeightingTooHigh","type":"error"},{"inputs":[],"name":"Empty","type":"error"},{"inputs":[],"name":"NotGovernor","type":"error"},{"inputs":[],"name":"NotPendingTeam","type":"error"},{"inputs":[],"name":"NotPendingVetoer","type":"error"},{"inputs":[],"name":"NotTeam","type":"error"},{"inputs":[],"name":"NotVetoer","type":"error"},{"inputs":[],"name":"ProposalNumeratorTooHigh","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTeam","type":"address"}],"name":"AcceptTeam","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vetoer","type":"address"}],"name":"AcceptVetoer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"comment","type":"string"}],"name":"Comment","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"voteStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voteEnd","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalVetoed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"QuorumNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"RenounceVetoer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"commentWeighting","type":"uint256"}],"name":"SetCommentWeighting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalNumerator","type":"uint256"}],"name":"SetProposalNumerator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"VoteCastWithParams","type":"event"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMMENT_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COUNTING_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"EXTENDED_BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PROPOSAL_NUMERATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROPOSAL_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptVetoer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"castVoteWithReasonAndParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteWithReasonAndParamsBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"message","type":"string"}],"name":"comment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"commentWeighting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"escrow","outputs":[{"internalType":"contract IVotingEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"},{"internalType":"address","name":"proposer","type":"address"}],"name":"execute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"timepoint","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"getVotesWithParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"},{"internalType":"address","name":"proposer","type":"address"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pendingTeam","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingVetoer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"relay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceVetoer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_commentWeighting","type":"uint256"}],"name":"setCommentWeighting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"}],"name":"setProposalNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingTeam","type":"address"}],"name":"setTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vetoer","type":"address"}],"name":"setVetoer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum IVetoGovernor.ProposalState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"team","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IVotes","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"updateQuorumNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ve","outputs":[{"internalType":"contract IVotingEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vetoer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101e060405260006003556000600e553480156200001c57600080fd5b50604051620062b0380380620062b08339810160408190526200003f91620007e2565b6019826040518060400160405280601381526020017f487964726f6d6574657220476f7665726e6f720000000000000000000000000081525084816200008a620001af60201b60201c565b62000097826000620001ca565b60e052620000a7816001620001ca565b61010052815160208084019190912061012052815190820120610140524660a052620001376101205161014051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05260026200014e8382620008c6565b506001600160a01b0390811661016052919091166101808190526101a05250620001788162000203565b50600c8054336001600160a01b03199182168117909255600a805490911690911790556001600160a01b03166101c0525062000a53565b6040805180820190915260018152603160f81b602082015290565b6000602083511015620001ea57620001e28362000386565b9050620001fd565b81620001f78482620008c6565b50600090505b92915050565b60648111156200028c5760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a4015b60405180910390fd5b600062000298620003c9565b90508015801590620002aa5750600954155b156200031257604080518082019091526000815260099060208101620002d084620003f8565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b62000347620003326200032462000467565b65ffffffffffff16620004de565b6200033d84620003f8565b6009919062000545565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a15050565b600080829050601f81511115620003b4578260405163305a27a960e01b815260040162000283919062000992565b8051620003c182620009e2565b179392505050565b60095460009015620003ef57620003e1600962000562565b6001600160e01b0316905090565b6008545b905090565b60006001600160e01b03821115620004635760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b606482015260840162000283565b5090565b6000610180516001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015620004c9575060408051601f3d908101601f19168201909252620004c69181019062000a07565b60015b620004d957620003f343620005b0565b919050565b600063ffffffff821115620004635760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b606482015260840162000283565b6000806200055585858562000619565b915091505b935093915050565b80546000908015620005a6576200058e836200058060018462000a31565b600091825260209091200190565b5464010000000090046001600160e01b0316620005a9565b60005b9392505050565b600065ffffffffffff821115620004635760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b606482015260840162000283565b8254600090819080156200076e5760006200063b876200058060018562000a31565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b031660208401529192509087161015620006bf5760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b6579730000000000604482015260640162000283565b805163ffffffff8088169116036200070d5784620006e4886200058060018662000a31565b80546001600160e01b03929092166401000000000263ffffffff9092169190911790556200075d565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216640100000000029216919091179101555b6020015192508391506200055a9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a8152918220955192519093166401000000000291909316179201919091559050816200055a565b6001600160a01b0381168114620007df57600080fd5b50565b60008060408385031215620007f657600080fd5b82516200080381620007c9565b60208401519092506200081681620007c9565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200084c57607f821691505b6020821081036200086d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620008c157600081815260208120601f850160051c810160208610156200089c5750805b601f850160051c820191505b81811015620008bd57828155600101620008a8565b5050505b505050565b81516001600160401b03811115620008e257620008e262000821565b620008fa81620008f3845462000837565b8462000873565b602080601f831160018114620009325760008415620009195750858301515b600019600386901b1c1916600185901b178555620008bd565b600085815260208120601f198616915b82811015620009635788860151825594840194600190910190840162000942565b5085821015620009825787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083528351808285015260005b81811015620009c157858101830151858201604001528201620009a3565b506000604082860101526040601f19601f8301168501019250505092915050565b805160208083015191908110156200086d5760001960209190910360031b1b16919050565b60006020828403121562000a1a57600080fd5b815165ffffffffffff81168114620005a957600080fd5b81810381811115620001fd57634e487b7160e01b600052601160045260246000fd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c05161576662000b4a6000396000818161065c01526116d101526000818161050b01528181611c62015281816125cf01528181612779015281816127fd01528181612856015281816129970152612a13015260008181610c11015281816117c101528181611bb501528181611dda01528181612168015281816126ed015281816128ff0152612a8d015260008181610b5101526112ef015260006141870152600061415f01526000611b6101526000611b37015260006140ba015260006140e40152600061410e01526157666000f3fe60806040526004361061039b5760003560e01c806367e2e078116101dc578063c01f9e3711610102578063dea112a6116100a0578063f8ce560a1161006f578063f8ce560a14610b9f578063f945970a14610bbf578063fa25f37714610bdf578063fc0c546a14610bff57600080fd5b8063dea112a614610aeb578063deaaa7cc14610b0b578063e2fdcc1714610b3f578063f23a6e6114610b7357600080fd5b8063cf781d45116100dc578063cf781d4514610a45578063d152a32e14610a65578063d8bff44014610a85578063dd4e2ba514610aa557600080fd5b8063c01f9e37146109d9578063c28bc2fa14610a12578063c2e863e414610a2557600080fd5b80639f8b33921161017a578063b58131b011610149578063b58131b014610963578063b5cc143a14610978578063bc197c811461098d578063be443ad0146109b957600080fd5b80639f8b3392146108f8578063a67d06351461090e578063a7713a701461092e578063aedbfe331461094357600080fd5b806391ddadf4116101b657806391ddadf41461088357806391f36633146108af57806395b6d6bd146108cf57806397c3d334146108e457600080fd5b806367e2e0781461082557806384b0196e1461083b57806385f2aef21461086357600080fd5b80633e4f49e6116102c1578063544ffc9c1161025f57806360c4247f1161022e57806360c4247f1461079e57806360e69a7b146107be578063638663ac146107d157806364390ff1146107e657600080fd5b8063544ffc9c146106df57806354fd4d5014610734578063592a84941461075e57806359d46ffc1461077e57600080fd5b806349758df21161029b57806349758df21461067e5780634bf5d7e91461069e578063501fa8bd146106b3578063525f9c3e146106c957600080fd5b80633e4f49e6146105fd578063452115d61461062a57806346c96aac1461064a57600080fd5b8063150b7a02116103395780632d63f693116103085780632d63f6931461055d5780632fe3e26114610593578063380a243a146105c75780633932abb1146105e757600080fd5b8063150b7a02146104a05780631d28dec7146104d95780631f850716146104f957806322b36ac61461054557600080fd5b806306fdde031161037557806306fdde031461041e578063095cf5c6146104405780630f8a88361461046057806311fd26f41461048057600080fd5b806301ffc9a7146103a957806302a251a3146103de57806306f3f9e6146103fe57600080fd5b366103a457005b005b600080fd5b3480156103b557600080fd5b506103c96103c4366004614659565b610c33565b60405190151581526020015b60405180910390f35b3480156103ea57600080fd5b50620697805b6040519081526020016103d5565b34801561040a57600080fd5b506103a2610419366004614683565b610ca0565b34801561042a57600080fd5b50610433610d12565b6040516103d591906146ec565b34801561044c57600080fd5b506103a261045b366004614714565b610da4565b34801561046c57600080fd5b506103f061047b36600461495d565b610e18565b34801561048c57600080fd5b506103f061049b366004614a27565b6111bb565b3480156104ac57600080fd5b506104c06104bb366004614a5c565b6111e7565b6040516001600160e01b031990911681526020016103d5565b3480156104e557600080fd5b506103a26104f4366004614683565b6111f8565b34801561050557600080fd5b5061052d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016103d5565b34801561055157600080fd5b506103f0633b9aca0081565b34801561056957600080fd5b506103f0610578366004614683565b6000908152600460205260409020546001600160401b031690565b34801561059f57600080fd5b506103f07fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156105d357600080fd5b506103a26105e2366004614b0f565b611230565b3480156105f357600080fd5b506202a3006103f0565b34801561060957600080fd5b5061061d610618366004614683565b61143f565b6040516103d59190614b77565b34801561063657600080fd5b506103f0610645366004614b9f565b61159b565b34801561065657600080fd5b5061052d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561068a57600080fd5b506103a2610699366004614683565b6116aa565b3480156106aa57600080fd5b506104336117bd565b3480156106bf57600080fd5b506103f06101f481565b3480156106d557600080fd5b506103f060035481565b3480156106eb57600080fd5b506107196106fa366004614683565b6000908152600760205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016103d5565b34801561074057600080fd5b506040805180820190915260018152603160f81b6020820152610433565b34801561076a57600080fd5b506103a2610779366004614683565b61187f565b34801561078a57600080fd5b50600b5461052d906001600160a01b031681565b3480156107aa57600080fd5b506103f06107b9366004614683565b611900565b6103f06107cc366004614c2e565b6119b1565b3480156107dd57600080fd5b506103a2611ac3565b3480156107f257600080fd5b506103c9610801366004614cd4565b60009182526007602090815260408084209284526003909201905290205460ff1690565b34801561083157600080fd5b506103f061271081565b34801561084757600080fd5b50610850611b29565b6040516103d59796959493929190614d31565b34801561086f57600080fd5b50600a5461052d906001600160a01b031681565b34801561088f57600080fd5b50610898611bb1565b60405165ffffffffffff90911681526020016103d5565b3480156108bb57600080fd5b506103f06108ca366004614cd4565b611c3f565b3480156108db57600080fd5b506103a2611cea565b3480156108f057600080fd5b5060646103f0565b34801561090457600080fd5b506103f0600e5481565b34801561091a57600080fd5b50600d5461052d906001600160a01b031681565b34801561093a57600080fd5b506103f0611d69565b34801561094f57600080fd5b506103f061095e366004614c2e565b611d93565b34801561096f57600080fd5b506103f0611dd0565b34801561098457600080fd5b506103a2611e87565b34801561099957600080fd5b506104c06109a8366004614da1565b63bc197c8160e01b95945050505050565b3480156109c557600080fd5b506103f06109d4366004614e52565b611f06565b3480156109e557600080fd5b506103f06109f4366004614683565b6000908152600460205260409020600101546001600160401b031690565b6103a2610a20366004614edd565b611f5d565b348015610a3157600080fd5b506103f0610a40366004614f20565b61204f565b348015610a5157600080fd5b506103f0610a60366004614f87565b612098565b348015610a7157600080fd5b506103a2610a80366004614714565b6120af565b348015610a9157600080fd5b50600c5461052d906001600160a01b031681565b348015610ab157600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610433565b348015610af757600080fd5b506103f0610b06366004614fd1565b612123565b348015610b1757600080fd5b506103f07f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610b4b57600080fd5b5061052d7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b7f57600080fd5b506104c0610b8e366004615006565b63f23a6e6160e01b95945050505050565b348015610bab57600080fd5b506103f0610bba366004614683565b612145565b348015610bcb57600080fd5b506103f0610bda36600461506e565b6121ef565b348015610beb57600080fd5b506103f0610bfa36600461511e565b6122e9565b348015610c0b57600080fd5b5061052d7f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b031982166367276c3760e01b1480610c6457506001600160e01b03198216631debdb9560e31b145b80610c7f57506001600160e01b03198216630271189760e51b145b80610c9a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b333014610cef5760405162461bcd60e51b8152602060048201526018602482015277476f7665726e6f723a206f6e6c79476f7665726e616e636560401b60448201526064015b60405180910390fd5b610d06565b80610cff6005612355565b03610cf457505b610d0f816123d4565b50565b606060028054610d2190615186565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4d90615186565b8015610d9a5780601f10610d6f57610100808354040283529160200191610d9a565b820191906000526020600020905b815481529060010190602001808311610d7d57829003601f168201915b5050505050905090565b6001600160a01b038116610dcb5760405163d92e233d60e01b815260040160405180910390fd5b600a546001600160a01b03163314610df657604051633a7cfa5d60e21b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60003381610e24611bb1565b65ffffffffffff169050610e36611dd0565b610e46838a61049b6001866151d6565b1015610eae5760405162461bcd60e51b815260206004820152603160248201527f476f7665726e6f723a2070726f706f73657220766f7465732062656c6f7720706044820152701c9bdc1bdcd85b081d1a1c995cda1bdb19607a1b6064820152608401610ce6565b6000610ec4888888888051906020012087611d93565b90508651885114610ee75760405162461bcd60e51b8152600401610ce6906151e9565b8551885114610f085760405162461bcd60e51b8152600401610ce6906151e9565b6000885111610f595760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c00000000000000006044820152606401610ce6565b600081815260046020526040902054600160401b90046001600160a01b031615610fcf5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b6064820152608401610ce6565b6000610fde6202a3008461522a565b90506000610fef620697808361522a565b905060405180610100016040528061100684612542565b6001600160401b031681526001600160a01b03871660208201526000604082015260600161103383612542565b6001600160401b0390811682526000602080840182905260408085018390526060808601849052608095860184905289845260048352928190208651815493880151888401519187166001600160e01b031990951694909417600160401b6001600160a01b039095168502176001600160e01b0316600160e01b60e092831c0217825593870151958701519585169590911c90910293909317600184015560a08401516002909301805460c0860151929095015161ffff1990951693151561ff00191693909317610100911515919091021762ff0000191662010000931515939093029290921790558a517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e091859188918e918e9181111561115757611157614731565b60405190808252806020026020018201604052801561118a57816020015b60608152602001906001900390816111755790505b508d88888f6040516111a4999897969594939291906152cb565b60405180910390a150909998505050505050505050565b60006111dd8484846111d860408051602081019091526000815290565b6125ae565b90505b9392505050565b630a85bd0160e11b5b949350505050565b600c546001600160a01b0316331461122357604051636184ba1160e01b815260040160405180910390fd5b61122c81612b05565b5050565b600084815260046020526040812060609161124a8761143f565b9050600181600881111561126057611260614b61565b148061127d5750600081600881111561127b5761127b614b61565b145b6112c95760405162461bcd60e51b815260206004820152601f60248201527f476f7665726e6f723a206e6f7420616374697665206f722070656e64696e67006044820152606401610ce6565b81546001600160401b03163360006112e3828a85896125ae565b905060006127106003547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e539e8c876040518263ffffffff1660e01b815260040161133b91815260200190565b602060405180830381865afa158015611358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137c91906153a2565b61138691906153bb565b61139091906153e8565b90508082116113ed5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20696e73756666696369656e7420766f74696e6720706f6044820152623bb2b960e91b6064820152608401610ce6565b89836001600160a01b03168c7fdb700dee4c69422ecdfd4ad68ffe25aa39c6ddffef4657f727571e095b642cc58c8c60405161142a9291906153fc565b60405180910390a45050505050505050505050565b6000818152600460205260408120600281015460ff16156114635750600792915050565b6002810154610100900460ff161561147e5750600292915050565b600281015462010000900460ff161561149a5750600892915050565b6000838152600460205260408120546001600160401b0316908190036115025760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c2069640000006044820152606401610ce6565b600061150c611bb1565b65ffffffffffff16905080821061152857506000949350505050565b6000858152600460205260409020600101546001600160401b03168181106115565750600195945050505050565b61155f86612c30565b801561157e575060008681526007602052604090208054600190910154115b1561158f5750600495945050505050565b50600395945050505050565b600033816115ac8787878786611d93565b905060006115b98261143f565b60088111156115ca576115ca614b61565b146116175760405162461bcd60e51b815260206004820152601c60248201527f476f7665726e6f723a20746f6f206c61746520746f2063616e63656c000000006044820152606401610ce6565b6000818152600460205260409020546001600160a01b03838116600160401b90920416146116925760405162461bcd60e51b815260206004820152602260248201527f476f7665726e6f723a206f6e6c792070726f706f7365722063616e2063616e63604482015261195b60f21b6064820152608401610ce6565b61169f8787878786612c7c565b979650505050505050565b633b9aca008111156116cf57604051634fa0e5e360e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611751919061542b565b6001600160a01b0316336001600160a01b03161461178257604051633b8d9d7560e21b815260040160405180910390fd5b60038190556040518181527f5abd4079db52a376d0f48814132d5f1f10624699a317971509682d7ec6db0a4f9060200160405180910390a150565b60607f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634bf5d7e96040518163ffffffff1660e01b8152600401600060405180830381865afa92505050801561183e57506040513d6000823e601f3d908101601f1916820160405261183b9190810190615448565b60015b61187a575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b600a546001600160a01b031633146118aa57604051633a7cfa5d60e21b815260040160405180910390fd5b6101f48111156118cd576040516314263b7360e11b815260040160405180910390fd5b600e81905560405181907f586fc658003980a786f5709cd2ad386034e0424082c948c863d3116f8f66566990600090a250565b600954600090808203611917575050600854919050565b600060096119266001846151d6565b81548110611936576119366154b5565b60009182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061198c57602001516001600160e01b03169392505050565b6119a061199885612dba565b600990612e1f565b6001600160e01b0316949350505050565b6000806119c18787878787611d93565b905060006119ce8261143f565b905060048160088111156119e4576119e4614b61565b14611a3b5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b6064820152608401610ce6565b60008281526004602052604090819020600201805460ff19166001179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90611a899084815260200190565b60405180910390a1611a9e8289898989612ed2565b611aab8289898989612f5c565b611ab88289898989612ed2565b509695505050505050565b600c546001600160a01b03163314611aee57604051636184ba1160e01b815260040160405180910390fd5b600c80546001600160a01b03191690556040517f62acb1bd035e6b0070db32c18d981d7ef3d5921d59efd75de499c7632df8dd7990600090a1565b600060608082808083611b5c7f00000000000000000000000000000000000000000000000000000000000000008361305e565b611b877f0000000000000000000000000000000000000000000000000000000000000000600161305e565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c2d575060408051601f3d908101601f19168201909252611c2a918101906154cb565b60015b61187a57611c3a4361310a565b905090565b6040516331a9108f60e11b81526004810183905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015611ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ccd919061542b565b90506111f0818585604051806020016040528060008152506125ae565b600d546001600160a01b03163314611d155760405163f37fda0760e01b815260040160405180910390fd5b600d8054600c80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517f03ae59c1e4263c9049c7aab44b77283fa0484d5d0f714e102cd9857f8fc5274d90600090a2565b60095460009015611d8c57611d7e6009613171565b6001600160e01b0316905090565b5060085490565b60008585858585604051602001611dae9594939291906154f3565b60408051601f1981840301815291905280516020909101209695505050505050565b6000612710600e547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e539e8c600142611e1491906151d6565b6040518263ffffffff1660e01b8152600401611e3291815260200190565b602060405180830381865afa158015611e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7391906153a2565b611e7d91906153bb565b611c3a91906153e8565b600b546001600160a01b03163314611eb25760405163071110c760e51b815260040160405180910390fd5b600b8054600a80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fe25466fe8250322bee73bc230e10775fe0da57be723ebdabfdc8b62b4ba0d10c90600090a2565b600080339050611f518882898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92506131aa915050565b98975050505050505050565b333014611fa75760405162461bcd60e51b8152602060048201526018602482015277476f7665726e6f723a206f6e6c79476f7665726e616e636560401b6044820152606401610ce6565b611fbe565b80611fb76005612355565b03611fac57505b600080856001600160a01b0316858585604051611fdc929190615176565b60006040518083038185875af1925050503d8060008114612019576040519150601f19603f3d011682016040523d82523d6000602084013e61201e565b606091505b509150915061204682826040518060600160405280602881526020016156e260289139613304565b50505050505050565b60008033905061169f8782888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061331d92505050565b60006120a6858585856125ae565b95945050505050565b600c546001600160a01b031633146120da57604051636184ba1160e01b815260040160405180910390fd5b6001600160a01b0381166121015760405163d92e233d60e01b815260040160405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000803390506120a6858286866040518060200160405280600081525061331d565b6000606461215283611900565b604051632394e7a360e21b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638e539e8c90602401602060405180830381865afa1580156121b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121db91906153a2565b6121e591906153bb565b610c9a91906153e8565b60008061229361228b7fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888d8c8c8c60405161222b929190615176565b60405180910390208b80519060200120604051602001612270959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b6040516020818303038152906040528051906020012061334b565b868686613378565b90506122da8b828c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506131aa915050565b9b9a5050505050505050505050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810187905260ff8516606082015260009081906123379061228b90608001612270565b9050611f51888289896040518060200160405280600081525061331d565b60006123708254600f81810b600160801b909204900b131590565b1561238e57604051631ed9509560e11b815260040160405180910390fd5b508054600f0b6000818152600180840160205260408220805492905583546fffffffffffffffffffffffffffffffff191692016001600160801b03169190911790915590565b60648111156124575760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a401610ce6565b6000612461611d69565b905080158015906124725750600954155b156124d657604080518082019091526000815260099060208101612495846133a0565b6001600160e01b039081169091528254600181018455600093845260209384902083519490930151909116600160201b0263ffffffff909316929092179101555b6125036124f16124e4611bb1565b65ffffffffffff16612dba565b6124fa846133a0565b60099190613409565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a15050565b60006001600160401b038211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610ce6565b5090565b60405161f8e560ef1b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637c72800090602401602060405180830381865afa158015612616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263a919061554f565b9050600281600281111561265057612650614b61565b036126a75760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a206d616e61676564206e66742063616e6e6f7420766f746044820152606560f81b6064820152608401610ce6565b60008160028111156126bb576126bb614b61565b0361276057604051634d6fb77560e01b81526001600160a01b03878116600483015260248201879052604482018690527f00000000000000000000000000000000000000000000000000000000000000001690634d6fb77590606401602060405180830381865afa158015612734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275891906153a2565b9150506111f0565b6040516319a0a9d560e01b8152600481018690526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906319a0a9d590602401602060405180830381865afa1580156127c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ec91906153a2565b905060006128246001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168388613424565b604051631e09967560e31b81526004810184905265ffffffffffff821660248201529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f04cb3a890604401608060405180830381865afa15801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190615570565b60600151905080600003612a6057604051634d6fb77560e01b81526001600160a01b038a81166004830152602482018a9052604482018990526000917f000000000000000000000000000000000000000000000000000000000000000090911690634d6fb77590606401602060405180830381865afa158015612948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296c91906153a2565b60405163145615f560e21b8152600481018b9052602481018690529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063515857d490604401602060405180830381865afa1580156129de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0291906153a2565b90506000612a3b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016878d8d613715565b905082612a48828461522a565b612a52919061522a565b9750505050505050506111f0565b604051634d6fb77560e01b81526001600160a01b038a81166004830152602482018a9052604482018990527f00000000000000000000000000000000000000000000000000000000000000001690634d6fb77590606401602060405180830381865afa158015612ad4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af891906153a2565b9998505050505050505050565b600080612b118361143f565b90506008816008811115612b2757612b27614b61565b14158015612b4757506002816008811115612b4457612b44614b61565b14155b8015612b6557506005816008811115612b6257612b62614b61565b14155b8015612b8357506007816008811115612b8057612b80614b61565b14155b612bcf5760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a2070726f706f73616c206e6f74206163746976650000006044820152606401610ce6565b60008381526004602052604090819020600201805462ff0000191662010000179055517fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690612c219085815260200190565b60405180910390a15090919050565b600081815260076020526040812060028101546001820154612c52919061522a565b600084815260046020526040902054612c73906001600160401b0316612145565b11159392505050565b600080612c8c8787878787611d93565b90506000612c998261143f565b90506008816008811115612caf57612caf614b61565b14158015612ccf57506002816008811115612ccc57612ccc614b61565b14155b8015612ced57506005816008811115612cea57612cea614b61565b14155b8015612d0b57506007816008811115612d0857612d08614b61565b14155b612d575760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a2070726f706f73616c206e6f74206163746976650000006044820152606401610ce6565b60008281526004602052604090819020600201805461ff001916610100179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90612da79084815260200190565b60405180910390a1509695505050505050565b600063ffffffff8211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610ce6565b815460009081816005811115612e7c576000612e3a84613cfc565b612e4490856151d6565b60008881526020902090915081015463ffffffff9081169087161015612e6c57809150612e7a565b612e7781600161522a565b92505b505b6000612e8a87878585613de4565b90508015612ec557612eaf87612ea16001846151d6565b600091825260209091200190565b54600160201b90046001600160e01b031661169f565b6000979650505050505050565b612f55565b8181101561204657306001600160a01b0316868281518110612efb57612efb6154b5565b60200260200101516001600160a01b031603612f4557612f45848281518110612f2657612f266154b5565b6020026020010151805190602001206005613e4290919063ffffffff16565b612f4e816155db565b9050612ed7565b5050505050565b600060405180606001604052806027815260200161570a60279139855190915060005b8181101561305457600080888381518110612f9c57612f9c6154b5565b60200260200101516001600160a01b0316888481518110612fbf57612fbf6154b5565b6020026020010151888581518110612fd957612fd96154b5565b6020026020010151604051612fee91906155f4565b60006040518083038185875af1925050503d806000811461302b576040519150601f19603f3d011682016040523d82523d6000602084013e613030565b606091505b5091509150613040828287613304565b5050508061304d906155db565b9050612f7f565b5050505050505050565b606060ff8316156130795761307283613e7e565b9050610c9a565b81805461308590615186565b80601f01602080910402602001604051908101604052809291908181526020018280546130b190615186565b80156130fe5780601f106130d3576101008083540402835291602001916130fe565b820191906000526020600020905b8154815290600101906020018083116130e157829003601f168201915b50505050509050610c9a565b600065ffffffffffff8211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b6064820152608401610ce6565b805460009080156131a15761318b83612ea16001846151d6565b54600160201b90046001600160e01b03166111e0565b60009392505050565b600086815260046020526040812060016131c38961143f565b60088111156131d4576131d4614b61565b1461322d5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b6064820152608401610ce6565b805460009061324990899089906001600160401b0316876125ae565b90506132588988888488613eb3565b83516000036132ae5786886001600160a01b03167f02ecdb7f59712b7ae7cb6851cce1c64e98f94e5b51ec63809112c054622b25548b89858a6040516132a19493929190615610565b60405180910390a3611f51565b86886001600160a01b03167f7dcdc52e34b09364e599a32b0e3ccb5b730a7b952ddbdf4f237ea785da228ce78b89858a8a6040516132f0959493929190615638565b60405180910390a398975050505050505050565b606083156133135750816111e0565b6111e08383614083565b6000613341868686868661333c60408051602081019091526000815290565b6131aa565b9695505050505050565b6000610c9a6133586140ad565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000613389878787876141d8565b915091506133968161429c565b5095945050505050565b60006001600160e01b038211156125aa5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401610ce6565b6000806134178585856143e6565b915091505b935093915050565b604051635058979360e01b81526004810183905260009081906001600160a01b03861690635058979390602401602060405180830381865afa15801561346e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349291906154cb565b90508065ffffffffffff166000036134ae5760009150506111e0565b826001600160a01b03861663f04cb3a8866134ca600186615672565b6040516001600160e01b031960e085901b168152600481019290925265ffffffffffff166024820152604401608060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135379190615570565b511161355057613548600182615672565b9150506111e0565b604051631e09967560e31b8152600481018590526000602482015283906001600160a01b0387169063f04cb3a890604401608060405180830381865afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c29190615570565b5111156135d35760009150506111e0565b6000806135e1600184615672565b905061361760405180608001604052806000815260200160006001600160a01b0316815260200160008152602001600081525090565b8265ffffffffffff168265ffffffffffff161115613709576000600261363d8585615672565b6136479190615698565b6136519084615672565b604051631e09967560e31b8152600481018a905265ffffffffffff821660248201529091506001600160a01b038a169063f04cb3a890604401608060405180830381865afa1580156136a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cb9190615570565b9150868260000151036136e45794506111e09350505050565b81518711156136f557809350613703565b613700600182615672565b92505b50613617565b50909695505050505050565b60405163539c6d4160e11b81526004810184905260009081906001600160a01b0387169063a738da8290602401602060405180830381865afa15801561375f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613783919061542b565b604051635058979360e01b8152600481018690529091506001600160a01b03821690635058979390602401602060405180830381865afa1580156137cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ef91906153a2565b6000036138005760009150506111f0565b6000866001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613840573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613864919061542b565b60405163f25e55a560e01b81526001600160a01b0380831660048301526024820188905291925060009160019183916138f0919087169063f25e55a590604401602060405180830381865afa1580156138c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e591906153a2565b62093a808106900390565b6040516328a3532760e21b8152600481018a9052602481018290529091506000906001600160a01b0387169063a28d4c9c90604401602060405180830381865afa158015613942573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061396691906153a2565b604051631277308160e21b8152600481018b90526024810182905290915060009081906001600160a01b038916906349dcc204906044016040805180830381865afa1580156139b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139dd91906156bd565b90925090506139f38462093a8084068403614585565b9350600062093a80613a0b86828e068e0383016151d6565b613a1591906153e8565b905060008115613ce95760005b82811015613ce7576001600160a01b038b1663a28d4c9c8f6001613a4962093a808c61522a565b613a5391906151d6565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa158015613a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab891906153a2565b95508a6001600160a01b03166349dcc2048f886040518363ffffffff1660e01b8152600401613af1929190918252602082015260400190565b6040805180830381865afa158015613b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3191906156bd565b90955093506001600160a01b038b1663f7412baf816376f4be366001613b5a62093a808d61522a565b613b6491906151d6565b6040518263ffffffff1660e01b8152600401613b8291815260200190565b602060405180830381865afa158015613b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc391906153a2565b6040518263ffffffff1660e01b8152600401613be191815260200190565b6040805180830381865afa158015613bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2191906156bd565b9250613c309050826001614585565b6040516392777b2960e01b81526001600160a01b038c81166004830152602482018a905291995089918d16906392777b2990604401602060405180830381865afa158015613c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca691906153a2565b613cb090866153bb565b613cba91906153e8565b613cc4908a61522a565b9850613cd362093a808861522a565b965080613cdf816155db565b915050613a22565b505b50959d9c50505050505050505050505050565b600081600003613d0e57506000919050565b60006001613d1b8461459b565b901c6001901b90506001818481613d3457613d346153d2565b048201901c90506001818481613d4c57613d4c6153d2565b048201901c90506001818481613d6457613d646153d2565b048201901c90506001818481613d7c57613d7c6153d2565b048201901c90506001818481613d9457613d946153d2565b048201901c90506001818481613dac57613dac6153d2565b048201901c90506001818481613dc457613dc46153d2565b048201901c90506111e081828581613dde57613dde6153d2565b0461462f565b60005b81831015613e3a576000613dfb848461463e565b60008781526020902090915063ffffffff86169082015463ffffffff161115613e2657809250613e34565b613e3181600161522a565b93505b50613de7565b509392505050565b8154600160801b90819004600f0b6000818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60408051602080825281830190925260609160ff84169160009180820181803683375050509182525060208101929092525090565b6000858152600760209081526040808320878452600381019092529091205460ff1615613f325760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f72566f74696e6753696d706c653a20766f746520616c726561604482015266191e4818d85cdd60ca1b6064820152608401610ce6565b60008311613f935760405162461bcd60e51b815260206004820152602860248201527f476f7665726e6f72566f74696e6753696d706c653a207a65726f20766f74696e60448201526719c81dd95a59da1d60c21b6064820152608401610ce6565b60008581526003820160205260409020805460ff1916600117905560ff8416613fd55782816000016000828254613fca919061522a565b9091555061407b9050565b60001960ff851601613ff55782816001016000828254613fca919061522a565b60011960ff8516016140155782816002016000828254613fca919061522a565b60405162461bcd60e51b815260206004820152603560248201527f476f7665726e6f72566f74696e6753696d706c653a20696e76616c69642076616044820152746c756520666f7220656e756d20566f74655479706560581b6064820152608401610ce6565b505050505050565b8151156140935781518083602001fd5b8060405162461bcd60e51b8152600401610ce691906146ec565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561410657507f000000000000000000000000000000000000000000000000000000000000000046145b1561413057507f000000000000000000000000000000000000000000000000000000000000000090565b611c3a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561420f5750600090506003614293565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614263573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661428c57600060019250925050614293565b9150600090505b94509492505050565b60008160048111156142b0576142b0614b61565b036142b85750565b60018160048111156142cc576142cc614b61565b036143195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610ce6565b600281600481111561432d5761432d614b61565b0361437a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610ce6565b600381600481111561438e5761438e614b61565b03610d0f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610ce6565b82546000908190801561452c57600061440487612ea16001856151d6565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144855760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606401610ce6565b805163ffffffff8088169116036144cd57846144a688612ea16001866151d6565b80546001600160e01b0392909216600160201b0263ffffffff90921691909117905561451c565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216600160201b029216919091179101555b60200151925083915061341c9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160201b02919093161792019190915590508161341c565b600081831161459457816111e0565b5090919050565b600080608083901c156145b057608092831c92015b604083901c156145c257604092831c92015b602083901c156145d457602092831c92015b601083901c156145e657601092831c92015b600883901c156145f857600892831c92015b600483901c1561460a57600492831c92015b600283901c1561461c57600292831c92015b600183901c15610c9a5760010192915050565b600081831061459457816111e0565b600061464d60028484186153e8565b6111e09084841661522a565b60006020828403121561466b57600080fd5b81356001600160e01b0319811681146111e057600080fd5b60006020828403121561469557600080fd5b5035919050565b60005b838110156146b757818101518382015260200161469f565b50506000910152565b600081518084526146d881602086016020860161469c565b601f01601f19169290920160200192915050565b6020815260006111e060208301846146c0565b6001600160a01b0381168114610d0f57600080fd5b60006020828403121561472657600080fd5b81356111e0816146ff565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561476f5761476f614731565b604052919050565b60006001600160401b0382111561479057614790614731565b5060051b60200190565b600082601f8301126147ab57600080fd5b813560206147c06147bb83614777565b614747565b82815260059290921b840181019181810190868411156147df57600080fd5b8286015b84811015611ab85780356147f6816146ff565b83529183019183016147e3565b600082601f83011261481457600080fd5b813560206148246147bb83614777565b82815260059290921b8401810191818101908684111561484357600080fd5b8286015b84811015611ab85780358352918301918301614847565b60006001600160401b0382111561487757614877614731565b50601f01601f191660200190565b60006148936147bb8461485e565b90508281528383830111156148a757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126148cf57600080fd5b6111e083833560208501614885565b600082601f8301126148ef57600080fd5b813560206148ff6147bb83614777565b82815260059290921b8401810191818101908684111561491e57600080fd5b8286015b84811015611ab85780356001600160401b038111156149415760008081fd5b61494f8986838b01016148be565b845250918301918301614922565b600080600080600060a0868803121561497557600080fd5b8535945060208601356001600160401b038082111561499357600080fd5b61499f89838a0161479a565b955060408801359150808211156149b557600080fd5b6149c189838a01614803565b945060608801359150808211156149d757600080fd5b6149e389838a016148de565b935060808801359150808211156149f957600080fd5b508601601f81018813614a0b57600080fd5b614a1a88823560208401614885565b9150509295509295909350565b600080600060608486031215614a3c57600080fd5b8335614a47816146ff565b95602085013595506040909401359392505050565b60008060008060808587031215614a7257600080fd5b8435614a7d816146ff565b93506020850135614a8d816146ff565b92506040850135915060608501356001600160401b03811115614aaf57600080fd5b614abb878288016148be565b91505092959194509250565b60008083601f840112614ad957600080fd5b5081356001600160401b03811115614af057600080fd5b602083019150836020828501011115614b0857600080fd5b9250929050565b60008060008060608587031215614b2557600080fd5b843593506020850135925060408501356001600160401b03811115614b4957600080fd5b614b5587828801614ac7565b95989497509550505050565b634e487b7160e01b600052602160045260246000fd5b6020810160098310614b9957634e487b7160e01b600052602160045260246000fd5b91905290565b60008060008060808587031215614bb557600080fd5b84356001600160401b0380821115614bcc57600080fd5b614bd88883890161479a565b95506020870135915080821115614bee57600080fd5b614bfa88838901614803565b94506040870135915080821115614c1057600080fd5b50614c1d878288016148de565b949793965093946060013593505050565b600080600080600060a08688031215614c4657600080fd5b85356001600160401b0380821115614c5d57600080fd5b614c6989838a0161479a565b96506020880135915080821115614c7f57600080fd5b614c8b89838a01614803565b95506040880135915080821115614ca157600080fd5b50614cae888289016148de565b935050606086013591506080860135614cc6816146ff565b809150509295509295909350565b60008060408385031215614ce757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614d2657815187529582019590820190600101614d0a565b509495945050505050565b60ff60f81b8816815260e060208201526000614d5060e08301896146c0565b8281036040840152614d6281896146c0565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050614d938185614cf6565b9a9950505050505050505050565b600080600080600060a08688031215614db957600080fd5b8535614dc4816146ff565b94506020860135614dd4816146ff565b935060408601356001600160401b0380821115614df057600080fd5b614dfc89838a01614803565b94506060880135915080821115614e1257600080fd5b614e1e89838a01614803565b93506080880135915080821115614e3457600080fd5b50614a1a888289016148be565b803560ff8116811461187a57600080fd5b60008060008060008060a08789031215614e6b57600080fd5b8635955060208701359450614e8260408801614e41565b935060608701356001600160401b0380821115614e9e57600080fd5b614eaa8a838b01614ac7565b90955093506080890135915080821115614ec357600080fd5b50614ed089828a016148be565b9150509295509295509295565b60008060008060608587031215614ef357600080fd5b8435614efe816146ff565b93506020850135925060408501356001600160401b03811115614b4957600080fd5b600080600080600060808688031215614f3857600080fd5b8535945060208601359350614f4f60408701614e41565b925060608601356001600160401b03811115614f6a57600080fd5b614f7688828901614ac7565b969995985093965092949392505050565b60008060008060808587031215614f9d57600080fd5b8435614fa8816146ff565b9350602085013592506040850135915060608501356001600160401b03811115614aaf57600080fd5b600080600060608486031215614fe657600080fd5b8335925060208401359150614ffd60408501614e41565b90509250925092565b600080600080600060a0868803121561501e57600080fd5b8535615029816146ff565b94506020860135615039816146ff565b9350604086013592506060860135915060808601356001600160401b0381111561506257600080fd5b614a1a888289016148be565b60008060008060008060008060006101008a8c03121561508d57600080fd5b8935985060208a013597506150a460408b01614e41565b965060608a01356001600160401b03808211156150c057600080fd5b6150cc8d838e01614ac7565b909850965060808c01359150808211156150e557600080fd5b506150f28c828d016148be565b94505061510160a08b01614e41565b925060c08a0135915060e08a013590509295985092959850929598565b60008060008060008060c0878903121561513757600080fd5b863595506020870135945061514e60408801614e41565b935061515c60608801614e41565b92506080870135915060a087013590509295509295509295565b8183823760009101908152919050565b600181811c9082168061519a57607f821691505b6020821081036151ba57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610c9a57610c9a6151c0565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b80820180821115610c9a57610c9a6151c0565b600081518084526020808501945080840160005b83811015614d265781516001600160a01b031687529582019590820190600101615251565b600081518084526020808501808196508360051b8101915082860160005b858110156152be5782840389526152ac8483516146c0565b98850198935090840190600101615294565b5091979650505050505050565b60006101208b8352602060018060a01b038c16818501528160408501526152f48285018c61523d565b91508382036060850152615308828b614cf6565b915083820360808501528189518084528284019150828160051b850101838c0160005b8381101561535957601f198784030185526153478383516146c0565b9486019492509085019060010161532b565b505086810360a088015261536d818c615276565b9450505050508560c08401528460e084015282810361010084015261539281856146c0565b9c9b505050505050505050505050565b6000602082840312156153b457600080fd5b5051919050565b8082028115828204841417610c9a57610c9a6151c0565b634e487b7160e01b600052601260045260246000fd5b6000826153f7576153f76153d2565b500490565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121561543d57600080fd5b81516111e0816146ff565b60006020828403121561545a57600080fd5b81516001600160401b0381111561547057600080fd5b8201601f8101841361548157600080fd5b805161548f6147bb8261485e565b8181528560208385010111156154a457600080fd5b6120a682602083016020860161469c565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156154dd57600080fd5b815165ffffffffffff811681146111e057600080fd5b60a08152600061550660a083018861523d565b82810360208401526155188188614cf6565b9050828103604084015261552c8187615276565b606084019590955250506001600160a01b03919091166080909101529392505050565b60006020828403121561556157600080fd5b8151600381106111e057600080fd5b60006080828403121561558257600080fd5b604051608081018181106001600160401b03821117156155a4576155a4614731565b6040528251815260208301516155b9816146ff565b6020820152604083810151908201526060928301519281019290925250919050565b6000600182016155ed576155ed6151c0565b5060010190565b6000825161560681846020870161469c565b9190910192915050565b84815260ff8416602082015282604082015260806060820152600061334160808301846146c0565b85815260ff8516602082015283604082015260a06060820152600061566060a08301856146c0565b8281036080840152611f5181856146c0565b65ffffffffffff828116828216039080821115615691576156916151c0565b5092915050565b600065ffffffffffff808416806156b1576156b16153d2565b92169190910492915050565b600080604083850312156156d057600080fd5b50508051602090910151909290915056fe476f7665726e6f723a2072656c617920726576657274656420776974686f7574206d657373616765476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765a2646970667358221220129f3447433c59a981e767b2f1452563adddce84ada246938e565b4cf0250b8564736f6c63430008130033000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1100000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d
Deployed Bytecode
0x60806040526004361061039b5760003560e01c806367e2e078116101dc578063c01f9e3711610102578063dea112a6116100a0578063f8ce560a1161006f578063f8ce560a14610b9f578063f945970a14610bbf578063fa25f37714610bdf578063fc0c546a14610bff57600080fd5b8063dea112a614610aeb578063deaaa7cc14610b0b578063e2fdcc1714610b3f578063f23a6e6114610b7357600080fd5b8063cf781d45116100dc578063cf781d4514610a45578063d152a32e14610a65578063d8bff44014610a85578063dd4e2ba514610aa557600080fd5b8063c01f9e37146109d9578063c28bc2fa14610a12578063c2e863e414610a2557600080fd5b80639f8b33921161017a578063b58131b011610149578063b58131b014610963578063b5cc143a14610978578063bc197c811461098d578063be443ad0146109b957600080fd5b80639f8b3392146108f8578063a67d06351461090e578063a7713a701461092e578063aedbfe331461094357600080fd5b806391ddadf4116101b657806391ddadf41461088357806391f36633146108af57806395b6d6bd146108cf57806397c3d334146108e457600080fd5b806367e2e0781461082557806384b0196e1461083b57806385f2aef21461086357600080fd5b80633e4f49e6116102c1578063544ffc9c1161025f57806360c4247f1161022e57806360c4247f1461079e57806360e69a7b146107be578063638663ac146107d157806364390ff1146107e657600080fd5b8063544ffc9c146106df57806354fd4d5014610734578063592a84941461075e57806359d46ffc1461077e57600080fd5b806349758df21161029b57806349758df21461067e5780634bf5d7e91461069e578063501fa8bd146106b3578063525f9c3e146106c957600080fd5b80633e4f49e6146105fd578063452115d61461062a57806346c96aac1461064a57600080fd5b8063150b7a02116103395780632d63f693116103085780632d63f6931461055d5780632fe3e26114610593578063380a243a146105c75780633932abb1146105e757600080fd5b8063150b7a02146104a05780631d28dec7146104d95780631f850716146104f957806322b36ac61461054557600080fd5b806306fdde031161037557806306fdde031461041e578063095cf5c6146104405780630f8a88361461046057806311fd26f41461048057600080fd5b806301ffc9a7146103a957806302a251a3146103de57806306f3f9e6146103fe57600080fd5b366103a457005b005b600080fd5b3480156103b557600080fd5b506103c96103c4366004614659565b610c33565b60405190151581526020015b60405180910390f35b3480156103ea57600080fd5b50620697805b6040519081526020016103d5565b34801561040a57600080fd5b506103a2610419366004614683565b610ca0565b34801561042a57600080fd5b50610433610d12565b6040516103d591906146ec565b34801561044c57600080fd5b506103a261045b366004614714565b610da4565b34801561046c57600080fd5b506103f061047b36600461495d565b610e18565b34801561048c57600080fd5b506103f061049b366004614a27565b6111bb565b3480156104ac57600080fd5b506104c06104bb366004614a5c565b6111e7565b6040516001600160e01b031990911681526020016103d5565b3480156104e557600080fd5b506103a26104f4366004614683565b6111f8565b34801561050557600080fd5b5061052d7f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1181565b6040516001600160a01b0390911681526020016103d5565b34801561055157600080fd5b506103f0633b9aca0081565b34801561056957600080fd5b506103f0610578366004614683565b6000908152600460205260409020546001600160401b031690565b34801561059f57600080fd5b506103f07fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156105d357600080fd5b506103a26105e2366004614b0f565b611230565b3480156105f357600080fd5b506202a3006103f0565b34801561060957600080fd5b5061061d610618366004614683565b61143f565b6040516103d59190614b77565b34801561063657600080fd5b506103f0610645366004614b9f565b61159b565b34801561065657600080fd5b5061052d7f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d81565b34801561068a57600080fd5b506103a2610699366004614683565b6116aa565b3480156106aa57600080fd5b506104336117bd565b3480156106bf57600080fd5b506103f06101f481565b3480156106d557600080fd5b506103f060035481565b3480156106eb57600080fd5b506107196106fa366004614683565b6000908152600760205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016103d5565b34801561074057600080fd5b506040805180820190915260018152603160f81b6020820152610433565b34801561076a57600080fd5b506103a2610779366004614683565b61187f565b34801561078a57600080fd5b50600b5461052d906001600160a01b031681565b3480156107aa57600080fd5b506103f06107b9366004614683565b611900565b6103f06107cc366004614c2e565b6119b1565b3480156107dd57600080fd5b506103a2611ac3565b3480156107f257600080fd5b506103c9610801366004614cd4565b60009182526007602090815260408084209284526003909201905290205460ff1690565b34801561083157600080fd5b506103f061271081565b34801561084757600080fd5b50610850611b29565b6040516103d59796959493929190614d31565b34801561086f57600080fd5b50600a5461052d906001600160a01b031681565b34801561088f57600080fd5b50610898611bb1565b60405165ffffffffffff90911681526020016103d5565b3480156108bb57600080fd5b506103f06108ca366004614cd4565b611c3f565b3480156108db57600080fd5b506103a2611cea565b3480156108f057600080fd5b5060646103f0565b34801561090457600080fd5b506103f0600e5481565b34801561091a57600080fd5b50600d5461052d906001600160a01b031681565b34801561093a57600080fd5b506103f0611d69565b34801561094f57600080fd5b506103f061095e366004614c2e565b611d93565b34801561096f57600080fd5b506103f0611dd0565b34801561098457600080fd5b506103a2611e87565b34801561099957600080fd5b506104c06109a8366004614da1565b63bc197c8160e01b95945050505050565b3480156109c557600080fd5b506103f06109d4366004614e52565b611f06565b3480156109e557600080fd5b506103f06109f4366004614683565b6000908152600460205260409020600101546001600160401b031690565b6103a2610a20366004614edd565b611f5d565b348015610a3157600080fd5b506103f0610a40366004614f20565b61204f565b348015610a5157600080fd5b506103f0610a60366004614f87565b612098565b348015610a7157600080fd5b506103a2610a80366004614714565b6120af565b348015610a9157600080fd5b50600c5461052d906001600160a01b031681565b348015610ab157600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610433565b348015610af757600080fd5b506103f0610b06366004614fd1565b612123565b348015610b1757600080fd5b506103f07f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610b4b57600080fd5b5061052d7f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1181565b348015610b7f57600080fd5b506104c0610b8e366004615006565b63f23a6e6160e01b95945050505050565b348015610bab57600080fd5b506103f0610bba366004614683565b612145565b348015610bcb57600080fd5b506103f0610bda36600461506e565b6121ef565b348015610beb57600080fd5b506103f0610bfa36600461511e565b6122e9565b348015610c0b57600080fd5b5061052d7f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1181565b60006001600160e01b031982166367276c3760e01b1480610c6457506001600160e01b03198216631debdb9560e31b145b80610c7f57506001600160e01b03198216630271189760e51b145b80610c9a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b333014610cef5760405162461bcd60e51b8152602060048201526018602482015277476f7665726e6f723a206f6e6c79476f7665726e616e636560401b60448201526064015b60405180910390fd5b610d06565b80610cff6005612355565b03610cf457505b610d0f816123d4565b50565b606060028054610d2190615186565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4d90615186565b8015610d9a5780601f10610d6f57610100808354040283529160200191610d9a565b820191906000526020600020905b815481529060010190602001808311610d7d57829003601f168201915b5050505050905090565b6001600160a01b038116610dcb5760405163d92e233d60e01b815260040160405180910390fd5b600a546001600160a01b03163314610df657604051633a7cfa5d60e21b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60003381610e24611bb1565b65ffffffffffff169050610e36611dd0565b610e46838a61049b6001866151d6565b1015610eae5760405162461bcd60e51b815260206004820152603160248201527f476f7665726e6f723a2070726f706f73657220766f7465732062656c6f7720706044820152701c9bdc1bdcd85b081d1a1c995cda1bdb19607a1b6064820152608401610ce6565b6000610ec4888888888051906020012087611d93565b90508651885114610ee75760405162461bcd60e51b8152600401610ce6906151e9565b8551885114610f085760405162461bcd60e51b8152600401610ce6906151e9565b6000885111610f595760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c00000000000000006044820152606401610ce6565b600081815260046020526040902054600160401b90046001600160a01b031615610fcf5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b6064820152608401610ce6565b6000610fde6202a3008461522a565b90506000610fef620697808361522a565b905060405180610100016040528061100684612542565b6001600160401b031681526001600160a01b03871660208201526000604082015260600161103383612542565b6001600160401b0390811682526000602080840182905260408085018390526060808601849052608095860184905289845260048352928190208651815493880151888401519187166001600160e01b031990951694909417600160401b6001600160a01b039095168502176001600160e01b0316600160e01b60e092831c0217825593870151958701519585169590911c90910293909317600184015560a08401516002909301805460c0860151929095015161ffff1990951693151561ff00191693909317610100911515919091021762ff0000191662010000931515939093029290921790558a517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e091859188918e918e9181111561115757611157614731565b60405190808252806020026020018201604052801561118a57816020015b60608152602001906001900390816111755790505b508d88888f6040516111a4999897969594939291906152cb565b60405180910390a150909998505050505050505050565b60006111dd8484846111d860408051602081019091526000815290565b6125ae565b90505b9392505050565b630a85bd0160e11b5b949350505050565b600c546001600160a01b0316331461122357604051636184ba1160e01b815260040160405180910390fd5b61122c81612b05565b5050565b600084815260046020526040812060609161124a8761143f565b9050600181600881111561126057611260614b61565b148061127d5750600081600881111561127b5761127b614b61565b145b6112c95760405162461bcd60e51b815260206004820152601f60248201527f476f7665726e6f723a206e6f7420616374697665206f722070656e64696e67006044820152606401610ce6565b81546001600160401b03163360006112e3828a85896125ae565b905060006127106003547f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b0316638e539e8c876040518263ffffffff1660e01b815260040161133b91815260200190565b602060405180830381865afa158015611358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137c91906153a2565b61138691906153bb565b61139091906153e8565b90508082116113ed5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20696e73756666696369656e7420766f74696e6720706f6044820152623bb2b960e91b6064820152608401610ce6565b89836001600160a01b03168c7fdb700dee4c69422ecdfd4ad68ffe25aa39c6ddffef4657f727571e095b642cc58c8c60405161142a9291906153fc565b60405180910390a45050505050505050505050565b6000818152600460205260408120600281015460ff16156114635750600792915050565b6002810154610100900460ff161561147e5750600292915050565b600281015462010000900460ff161561149a5750600892915050565b6000838152600460205260408120546001600160401b0316908190036115025760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c2069640000006044820152606401610ce6565b600061150c611bb1565b65ffffffffffff16905080821061152857506000949350505050565b6000858152600460205260409020600101546001600160401b03168181106115565750600195945050505050565b61155f86612c30565b801561157e575060008681526007602052604090208054600190910154115b1561158f5750600495945050505050565b50600395945050505050565b600033816115ac8787878786611d93565b905060006115b98261143f565b60088111156115ca576115ca614b61565b146116175760405162461bcd60e51b815260206004820152601c60248201527f476f7665726e6f723a20746f6f206c61746520746f2063616e63656c000000006044820152606401610ce6565b6000818152600460205260409020546001600160a01b03838116600160401b90920416146116925760405162461bcd60e51b815260206004820152602260248201527f476f7665726e6f723a206f6e6c792070726f706f7365722063616e2063616e63604482015261195b60f21b6064820152608401610ce6565b61169f8787878786612c7c565b979650505050505050565b633b9aca008111156116cf57604051634fa0e5e360e01b815260040160405180910390fd5b7f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d6001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611751919061542b565b6001600160a01b0316336001600160a01b03161461178257604051633b8d9d7560e21b815260040160405180910390fd5b60038190556040518181527f5abd4079db52a376d0f48814132d5f1f10624699a317971509682d7ec6db0a4f9060200160405180910390a150565b60607f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b0316634bf5d7e96040518163ffffffff1660e01b8152600401600060405180830381865afa92505050801561183e57506040513d6000823e601f3d908101601f1916820160405261183b9190810190615448565b60015b61187a575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b600a546001600160a01b031633146118aa57604051633a7cfa5d60e21b815260040160405180910390fd5b6101f48111156118cd576040516314263b7360e11b815260040160405180910390fd5b600e81905560405181907f586fc658003980a786f5709cd2ad386034e0424082c948c863d3116f8f66566990600090a250565b600954600090808203611917575050600854919050565b600060096119266001846151d6565b81548110611936576119366154b5565b60009182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061198c57602001516001600160e01b03169392505050565b6119a061199885612dba565b600990612e1f565b6001600160e01b0316949350505050565b6000806119c18787878787611d93565b905060006119ce8261143f565b905060048160088111156119e4576119e4614b61565b14611a3b5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b6064820152608401610ce6565b60008281526004602052604090819020600201805460ff19166001179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90611a899084815260200190565b60405180910390a1611a9e8289898989612ed2565b611aab8289898989612f5c565b611ab88289898989612ed2565b509695505050505050565b600c546001600160a01b03163314611aee57604051636184ba1160e01b815260040160405180910390fd5b600c80546001600160a01b03191690556040517f62acb1bd035e6b0070db32c18d981d7ef3d5921d59efd75de499c7632df8dd7990600090a1565b600060608082808083611b5c7f487964726f6d6574657220476f7665726e6f72000000000000000000000000138361305e565b611b877f3100000000000000000000000000000000000000000000000000000000000001600161305e565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60007f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c2d575060408051601f3d908101601f19168201909252611c2a918101906154cb565b60015b61187a57611c3a4361310a565b905090565b6040516331a9108f60e11b81526004810183905260009081906001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111690636352211e90602401602060405180830381865afa158015611ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ccd919061542b565b90506111f0818585604051806020016040528060008152506125ae565b600d546001600160a01b03163314611d155760405163f37fda0760e01b815260040160405180910390fd5b600d8054600c80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517f03ae59c1e4263c9049c7aab44b77283fa0484d5d0f714e102cd9857f8fc5274d90600090a2565b60095460009015611d8c57611d7e6009613171565b6001600160e01b0316905090565b5060085490565b60008585858585604051602001611dae9594939291906154f3565b60408051601f1981840301815291905280516020909101209695505050505050565b6000612710600e547f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b0316638e539e8c600142611e1491906151d6565b6040518263ffffffff1660e01b8152600401611e3291815260200190565b602060405180830381865afa158015611e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7391906153a2565b611e7d91906153bb565b611c3a91906153e8565b600b546001600160a01b03163314611eb25760405163071110c760e51b815260040160405180910390fd5b600b8054600a80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fe25466fe8250322bee73bc230e10775fe0da57be723ebdabfdc8b62b4ba0d10c90600090a2565b600080339050611f518882898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92506131aa915050565b98975050505050505050565b333014611fa75760405162461bcd60e51b8152602060048201526018602482015277476f7665726e6f723a206f6e6c79476f7665726e616e636560401b6044820152606401610ce6565b611fbe565b80611fb76005612355565b03611fac57505b600080856001600160a01b0316858585604051611fdc929190615176565b60006040518083038185875af1925050503d8060008114612019576040519150601f19603f3d011682016040523d82523d6000602084013e61201e565b606091505b509150915061204682826040518060600160405280602881526020016156e260289139613304565b50505050505050565b60008033905061169f8782888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061331d92505050565b60006120a6858585856125ae565b95945050505050565b600c546001600160a01b031633146120da57604051636184ba1160e01b815260040160405180910390fd5b6001600160a01b0381166121015760405163d92e233d60e01b815260040160405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000803390506120a6858286866040518060200160405280600081525061331d565b6000606461215283611900565b604051632394e7a360e21b8152600481018590527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690638e539e8c90602401602060405180830381865afa1580156121b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121db91906153a2565b6121e591906153bb565b610c9a91906153e8565b60008061229361228b7fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888d8c8c8c60405161222b929190615176565b60405180910390208b80519060200120604051602001612270959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b6040516020818303038152906040528051906020012061334b565b868686613378565b90506122da8b828c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506131aa915050565b9b9a5050505050505050505050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810187905260ff8516606082015260009081906123379061228b90608001612270565b9050611f51888289896040518060200160405280600081525061331d565b60006123708254600f81810b600160801b909204900b131590565b1561238e57604051631ed9509560e11b815260040160405180910390fd5b508054600f0b6000818152600180840160205260408220805492905583546fffffffffffffffffffffffffffffffff191692016001600160801b03169190911790915590565b60648111156124575760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a401610ce6565b6000612461611d69565b905080158015906124725750600954155b156124d657604080518082019091526000815260099060208101612495846133a0565b6001600160e01b039081169091528254600181018455600093845260209384902083519490930151909116600160201b0263ffffffff909316929092179101555b6125036124f16124e4611bb1565b65ffffffffffff16612dba565b6124fa846133a0565b60099190613409565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a15050565b60006001600160401b038211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610ce6565b5090565b60405161f8e560ef1b81526004810184905260009081906001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111690637c72800090602401602060405180830381865afa158015612616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263a919061554f565b9050600281600281111561265057612650614b61565b036126a75760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a206d616e61676564206e66742063616e6e6f7420766f746044820152606560f81b6064820152608401610ce6565b60008160028111156126bb576126bb614b61565b0361276057604051634d6fb77560e01b81526001600160a01b03878116600483015260248201879052604482018690527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111690634d6fb77590606401602060405180830381865afa158015612734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275891906153a2565b9150506111f0565b6040516319a0a9d560e01b8152600481018690526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b0316906319a0a9d590602401602060405180830381865afa1580156127c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ec91906153a2565b905060006128246001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11168388613424565b604051631e09967560e31b81526004810184905265ffffffffffff821660248201529091506000906001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11169063f04cb3a890604401608060405180830381865afa15801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190615570565b60600151905080600003612a6057604051634d6fb77560e01b81526001600160a01b038a81166004830152602482018a9052604482018990526000917f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1190911690634d6fb77590606401602060405180830381865afa158015612948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296c91906153a2565b60405163145615f560e21b8152600481018b9052602481018690529091506000906001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11169063515857d490604401602060405180830381865afa1580156129de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0291906153a2565b90506000612a3b6001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1116878d8d613715565b905082612a48828461522a565b612a52919061522a565b9750505050505050506111f0565b604051634d6fb77560e01b81526001600160a01b038a81166004830152602482018a9052604482018990527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111690634d6fb77590606401602060405180830381865afa158015612ad4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af891906153a2565b9998505050505050505050565b600080612b118361143f565b90506008816008811115612b2757612b27614b61565b14158015612b4757506002816008811115612b4457612b44614b61565b14155b8015612b6557506005816008811115612b6257612b62614b61565b14155b8015612b8357506007816008811115612b8057612b80614b61565b14155b612bcf5760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a2070726f706f73616c206e6f74206163746976650000006044820152606401610ce6565b60008381526004602052604090819020600201805462ff0000191662010000179055517fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690612c219085815260200190565b60405180910390a15090919050565b600081815260076020526040812060028101546001820154612c52919061522a565b600084815260046020526040902054612c73906001600160401b0316612145565b11159392505050565b600080612c8c8787878787611d93565b90506000612c998261143f565b90506008816008811115612caf57612caf614b61565b14158015612ccf57506002816008811115612ccc57612ccc614b61565b14155b8015612ced57506005816008811115612cea57612cea614b61565b14155b8015612d0b57506007816008811115612d0857612d08614b61565b14155b612d575760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a2070726f706f73616c206e6f74206163746976650000006044820152606401610ce6565b60008281526004602052604090819020600201805461ff001916610100179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90612da79084815260200190565b60405180910390a1509695505050505050565b600063ffffffff8211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610ce6565b815460009081816005811115612e7c576000612e3a84613cfc565b612e4490856151d6565b60008881526020902090915081015463ffffffff9081169087161015612e6c57809150612e7a565b612e7781600161522a565b92505b505b6000612e8a87878585613de4565b90508015612ec557612eaf87612ea16001846151d6565b600091825260209091200190565b54600160201b90046001600160e01b031661169f565b6000979650505050505050565b612f55565b8181101561204657306001600160a01b0316868281518110612efb57612efb6154b5565b60200260200101516001600160a01b031603612f4557612f45848281518110612f2657612f266154b5565b6020026020010151805190602001206005613e4290919063ffffffff16565b612f4e816155db565b9050612ed7565b5050505050565b600060405180606001604052806027815260200161570a60279139855190915060005b8181101561305457600080888381518110612f9c57612f9c6154b5565b60200260200101516001600160a01b0316888481518110612fbf57612fbf6154b5565b6020026020010151888581518110612fd957612fd96154b5565b6020026020010151604051612fee91906155f4565b60006040518083038185875af1925050503d806000811461302b576040519150601f19603f3d011682016040523d82523d6000602084013e613030565b606091505b5091509150613040828287613304565b5050508061304d906155db565b9050612f7f565b5050505050505050565b606060ff8316156130795761307283613e7e565b9050610c9a565b81805461308590615186565b80601f01602080910402602001604051908101604052809291908181526020018280546130b190615186565b80156130fe5780601f106130d3576101008083540402835291602001916130fe565b820191906000526020600020905b8154815290600101906020018083116130e157829003601f168201915b50505050509050610c9a565b600065ffffffffffff8211156125aa5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b6064820152608401610ce6565b805460009080156131a15761318b83612ea16001846151d6565b54600160201b90046001600160e01b03166111e0565b60009392505050565b600086815260046020526040812060016131c38961143f565b60088111156131d4576131d4614b61565b1461322d5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b6064820152608401610ce6565b805460009061324990899089906001600160401b0316876125ae565b90506132588988888488613eb3565b83516000036132ae5786886001600160a01b03167f02ecdb7f59712b7ae7cb6851cce1c64e98f94e5b51ec63809112c054622b25548b89858a6040516132a19493929190615610565b60405180910390a3611f51565b86886001600160a01b03167f7dcdc52e34b09364e599a32b0e3ccb5b730a7b952ddbdf4f237ea785da228ce78b89858a8a6040516132f0959493929190615638565b60405180910390a398975050505050505050565b606083156133135750816111e0565b6111e08383614083565b6000613341868686868661333c60408051602081019091526000815290565b6131aa565b9695505050505050565b6000610c9a6133586140ad565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000613389878787876141d8565b915091506133968161429c565b5095945050505050565b60006001600160e01b038211156125aa5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401610ce6565b6000806134178585856143e6565b915091505b935093915050565b604051635058979360e01b81526004810183905260009081906001600160a01b03861690635058979390602401602060405180830381865afa15801561346e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349291906154cb565b90508065ffffffffffff166000036134ae5760009150506111e0565b826001600160a01b03861663f04cb3a8866134ca600186615672565b6040516001600160e01b031960e085901b168152600481019290925265ffffffffffff166024820152604401608060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135379190615570565b511161355057613548600182615672565b9150506111e0565b604051631e09967560e31b8152600481018590526000602482015283906001600160a01b0387169063f04cb3a890604401608060405180830381865afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c29190615570565b5111156135d35760009150506111e0565b6000806135e1600184615672565b905061361760405180608001604052806000815260200160006001600160a01b0316815260200160008152602001600081525090565b8265ffffffffffff168265ffffffffffff161115613709576000600261363d8585615672565b6136479190615698565b6136519084615672565b604051631e09967560e31b8152600481018a905265ffffffffffff821660248201529091506001600160a01b038a169063f04cb3a890604401608060405180830381865afa1580156136a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cb9190615570565b9150868260000151036136e45794506111e09350505050565b81518711156136f557809350613703565b613700600182615672565b92505b50613617565b50909695505050505050565b60405163539c6d4160e11b81526004810184905260009081906001600160a01b0387169063a738da8290602401602060405180830381865afa15801561375f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613783919061542b565b604051635058979360e01b8152600481018690529091506001600160a01b03821690635058979390602401602060405180830381865afa1580156137cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ef91906153a2565b6000036138005760009150506111f0565b6000866001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613840573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613864919061542b565b60405163f25e55a560e01b81526001600160a01b0380831660048301526024820188905291925060009160019183916138f0919087169063f25e55a590604401602060405180830381865afa1580156138c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e591906153a2565b62093a808106900390565b6040516328a3532760e21b8152600481018a9052602481018290529091506000906001600160a01b0387169063a28d4c9c90604401602060405180830381865afa158015613942573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061396691906153a2565b604051631277308160e21b8152600481018b90526024810182905290915060009081906001600160a01b038916906349dcc204906044016040805180830381865afa1580156139b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139dd91906156bd565b90925090506139f38462093a8084068403614585565b9350600062093a80613a0b86828e068e0383016151d6565b613a1591906153e8565b905060008115613ce95760005b82811015613ce7576001600160a01b038b1663a28d4c9c8f6001613a4962093a808c61522a565b613a5391906151d6565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa158015613a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab891906153a2565b95508a6001600160a01b03166349dcc2048f886040518363ffffffff1660e01b8152600401613af1929190918252602082015260400190565b6040805180830381865afa158015613b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3191906156bd565b90955093506001600160a01b038b1663f7412baf816376f4be366001613b5a62093a808d61522a565b613b6491906151d6565b6040518263ffffffff1660e01b8152600401613b8291815260200190565b602060405180830381865afa158015613b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc391906153a2565b6040518263ffffffff1660e01b8152600401613be191815260200190565b6040805180830381865afa158015613bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2191906156bd565b9250613c309050826001614585565b6040516392777b2960e01b81526001600160a01b038c81166004830152602482018a905291995089918d16906392777b2990604401602060405180830381865afa158015613c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca691906153a2565b613cb090866153bb565b613cba91906153e8565b613cc4908a61522a565b9850613cd362093a808861522a565b965080613cdf816155db565b915050613a22565b505b50959d9c50505050505050505050505050565b600081600003613d0e57506000919050565b60006001613d1b8461459b565b901c6001901b90506001818481613d3457613d346153d2565b048201901c90506001818481613d4c57613d4c6153d2565b048201901c90506001818481613d6457613d646153d2565b048201901c90506001818481613d7c57613d7c6153d2565b048201901c90506001818481613d9457613d946153d2565b048201901c90506001818481613dac57613dac6153d2565b048201901c90506001818481613dc457613dc46153d2565b048201901c90506111e081828581613dde57613dde6153d2565b0461462f565b60005b81831015613e3a576000613dfb848461463e565b60008781526020902090915063ffffffff86169082015463ffffffff161115613e2657809250613e34565b613e3181600161522a565b93505b50613de7565b509392505050565b8154600160801b90819004600f0b6000818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60408051602080825281830190925260609160ff84169160009180820181803683375050509182525060208101929092525090565b6000858152600760209081526040808320878452600381019092529091205460ff1615613f325760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f72566f74696e6753696d706c653a20766f746520616c726561604482015266191e4818d85cdd60ca1b6064820152608401610ce6565b60008311613f935760405162461bcd60e51b815260206004820152602860248201527f476f7665726e6f72566f74696e6753696d706c653a207a65726f20766f74696e60448201526719c81dd95a59da1d60c21b6064820152608401610ce6565b60008581526003820160205260409020805460ff1916600117905560ff8416613fd55782816000016000828254613fca919061522a565b9091555061407b9050565b60001960ff851601613ff55782816001016000828254613fca919061522a565b60011960ff8516016140155782816002016000828254613fca919061522a565b60405162461bcd60e51b815260206004820152603560248201527f476f7665726e6f72566f74696e6753696d706c653a20696e76616c69642076616044820152746c756520666f7220656e756d20566f74655479706560581b6064820152608401610ce6565b505050505050565b8151156140935781518083602001fd5b8060405162461bcd60e51b8152600401610ce691906146ec565b6000306001600160a01b037f000000000000000000000000cc94f67da67311b187407979ee94cd7b52c8f2701614801561410657507f000000000000000000000000000000000000000000000000000000000000009246145b1561413057507f8d03e11d94d46b25eae262a8a05a339631a2ff8ae169d68e840162105e29db0f90565b611c3a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f27e7e8165e00d498bb1b43e931120d24a22f4d62bf3e60214827889b57bf91c3918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561420f5750600090506003614293565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614263573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661428c57600060019250925050614293565b9150600090505b94509492505050565b60008160048111156142b0576142b0614b61565b036142b85750565b60018160048111156142cc576142cc614b61565b036143195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610ce6565b600281600481111561432d5761432d614b61565b0361437a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610ce6565b600381600481111561438e5761438e614b61565b03610d0f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610ce6565b82546000908190801561452c57600061440487612ea16001856151d6565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144855760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606401610ce6565b805163ffffffff8088169116036144cd57846144a688612ea16001866151d6565b80546001600160e01b0392909216600160201b0263ffffffff90921691909117905561451c565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216600160201b029216919091179101555b60200151925083915061341c9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160201b02919093161792019190915590508161341c565b600081831161459457816111e0565b5090919050565b600080608083901c156145b057608092831c92015b604083901c156145c257604092831c92015b602083901c156145d457602092831c92015b601083901c156145e657601092831c92015b600883901c156145f857600892831c92015b600483901c1561460a57600492831c92015b600283901c1561461c57600292831c92015b600183901c15610c9a5760010192915050565b600081831061459457816111e0565b600061464d60028484186153e8565b6111e09084841661522a565b60006020828403121561466b57600080fd5b81356001600160e01b0319811681146111e057600080fd5b60006020828403121561469557600080fd5b5035919050565b60005b838110156146b757818101518382015260200161469f565b50506000910152565b600081518084526146d881602086016020860161469c565b601f01601f19169290920160200192915050565b6020815260006111e060208301846146c0565b6001600160a01b0381168114610d0f57600080fd5b60006020828403121561472657600080fd5b81356111e0816146ff565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561476f5761476f614731565b604052919050565b60006001600160401b0382111561479057614790614731565b5060051b60200190565b600082601f8301126147ab57600080fd5b813560206147c06147bb83614777565b614747565b82815260059290921b840181019181810190868411156147df57600080fd5b8286015b84811015611ab85780356147f6816146ff565b83529183019183016147e3565b600082601f83011261481457600080fd5b813560206148246147bb83614777565b82815260059290921b8401810191818101908684111561484357600080fd5b8286015b84811015611ab85780358352918301918301614847565b60006001600160401b0382111561487757614877614731565b50601f01601f191660200190565b60006148936147bb8461485e565b90508281528383830111156148a757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126148cf57600080fd5b6111e083833560208501614885565b600082601f8301126148ef57600080fd5b813560206148ff6147bb83614777565b82815260059290921b8401810191818101908684111561491e57600080fd5b8286015b84811015611ab85780356001600160401b038111156149415760008081fd5b61494f8986838b01016148be565b845250918301918301614922565b600080600080600060a0868803121561497557600080fd5b8535945060208601356001600160401b038082111561499357600080fd5b61499f89838a0161479a565b955060408801359150808211156149b557600080fd5b6149c189838a01614803565b945060608801359150808211156149d757600080fd5b6149e389838a016148de565b935060808801359150808211156149f957600080fd5b508601601f81018813614a0b57600080fd5b614a1a88823560208401614885565b9150509295509295909350565b600080600060608486031215614a3c57600080fd5b8335614a47816146ff565b95602085013595506040909401359392505050565b60008060008060808587031215614a7257600080fd5b8435614a7d816146ff565b93506020850135614a8d816146ff565b92506040850135915060608501356001600160401b03811115614aaf57600080fd5b614abb878288016148be565b91505092959194509250565b60008083601f840112614ad957600080fd5b5081356001600160401b03811115614af057600080fd5b602083019150836020828501011115614b0857600080fd5b9250929050565b60008060008060608587031215614b2557600080fd5b843593506020850135925060408501356001600160401b03811115614b4957600080fd5b614b5587828801614ac7565b95989497509550505050565b634e487b7160e01b600052602160045260246000fd5b6020810160098310614b9957634e487b7160e01b600052602160045260246000fd5b91905290565b60008060008060808587031215614bb557600080fd5b84356001600160401b0380821115614bcc57600080fd5b614bd88883890161479a565b95506020870135915080821115614bee57600080fd5b614bfa88838901614803565b94506040870135915080821115614c1057600080fd5b50614c1d878288016148de565b949793965093946060013593505050565b600080600080600060a08688031215614c4657600080fd5b85356001600160401b0380821115614c5d57600080fd5b614c6989838a0161479a565b96506020880135915080821115614c7f57600080fd5b614c8b89838a01614803565b95506040880135915080821115614ca157600080fd5b50614cae888289016148de565b935050606086013591506080860135614cc6816146ff565b809150509295509295909350565b60008060408385031215614ce757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614d2657815187529582019590820190600101614d0a565b509495945050505050565b60ff60f81b8816815260e060208201526000614d5060e08301896146c0565b8281036040840152614d6281896146c0565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050614d938185614cf6565b9a9950505050505050505050565b600080600080600060a08688031215614db957600080fd5b8535614dc4816146ff565b94506020860135614dd4816146ff565b935060408601356001600160401b0380821115614df057600080fd5b614dfc89838a01614803565b94506060880135915080821115614e1257600080fd5b614e1e89838a01614803565b93506080880135915080821115614e3457600080fd5b50614a1a888289016148be565b803560ff8116811461187a57600080fd5b60008060008060008060a08789031215614e6b57600080fd5b8635955060208701359450614e8260408801614e41565b935060608701356001600160401b0380821115614e9e57600080fd5b614eaa8a838b01614ac7565b90955093506080890135915080821115614ec357600080fd5b50614ed089828a016148be565b9150509295509295509295565b60008060008060608587031215614ef357600080fd5b8435614efe816146ff565b93506020850135925060408501356001600160401b03811115614b4957600080fd5b600080600080600060808688031215614f3857600080fd5b8535945060208601359350614f4f60408701614e41565b925060608601356001600160401b03811115614f6a57600080fd5b614f7688828901614ac7565b969995985093965092949392505050565b60008060008060808587031215614f9d57600080fd5b8435614fa8816146ff565b9350602085013592506040850135915060608501356001600160401b03811115614aaf57600080fd5b600080600060608486031215614fe657600080fd5b8335925060208401359150614ffd60408501614e41565b90509250925092565b600080600080600060a0868803121561501e57600080fd5b8535615029816146ff565b94506020860135615039816146ff565b9350604086013592506060860135915060808601356001600160401b0381111561506257600080fd5b614a1a888289016148be565b60008060008060008060008060006101008a8c03121561508d57600080fd5b8935985060208a013597506150a460408b01614e41565b965060608a01356001600160401b03808211156150c057600080fd5b6150cc8d838e01614ac7565b909850965060808c01359150808211156150e557600080fd5b506150f28c828d016148be565b94505061510160a08b01614e41565b925060c08a0135915060e08a013590509295985092959850929598565b60008060008060008060c0878903121561513757600080fd5b863595506020870135945061514e60408801614e41565b935061515c60608801614e41565b92506080870135915060a087013590509295509295509295565b8183823760009101908152919050565b600181811c9082168061519a57607f821691505b6020821081036151ba57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610c9a57610c9a6151c0565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b80820180821115610c9a57610c9a6151c0565b600081518084526020808501945080840160005b83811015614d265781516001600160a01b031687529582019590820190600101615251565b600081518084526020808501808196508360051b8101915082860160005b858110156152be5782840389526152ac8483516146c0565b98850198935090840190600101615294565b5091979650505050505050565b60006101208b8352602060018060a01b038c16818501528160408501526152f48285018c61523d565b91508382036060850152615308828b614cf6565b915083820360808501528189518084528284019150828160051b850101838c0160005b8381101561535957601f198784030185526153478383516146c0565b9486019492509085019060010161532b565b505086810360a088015261536d818c615276565b9450505050508560c08401528460e084015282810361010084015261539281856146c0565b9c9b505050505050505050505050565b6000602082840312156153b457600080fd5b5051919050565b8082028115828204841417610c9a57610c9a6151c0565b634e487b7160e01b600052601260045260246000fd5b6000826153f7576153f76153d2565b500490565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121561543d57600080fd5b81516111e0816146ff565b60006020828403121561545a57600080fd5b81516001600160401b0381111561547057600080fd5b8201601f8101841361548157600080fd5b805161548f6147bb8261485e565b8181528560208385010111156154a457600080fd5b6120a682602083016020860161469c565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156154dd57600080fd5b815165ffffffffffff811681146111e057600080fd5b60a08152600061550660a083018861523d565b82810360208401526155188188614cf6565b9050828103604084015261552c8187615276565b606084019590955250506001600160a01b03919091166080909101529392505050565b60006020828403121561556157600080fd5b8151600381106111e057600080fd5b60006080828403121561558257600080fd5b604051608081018181106001600160401b03821117156155a4576155a4614731565b6040528251815260208301516155b9816146ff565b6020820152604083810151908201526060928301519281019290925250919050565b6000600182016155ed576155ed6151c0565b5060010190565b6000825161560681846020870161469c565b9190910192915050565b84815260ff8416602082015282604082015260806060820152600061334160808301846146c0565b85815260ff8516602082015283604082015260a06060820152600061566060a08301856146c0565b8281036080840152611f5181856146c0565b65ffffffffffff828116828216039080821115615691576156916151c0565b5092915050565b600065ffffffffffff808416806156b1576156b16153d2565b92169190910492915050565b600080604083850312156156d057600080fd5b50508051602090910151909290915056fe476f7665726e6f723a2072656c617920726576657274656420776974686f7574206d657373616765476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765a2646970667358221220129f3447433c59a981e767b2f1452563adddce84ada246938e565b4cf0250b8564736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1100000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d
-----Decoded View---------------
Arg [0] : _ve (address): 0xe0d35cf2ab00f3C11F10535DB27807F3DE139F11
Arg [1] : _voter (address): 0x50a459FC0069843750091D6382aFC960d0b22b6d
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11
Arg [1] : 00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d
Deployed Bytecode Sourcemap
219994:4109:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;183683:37;219994:4109;;;;;183800:961;;;;;;;;;;-1:-1:-1;183800:961:0;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;183800:961:0;;;;;;;;221411:112;;;;;;;;;;-1:-1:-1;221508:6:0;221411:112;;;643:25:1;;;631:2;616:18;221411:112:0;497:177:1;218343:152:0;;;;;;;;;;-1:-1:-1;218343:152:0;;;;;:::i;:::-;;:::i;184826:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;222033:207::-;;;;;;;;;;-1:-1:-1;222033:207:0;;;;;:::i;:::-;;:::i;189870:1732::-;;;;;;;;;;-1:-1:-1;189870:1732:0;;;;;:::i;:::-;;:::i;197006:234::-;;;;;;;;;;-1:-1:-1;197006:234:0;;;;;:::i;:::-;;:::i;204100:164::-;;;;;;;;;;-1:-1:-1;204100:164:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;8116:33:1;;;8098:52;;8086:2;8071:18;204100:164:0;7954:202:1;223232:136:0;;;;;;;;;;-1:-1:-1;223232:136:0;;;;;:::i;:::-;;:::i;212397:33::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8347:32:1;;;8329:51;;8317:2;8302:18;212397:33:0;8161:225:1;181354:68:0;;;;;;;;;;;;181409:13;181354:68;;187915:151;;;;;;;;;;-1:-1:-1;187915:151:0;;;;;:::i;:::-;187999:7;188026:22;;;:10;:22;;;;;:32;-1:-1:-1;;;;;188026:32:0;;187915:151;180567:148;;;;;;;;;;;;180627:88;180567:148;;202180:789;;;;;;;;;;-1:-1:-1;202180:789:0;;;;;:::i;:::-;;:::i;221292:111::-;;;;;;;;;;-1:-1:-1;221388:6:0;221292:111;;186501:1088;;;;;;;;;;-1:-1:-1;186501:1088:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;192592:627::-;;;;;;;;;;-1:-1:-1;192592:627:0;;;;;:::i;:::-;;:::i;220144:29::-;;;;;;;;;;;;;;;223769:331;;;;;;;;;;-1:-1:-1;223769:331:0;;;;;:::i;:::-;;:::i;213146:284::-;;;;;;;;;;;;;:::i;220302:52::-;;;;;;;;;;;;220351:3;220302:52;;181303:44;;;;;;;;;;;;;;;;206154:326;;;;;;;;;;-1:-1:-1;206154:326:0;;;;;:::i;:::-;206242:20;206351:26;;;:14;:26;;;;;206396:25;;206423:21;;;;206446:25;;;;;206396;;206154:326;;;;;11288:25:1;;;11344:2;11329:18;;11322:34;;;;11372:18;;;11365:34;11276:2;11261:18;206154:326:0;11086:319:1;184994:101:0;;;;;;;;;;-1:-1:-1;185077:10:0;;;;;;;;;;;;-1:-1:-1;;;185077:10:0;;;;184994:101;;221531:288;;;;;;;;;;-1:-1:-1;221531:288:0;;;;;:::i;:::-;;:::i;220206:26::-;;;;;;;;;;-1:-1:-1;220206:26:0;;;;-1:-1:-1;;;;;220206:26:0;;;216841:671;;;;;;;;;;-1:-1:-1;216841:671:0;;;;;:::i;:::-;;:::i;191670:855::-;;;;;;:::i;:::-;;:::i;223376:154::-;;;;;;;;;;;;;:::i;205908:169::-;;;;;;;;;;-1:-1:-1;205908:169:0;;;;;:::i;:::-;206001:4;206025:26;;;:14;:26;;;;;;;;:44;;;:35;;;;:44;;;;;;;;205908:169;220371:53;;;;;;;;;;;;220418:6;220371:53;;142918:657;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;220180:19::-;;;;;;;;;;-1:-1:-1;220180:19:0;;;;-1:-1:-1;;;;;220180:19:0;;;212725:260;;;;;;;;;;;;;:::i;:::-;;;14448:14:1;14436:27;;;14418:46;;14406:2;14391:18;212725:260:0;14274:196:1;215059:202:0;;;;;;;;;;-1:-1:-1;215059:202:0;;;;;:::i;:::-;;:::i;222947:210::-;;;;;;;;;;;;;:::i;217623:96::-;;;;;;;;;;-1:-1:-1;217708:3:0;217623:96;;220431:36;;;;;;;;;;;;;;;;220267:28;;;;;;;;;;-1:-1:-1;220267:28:0;;;;-1:-1:-1;;;;;220267:28:0;;;216530:193;;;;;;;;;;;;;:::i;186083:352::-;;;;;;;;;;-1:-1:-1;186083:352:0;;;;;:::i;:::-;;:::i;221827:198::-;;;;;;;;;;;;;:::i;222248:194::-;;;;;;;;;;;;;:::i;204658:255::-;;;;;;;;;;-1:-1:-1;204658:255:0;;;;;:::i;:::-;-1:-1:-1;;;204658:255:0;;;;;;;;198354:355;;;;;;;;;;-1:-1:-1;198354:355:0;;;;;:::i;:::-;;:::i;188143:149::-;;;;;;;;;;-1:-1:-1;188143:149:0;;;;;:::i;:::-;188227:7;188254:22;;;:10;:22;;;;;:30;;;-1:-1:-1;;;;;188254:30:0;;188143:149;203428:299;;;;;;:::i;:::-;;:::i;197958:308::-;;;;;;;;;;-1:-1:-1;197958:308:0;;;;;:::i;:::-;;:::i;197319:264::-;;;;;;;;;;-1:-1:-1;197319:264:0;;;;;:::i;:::-;;:::i;222739:200::-;;;;;;;;;;-1:-1:-1;222739:200:0;;;;;:::i;:::-;;:::i;220239:21::-;;;;;;;;;;-1:-1:-1;220239:21:0;;;;-1:-1:-1;;;;;220239:21:0;;;205705:138;;;;;;;;;;-1:-1:-1;205794:41:0;;;;;;;;;;;;;;;;;;205705:138;;197652:227;;;;;;;;;;-1:-1:-1;197652:227:0;;;;;:::i;:::-;;:::i;180465:95::-;;;;;;;;;;;;180507:53;180465:95;;181429:46;;;;;;;;;;;;;;;204345:227;;;;;;;;;;-1:-1:-1;204345:227:0;;;;;:::i;:::-;-1:-1:-1;;;204345:227:0;;;;;;;;217859:196;;;;;;;;;;-1:-1:-1;217859:196:0;;;;;:::i;:::-;;:::i;199352:846::-;;;;;;;;;;-1:-1:-1;199352:846:0;;;;;:::i;:::-;;:::i;198783:476::-;;;;;;;;;;-1:-1:-1;198783:476:0;;;;;:::i;:::-;;:::i;212361:29::-;;;;;;;;;;;;;;;183800:961;183902:4;-1:-1:-1;;;;;;184128:326:0;;-1:-1:-1;;;184128:326:0;;:506;;-1:-1:-1;;;;;;;184534:100:0;;-1:-1:-1;;;184534:100:0;184128:506;:572;;;-1:-1:-1;;;;;;;184651:49:0;;-1:-1:-1;;;184651:49:0;184128:572;:625;;;-1:-1:-1;;;;;;;;;;112792:40:0;;;184717:36;184108:645;183800:961;-1:-1:-1;;183800:961:0:o;218343:152::-;736:10;204008:4;182910:27;182902:64;;;;-1:-1:-1;;;182902:64:0;;21464:2:1;182902:64:0;;;21446:21:1;21503:2;21483:18;;;21476:30;-1:-1:-1;;;21522:18:1;;;21515:54;21586:18;;182902:64:0;;;;;;;;;182977:281;;183195:52;183232:11;183202:26;:15;:24;:26::i;:::-;:41;183195:52;;183011:247;182977:281;218445:42:::1;218468:18;218445:22;:42::i;:::-;218343:152:::0;:::o;184826:100::-;184880:13;184913:5;184906:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;184826:100;:::o;222033:207::-;-1:-1:-1;;;;;222096:26:0;;222092:52;;222131:13;;-1:-1:-1;;;222131:13:0;;;;;;;;;;;222092:52;222173:4;;-1:-1:-1;;;;;222173:4:0;222159:10;:18;222155:40;;222186:9;;-1:-1:-1;;;222186:9:0;;;;;;;;;;;222155:40;222206:11;:26;;-1:-1:-1;;;;;;222206:26:0;-1:-1:-1;;;;;222206:26:0;;;;;;;;;;222033:207::o;189870:1732::-;190093:7;736:10;190093:7;190182;:5;:7::i;:::-;190155:34;;;;190277:19;:17;:19::i;:::-;190224:49;190233:8;190243:7;190252:20;190271:1;190252:16;:20;:::i;190224:49::-;:72;;190202:171;;;;-1:-1:-1;;;190202:171:0;;22743:2:1;190202:171:0;;;22725:21:1;22782:2;22762:18;;;22755:30;22821:34;22801:18;;;22794:62;-1:-1:-1;;;22872:18:1;;;22865:47;22929:19;;190202:171:0;22541:413:1;190202:171:0;190386:18;190407:81;190420:7;190429:6;190437:9;190464:11;190448:29;;;;;;190479:8;190407:12;:81::i;:::-;190386:102;;190527:6;:13;190509:7;:14;:31;190501:77;;;;-1:-1:-1;;;190501:77:0;;;;;;;:::i;:::-;190615:9;:16;190597:7;:14;:34;190589:80;;;;-1:-1:-1;;;190589:80:0;;;;;;;:::i;:::-;190705:1;190688:7;:14;:18;190680:55;;;;-1:-1:-1;;;190680:55:0;;23563:2:1;190680:55:0;;;23545:21:1;23602:2;23582:18;;;23575:30;23641:26;23621:18;;;23614:54;23685:18;;190680:55:0;23361:348:1;190680:55:0;190797:1;190754:22;;;:10;:22;;;;;:31;-1:-1:-1;;;190754:31:0;;-1:-1:-1;;;;;190754:31:0;:45;190746:91;;;;-1:-1:-1;;;190746:91:0;;23916:2:1;190746:91:0;;;23898:21:1;23955:2;23935:18;;;23928:30;23994:34;23974:18;;;23967:62;-1:-1:-1;;;24045:18:1;;;24038:31;24086:19;;190746:91:0;23714:397:1;190746:91:0;190850:16;190869:32;221388:6;190869:16;:32;:::i;:::-;190850:51;-1:-1:-1;190912:16:0;190931:25;221508:6;190850:51;190931:25;:::i;:::-;190912:44;;190994:296;;;;;;;;191033:19;:8;:17;:19::i;:::-;-1:-1:-1;;;;;190994:296:0;;;-1:-1:-1;;;;;190994:296:0;;;;;;-1:-1:-1;190994:296:0;;;;;;191140:19;:8;:17;:19::i;:::-;-1:-1:-1;;;;;190994:296:0;;;;;191189:1;190994:296;;;;;;;;;;;;;;;;;;;;;;;;;;;;190969:22;;;:10;:22;;;;;;:321;;;;;;;;;;;;;;;-1:-1:-1;;;;;;190969:321:0;;;;;;;-1:-1:-1;;;;;;;;190969:321:0;;;;;;-1:-1:-1;;;;;190969:321:0;-1:-1:-1;;;190969:321:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;190969:321:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;190969:321:0;;;;;;-1:-1:-1;;190969:321:0;;;;;;;;;;;;;;-1:-1:-1;;190969:321:0;;;;;;;;;;;;;;;191442:14;;191308:256;;190969:22;;191363:8;;191442:14;;191408:6;;191429:28;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;191472:9;191496:8;191519;191542:11;191308:256;;;;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;191584:10:0;;189870:1732;-1:-1:-1;;;;;;;;;189870:1732:0:o;197006:234::-;197149:7;197176:56;197186:7;197195;197204:9;197215:16;189785:9;;;;;;;;;-1:-1:-1;189785:9:0;;;189703:99;197215:16;197176:9;:56::i;:::-;197169:63;;197006:234;;;;;;:::o;204100:164::-;-1:-1:-1;;;204100:164:0;;;;;;;:::o;223232:136::-;223305:6;;-1:-1:-1;;;;;223305:6:0;223291:10;:20;223287:44;;223320:11;;-1:-1:-1;;;223320:11:0;;;;;;;;;;;223287:44;223342:18;223348:11;223342:5;:18::i;:::-;;223232:136;:::o;202180:789::-;202326:29;202358:22;;;:10;:22;;;;;202296:19;;202414:17;202369:10;202414:5;:17::i;:::-;202391:40;-1:-1:-1;202460:20:0;202450:6;:30;;;;;;;;:::i;:::-;;:65;;;-1:-1:-1;202494:21:0;202484:6;:31;;;;;;;;:::i;:::-;;202450:65;202442:109;;;;-1:-1:-1;;;202442:109:0;;27403:2:1;202442:109:0;;;27385:21:1;27442:2;27422:18;;;27415:30;27481:33;27461:18;;;27454:61;27532:18;;202442:109:0;27201:355:1;202442:109:0;202582:18;;-1:-1:-1;;;;;202582:18:0;736:10;202562:17;202669:46;736:10;202688:7;202582:18;202708:6;202669:9;:46::i;:::-;202652:63;;202726:21;202810:6;202790:16;;202751:6;-1:-1:-1;;;;;202751:25:0;;202777:9;202751:36;;;;;;;;;;;;;643:25:1;;631:2;616:18;;497:177;202751:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:55;;;;:::i;:::-;202750:66;;;;:::i;:::-;202726:90;;202844:13;202835:6;:22;202827:70;;;;-1:-1:-1;;;202827:70:0;;28382:2:1;202827:70:0;;;28364:21:1;28421:2;28401:18;;;28394:30;28460:34;28440:18;;;28433:62;-1:-1:-1;;;28511:18:1;;;28504:33;28554:19;;202827:70:0;28180:399:1;202827:70:0;202944:7;202935;-1:-1:-1;;;;;202915:46:0;202923:10;202915:46;202953:7;;202915:46;;;;;;;:::i;:::-;;;;;;;;202285:684;;;;;;;202180:789;;;;:::o;186501:1088::-;186574:13;186632:22;;;:10;:22;;;;;186671:17;;;;;;186667:79;;;-1:-1:-1;186712:22:0;;186501:1088;-1:-1:-1;;186501:1088:0:o;186667:79::-;186762:17;;;;;;;;;186758:79;;;-1:-1:-1;186803:22:0;;186501:1088;-1:-1:-1;;186501:1088:0:o;186758:79::-;186853:15;;;;;;;;;186849:75;;;-1:-1:-1;186892:20:0;;186501:1088;-1:-1:-1;;186501:1088:0:o;186849:75::-;186936:16;188026:22;;;:10;:22;;;;;:32;-1:-1:-1;;;;;188026:32:0;;187000:13;;;186996:85;;187030:39;;-1:-1:-1;;;187030:39:0;;29181:2:1;187030:39:0;;;29163:21:1;29220:2;29200:18;;;29193:30;29259:31;29239:18;;;29232:59;29308:18;;187030:39:0;28979:353:1;186996:85:0;187093:24;187120:7;:5;:7::i;:::-;187093:34;;;;187156:16;187144:8;:28;187140:89;;-1:-1:-1;187196:21:0;;186501:1088;-1:-1:-1;;;;186501:1088:0:o;187140:89::-;187241:16;188254:22;;;:10;:22;;;;;:30;;;-1:-1:-1;;;;;188254:30:0;187305:28;;;187301:88;;-1:-1:-1;187357:20:0;;186501:1088;-1:-1:-1;;;;;186501:1088:0:o;187301:88::-;187405:26;187420:10;187405:14;:26::i;:::-;:56;;;;-1:-1:-1;207053:4:0;207106:26;;;:14;:26;;;;;207176:25;;207152:21;;;;;:49;187435:26;187401:181;;;-1:-1:-1;187485:23:0;;186501:1088;-1:-1:-1;;;;;186501:1088:0:o;187401:181::-;-1:-1:-1;187548:22:0;;186501:1088;-1:-1:-1;;;;;186501:1088:0:o;192592:627::-;192786:7;736:10;192786:7;192869:67;192882:7;192891:6;192899:9;192910:15;736:10;192869:12;:67::i;:::-;192848:88;-1:-1:-1;192976:21:0;192955:17;192961:10;192955:5;:17::i;:::-;:42;;;;;;;;:::i;:::-;;192947:83;;;;-1:-1:-1;;;192947:83:0;;29539:2:1;192947:83:0;;;29521:21:1;29578:2;29558:18;;;29551:30;29617;29597:18;;;29590:58;29665:18;;192947:83:0;29337:352:1;192947:83:0;193061:22;;;;:10;:22;;;;;:31;-1:-1:-1;;;;;193049:43:0;;;-1:-1:-1;;;193061:31:0;;;;193049:43;193041:90;;;;-1:-1:-1;;;193041:90:0;;29896:2:1;193041:90:0;;;29878:21:1;29935:2;29915:18;;;29908:30;29974:34;29954:18;;;29947:62;-1:-1:-1;;;30025:18:1;;;30018:32;30067:19;;193041:90:0;29694:398:1;193041:90:0;193149:62;193157:7;193166:6;193174:9;193185:15;193202:8;193149:7;:62::i;:::-;193142:69;192592:627;-1:-1:-1;;;;;;;192592:627:0:o;223769:331::-;181409:13;223849:17;:39;223845:77;;;223897:25;;-1:-1:-1;;;223897:25:0;;;;;;;;;;;223845:77;223951:5;-1:-1:-1;;;;;223951:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;223937:30:0;:10;-1:-1:-1;;;;;223937:30:0;;223933:56;;223976:13;;-1:-1:-1;;;223976:13:0;;;;;;;;;;;223933:56;224000:16;:36;;;224054:38;;643:25:1;;;224054:38:0;;631:2:1;616:18;224054:38:0;;;;;;;223769:331;:::o;213146:284::-;213206:13;213253:5;-1:-1:-1;;;;;213236:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;213236:37:0;;;;;;;;;;;;:::i;:::-;;;213232:191;;-1:-1:-1;213373:38:0;;;;;;;;;;;;;;;;;;213146:284::o;213232:191::-;213330:9;213146:284;-1:-1:-1;213146:284:0:o;221531:288::-;221618:4;;-1:-1:-1;;;;;221618:4:0;221604:10;:18;221600:40;;221631:9;;-1:-1:-1;;;221631:9:0;;;;;;;;;;;221600:40;220351:3;221655:9;:34;221651:73;;;221698:26;;-1:-1:-1;;;221698:26:0;;;;;;;;;;;221651:73;221735:17;:29;;;221780:31;;221755:9;;221780:31;;;;;221531:288;:::o;216841:671::-;217008:23;:43;216914:7;;217066:11;;;217062:67;;-1:-1:-1;;217101:16:0;;;216841:671;-1:-1:-1;216841:671:0:o;217062:67::-;217200:39;217242:23;217279:10;217288:1;217279:6;:10;:::i;:::-;217242:48;;;;;;;;:::i;:::-;;;;;;;;;;217200:90;;;;;;;;;217242:48;;217200:90;;;;;;;-1:-1:-1;;;217200:90:0;;;-1:-1:-1;;;;;217200:90:0;;;;;;;;;-1:-1:-1;;;217301:77:0;;217353:13;;;-1:-1:-1;;;;;217346:20:0;;216841:671;-1:-1:-1;;;216841:671:0:o;217301:77::-;217441:63;217483:20;:9;:18;:20::i;:::-;217441:23;;:41;:63::i;:::-;-1:-1:-1;;;;;217434:70:0;;216841:671;-1:-1:-1;;;;216841:671:0:o;191670:855::-;191900:7;191920:18;191941:67;191954:7;191963:6;191971:9;191982:15;191999:8;191941:12;:67::i;:::-;191920:88;;192021:20;192044:17;192050:10;192044:5;:17::i;:::-;192021:40;-1:-1:-1;192090:23:0;192080:6;:33;;;;;;;;:::i;:::-;;192072:79;;;;-1:-1:-1;;;192072:79:0;;31340:2:1;192072:79:0;;;31322:21:1;31379:2;31359:18;;;31352:30;31418:34;31398:18;;;31391:62;-1:-1:-1;;;31469:18:1;;;31462:31;31510:19;;192072:79:0;31138:397:1;192072:79:0;192162:22;;;;:10;:22;;;;;;;:31;;:38;;-1:-1:-1;;192162:38:0;192196:4;192162:38;;;192218:28;;;;;192173:10;643:25:1;;631:2;616:18;;497:177;192218:28:0;;;;;;;;192259:71;192274:10;192286:7;192295:6;192303:9;192314:15;192259:14;:71::i;:::-;192341:65;192350:10;192362:7;192371:6;192379:9;192390:15;192341:8;:65::i;:::-;192417:70;192431:10;192443:7;192452:6;192460:9;192471:15;192417:13;:70::i;:::-;-1:-1:-1;192507:10:0;191670:855;-1:-1:-1;;;;;;191670:855:0:o;223376:154::-;223440:6;;-1:-1:-1;;;;;223440:6:0;223426:10;:20;223422:44;;223455:11;;-1:-1:-1;;;223455:11:0;;;;;;;;;;;223422:44;223484:6;223477:13;;-1:-1:-1;;;;;;223477:13:0;;;223506:16;;;;223484:6;;223506:16;223376:154::o;142918:657::-;143039:13;143067:18;;143039:13;;;143067:18;143341:41;:5;143039:13;143341:26;:41::i;:::-;143397:47;:8;143427:16;143397:29;:47::i;:::-;143540:16;;;143523:1;143540:16;;;;;;;;;-1:-1:-1;;;143288:279:0;;;-1:-1:-1;143288:279:0;;-1:-1:-1;143459:13:0;;-1:-1:-1;143495:4:0;;-1:-1:-1;143523:1:0;-1:-1:-1;143540:16:0;-1:-1:-1;143288:279:0;-1:-1:-1;142918:657:0:o;212725:260::-;212780:6;212820:5;-1:-1:-1;;;;;212803:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;212803:32:0;;;;;;;;-1:-1:-1;;212803:32:0;;;;;;;;;;;;:::i;:::-;;;212799:179;;212935:31;212953:12;212935:17;:31::i;:::-;212928:38;;212725:260;:::o;215059:202::-;215174:19;;-1:-1:-1;;;215174:19:0;;;;;643:25:1;;;215136:7:0;;;;-1:-1:-1;;;;;215174:2:0;:10;;;;616:18:1;;215174:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;215156:37;;215211:42;215221:7;215230;215239:9;215211:42;;;;;;;;;;;;:9;:42::i;222947:210::-;223009:13;;-1:-1:-1;;;;;223009:13:0;222995:10;:27;222991:58;;223031:18;;-1:-1:-1;;;223031:18:0;;;;;;;;;;;222991:58;223069:13;;;223060:6;:22;;-1:-1:-1;;;;;223069:13:0;;-1:-1:-1;;;;;;223060:22:0;;;;;;;;223093:20;;;;;;223129;;;;-1:-1:-1;;223129:20:0;222947:210::o;216530:193::-;216613:23;:43;216586:7;;216613:48;:102;;216683:32;:23;:30;:32::i;:::-;-1:-1:-1;;;;;216613:102:0;212928:38;;212725:260;:::o;216613:102::-;-1:-1:-1;216664:16:0;;;216530:193::o;186083:352::-;186315:7;186371;186380:6;186388:9;186399:15;186416:8;186360:65;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;186360:65:0;;;;;;;;;186350:76;;186360:65;186350:76;;;;;186083:352;-1:-1:-1;;;;;;186083:352:0:o;221827:198::-;221900:7;220418:6;221976:17;;221928:5;-1:-1:-1;;;;;221928:24:0;;221971:1;221953:15;:19;;;;:::i;:::-;221928:45;;;;;;;;;;;;;643:25:1;;631:2;616:18;;497:177;221928:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:65;;;;:::i;:::-;221927:90;;;;:::i;222248:194::-;222308:11;;-1:-1:-1;;;;;222308:11:0;222294:10;:25;222290:54;;222328:16;;-1:-1:-1;;;222328:16:0;;;;;;;;;;;222290:54;222362:11;;;222355:4;:18;;-1:-1:-1;;;;;222362:11:0;;-1:-1:-1;;;;;;222355:18:0;;;;;;;;222384;;;;;;222418:16;;;;-1:-1:-1;;222418:16:0;222248:194::o;198354:355::-;198573:7;;736:10;198593:28;;198639:62;198649:10;198661:5;198668:7;198677;198686:6;;198639:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;198694:6:0;;-1:-1:-1;198639:9:0;;-1:-1:-1;;198639:62:0:i;:::-;198632:69;198354:355;-1:-1:-1;;;;;;;;198354:355:0:o;203428:299::-;736:10;204008:4;182910:27;182902:64;;;;-1:-1:-1;;;182902:64:0;;21464:2:1;182902:64:0;;;21446:21:1;21503:2;21483:18;;;21476:30;-1:-1:-1;;;21522:18:1;;;21515:54;21586:18;;182902:64:0;21262:348:1;182902:64:0;182977:281;;183195:52;183232:11;183202:26;:15;:24;:26::i;:::-;:41;183195:52;;183011:247;182977:281;203547:12:::1;203561:23:::0;203588:6:::1;-1:-1:-1::0;;;;;203588:11:0::1;203607:5;203614:4;;203588:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;203546:73;;;;203630:89;203655:7;203664:10;203630:89;;;;;;;;;;;;;;;;;:24;:89::i;:::-;;203535:192;;203428:299:::0;;;;:::o;197958:308::-;198138:7;;736:10;198158:28;;198204:54;198214:10;198226:5;198233:7;198242;198251:6;;198204:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;198204:9:0;;-1:-1:-1;;;198204:54:0:i;197319:264::-;197502:7;197529:46;197539:7;197548;197557:9;197568:6;197529:9;:46::i;:::-;197522:53;197319:264;-1:-1:-1;;;;;197319:264:0:o;222739:200::-;222813:6;;-1:-1:-1;;;;;222813:6:0;222799:10;:20;222795:44;;222828:11;;-1:-1:-1;;;222828:11:0;;;;;;;;;;;222795:44;-1:-1:-1;;;;;222854:21:0;;222850:47;;222884:13;;-1:-1:-1;;;222884:13:0;;;;;;;;;;;222850:47;222908:13;:23;;-1:-1:-1;;;;;;222908:23:0;-1:-1:-1;;;;;222908:23:0;;;;;;;;;;222739:200::o;197652:227::-;197755:7;;736:10;197775:28;;197821:50;197831:10;197843:5;197850:7;197859;197821:50;;;;;;;;;;;;:9;:50::i;217859:196::-;217932:7;217708:3;217998:26;218014:9;217998:15;:26::i;:::-;217960:35;;-1:-1:-1;;;217960:35:0;;;;;643:25:1;;;217960:5:0;-1:-1:-1;;;;;217960:24:0;;;;616:18:1;;217960:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:64;;;;:::i;:::-;217959:88;;;;:::i;199352:846::-;199634:7;199654:13;199670:438;199698:351;180627:88;199853:10;199890:7;199940:6;;199924:24;;;;;;;:::i;:::-;;;;;;;;199985:6;199975:17;;;;;;199765:250;;;;;;;;;;;32945:25:1;;;33001:2;32986:18;;32979:34;;;;33061:4;33049:17;;;;33044:2;33029:18;;33022:45;33098:2;33083:18;;33076:34;33141:3;33126:19;;33119:35;32932:3;32917:19;;32690:470;199765:250:0;;;;;;;;;;;;;199733:301;;;;;;199698:16;:351::i;:::-;200064:1;200080;200096;199670:13;:438::i;:::-;199654:454;;200128:62;200138:10;200150:5;200157:7;200166;200175:6;;200128:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;200183:6:0;;-1:-1:-1;200128:9:0;;-1:-1:-1;;200128:62:0:i;:::-;200121:69;199352:846;-1:-1:-1;;;;;;;;;;;199352:846:0:o;198783:476::-;199074:48;;;180507:53;199074:48;;;33363:25:1;33404:18;;;33397:34;;;33479:4;33467:17;;33447:18;;;33440:45;198983:7:0;;;;199019:164;;199047:77;;33336:18:1;;199074:48:0;33165:326:1;199019:164:0;199003:180;;199201:50;199211:10;199223:5;199230:7;199239;199201:50;;;;;;;;;;;;:9;:50::i;108216:332::-;108280:13;108310:12;108316:5;110883:12;;;;;-1:-1:-1;;;110869:10:0;;;;;:26;;;110779:124;108310:12;108306:32;;;108331:7;;-1:-1:-1;;;108331:7:0;;;;;;;;;;;108306:32;-1:-1:-1;108369:12:0;;;;108349:17;108400:23;;;108369:12;108400:11;;;:23;;;;;;;108434:30;;;108500:29;;-1:-1:-1;;108500:29:0;108515:14;;-1:-1:-1;;;;;108500:29:0;;;;;;;;108400:23;108216:332::o;218727:925::-;217708:3;218837:18;:41;;218815:158;;;;-1:-1:-1;;;218815:158:0;;33698:2:1;218815:158:0;;;33680:21:1;33737:2;33717:18;;;33710:30;33776:34;33756:18;;;33749:62;33847:34;33827:18;;;33820:62;-1:-1:-1;;;33898:19:1;;;33891:34;33942:19;;218815:158:0;33496:471:1;218815:158:0;218986:26;219015:17;:15;:17::i;:::-;218986:46;-1:-1:-1;219169:23:0;;;;;:75;;-1:-1:-1;219196:23:0;:43;:48;219169:75;219165:259;;;219321:76;;;;;;;;;219261:36;219321:76;;219261:23;;219321:76;;;219365:30;:18;:28;:30::i;:::-;-1:-1:-1;;;;;219321:76:0;;;;;;219261:151;;;;;;;-1:-1:-1;219261:151:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;219261:151:0;;;;;;;;;;;;219165:259;219484:80;219513:18;:7;:5;:7::i;:::-;:16;;;:18::i;:::-;219533:30;:18;:28;:30::i;:::-;219484:23;;:80;:28;:80::i;:::-;-1:-1:-1;;219582:62:0;;;34146:25:1;;;34202:2;34187:18;;34180:34;;;219582:62:0;;34119:18:1;219582:62:0;;;;;;;218804:848;218727:925;:::o;28544:190::-;28600:6;-1:-1:-1;;;;;28627:25:0;;;28619:76;;;;-1:-1:-1;;;28619:76:0;;34427:2:1;28619:76:0;;;34409:21:1;34466:2;34446:18;;;34439:30;34505:34;34485:18;;;34478:62;-1:-1:-1;;;34556:18:1;;;34549:36;34602:19;;28619:76:0;34225:402:1;28619:76:0;-1:-1:-1;28720:5:0;28544:190::o;213560:1491::-;213798:22;;-1:-1:-1;;;213798:22:0;;;;;643:25:1;;;213740:7:0;;;;-1:-1:-1;;;;;213798:2:0;:13;;;;616:18:1;;213798:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;213760:60;-1:-1:-1;213853:32:0;213839:10;:46;;;;;;;;:::i;:::-;;213831:92;;;;-1:-1:-1;;;213831:92:0;;35114:2:1;213831:92:0;;;35096:21:1;35153:2;35133:18;;;35126:30;35192:34;35172:18;;;35165:62;-1:-1:-1;;;35243:18:1;;;35236:31;35284:19;;213831:92:0;34912:397:1;213831:92:0;213954:31;213940:10;:45;;;;;;;;:::i;:::-;;213936:132;;214009:47;;-1:-1:-1;;;214009:47:0;;-1:-1:-1;;;;;35534:32:1;;;214009:47:0;;;35516:51:1;35583:18;;;35576:34;;;35626:18;;;35619:34;;;214009:5:0;:18;;;;35489::1;;214009:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;214002:54;;;;;213936:132;214188:23;;-1:-1:-1;;;214188:23:0;;;;;643:25:1;;;214169:16:0;;214188:2;-1:-1:-1;;;;;214188:14:0;;;;616:18:1;;214188:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;214169:42;-1:-1:-1;214222:12:0;214237:46;-1:-1:-1;;;;;214237:2:0;:25;214169:42;214273:9;214237:25;:46::i;:::-;214314:31;;-1:-1:-1;;;214314:31:0;;;;;35836:25:1;;;35909:14;35897:27;;35877:18;;;35870:55;214222:61:0;;-1:-1:-1;214294:17:0;;-1:-1:-1;;;;;214314:2:0;:14;;;;35809:18:1;;214314:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;214294:61;;214370:9;214383:1;214370:14;214366:507;;214579:47;;-1:-1:-1;;;214579:47:0;;-1:-1:-1;;;;;35534:32:1;;;214579:47:0;;;35516:51:1;35583:18;;;35576:34;;;35626:18;;;35619:34;;;214552:24:0;;214579:5;:18;;;;;;35489::1;;214579:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;214658:29;;-1:-1:-1;;;214658:29:0;;;;;34146:25:1;;;34187:18;;;34180:34;;;214552:74:0;;-1:-1:-1;214641:14:0;;-1:-1:-1;;;;;214658:2:0;:10;;;;34119:18:1;;214658:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;214641:46;-1:-1:-1;214728:15:0;214746:39;-1:-1:-1;;;;;214746:2:0;:9;214756:8;214766:7;214775:9;214746;:39::i;:::-;214728:57;-1:-1:-1;214845:16:0;214826;214728:57;214826:6;:16;:::i;:::-;:35;;;;:::i;:::-;214819:42;;;;;;;;;;;214366:507;214996:47;;-1:-1:-1;;;214996:47:0;;-1:-1:-1;;;;;35534:32:1;;;214996:47:0;;;35516:51:1;35583:18;;;35576:34;;;35626:18;;;35619:34;;;214996:5:0;:18;;;;35489::1;;214996:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;214989:54;213560:1491;-1:-1:-1;;;;;;;;;213560:1491:0:o;195334:522::-;195387:7;195407:20;195430:17;195436:10;195430:5;:17::i;:::-;195407:40;-1:-1:-1;195492:20:0;195482:6;:30;;;;;;;;:::i;:::-;;;:83;;;;-1:-1:-1;195543:22:0;195533:6;:32;;;;;;;;:::i;:::-;;;195482:83;:135;;;;-1:-1:-1;195596:21:0;195586:6;:31;;;;;;;;:::i;:::-;;;195482:135;:188;;;;-1:-1:-1;195648:22:0;195638:6;:32;;;;;;;;:::i;:::-;;;195482:188;195460:267;;;;-1:-1:-1;;;195460:267:0;;36834:2:1;195460:267:0;;;36816:21:1;36873:2;36853:18;;;36846:30;36912:31;36892:18;;;36885:59;36961:18;;195460:267:0;36632:353:1;195460:267:0;195738:22;;;;:10;:22;;;;;;;:29;;:36;;-1:-1:-1;;195738:36:0;;;;;195792:26;;;;;195749:10;643:25:1;;631:2;616:18;;497:177;195792:26:0;;;;;;;;-1:-1:-1;195838:10:0;;195334:522;-1:-1:-1;195334:522:0:o;206550:280::-;206634:4;206687:26;;;:14;:26;;;;;206797:25;;;;206773:21;;;;:49;;206797:25;206773:49;:::i;:::-;187999:7;188026:22;;;:10;:22;;;;;:32;206733:36;;-1:-1:-1;;;;;188026:32:0;217859:196;:::i;206733:36::-;:89;;;206550:280;-1:-1:-1;;;206550:280:0:o;196148:789::-;196363:7;196383:18;196404:67;196417:7;196426:6;196434:9;196445:15;196462:8;196404:12;:67::i;:::-;196383:88;;196484:20;196507:17;196513:10;196507:5;:17::i;:::-;196484:40;-1:-1:-1;196569:20:0;196559:6;:30;;;;;;;;:::i;:::-;;;:83;;;;-1:-1:-1;196620:22:0;196610:6;:32;;;;;;;;:::i;:::-;;;196559:83;:135;;;;-1:-1:-1;196673:21:0;196663:6;:31;;;;;;;;:::i;:::-;;;196559:135;:188;;;;-1:-1:-1;196725:22:0;196715:6;:32;;;;;;;;:::i;:::-;;;196559:188;196537:267;;;;-1:-1:-1;;;196537:267:0;;36834:2:1;196537:267:0;;;36816:21:1;36873:2;36853:18;;;36846:30;36912:31;36892:18;;;36885:59;36961:18;;196537:267:0;36632:353:1;196537:267:0;196815:22;;;;:10;:22;;;;;;;:31;;:38;;-1:-1:-1;;196815:38:0;;;;;196871:28;;;;;196826:10;643:25:1;;631:2;616:18;;497:177;196871:28:0;;;;;;;;-1:-1:-1;196919:10:0;196148:789;-1:-1:-1;;;;;;196148:789:0:o;30660:190::-;30716:6;30752:16;30743:25;;;30735:76;;;;-1:-1:-1;;;30735:76:0;;37192:2:1;30735:76:0;;;37174:21:1;37231:2;37211:18;;;37204:30;37270:34;37250:18;;;37243:62;-1:-1:-1;;;37321:18:1;;;37314:36;37367:19;;30735:76:0;36990:402:1;84111:624:0;84230:24;;84196:7;;;84230:24;84334:1;84328:7;;84324:241;;;84352:11;84372:14;84382:3;84372:9;:14::i;:::-;84366:20;;:3;:20;:::i;:::-;88727:28;88792:20;;;88858:4;88845:18;;84352:34;;-1:-1:-1;88841:28:0;;84411:42;;;;;84405:48;;;;84401:153;;;84481:3;84474:10;;84401:153;;;84531:7;:3;84537:1;84531:7;:::i;:::-;84525:13;;84401:153;84337:228;84324:241;84577:11;84591:53;84610:4;84629:3;84634;84639:4;84591:18;:53::i;:::-;84577:67;-1:-1:-1;84664:8:0;;:63;;84679:41;84693:4;84712:7;84718:1;84712:3;:7;:::i;:::-;88727:28;88792:20;;;88858:4;88845:18;;;88841:28;;88614:273;84679:41;:48;-1:-1:-1;;;84679:48:0;;-1:-1:-1;;;;;84679:48:0;84664:63;;;84675:1;84657:70;84111:624;-1:-1:-1;;;;;;;84111:624:0:o;194013:553::-;194255:304;;194351:197;194375:7;194371:1;:11;194351:197;;;194434:4;-1:-1:-1;;;;;194412:27:0;:7;194420:1;194412:10;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;194412:27:0;;194408:125;;194464:49;194499:9;194509:1;194499:12;;;;;;;;:::i;:::-;;;;;;;194489:23;;;;;;194464:15;:24;;:49;;;;:::i;:::-;194384:3;;;:::i;:::-;;;194351:197;;194255:304;194013:553;;;;;:::o;193349:589::-;193579:26;:70;;;;;;;;;;;;;;;;;193678:14;;193579:70;;-1:-1:-1;193660:15:0;193703:228;193727:7;193723:1;:11;193703:228;;;193757:12;193771:23;193798:7;193806:1;193798:10;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;193798:15:0;193821:6;193828:1;193821:9;;;;;;;;:::i;:::-;;;;;;;193832;193842:1;193832:12;;;;;;;;:::i;:::-;;;;;;;193798:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;193756:89;;;;193860:59;193885:7;193894:10;193906:12;193860:24;:59::i;:::-;;193741:190;;193736:3;;;;:::i;:::-;;;193703:228;;;;193568:370;;193349:589;;;;;:::o;65836:244::-;65930:13;65238:4;65202:40;;65960:17;65956:117;;66001:15;66010:5;66001:8;:15::i;:::-;65994:22;;;;65956:117;66056:5;66049:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29602:190;29658:6;29694:16;29685:25;;;29677:76;;;;-1:-1:-1;;;29677:76:0;;38031:2:1;29677:76:0;;;38013:21:1;38070:2;38050:18;;;38043:30;38109:34;38089:18;;;38082:62;-1:-1:-1;;;38160:18:1;;;38153:36;38206:19;;29677:76:0;37829:402:1;84860:209:0;84956:24;;84922:7;;84998:8;;:63;;85013:41;85027:4;85046:7;85052:1;85046:3;:7;:::i;85013:41::-;:48;-1:-1:-1;;;85013:48:0;;-1:-1:-1;;;;;85013:48:0;84998:63;;;85009:1;84991:70;84860:209;-1:-1:-1;;;84860:209:0:o;201118:828::-;201336:7;201388:22;;;:10;:22;;;;;201450:20;201429:17;201435:10;201429:5;:17::i;:::-;:41;;;;;;;;:::i;:::-;;201421:89;;;;-1:-1:-1;;;201421:89:0;;38438:2:1;201421:89:0;;;38420:21:1;38477:2;38457:18;;;38450:30;38516:34;38496:18;;;38489:62;-1:-1:-1;;;38567:18:1;;;38560:33;38610:19;;201421:89:0;38236:399:1;201421:89:0;201568:18;;201523:14;;201540:55;;201550:7;;201559;;-1:-1:-1;;;;;201568:18:0;201588:6;201540:9;:55::i;:::-;201523:72;;201606:56;201617:10;201629:7;201638;201647:6;201655;201606:10;:56::i;:::-;201679:6;:13;201696:1;201679:18;201675:238;;201737:7;201728;-1:-1:-1;;;;;201719:63:0;;201746:10;201758:7;201767:6;201775;201719:63;;;;;;;;;:::i;:::-;;;;;;;;201675:238;;;201848:7;201839;-1:-1:-1;;;;;201820:81:0;;201857:10;201869:7;201878:6;201886;201894;201820:81;;;;;;;;;;:::i;:::-;;;;;;;;201932:6;201118:828;-1:-1:-1;;;;;;;;201118:828:0:o;104025:305::-;104175:12;104204:7;104200:123;;;-1:-1:-1;104235:10:0;104228:17;;104200:123;104278:33;104286:10;104298:12;104278:7;:33::i;200523:297::-;200711:7;200738:74;200748:10;200760:7;200769;200778;200787:6;200795:16;189785:9;;;;;;;;;-1:-1:-1;189785:9:0;;;189703:99;200795:16;200738:9;:74::i;:::-;200731:81;200523:297;-1:-1:-1;;;;;;200523:297:0:o;142696:167::-;142773:7;142800:55;142822:20;:18;:20::i;:::-;142844:10;137245:4;137239:11;-1:-1:-1;;;137264:23:0;;137317:4;137308:14;;137301:39;;;;137370:4;137361:14;;137354:34;137425:4;137410:20;;;137042:406;135258:236;135343:7;135364:17;135383:18;135405:25;135416:4;135422:1;135425;135428;135405:10;:25::i;:::-;135363:67;;;;135441:18;135453:5;135441:11;:18::i;:::-;-1:-1:-1;135477:9:0;135258:236;-1:-1:-1;;;;;135258:236:0:o;17824:195::-;17881:7;-1:-1:-1;;;;;17909:26:0;;;17901:78;;;;-1:-1:-1;;;17901:78:0;;39898:2:1;17901:78:0;;;39880:21:1;39937:2;39917:18;;;39910:30;39976:34;39956:18;;;39949:62;-1:-1:-1;;;40027:18:1;;;40020:37;40074:19;;17901:78:0;39696:403:1;82795:164:0;82877:7;;82913:38;82921:4;82940:3;82945:5;82913:7;:38::i;:::-;82906:45;;;;82795:164;;;;;;;:::o;208586:1105::-;208771:27;;-1:-1:-1;;;208771:27:0;;;;;643:25:1;;;208730:6:0;;;;-1:-1:-1;;;;;208771:17:0;;;;;616:18:1;;208771:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;208749:49;;208813:12;:17;;208829:1;208813:17;208809:31;;208839:1;208832:8;;;;;208809:31;208959:9;-1:-1:-1;;;;;208899:14:0;;;208914:8;208924:16;208939:1;208924:12;:16;:::i;:::-;208899:42;;-1:-1:-1;;;;;;208899:42:0;;;;;;;;;;35836:25:1;;;;35909:14;35897:27;35877:18;;;35870:55;35809:18;;208899:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:56;:69;208895:100;;208978:16;208993:1;208978:12;:16;:::i;:::-;208970:25;;;;;208895:100;209055:27;;-1:-1:-1;;;209055:27:0;;;;;35836:25:1;;;209080:1:0;35877:18:1;;;35870:55;209099:9:0;;-1:-1:-1;;;;;209055:14:0;;;;;35809:18:1;;209055:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;:53;209051:67;;;209117:1;209110:8;;;;;209051:67;209131:12;;209173:16;209188:1;209173:12;:16;:::i;:::-;209158:31;;209200:34;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;209200:34:0;209260:5;209252:13;;:5;:13;;;209245:416;;;209282:13;209324:1;209307:13;209315:5;209307;:13;:::i;:::-;209306:19;;;;:::i;:::-;209298:27;;:5;:27;:::i;:::-;209372:32;;-1:-1:-1;;;209372:32:0;;;;;35836:25:1;;;35909:14;35897:27;;35877:18;;;35870:55;209282:43:0;;-1:-1:-1;;;;;;209372:14:0;;;;;35809:18:1;;209372:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;209367:37;;209443:9;209423:2;:16;;;:29;209419:231;;209480:6;-1:-1:-1;209473:13:0;;-1:-1:-1;;;;209473:13:0;209419:231;209512:16;;:28;-1:-1:-1;209508:142:0;;;209569:6;209561:14;;209508:142;;;209624:10;209633:1;209624:6;:10;:::i;:::-;209616:18;;209508:142;209267:394;209245:416;;;-1:-1:-1;209678:5:0;;208586:1105;-1:-1:-1;;;;;;208586:1105:0:o;210175:1879::-;210371:28;;-1:-1:-1;;;210371:28:0;;;;;643:25:1;;;210329:7:0;;;;-1:-1:-1;;;;;210371:18:0;;;;;616::1;;210371:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;210415:27;;-1:-1:-1;;;210415:27:0;;;;;643:25:1;;;210349:51:0;;-1:-1:-1;;;;;;210415:18:0;;;;;616::1;;210415:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;210446:1;210415:32;210411:73;;210471:1;210464:8;;;;;210411:73;210496:20;210519:2;-1:-1:-1;;;;;210519:8:0;;:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;210648:35;;-1:-1:-1;;;210648:35:0;;-1:-1:-1;;;;;40961:32:1;;;210648:35:0;;;40943:51:1;41010:18;;;41003:34;;;210496:33:0;;-1:-1:-1;210540:14:0;;210587:1;;210540:14;;210617:67;;210648:12;;;;;;40916:18:1;;210648:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56154:6;56360:16;;56347:30;;;56233:163;210617:67;210760:42;;-1:-1:-1;;;210760:42:0;;;;;34146:25:1;;;34187:18;;;34180:34;;;210599:85:0;;-1:-1:-1;210743:14:0;;-1:-1:-1;;;;;210760:24:0;;;;;34119:18:1;;210760:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;210853:32;;-1:-1:-1;;;210853:32:0;;;;;34146:25:1;;;34187:18;;;34180:34;;;210743:59:0;;-1:-1:-1;210814:13:0;;;;-1:-1:-1;;;;;210853:15:0;;;;;34119:18:1;;210853:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;210813:72;;-1:-1:-1;210813:72:0;-1:-1:-1;210980:56:0;210989:7;56154:6;56360:16;;56347:30;;210980:8;:56::i;:::-;210970:66;-1:-1:-1;211154:17:0;208367:6;211175:50;210970:66;56595:16;;;56582:30;;:37;;211175:50;:::i;:::-;211174:63;;;;:::i;:::-;211154:83;-1:-1:-1;211248:20:0;211285:13;;211281:740;;211320:9;211315:695;211339:9;211335:1;:13;211315:695;;;-1:-1:-1;;;;;211446:24:0;;;211471:7;211501:1;211480:18;208367:6;211480:7;:18;:::i;:::-;:22;;;;:::i;:::-;211446:57;;-1:-1:-1;;;;;;211446:57:0;;;;;;;;;;34146:25:1;;;;34187:18;;;34180:34;34119:18;;211446:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;211437:66;;211595:3;-1:-1:-1;;;;;211595:15:0;;211611:7;211620:6;211595:32;;;;;;;;;;;;;;;34146:25:1;;;34202:2;34187:18;;34180:34;34134:2;34119:18;;33972:248;211595:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;211571:56;;-1:-1:-1;211571:56:0;-1:-1:-1;;;;;;211729:21:0;;;;211751:23;211796:1;211775:18;208367:6;211775:7;:18;:::i;:::-;:22;;;;:::i;:::-;211751:47;;;;;;;;;;;;;643:25:1;;631:2;616:18;;497:177;211751:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;211729:70;;;;;;;;;;;;;643:25:1;;631:2;616:18;;497:177;211729:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;211710:89;-1:-1:-1;211828:25:0;;-1:-1:-1;211710:89:0;211851:1;211828:8;:25::i;:::-;211898:47;;-1:-1:-1;;;211898:47:0;;-1:-1:-1;;;;;40961:32:1;;;211898:47:0;;;40943:51:1;41010:18;;;41003:34;;;211818:35:0;;-1:-1:-1;211818:35:0;;211898:24;;;;;40916:18:1;;211898:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;211883:62;;:12;:62;:::i;:::-;211882:74;;;;:::i;:::-;211872:84;;;;:::i;:::-;;-1:-1:-1;211975:19:0;208367:6;211975:19;;:::i;:::-;;-1:-1:-1;211350:3:0;;;;:::i;:::-;;;;211315:695;;;;211281:740;-1:-1:-1;212040:6:0;;210175:1879;-1:-1:-1;;;;;;;;;;;;;210175:1879:0:o;7220:1673::-;7268:7;7292:1;7297;7292:6;7288:47;;-1:-1:-1;7322:1:0;;7220:1673;-1:-1:-1;7220:1673:0:o;7288:47::-;8026:14;8060:1;8049:7;8054:1;8049:4;:7::i;:::-;:12;;8043:1;:19;;8026:36;;8528:1;8517:6;8513:1;:10;;;;;:::i;:::-;;8504:6;:19;8503:26;;8494:35;;8578:1;8567:6;8563:1;:10;;;;;:::i;:::-;;8554:6;:19;8553:26;;8544:35;;8628:1;8617:6;8613:1;:10;;;;;:::i;:::-;;8604:6;:19;8603:26;;8594:35;;8678:1;8667:6;8663:1;:10;;;;;:::i;:::-;;8654:6;:19;8653:26;;8644:35;;8728:1;8717:6;8713:1;:10;;;;;:::i;:::-;;8704:6;:19;8703:26;;8694:35;;8778:1;8767:6;8763:1;:10;;;;;:::i;:::-;;8754:6;:19;8753:26;;8744:35;;8828:1;8817:6;8813:1;:10;;;;;:::i;:::-;;8804:6;:19;8803:26;;8794:35;;8851:23;8855:6;8867;8863:1;:10;;;;;:::i;:::-;;8851:3;:23::i;87222:448::-;87384:7;87404:237;87417:4;87411:3;:10;87404:237;;;87438:11;87452:23;87465:3;87470:4;87452:12;:23::i;:::-;88727:28;88792:20;;;88858:4;88845:18;;87438:37;;-1:-1:-1;87494:35:0;;;;88841:28;;87494:29;;;:35;87490:140;;;87557:3;87550:10;;87490:140;;;87607:7;:3;87613:1;87607:7;:::i;:::-;87601:13;;87490:140;87423:218;87404:237;;;-1:-1:-1;87658:4:0;87222:448;-1:-1:-1;;;87222:448:0:o;106976:232::-;107076:10;;-1:-1:-1;;;107076:10:0;;;;;;107057:16;107097:22;;;:11;;;;:22;;;;;;:30;;;;107163:26;;-1:-1:-1;;;;;107163:26:0;;;107176:13;;;;107163:26;;;;;106976:232::o;64630:411::-;64851:14;;;64862:2;64851:14;;;;;;;;;64689:13;;65238:4;65202:40;;;64715:11;;64851:14;;;64862:2;;64851:14;;;-1:-1:-1;;;64944:16:0;;;-1:-1:-1;64990:4:0;64981:14;;64974:28;;;;-1:-1:-1;64944:16:0;64630:411::o;207354:907::-;207555:33;207591:26;;;:14;:26;;;;;;;;207639:30;;;:21;;;:30;;;;;;;;;207638:31;207630:83;;;;-1:-1:-1;;;207630:83:0;;41500:2:1;207630:83:0;;;41482:21:1;41539:2;41519:18;;;41512:30;41578:34;41558:18;;;41551:62;-1:-1:-1;;;41629:18:1;;;41622:37;41676:19;;207630:83:0;41298:403:1;207630:83:0;207741:1;207732:6;:10;207724:63;;;;-1:-1:-1;;;207724:63:0;;41908:2:1;207724:63:0;;;41890:21:1;41947:2;41927:18;;;41920:30;41986:34;41966:18;;;41959:62;-1:-1:-1;;;42037:18:1;;;42030:38;42085:19;;207724:63:0;41706:404:1;207724:63:0;207798:30;;;;:21;;;:30;;;;;:37;;-1:-1:-1;;207798:37:0;207831:4;207798:37;;;207852:34;;;207848:406;;207932:6;207903:12;:25;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;207848:406:0;;-1:-1:-1;207848:406:0;;-1:-1:-1;;207960:30:0;;;;207956:298;;208032:6;208007:12;:21;;;:31;;;;;;;:::i;207956:298::-;-1:-1:-1;;208060:34:0;;;;208056:198;;208140:6;208111:12;:25;;;:35;;;;;;;:::i;208056:198::-;208179:63;;-1:-1:-1;;;208179:63:0;;42317:2:1;208179:63:0;;;42299:21:1;42356:2;42336:18;;;42329:30;42395:34;42375:18;;;42368:62;-1:-1:-1;;;42446:18:1;;;42439:51;42507:19;;208179:63:0;42115:417:1;208056:198:0;207544:717;207354:907;;;;;:::o;104338:552::-;104499:17;;:21;104495:388;;104731:10;104725:17;104788:15;104775:10;104771:2;104767:19;104760:44;104495:388;104858:12;104851:20;;-1:-1:-1;;;104851:20:0;;;;;;;;:::i;141596:268::-;141649:7;141681:4;-1:-1:-1;;;;;141690:11:0;141673:28;;:63;;;;;141722:14;141705:13;:31;141673:63;141669:188;;;-1:-1:-1;141760:22:0;;141596:268::o;141669:188::-;141822:23;141964:81;;;139695:95;141964:81;;;44671:25:1;141987:11:0;44712:18:1;;;44705:34;;;;142000:14:0;44755:18:1;;;44748:34;142016:13:0;44798:18:1;;;44791:34;142039:4:0;44841:19:1;;;44834:61;141927:7:0;;44643:19:1;;141964:81:0;;;;;;;;;;;;141954:92;;;;;;141947:99;;141872:182;;133642:1477;133730:7;;134664:66;134651:79;;134647:163;;;-1:-1:-1;134763:1:0;;-1:-1:-1;134767:30:0;134747:51;;134647:163;134924:24;;;134907:14;134924:24;;;;;;;;;42764:25:1;;;42837:4;42825:17;;42805:18;;;42798:45;;;;42859:18;;;42852:34;;;42902:18;;;42895:34;;;134924:24:0;;42736:19:1;;134924:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;134924:24:0;;-1:-1:-1;;134924:24:0;;;-1:-1:-1;;;;;;;134963:20:0;;134959:103;;135016:1;135020:29;135000:50;;;;;;;134959:103;135082:6;-1:-1:-1;135090:20:0;;-1:-1:-1;133642:1477:0;;;;;;;;:::o;129102:521::-;129180:20;129171:5;:29;;;;;;;;:::i;:::-;;129167:449;;129102:521;:::o;129167:449::-;129278:29;129269:5;:38;;;;;;;;:::i;:::-;;129265:351;;129324:34;;-1:-1:-1;;;129324:34:0;;43142:2:1;129324:34:0;;;43124:21:1;43181:2;43161:18;;;43154:30;43220:26;43200:18;;;43193:54;43264:18;;129324:34:0;42940:348:1;129265:351:0;129389:35;129380:5;:44;;;;;;;;:::i;:::-;;129376:240;;129441:41;;-1:-1:-1;;;129441:41:0;;43495:2:1;129441:41:0;;;43477:21:1;43534:2;43514:18;;;43507:30;43573:33;43553:18;;;43546:61;43624:18;;129441:41:0;43293:355:1;129376:240:0;129513:30;129504:5;:39;;;;;;;;:::i;:::-;;129500:116;;129560:44;;-1:-1:-1;;;129560:44:0;;43855:2:1;129560:44:0;;;43837:21:1;43894:2;43874:18;;;43867:30;43933:34;43913:18;;;43906:62;-1:-1:-1;;;43984:18:1;;;43977:32;44026:19;;129560:44:0;43653:398:1;86026:857:0;86160:11;;86117:7;;;;86188;;86184:692;;86265:25;86293:28;86307:4;86313:7;86319:1;86313:3;:7;:::i;86293:28::-;86265:56;;;;;;;;;;;;;;;;;;-1:-1:-1;;;86265:56:0;;;-1:-1:-1;;;;;86265:56:0;;;;;;;-1:-1:-1;86402:16:0;;;-1:-1:-1;86402:16:0;86394:56;;;;-1:-1:-1;;;86394:56:0;;44258:2:1;86394:56:0;;;44240:21:1;44297:2;44277:18;;;44270:30;44336:29;44316:18;;;44309:57;44383:18;;86394:56:0;44056:351:1;86394:56:0;86517:9;;:16;;;;;;;86513:193;;86592:5;86554:28;86568:4;86574:7;86580:1;86574:3;:7;:::i;86554:28::-;:43;;-1:-1:-1;;;;;86554:43:0;;;;-1:-1:-1;;;86554:43:0;;;;;;;;;;;86513:193;;;86648:41;;;;;;;;;;;;;;;-1:-1:-1;;;;;86648:41:0;;;;;;;;;;86638:52;;;;;;;-1:-1:-1;86638:52:0;;;;;;;;;;;;;;-1:-1:-1;;;86638:52:0;;;;;;;;;;86513:193;86728:11;;;;-1:-1:-1;86741:5:0;;-1:-1:-1;86720:27:0;;-1:-1:-1;86720:27:0;86184:692;-1:-1:-1;;86790:41:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;86790:41:0;;;;;;;;;;86780:52;;;;;;;-1:-1:-1;86780:52:0;;;;;;;;;;;;;-1:-1:-1;;;86780:52:0;;;;;;;;;;;;-1:-1:-1;;86824:5:0;86847:17;;1266:106;1324:7;1355:1;1351;:5;:13;;1363:1;1351:13;;;-1:-1:-1;1359:1:0;;1344:20;-1:-1:-1;1266:106:0:o;9370:1019::-;9422:7;;9509:3;9500:12;;;:16;9496:102;;9547:3;9537:13;;;;9569;9496:102;9625:2;9616:11;;;:15;9612:99;;9662:2;9652:12;;;;9683;9612:99;9738:2;9729:11;;;:15;9725:99;;9775:2;9765:12;;;;9796;9725:99;9851:2;9842:11;;;:15;9838:99;;9888:2;9878:12;;;;9909;9838:99;9964:1;9955:10;;;:14;9951:96;;10000:1;9990:11;;;;10020;9951:96;10074:1;10065:10;;;:14;10061:96;;10110:1;10100:11;;;;10130;10061:96;10184:1;10175:10;;;:14;10171:96;;10220:1;10210:11;;;;10240;10171:96;10294:1;10285:10;;;:14;10281:66;;10330:1;10320:11;10375:6;9370:1019;-1:-1:-1;;9370:1019:0:o;1448:106::-;1506:7;1537:1;1533;:5;:13;;1545:1;1533:13;;1673:156;1735:7;1810:11;1820:1;1811:5;;;1810:11;:::i;:::-;1800:21;;1801:5;;;1800:21;:::i;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;679:180;738:6;791:2;779:9;770:7;766:23;762:32;759:52;;;807:1;804;797:12;759:52;-1:-1:-1;830:23:1;;679:180;-1:-1:-1;679:180:1:o;864:250::-;949:1;959:113;973:6;970:1;967:13;959:113;;;1049:11;;;1043:18;1030:11;;;1023:39;995:2;988:10;959:113;;;-1:-1:-1;;1106:1:1;1088:16;;1081:27;864:250::o;1119:271::-;1161:3;1199:5;1193:12;1226:6;1221:3;1214:19;1242:76;1311:6;1304:4;1299:3;1295:14;1288:4;1281:5;1277:16;1242:76;:::i;:::-;1372:2;1351:15;-1:-1:-1;;1347:29:1;1338:39;;;;1379:4;1334:50;;1119:271;-1:-1:-1;;1119:271:1:o;1395:220::-;1544:2;1533:9;1526:21;1507:4;1564:45;1605:2;1594:9;1590:18;1582:6;1564:45;:::i;1620:131::-;-1:-1:-1;;;;;1695:31:1;;1685:42;;1675:70;;1741:1;1738;1731:12;1756:247;1815:6;1868:2;1856:9;1847:7;1843:23;1839:32;1836:52;;;1884:1;1881;1874:12;1836:52;1923:9;1910:23;1942:31;1967:5;1942:31;:::i;2008:127::-;2069:10;2064:3;2060:20;2057:1;2050:31;2100:4;2097:1;2090:15;2124:4;2121:1;2114:15;2140:275;2211:2;2205:9;2276:2;2257:13;;-1:-1:-1;;2253:27:1;2241:40;;-1:-1:-1;;;;;2296:34:1;;2332:22;;;2293:62;2290:88;;;2358:18;;:::i;:::-;2394:2;2387:22;2140:275;;-1:-1:-1;2140:275:1:o;2420:183::-;2480:4;-1:-1:-1;;;;;2505:6:1;2502:30;2499:56;;;2535:18;;:::i;:::-;-1:-1:-1;2580:1:1;2576:14;2592:4;2572:25;;2420:183::o;2608:737::-;2662:5;2715:3;2708:4;2700:6;2696:17;2692:27;2682:55;;2733:1;2730;2723:12;2682:55;2769:6;2756:20;2795:4;2819:60;2835:43;2875:2;2835:43;:::i;:::-;2819:60;:::i;:::-;2913:15;;;2999:1;2995:10;;;;2983:23;;2979:32;;;2944:12;;;;3023:15;;;3020:35;;;3051:1;3048;3041:12;3020:35;3087:2;3079:6;3075:15;3099:217;3115:6;3110:3;3107:15;3099:217;;;3195:3;3182:17;3212:31;3237:5;3212:31;:::i;:::-;3256:18;;3294:12;;;;3132;;3099:217;;3350:662;3404:5;3457:3;3450:4;3442:6;3438:17;3434:27;3424:55;;3475:1;3472;3465:12;3424:55;3511:6;3498:20;3537:4;3561:60;3577:43;3617:2;3577:43;:::i;3561:60::-;3655:15;;;3741:1;3737:10;;;;3725:23;;3721:32;;;3686:12;;;;3765:15;;;3762:35;;;3793:1;3790;3783:12;3762:35;3829:2;3821:6;3817:15;3841:142;3857:6;3852:3;3849:15;3841:142;;;3923:17;;3911:30;;3961:12;;;;3874;;3841:142;;4017:186;4065:4;-1:-1:-1;;;;;4090:6:1;4087:30;4084:56;;;4120:18;;:::i;:::-;-1:-1:-1;4186:2:1;4165:15;-1:-1:-1;;4161:29:1;4192:4;4157:40;;4017:186::o;4208:336::-;4272:5;4301:52;4317:35;4345:6;4317:35;:::i;4301:52::-;4292:61;;4376:6;4369:5;4362:21;4416:3;4407:6;4402:3;4398:16;4395:25;4392:45;;;4433:1;4430;4423:12;4392:45;4482:6;4477:3;4470:4;4463:5;4459:16;4446:43;4536:1;4529:4;4520:6;4513:5;4509:18;4505:29;4498:40;4208:336;;;;;:::o;4549:220::-;4591:5;4644:3;4637:4;4629:6;4625:17;4621:27;4611:55;;4662:1;4659;4652:12;4611:55;4684:79;4759:3;4750:6;4737:20;4730:4;4722:6;4718:17;4684:79;:::i;4774:886::-;4826:5;4879:3;4872:4;4864:6;4860:17;4856:27;4846:55;;4897:1;4894;4887:12;4846:55;4933:6;4920:20;4959:4;4983:60;4999:43;5039:2;4999:43;:::i;4983:60::-;5077:15;;;5163:1;5159:10;;;;5147:23;;5143:32;;;5108:12;;;;5187:15;;;5184:35;;;5215:1;5212;5205:12;5184:35;5251:2;5243:6;5239:15;5263:368;5279:6;5274:3;5271:15;5263:368;;;5365:3;5352:17;-1:-1:-1;;;;;5388:11:1;5385:35;5382:125;;;5461:1;5490:2;5486;5479:14;5382:125;5532:56;5584:3;5579:2;5565:11;5557:6;5553:24;5549:33;5532:56;:::i;:::-;5520:69;;-1:-1:-1;5609:12:1;;;;5296;;5263:368;;5665:1226;5854:6;5862;5870;5878;5886;5939:3;5927:9;5918:7;5914:23;5910:33;5907:53;;;5956:1;5953;5946:12;5907:53;5992:9;5979:23;5969:33;;6053:2;6042:9;6038:18;6025:32;-1:-1:-1;;;;;6117:2:1;6109:6;6106:14;6103:34;;;6133:1;6130;6123:12;6103:34;6156:61;6209:7;6200:6;6189:9;6185:22;6156:61;:::i;:::-;6146:71;;6270:2;6259:9;6255:18;6242:32;6226:48;;6299:2;6289:8;6286:16;6283:36;;;6315:1;6312;6305:12;6283:36;6338:63;6393:7;6382:8;6371:9;6367:24;6338:63;:::i;:::-;6328:73;;6454:2;6443:9;6439:18;6426:32;6410:48;;6483:2;6473:8;6470:16;6467:36;;;6499:1;6496;6489:12;6467:36;6522:61;6575:7;6564:8;6553:9;6549:24;6522:61;:::i;:::-;6512:71;;6636:3;6625:9;6621:19;6608:33;6592:49;;6666:2;6656:8;6653:16;6650:36;;;6682:1;6679;6672:12;6650:36;-1:-1:-1;6705:24:1;;6760:4;6752:13;;6748:27;-1:-1:-1;6738:55:1;;6789:1;6786;6779:12;6738:55;6812:73;6877:7;6872:2;6859:16;6854:2;6850;6846:11;6812:73;:::i;:::-;6802:83;;;5665:1226;;;;;;;;:::o;6896:383::-;6973:6;6981;6989;7042:2;7030:9;7021:7;7017:23;7013:32;7010:52;;;7058:1;7055;7048:12;7010:52;7097:9;7084:23;7116:31;7141:5;7116:31;:::i;:::-;7166:5;7218:2;7203:18;;7190:32;;-1:-1:-1;7269:2:1;7254:18;;;7241:32;;6896:383;-1:-1:-1;;;6896:383:1:o;7284:665::-;7379:6;7387;7395;7403;7456:3;7444:9;7435:7;7431:23;7427:33;7424:53;;;7473:1;7470;7463:12;7424:53;7512:9;7499:23;7531:31;7556:5;7531:31;:::i;:::-;7581:5;-1:-1:-1;7638:2:1;7623:18;;7610:32;7651:33;7610:32;7651:33;:::i;:::-;7703:7;-1:-1:-1;7757:2:1;7742:18;;7729:32;;-1:-1:-1;7812:2:1;7797:18;;7784:32;-1:-1:-1;;;;;7828:30:1;;7825:50;;;7871:1;7868;7861:12;7825:50;7894:49;7935:7;7926:6;7915:9;7911:22;7894:49;:::i;:::-;7884:59;;;7284:665;;;;;;;:::o;8573:348::-;8625:8;8635:6;8689:3;8682:4;8674:6;8670:17;8666:27;8656:55;;8707:1;8704;8697:12;8656:55;-1:-1:-1;8730:20:1;;-1:-1:-1;;;;;8762:30:1;;8759:50;;;8805:1;8802;8795:12;8759:50;8842:4;8834:6;8830:17;8818:29;;8894:3;8887:4;8878:6;8870;8866:19;8862:30;8859:39;8856:59;;;8911:1;8908;8901:12;8856:59;8573:348;;;;;:::o;8926:547::-;9015:6;9023;9031;9039;9092:2;9080:9;9071:7;9067:23;9063:32;9060:52;;;9108:1;9105;9098:12;9060:52;9144:9;9131:23;9121:33;;9201:2;9190:9;9186:18;9173:32;9163:42;;9256:2;9245:9;9241:18;9228:32;-1:-1:-1;;;;;9275:6:1;9272:30;9269:50;;;9315:1;9312;9305:12;9269:50;9354:59;9405:7;9396:6;9385:9;9381:22;9354:59;:::i;:::-;8926:547;;;;-1:-1:-1;9432:8:1;-1:-1:-1;;;;8926:547:1:o;9478:127::-;9539:10;9534:3;9530:20;9527:1;9520:31;9570:4;9567:1;9560:15;9594:4;9591:1;9584:15;9610:346;9760:2;9745:18;;9793:1;9782:13;;9772:144;;9838:10;9833:3;9829:20;9826:1;9819:31;9873:4;9870:1;9863:15;9901:4;9898:1;9891:15;9772:144;9925:25;;;9610:346;:::o;9961:897::-;10131:6;10139;10147;10155;10208:3;10196:9;10187:7;10183:23;10179:33;10176:53;;;10225:1;10222;10215:12;10176:53;10265:9;10252:23;-1:-1:-1;;;;;10335:2:1;10327:6;10324:14;10321:34;;;10351:1;10348;10341:12;10321:34;10374:61;10427:7;10418:6;10407:9;10403:22;10374:61;:::i;:::-;10364:71;;10488:2;10477:9;10473:18;10460:32;10444:48;;10517:2;10507:8;10504:16;10501:36;;;10533:1;10530;10523:12;10501:36;10556:63;10611:7;10600:8;10589:9;10585:24;10556:63;:::i;:::-;10546:73;;10672:2;10661:9;10657:18;10644:32;10628:48;;10701:2;10691:8;10688:16;10685:36;;;10717:1;10714;10707:12;10685:36;;10740:61;10793:7;10782:8;10771:9;10767:24;10740:61;:::i;:::-;9961:897;;;;-1:-1:-1;10730:71:1;;10848:2;10833:18;10820:32;;-1:-1:-1;;;9961:897:1:o;11618:1033::-;11797:6;11805;11813;11821;11829;11882:3;11870:9;11861:7;11857:23;11853:33;11850:53;;;11899:1;11896;11889:12;11850:53;11939:9;11926:23;-1:-1:-1;;;;;12009:2:1;12001:6;11998:14;11995:34;;;12025:1;12022;12015:12;11995:34;12048:61;12101:7;12092:6;12081:9;12077:22;12048:61;:::i;:::-;12038:71;;12162:2;12151:9;12147:18;12134:32;12118:48;;12191:2;12181:8;12178:16;12175:36;;;12207:1;12204;12197:12;12175:36;12230:63;12285:7;12274:8;12263:9;12259:24;12230:63;:::i;:::-;12220:73;;12346:2;12335:9;12331:18;12318:32;12302:48;;12375:2;12365:8;12362:16;12359:36;;;12391:1;12388;12381:12;12359:36;;12414:61;12467:7;12456:8;12445:9;12441:24;12414:61;:::i;:::-;12404:71;;;12522:2;12511:9;12507:18;12494:32;12484:42;;12576:3;12565:9;12561:19;12548:33;12590:31;12615:5;12590:31;:::i;:::-;12640:5;12630:15;;;11618:1033;;;;;;;;:::o;12656:248::-;12724:6;12732;12785:2;12773:9;12764:7;12760:23;12756:32;12753:52;;;12801:1;12798;12791:12;12753:52;-1:-1:-1;;12824:23:1;;;12894:2;12879:18;;;12866:32;;-1:-1:-1;12656:248:1:o;12909:435::-;12962:3;13000:5;12994:12;13027:6;13022:3;13015:19;13053:4;13082:2;13077:3;13073:12;13066:19;;13119:2;13112:5;13108:14;13140:1;13150:169;13164:6;13161:1;13158:13;13150:169;;;13225:13;;13213:26;;13259:12;;;;13294:15;;;;13186:1;13179:9;13150:169;;;-1:-1:-1;13335:3:1;;12909:435;-1:-1:-1;;;;;12909:435:1:o;13349:920::-;13755:3;13750;13746:13;13738:6;13734:26;13723:9;13716:45;13797:3;13792:2;13781:9;13777:18;13770:31;13697:4;13824:46;13865:3;13854:9;13850:19;13842:6;13824:46;:::i;:::-;13918:9;13910:6;13906:22;13901:2;13890:9;13886:18;13879:50;13952:33;13978:6;13970;13952:33;:::i;:::-;14016:2;14001:18;;13994:34;;;-1:-1:-1;;;;;14065:32:1;;14059:3;14044:19;;14037:61;14085:3;14114:19;;14107:35;;;14179:22;;;14173:3;14158:19;;14151:51;13938:47;-1:-1:-1;14219:44:1;13938:47;14248:6;14219:44;:::i;:::-;14211:52;13349:920;-1:-1:-1;;;;;;;;;;13349:920:1:o;14475:1071::-;14629:6;14637;14645;14653;14661;14714:3;14702:9;14693:7;14689:23;14685:33;14682:53;;;14731:1;14728;14721:12;14682:53;14770:9;14757:23;14789:31;14814:5;14789:31;:::i;:::-;14839:5;-1:-1:-1;14896:2:1;14881:18;;14868:32;14909:33;14868:32;14909:33;:::i;:::-;14961:7;-1:-1:-1;15019:2:1;15004:18;;14991:32;-1:-1:-1;;;;;15072:14:1;;;15069:34;;;15099:1;15096;15089:12;15069:34;15122:61;15175:7;15166:6;15155:9;15151:22;15122:61;:::i;:::-;15112:71;;15236:2;15225:9;15221:18;15208:32;15192:48;;15265:2;15255:8;15252:16;15249:36;;;15281:1;15278;15271:12;15249:36;15304:63;15359:7;15348:8;15337:9;15333:24;15304:63;:::i;:::-;15294:73;;15420:3;15409:9;15405:19;15392:33;15376:49;;15450:2;15440:8;15437:16;15434:36;;;15466:1;15463;15456:12;15434:36;;15489:51;15532:7;15521:8;15510:9;15506:24;15489:51;:::i;15551:156::-;15617:20;;15677:4;15666:16;;15656:27;;15646:55;;15697:1;15694;15687:12;15712:838;15826:6;15834;15842;15850;15858;15866;15919:3;15907:9;15898:7;15894:23;15890:33;15887:53;;;15936:1;15933;15926:12;15887:53;15972:9;15959:23;15949:33;;16029:2;16018:9;16014:18;16001:32;15991:42;;16052:36;16084:2;16073:9;16069:18;16052:36;:::i;:::-;16042:46;;16139:2;16128:9;16124:18;16111:32;-1:-1:-1;;;;;16203:2:1;16195:6;16192:14;16189:34;;;16219:1;16216;16209:12;16189:34;16258:59;16309:7;16300:6;16289:9;16285:22;16258:59;:::i;:::-;16336:8;;-1:-1:-1;16232:85:1;-1:-1:-1;16424:3:1;16409:19;;16396:33;;-1:-1:-1;16441:16:1;;;16438:36;;;16470:1;16467;16460:12;16438:36;;16493:51;16536:7;16525:8;16514:9;16510:24;16493:51;:::i;:::-;16483:61;;;15712:838;;;;;;;;:::o;16555:613::-;16643:6;16651;16659;16667;16720:2;16708:9;16699:7;16695:23;16691:32;16688:52;;;16736:1;16733;16726:12;16688:52;16775:9;16762:23;16794:31;16819:5;16794:31;:::i;:::-;16844:5;-1:-1:-1;16896:2:1;16881:18;;16868:32;;-1:-1:-1;16951:2:1;16936:18;;16923:32;-1:-1:-1;;;;;16967:30:1;;16964:50;;;17010:1;17007;17000:12;17173:618;17269:6;17277;17285;17293;17301;17354:3;17342:9;17333:7;17329:23;17325:33;17322:53;;;17371:1;17368;17361:12;17322:53;17407:9;17394:23;17384:33;;17464:2;17453:9;17449:18;17436:32;17426:42;;17487:36;17519:2;17508:9;17504:18;17487:36;:::i;:::-;17477:46;;17574:2;17563:9;17559:18;17546:32;-1:-1:-1;;;;;17593:6:1;17590:30;17587:50;;;17633:1;17630;17623:12;17587:50;17672:59;17723:7;17714:6;17703:9;17699:22;17672:59;:::i;:::-;17173:618;;;;-1:-1:-1;17173:618:1;;-1:-1:-1;17750:8:1;;17646:85;17173:618;-1:-1:-1;;;17173:618:1:o;17796:592::-;17891:6;17899;17907;17915;17968:3;17956:9;17947:7;17943:23;17939:33;17936:53;;;17985:1;17982;17975:12;17936:53;18024:9;18011:23;18043:31;18068:5;18043:31;:::i;:::-;18093:5;-1:-1:-1;18145:2:1;18130:18;;18117:32;;-1:-1:-1;18196:2:1;18181:18;;18168:32;;-1:-1:-1;18251:2:1;18236:18;;18223:32;-1:-1:-1;;;;;18267:30:1;;18264:50;;;18310:1;18307;18300:12;18393:318;18468:6;18476;18484;18537:2;18525:9;18516:7;18512:23;18508:32;18505:52;;;18553:1;18550;18543:12;18505:52;18589:9;18576:23;18566:33;;18646:2;18635:9;18631:18;18618:32;18608:42;;18669:36;18701:2;18690:9;18686:18;18669:36;:::i;:::-;18659:46;;18393:318;;;;;:::o;18716:734::-;18820:6;18828;18836;18844;18852;18905:3;18893:9;18884:7;18880:23;18876:33;18873:53;;;18922:1;18919;18912:12;18873:53;18961:9;18948:23;18980:31;19005:5;18980:31;:::i;:::-;19030:5;-1:-1:-1;19087:2:1;19072:18;;19059:32;19100:33;19059:32;19100:33;:::i;:::-;19152:7;-1:-1:-1;19206:2:1;19191:18;;19178:32;;-1:-1:-1;19257:2:1;19242:18;;19229:32;;-1:-1:-1;19312:3:1;19297:19;;19284:33;-1:-1:-1;;;;;19329:30:1;;19326:50;;;19372:1;19369;19362:12;19326:50;19395:49;19436:7;19427:6;19416:9;19412:22;19395:49;:::i;19455:1047::-;19594:6;19602;19610;19618;19626;19634;19642;19650;19658;19711:3;19699:9;19690:7;19686:23;19682:33;19679:53;;;19728:1;19725;19718:12;19679:53;19764:9;19751:23;19741:33;;19821:2;19810:9;19806:18;19793:32;19783:42;;19844:36;19876:2;19865:9;19861:18;19844:36;:::i;:::-;19834:46;;19931:2;19920:9;19916:18;19903:32;-1:-1:-1;;;;;19995:2:1;19987:6;19984:14;19981:34;;;20011:1;20008;20001:12;19981:34;20050:59;20101:7;20092:6;20081:9;20077:22;20050:59;:::i;:::-;20128:8;;-1:-1:-1;20024:85:1;-1:-1:-1;20216:3:1;20201:19;;20188:33;;-1:-1:-1;20233:16:1;;;20230:36;;;20262:1;20259;20252:12;20230:36;;20285:51;20328:7;20317:8;20306:9;20302:24;20285:51;:::i;:::-;20275:61;;;20355:37;20387:3;20376:9;20372:19;20355:37;:::i;:::-;20345:47;;20439:3;20428:9;20424:19;20411:33;20401:43;;20491:3;20480:9;20476:19;20463:33;20453:43;;19455:1047;;;;;;;;;;;:::o;20507:527::-;20607:6;20615;20623;20631;20639;20647;20700:3;20688:9;20679:7;20675:23;20671:33;20668:53;;;20717:1;20714;20707:12;20668:53;20753:9;20740:23;20730:33;;20810:2;20799:9;20795:18;20782:32;20772:42;;20833:36;20865:2;20854:9;20850:18;20833:36;:::i;:::-;20823:46;;20888:36;20920:2;20909:9;20905:18;20888:36;:::i;:::-;20878:46;;20971:3;20960:9;20956:19;20943:33;20933:43;;21023:3;21012:9;21008:19;20995:33;20985:43;;20507:527;;;;;;;;:::o;21615:271::-;21798:6;21790;21785:3;21772:33;21754:3;21824:16;;21849:13;;;21824:16;21615:271;-1:-1:-1;21615:271:1:o;21891:380::-;21970:1;21966:12;;;;22013;;;22034:61;;22088:4;22080:6;22076:17;22066:27;;22034:61;22141:2;22133:6;22130:14;22110:18;22107:38;22104:161;;22187:10;22182:3;22178:20;22175:1;22168:31;22222:4;22219:1;22212:15;22250:4;22247:1;22240:15;22104:161;;21891:380;;;:::o;22276:127::-;22337:10;22332:3;22328:20;22325:1;22318:31;22368:4;22365:1;22358:15;22392:4;22389:1;22382:15;22408:128;22475:9;;;22496:11;;;22493:37;;;22510:18;;:::i;22959:397::-;23161:2;23143:21;;;23200:2;23180:18;;;23173:30;23239:34;23234:2;23219:18;;23212:62;-1:-1:-1;;;23305:2:1;23290:18;;23283:31;23346:3;23331:19;;22959:397::o;24116:125::-;24181:9;;;24202:10;;;24199:36;;;24215:18;;:::i;24246:461::-;24299:3;24337:5;24331:12;24364:6;24359:3;24352:19;24390:4;24419:2;24414:3;24410:12;24403:19;;24456:2;24449:5;24445:14;24477:1;24487:195;24501:6;24498:1;24495:13;24487:195;;;24566:13;;-1:-1:-1;;;;;24562:39:1;24550:52;;24622:12;;;;24657:15;;;;24598:1;24516:9;24487:195;;24712:615;24763:3;24801:5;24795:12;24828:6;24823:3;24816:19;24854:4;24895:2;24890:3;24886:12;24920:11;24947;24940:18;;24997:6;24994:1;24990:14;24983:5;24979:26;24967:38;;25039:2;25032:5;25028:14;25060:1;25070:231;25084:6;25081:1;25078:13;25070:231;;;25155:5;25149:4;25145:16;25140:3;25133:29;25183:38;25216:4;25207:6;25201:13;25183:38;:::i;:::-;25279:12;;;;25175:46;-1:-1:-1;25244:15:1;;;;25106:1;25099:9;25070:231;;;-1:-1:-1;25317:4:1;;24712:615;-1:-1:-1;;;;;;;24712:615:1:o;25332:1864::-;25906:4;25935:3;25965:6;25954:9;25947:25;25991:2;26058:1;26054;26049:3;26045:11;26041:19;26033:6;26029:32;26024:2;26013:9;26009:18;26002:60;26098:2;26093;26082:9;26078:18;26071:30;26124:56;26176:2;26165:9;26161:18;26153:6;26124:56;:::i;:::-;26110:70;;26228:9;26220:6;26216:22;26211:2;26200:9;26196:18;26189:50;26262:44;26299:6;26291;26262:44;:::i;:::-;26248:58;;26355:9;26347:6;26343:22;26337:3;26326:9;26322:19;26315:51;26386:6;26421;26415:13;26452:6;26444;26437:22;26487:2;26479:6;26475:15;26468:22;;26546:2;26536:6;26533:1;26529:14;26521:6;26517:27;26513:36;26584:2;26576:6;26572:15;26605:1;26615:252;26629:6;26626:1;26623:13;26615:252;;;26719:2;26715:7;26706:6;26698;26694:19;26690:33;26685:3;26678:46;26747:40;26780:6;26771;26765:13;26747:40;:::i;:::-;26845:12;;;;26737:50;-1:-1:-1;26810:15:1;;;;26651:1;26644:9;26615:252;;;26619:3;;26916:9;26908:6;26904:22;26898:3;26887:9;26883:19;26876:51;26950:42;26985:6;26977;26950:42;:::i;:::-;26936:56;;;;;;27029:6;27023:3;27012:9;27008:19;27001:35;27073:6;27067:3;27056:9;27052:19;27045:35;27129:9;27121:6;27117:22;27111:3;27100:9;27096:19;27089:51;27157:33;27183:6;27175;27157:33;:::i;:::-;27149:41;25332:1864;-1:-1:-1;;;;;;;;;;;;25332:1864:1:o;27561:184::-;27631:6;27684:2;27672:9;27663:7;27659:23;27655:32;27652:52;;;27700:1;27697;27690:12;27652:52;-1:-1:-1;27723:16:1;;27561:184;-1:-1:-1;27561:184:1:o;27750:168::-;27823:9;;;27854;;27871:15;;;27865:22;;27851:37;27841:71;;27892:18;;:::i;27923:127::-;27984:10;27979:3;27975:20;27972:1;27965:31;28015:4;28012:1;28005:15;28039:4;28036:1;28029:15;28055:120;28095:1;28121;28111:35;;28126:18;;:::i;:::-;-1:-1:-1;28160:9:1;;28055:120::o;28584:390::-;28743:2;28732:9;28725:21;28782:6;28777:2;28766:9;28762:18;28755:34;28839:6;28831;28826:2;28815:9;28811:18;28798:48;28895:1;28866:22;;;28890:2;28862:31;;;28855:42;;;;28958:2;28937:15;;;-1:-1:-1;;28933:29:1;28918:45;28914:54;;28584:390;-1:-1:-1;28584:390:1:o;30097:251::-;30167:6;30220:2;30208:9;30199:7;30195:23;30191:32;30188:52;;;30236:1;30233;30226:12;30188:52;30268:9;30262:16;30287:31;30312:5;30287:31;:::i;30353:648::-;30433:6;30486:2;30474:9;30465:7;30461:23;30457:32;30454:52;;;30502:1;30499;30492:12;30454:52;30535:9;30529:16;-1:-1:-1;;;;;30560:6:1;30557:30;30554:50;;;30600:1;30597;30590:12;30554:50;30623:22;;30676:4;30668:13;;30664:27;-1:-1:-1;30654:55:1;;30705:1;30702;30695:12;30654:55;30734:2;30728:9;30759:48;30775:31;30803:2;30775:31;:::i;30759:48::-;30830:2;30823:5;30816:17;30870:7;30865:2;30860;30856;30852:11;30848:20;30845:33;30842:53;;;30891:1;30888;30881:12;30842:53;30904:67;30968:2;30963;30956:5;30952:14;30947:2;30943;30939:11;30904:67;:::i;31006:127::-;31067:10;31062:3;31058:20;31055:1;31048:31;31098:4;31095:1;31088:15;31122:4;31119:1;31112:15;31540:284;31609:6;31662:2;31650:9;31641:7;31637:23;31633:32;31630:52;;;31678:1;31675;31668:12;31630:52;31710:9;31704:16;31760:14;31753:5;31749:26;31742:5;31739:37;31729:65;;31790:1;31787;31780:12;31829:856;32238:3;32227:9;32220:22;32201:4;32265:57;32317:3;32306:9;32302:19;32294:6;32265:57;:::i;:::-;32370:9;32362:6;32358:22;32353:2;32342:9;32338:18;32331:50;32404:44;32441:6;32433;32404:44;:::i;:::-;32390:58;;32496:9;32488:6;32484:22;32479:2;32468:9;32464:18;32457:50;32524:42;32559:6;32551;32524:42;:::i;:::-;32597:2;32582:18;;32575:34;;;;-1:-1:-1;;;;;;;32646:32:1;;;;32640:3;32625:19;;;32618:61;32516:50;31829:856;-1:-1:-1;;;31829:856:1:o;34632:275::-;34717:6;34770:2;34758:9;34749:7;34745:23;34741:32;34738:52;;;34786:1;34783;34776:12;34738:52;34818:9;34812:16;34857:1;34850:5;34847:12;34837:40;;34873:1;34870;34863:12;35936:691;36034:6;36087:3;36075:9;36066:7;36062:23;36058:33;36055:53;;;36104:1;36101;36094:12;36055:53;36137:2;36131:9;36179:3;36171:6;36167:16;36249:6;36237:10;36234:22;-1:-1:-1;;;;;36201:10:1;36198:34;36195:62;36192:88;;;36260:18;;:::i;:::-;36296:2;36289:22;36335:16;;36320:32;;36395:2;36380:18;;36374:25;36408:31;36374:25;36408:31;:::i;:::-;36467:2;36455:15;;36448:30;36532:2;36517:18;;;36511:25;36494:15;;;36487:50;36591:2;36576:18;;;36570:25;36553:15;;;36546:50;;;;-1:-1:-1;36459:6:1;35936:691;-1:-1:-1;35936:691:1:o;37397:135::-;37436:3;37457:17;;;37454:43;;37477:18;;:::i;:::-;-1:-1:-1;37524:1:1;37513:13;;37397:135::o;37537:287::-;37666:3;37704:6;37698:13;37720:66;37779:6;37774:3;37767:4;37759:6;37755:17;37720:66;:::i;:::-;37802:16;;;;;37537:287;-1:-1:-1;;37537:287:1:o;38640:442::-;38869:6;38858:9;38851:25;38924:4;38916:6;38912:17;38907:2;38896:9;38892:18;38885:45;38966:6;38961:2;38950:9;38946:18;38939:34;39009:3;39004:2;38993:9;38989:18;38982:31;38832:4;39030:46;39071:3;39060:9;39056:19;39048:6;39030:46;:::i;39087:604::-;39362:6;39351:9;39344:25;39417:4;39409:6;39405:17;39400:2;39389:9;39385:18;39378:45;39459:6;39454:2;39443:9;39439:18;39432:34;39502:3;39497:2;39486:9;39482:18;39475:31;39325:4;39529:46;39570:3;39559:9;39555:19;39547:6;39529:46;:::i;:::-;39624:9;39616:6;39612:22;39606:3;39595:9;39591:19;39584:51;39652:33;39678:6;39670;39652:33;:::i;40104:179::-;40172:14;40219:10;;;40207;;;40203:27;;40242:12;;;40239:38;;;40257:18;;:::i;:::-;40239:38;40104:179;;;;:::o;40569:195::-;40608:1;40634:14;40675:2;40672:1;40668:10;40697:3;40687:37;;40704:18;;:::i;:::-;40742:10;;40738:20;;;;;40569:195;-1:-1:-1;;40569:195:1:o;41048:245::-;41127:6;41135;41188:2;41176:9;41167:7;41163:23;41159:32;41156:52;;;41204:1;41201;41194:12;41156:52;-1:-1:-1;;41227:16:1;;41283:2;41268:18;;;41262:25;41227:16;;41262:25;;-1:-1:-1;41048:245:1:o
Swarm Source
ipfs://129f3447433c59a981e767b2f1452563adddce84ada246938e565b4cf0250b85
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.