Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 209 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Approve | 19627620 | 109 days ago | IN | 0 ETH | 0.00094922 | ||||
Approve | 17017465 | 476 days ago | IN | 0 ETH | 0.00058804 | ||||
Approve | 16790211 | 508 days ago | IN | 0 ETH | 0.00050843 | ||||
Approve | 15575992 | 677 days ago | IN | 0 ETH | 0.00102535 | ||||
Approve | 15575188 | 677 days ago | IN | 0 ETH | 0.00209731 | ||||
Approve | 15575187 | 677 days ago | IN | 0 ETH | 0.00044604 | ||||
Approve | 15575187 | 677 days ago | IN | 0 ETH | 0.00079867 | ||||
Approve | 15567431 | 679 days ago | IN | 0 ETH | 0.00019008 | ||||
Approve | 15566990 | 679 days ago | IN | 0 ETH | 0.00029615 | ||||
Approve | 15561003 | 679 days ago | IN | 0 ETH | 0.00028832 | ||||
Approve | 15560307 | 680 days ago | IN | 0 ETH | 0.00038444 | ||||
Revoke Role | 15558252 | 680 days ago | IN | 0 ETH | 0.00008838 | ||||
Revoke Role | 15558249 | 680 days ago | IN | 0 ETH | 0.00015282 | ||||
Approve | 15557647 | 680 days ago | IN | 0 ETH | 0.00027278 | ||||
Approve | 15557491 | 680 days ago | IN | 0 ETH | 0.00017331 | ||||
Approve | 15557477 | 680 days ago | IN | 0 ETH | 0.0002604 | ||||
Approve | 15556025 | 680 days ago | IN | 0 ETH | 0.00027777 | ||||
Approve | 15555705 | 680 days ago | IN | 0 ETH | 0.00095526 | ||||
Approve | 15555644 | 680 days ago | IN | 0 ETH | 0.00028996 | ||||
Approve | 15555622 | 680 days ago | IN | 0 ETH | 0.00039287 | ||||
Approve | 15555604 | 680 days ago | IN | 0 ETH | 0.00035808 | ||||
Approve | 15555285 | 680 days ago | IN | 0 ETH | 0.00028068 | ||||
Revoke Role | 15555068 | 680 days ago | IN | 0 ETH | 0.00020327 | ||||
Revoke Role | 15554916 | 680 days ago | IN | 0 ETH | 0.00020702 | ||||
Approve | 15554864 | 680 days ago | IN | 0 ETH | 0.00025698 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PandaToken
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-09-16 */ // SPDX-License-Identifier: MIT // PPPPPPPPP5P5555555555555555555YYYYYY55YYY55555YYYYYYJJJYYYYYYYYYY5Y5Y5Y555555555 // PPPPPPPPPPPP5555555555555555YYYYYYYYYYYYYY5YYYYYYYYYYYYYYYYYYYYYYYYYYYY555555555 // PPPPPPPP555PPPGGGGGGP5555555YYYYYYYYYYYYYYYYYYYYYYYYJJJYYYYYYYYYYYYYY55555555555 // PPPPPP555GB#&&&&&&&&&##BG5YYYYYYYYYYYYYYYYYYYYYYYYYY55PGGBBBBGGP55YYY55555555555 // PPPPP555B&&&&&&&&&&##&&#&&BPYYYYYYYYYYYYYYY5YYYYY5G##&&&&&&&&&&&&#B5YY5555555555 // PPPP555P&&&#BGGB#&&#&###&&&&G7!~~~~!7????77YYYYP#&&&&&&&&#BBBBBB#&&&5Y5Y55555555 // 5555555G&&##PJJJJYY?G&BP5J7!^.... ........::^~7J5GB###B5YJYPPGBB&&&GYYY55555555 // 5555555P&##BG5JJ?7!^^!:.....:^^:::............. .:^!?7???J5PB&&&&&PYYYY5555555 // 5555555P&&&&B5?7!^... .:::^^^^^^^^:::::::...:::::.... ..:^~7J5B##&YYY55555555 // PP55555P&&&&&G!:.....:^^^^^^^^^^^^^^^^::::^^^^^^^^:::::....:!P##&&&BYYYY5555555P // P5555555#&&&G:....:^^~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^::..!#&#&BYYYY555Y55555 // PP555555P&&B!...:^~~^^^^^~^^~^^^^^^^^^^^^^^^~~^^^^~~^^^^^^^^:.~G&BYYYYY55Y555555 // PP5555555G&G:.:^~~^^^~~^~~~~~~~~~~~^^~~~^~~~~~~~~~~~~~^^^~~~~^.!GYYYYYYY5YY55555 // PPP5555555PJ:^^~~~^^~^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^!JJYYYYYYYY55555 // 5555555555?:^^~~~~~!777!!!~~~!!!~~~~~~~~~~~~~!!!!!!!!!!77777!~~~^~JJYYY555555555 // 555555555Y^^~~~~~?5PGGGGP5Y?7????7!!!!!!!!!!7???????JJY5GGGGGY7~~^7JYYY555555555 // 5555555557:~~~~7PB#&&@&@@&BPYYJJ???77!!7777??JJJJYY5PG#&@@@@@&G?~^~JYY5555555555 // 5YYYY5YYJ:^~~~7G&@@@@@@&#&@&G5JJJJJ??7!!77?JJJYY555G#&&GG#@@@@@B?~^!JYY555555555 // 5YYYY5YY~.~!!~Y&@@@@@@@Y!?&@@BYJJJJ7~^:::^~7JYY555B&&@G??P&@@@@@P!^~J55555555555 // 55555YYJ:.!7!!P&&@@@@@@&B#@@@&5JJ7^:........:7Y55P#&&&&&&&@@@@&@B!^^?5555555555P // 5555555J..!???Y#@@@@@@@@@@@@&BYJ!^:^^!!7!!^:::7Y5PB##&&&@@@@&&&&57^^!Y55555555PP // 5555555Y: ^???JP#&@&&@@@&&&BPY?!!!!?YPPPPPY?~^^!J5PB###&&&&&&#B5J7~^!Y555555PP5P // 555555557 :??JJY5GBBBBBBGP5YJ?7777YG#&&B#@&B5!~~7JY55PGGGGBGP55YJ?!^7Y555555PP55 // 55555555Y:.7JJYYYYYYYYYYYYJ??7777JG####B#&&&GJ!!!?Y5YY55555YYYJJJJ7^JY5555555555 // P555555557.:?JJYYYYYYYYYYJJJJ????JYPB#&&&#BP5J????JY5555555YYYJJJJ77JY5555555555 // P55555555J:.^JJYYYYYYYYYYYYYYJJJYYYYY5G&#PYYJJJJJJYY5555555YYYJJJ?7JYY5555555555 // 5P55555555?~^?YYY555YYYYYYYYYYYYYY5PGB###BPYYJJJJJYY5555555YYYYJJ?JYYY5555555555 // 5P5555PP555YJJJYY555555YYYYYYYYYY55PGPPPP5P5555YYYY555555YYYYYYY55JYYYY5Y5555555 // 5PP55PPP55555BGP55YY55555YY555555PPPPPPPPPPPP55555555555YYYYY5G###PYYYYY55555555 // PPP555PP5555G###&#BGP555PPPPPPPPPPPPPPPPPPP555PPP55555555PG#&&@@&##B5YYY55555555 // PPPP5555555G###&&&&&&#BGGPPPPPPPPPPPPPPPPPPP55555555PGB#&&@@@@@@@&&&B5YYYY555555 // PPP555P555P#####&&&&&&&&&&##BBGGPPPPPPPPPPPPPPPPGB#&&@@@@@@@@@@@@&&&&G5555555555 // PPPPPPPP5PB#&&##&&&&&&&&&&&@@@@&&&###B#B#####&&&@@@@@@@@@@@@@@@@@@&&&#G555555555 // PPPPPPPP5G#&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&#G55555555 // PPPPPPPPP#&&&&&&&&@@@@@&&&@@@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&#PY555555 // PPPPPPPP##&&&&&&&&##&&@@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&#P555555 // PPPPPPPB&&####&&&&#&#&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#&&&&#P55555 // PPPPPPB##&&###&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&#B55555 pragma solidity 0.8.0; /** * @title SafeMathInt * @dev Math operations for int256 with overflow safety checks. */ library SafeMathInt { int256 private constant MIN_INT256 = int256(1) << 255; int256 private constant MAX_INT256 = ~(int256(1) << 255); /** * @dev Multiplies two int256 variables and fails on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { int256 c = a * b; // Detect overflow when multiplying MIN_INT256 with -1 require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256)); require((b == 0) || (c / b == a)); return c; } /** * @dev Division of two int256 variables and fails on overflow. */ function div(int256 a, int256 b) internal pure returns (int256) { // Prevent overflow when dividing MIN_INT256 by -1 require(b != -1 || a != MIN_INT256); // Solidity already throws when dividing by 0. return a / b; } /** * @dev Subtracts two int256 variables and fails on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two int256 variables and fails on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } /** * @dev Converts to absolute value, and fails on overflow. */ function abs(int256 a) internal pure returns (int256) { require(a != MIN_INT256); return a < 0 ? -a : a; } /** * @dev Computes 2^exp with limited precision where -100 <= exp <= 100 * one * @param one 1.0 represented in the same fixed point number format as exp * @param exp The power to raise 2 to -100 <= exp <= 100 * one * @return 2^exp represented with same number of decimals after the point as one */ function twoPower(int256 exp, int256 one) internal pure returns (int256) { bool reciprocal = false; if (exp < 0) { reciprocal = true; exp = abs(exp); } // Precomputed values for 2^(1/2^i) in 18 decimals fixed point numbers int256[5] memory ks = [ int256(1414213562373095049), 1189207115002721067, 1090507732665257659, 1044273782427413840, 1021897148654116678 ]; int256 whole = div(exp, one); require(whole <= 100); int256 result = mul(int256(uint256(1) << uint256(whole)), one); int256 remaining = sub(exp, mul(whole, one)); int256 current = div(one, 2); for (uint256 i = 0; i < 5; i++) { if (remaining >= current) { remaining = sub(remaining, current); result = div(mul(result, ks[i]), 10**18); // 10**18 to match hardcoded ks values } current = div(current, 2); } if (reciprocal) { result = div(mul(one, one), result); } return result; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol // 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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol // 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; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.7.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); /////////////////////////////////////////////// // 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 10, 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 * 8) < value ? 1 : 0); } } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.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 `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); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/IAccessControlEnumerable.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol // 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; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControlEnumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Burnable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } } // File: contracts/ERC20PresetMinterRebaser.sol pragma solidity ^0.8.0; contract ERC20PresetMinterRebaser is Context, AccessControlEnumerable, ERC20Burnable { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant REBASER_ROLE = keccak256("REBASER_ROLE"); constructor(string memory name, string memory symbol) ERC20(name, symbol) { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(REBASER_ROLE, _msgSender()); } function mint(address to, uint256 amount) public virtual { require(hasRole(MINTER_ROLE, _msgSender()), "ERC20Preset: must have minter role to mint"); _mint(to, amount); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: contracts/PandaToken.sol pragma solidity ^0.8.0; /** * @title uFragments ERC20 token * @dev This is part of an implementation of the uFragments Ideal Money protocol. * uFragments is a normal ERC20 token, but its supply can be adjusted by splitting and * combining tokens proportionally across all wallets. * * uFragment balances are internally represented with a hidden denomination, 'gons'. * We support splitting the currency in expansion and combining the currency on contraction by * changing the exchange rate between the hidden 'gons' and the public 'fragments'. */ contract PandaToken is ERC20PresetMinterRebaser, Ownable { // PLEASE READ BEFORE CHANGING ANY ACCOUNTING OR MATH // Anytime there is division, there is a risk of numerical instability from rounding errors. In // order to minimize this risk, we adhere to the following guidelines: // 1) The conversion rate adopted is the number of gons that equals 1 fragment. // The inverse rate must not be used--TOTAL_GONS is always the numerator and _totalSupply is // always the denominator. (i.e. If you want to convert gons to fragments instead of // multiplying by the inverse rate, you should divide by the normal rate) // 2) Gon balances converted into Fragments are always rounded down (truncated). // // We make the following guarantees: // - If address 'A' transfers x Fragments to address 'B'. A's resulting external balance will // be decreased by precisely x Fragments, and B's external balance will be precisely // increased by x Fragments. // // We do not guarantee that the sum of all balances equals the result of calling totalSupply(). // This is because, for any conversion function 'f()' that has non-zero rounding error, // f(x0) + f(x1) + ... + f(xn) is not always equal to f(x0 + x1 + ... xn). using SafeMath for uint256; using SafeMathInt for int256; event LogRebase(uint256 indexed epoch, uint256 totalSupply); bool private rebasePausedDeprecated; bool private tokenPausedDeprecated; modifier validRecipient(address to) { require(to != address(0x0)); require(to != address(this)); _; } uint256 private constant DECIMALS = 9; uint256 private constant MAX_UINT256 = type(uint256).max; uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 1663224179 * 10**DECIMALS; // TOTAL_GONS is a multiple of INITIAL_FRAGMENTS_SUPPLY so that _gonsPerFragment is an integer. // Use the highest value that fits in a uint256 for max granularity. uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY); // MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_GONS + 1) - 1) / 2 uint256 private constant MAX_SUPPLY = type(uint128).max; // (2^128) - 1 uint256 private _totalSupply; uint256 private _gonsPerFragment; mapping(address => uint256) private _gonBalances; // This is denominated in Fragments, because the gons-fragments conversion might change before // it's fully paid. mapping(address => mapping(address => uint256)) private _allowedFragments; // EIP-2612: permit – 712-signed approvals // https://eips.ethereum.org/EIPS/eip-2612 string public constant EIP712_REVISION = "1"; bytes32 public constant EIP712_DOMAIN = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); bytes32 public constant PERMIT_TYPEHASH = keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ); // EIP-2612: keeps track of number of permits per address mapping(address => uint256) private _nonces; constructor() ERC20PresetMinterRebaser("Rebase Panda", "PANDA") { rebasePausedDeprecated = false; tokenPausedDeprecated = false; _totalSupply = INITIAL_FRAGMENTS_SUPPLY; _gonBalances[owner()] = TOTAL_GONS; _gonsPerFragment = TOTAL_GONS.div(_totalSupply); _mint(msg.sender, _totalSupply); } function decimals() public view virtual override returns (uint8) { return 9; } /** * @dev Notifies Fragments contract about a new rebase cycle. * @param supplyDelta The number of new fragment tokens to add into circulation via expansion. * @return The total number of fragments after the supply adjustment. */ function rebase(uint256 epoch, int256 supplyDelta) external returns (uint256) { require(hasRole(REBASER_ROLE, _msgSender()), "Must have rebaser role."); if (supplyDelta == 0) { emit LogRebase(epoch, _totalSupply); return _totalSupply; } if (supplyDelta < 0) { _totalSupply = _totalSupply.sub(uint256(supplyDelta.abs())); } else { _totalSupply = _totalSupply.add(uint256(supplyDelta)); } if (_totalSupply > MAX_SUPPLY) { _totalSupply = MAX_SUPPLY; } _gonsPerFragment = TOTAL_GONS.div(_totalSupply); // From this point forward, _gonsPerFragment is taken as the source of truth. // We recalculate a new _totalSupply to be in agreement with the _gonsPerFragment // conversion rate. // This means our applied supplyDelta can deviate from the requested supplyDelta, // but this deviation is guaranteed to be < (_totalSupply^2)/(TOTAL_GONS - _totalSupply). // // In the case of _totalSupply <= MAX_UINT128 (our current supply cap), this // deviation is guaranteed to be < 1, so we can omit this step. If the supply cap is // ever increased, it must be re-included. // _totalSupply = TOTAL_GONS.div(_gonsPerFragment) emit LogRebase(epoch, _totalSupply); return _totalSupply; } /** * @return The total number of fragments. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @param who The address to query. * @return The balance of the specified address. */ function balanceOf(address who) public view override returns (uint256) { return _gonBalances[who].div(_gonsPerFragment); } /** * @param who The address to query. * @return The gon balance of the specified address. */ function scaledBalanceOf(address who) external view returns (uint256) { return _gonBalances[who]; } /** * @return the total number of gons. */ function scaledTotalSupply() external pure returns (uint256) { return TOTAL_GONS; } /** * @return The number of successful permits by the specified address. */ function nonces(address who) public view returns (uint256) { return _nonces[who]; } /** * @return The computed DOMAIN_SEPARATOR to be used off-chain services * which implement EIP-712. * https://eips.ethereum.org/EIPS/eip-2612 */ function DOMAIN_SEPARATOR() public view returns (bytes32) { uint256 chainId; assembly { chainId := chainid() } return keccak256( abi.encode( EIP712_DOMAIN, keccak256(bytes(name())), keccak256(bytes(EIP712_REVISION)), chainId, address(this) ) ); } /** * @dev Transfer tokens to a specified address. * @param to The address to transfer to. * @param value The amount to be transferred. * @return True on success, false otherwise. */ function transfer(address to, uint256 value) public override validRecipient(to) returns (bool) { uint256 gonValue = value.mul(_gonsPerFragment); _gonBalances[msg.sender] = _gonBalances[msg.sender].sub(gonValue); _gonBalances[to] = _gonBalances[to].add(gonValue); emit Transfer(msg.sender, to, value); return true; } /** * @dev Transfer all of the sender's wallet balance to a specified address. * @param to The address to transfer to. * @return True on success, false otherwise. */ function transferAll(address to) external validRecipient(to) returns (bool) { uint256 gonValue = _gonBalances[msg.sender]; uint256 value = gonValue.div(_gonsPerFragment); delete _gonBalances[msg.sender]; _gonBalances[to] = _gonBalances[to].add(gonValue); emit Transfer(msg.sender, to, value); return true; } /** * @dev Function to check the amount of tokens that an owner has allowed to a spender. * @param owner_ The address which owns the funds. * @param spender The address which will spend the funds. * @return The number of tokens still available for the spender. */ function allowance(address owner_, address spender) public view override returns (uint256) { return _allowedFragments[owner_][spender]; } /** * @dev Transfer tokens from one address to another. * @param from The address you want to send tokens from. * @param to The address you want to transfer to. * @param value The amount of tokens to be transferred. */ function transferFrom( address from, address to, uint256 value ) public override validRecipient(to) returns (bool) { _allowedFragments[from][msg.sender] = _allowedFragments[from][msg.sender].sub(value); uint256 gonValue = value.mul(_gonsPerFragment); _gonBalances[from] = _gonBalances[from].sub(gonValue); _gonBalances[to] = _gonBalances[to].add(gonValue); emit Transfer(from, to, value); return true; } /** * @dev Transfer all balance tokens from one address to another. * @param from The address you want to send tokens from. * @param to The address you want to transfer to. */ function transferAllFrom(address from, address to) external validRecipient(to) returns (bool) { uint256 gonValue = _gonBalances[from]; uint256 value = gonValue.div(_gonsPerFragment); _allowedFragments[from][msg.sender] = _allowedFragments[from][msg.sender].sub(value); delete _gonBalances[from]; _gonBalances[to] = _gonBalances[to].add(gonValue); emit Transfer(from, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of * msg.sender. This method is included for ERC20 compatibility. * increaseAllowance and decreaseAllowance should be used instead. * Changing an allowance with this method brings the risk that someone may transfer both * the old and the new allowance - if they are both greater than zero - if a transfer * transaction is mined before the later approve() call is mined. * * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public override returns (bool) { _allowedFragments[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } /** * @dev Increase the amount of tokens that an owner has allowed to a spender. * This method should be used instead of approve() to avoid the double approval vulnerability * described above. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public override returns (bool) { _allowedFragments[msg.sender][spender] = _allowedFragments[msg.sender][spender].add( addedValue ); emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]); return true; } /** * @dev Decrease the amount of tokens that an owner has allowed to a spender. * * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public override returns (bool) { uint256 oldValue = _allowedFragments[msg.sender][spender]; _allowedFragments[msg.sender][spender] = (subtractedValue >= oldValue) ? 0 : oldValue.sub(subtractedValue); emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]); return true; } /** * @dev Allows for approvals to be made via secp256k1 signatures. * @param owner The owner of the funds * @param spender The spender * @param value The amount * @param deadline The deadline timestamp, type(uint256).max for max deadline * @param v Signature param * @param s Signature param * @param r Signature param */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public { require(block.timestamp <= deadline); uint256 ownerNonce = _nonces[owner]; bytes32 permitDataDigest = keccak256( abi.encode(PERMIT_TYPEHASH, owner, spender, value, ownerNonce, deadline) ); bytes32 digest = keccak256( abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), permitDataDigest) ); require(owner == ecrecover(digest, v, r, s)); _nonces[owner] = ownerNonce.add(1); _allowedFragments[owner][spender] = value; emit Approval(owner, spender, value); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"LogRebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_REVISION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REBASER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"int256","name":"supplyDelta","type":"int256"}],"name":"rebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"scaledBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scaledTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"transferAllFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040518060400160405280600c81526020016b5265626173652050616e646160a01b8152506040518060400160405280600581526020016450414e444160d81b815250818181600590805190602001906200006f929190620004d3565b50805162000085906006906020840190620004d3565b50620000a09150600090506200009a62000215565b62000219565b620000cf7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66200009a62000215565b620000fe7f5fde63b561377d1441afa201ff619faac2ff8fed70a7fbdbe7a5cb07768c0b756200009a62000215565b506200011590506200010f62000215565b62000229565b6007805461ffff60a01b19169055620001316009600a62000638565b6200014190636322c97362000722565b600855620001526009600a62000638565b6200016290636322c97362000722565b62000170906000196200079b565b6200017e9060001962000744565b600a60006200018c6200027b565b6001600160a01b03168152602081019190915260400160002055600854620001fc90620001bc6009600a62000638565b620001cc90636322c97362000722565b620001da906000196200079b565b620001e89060001962000744565b6200028a60201b620011ec1790919060201c565b6009556008546200020f903390620002a1565b620007de565b3390565b6200022582826200035f565b5050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6007546001600160a01b031690565b6000620002988284620005d4565b90505b92915050565b6001600160a01b038216620002d35760405162461bcd60e51b8152600401620002ca9062000579565b60405180910390fd5b620002e1600083836200039d565b8060046000828254620002f59190620005b9565b90915550506001600160a01b038216600081815260026020526040808220805485019055517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9062000349908590620005b0565b60405180910390a362000225600083836200039d565b620003768282620003a260201b620011f81760201c565b60008281526001602090815260409091206200039d9183906200127d6200042c821b17901c565b505050565b620003ae828262000443565b62000225576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003e862000215565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000298836001600160a01b0384166200046c565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60006200047a8383620004bb565b620004b2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200029b565b5060006200029b565b60009081526001919091016020526040902054151590565b828054620004e1906200075e565b90600052602060002090601f01602090048101928262000505576000855562000550565b82601f106200052057805160ff191683800117855562000550565b8280016001018555821562000550579182015b828111156200055057825182559160200191906001019062000533565b506200055e92915062000562565b5090565b5b808211156200055e576000815560010162000563565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b90815260200190565b60008219821115620005cf57620005cf620007b2565b500190565b600082620005e657620005e6620007c8565b500490565b80825b6001808611620005ff57506200062f565b818704821115620006145762000614620007b2565b808616156200062257918102915b9490941c938002620005ee565b94509492505050565b600062000298600019848460008262000654575060016200071b565b8162000663575060006200071b565b81600181146200067c57600281146200068757620006bb565b60019150506200071b565b60ff8411156200069b576200069b620007b2565b6001841b915084821115620006b457620006b4620007b2565b506200071b565b5060208310610133831016604e8410600b8410161715620006f3575081810a83811115620006ed57620006ed620007b2565b6200071b565b620007028484846001620005eb565b808604821115620007175762000717620007b2565b0290505b9392505050565b60008160001904831182151516156200073f576200073f620007b2565b500290565b600082821015620007595762000759620007b2565b500390565b6002810460018216806200077357607f821691505b602082108114156200079557634e487b7160e01b600052602260045260246000fd5b50919050565b600082620007ad57620007ad620007c8565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6123bf80620007ee6000396000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80637a43e23f1161013b578063a457c2d7116100b8578063d53913931161007c578063d539139314610490578063d547741f14610498578063dd62ed3e146104ab578063e1b11da4146104be578063f2fde38b146104c65761023d565b8063a457c2d71461043c578063a9059cbb1461044f578063b1bf962d14610462578063ca15c8731461046a578063d505accf1461047d5761023d565b80639010d07c116100ff5780639010d07c146103f357806391d148541461040657806395d89b4114610419578063a217fddf14610421578063a3a7e7f3146104295761023d565b80637a43e23f1461039d5780637ecebe00146103b057806383eb70e5146103c357806384d4b410146103cb5780638da5cb5b146103de5761023d565b8063313ce567116101c957806342966c681161018d57806342966c681461035457806370a0823114610367578063715018a61461037a578063781603761461038257806379cc67901461038a5761023d565b8063313ce567146102fe5780633644e5151461031357806336568abe1461031b578063395093511461032e57806340c10f19146103415761023d565b80631da24f3e116102105780631da24f3e146102a857806323b872dd146102bb578063248a9ca3146102ce5780632f2ff15d146102e157806330adf81f146102f65761023d565b806301ffc9a71461024257806306fdde031461026b578063095ea7b31461028057806318160ddd14610293575b600080fd5b610255610250366004611c6b565b6104d9565b6040516102629190611d37565b60405180910390f35b610273610506565b6040516102629190611dc9565b61025561028e366004611be7565b610598565b61029b6105f1565b6040516102629190611d42565b61029b6102b6366004611aef565b6105f7565b6102556102c9366004611b3b565b610612565b61029b6102dc366004611c10565b61074a565b6102f46102ef366004611c28565b61075f565b005b61029b610780565b6103066107a4565b60405161026291906120f3565b61029b6107a9565b6102f4610329366004611c28565b610841565b61025561033c366004611be7565b610890565b6102f461034f366004611be7565b610904565b6102f4610362366004611c10565b610956565b61029b610375366004611aef565b61096a565b6102f4610992565b6102736109a6565b6102f4610398366004611be7565b6109c3565b61029b6103ab366004611c4a565b6109df565b61029b6103be366004611aef565b610b4d565b61029b610b68565b6102556103d9366004611b09565b610b8c565b6103e6610c9a565b6040516102629190611d23565b6103e6610401366004611c4a565b610ca9565b610255610414366004611c28565b610cc8565b610273610cf1565b61029b610d00565b610255610437366004611aef565b610d05565b61025561044a366004611be7565b610dd3565b61025561045d366004611be7565b610e69565b61029b610f45565b61029b610478366004611c10565b610f7e565b6102f461048b366004611b76565b610f95565b61029b611126565b6102f46104a6366004611c28565b61114a565b61029b6104b9366004611b09565b611166565b61029b611191565b6102f46104d4366004611aef565b6111b5565b60006001600160e01b03198216635a05180f60e01b14806104fe57506104fe82611292565b90505b919050565b606060058054610515906122ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610541906122ba565b801561058e5780601f106105635761010080835404028352916020019161058e565b820191906000526020600020905b81548152906001019060200180831161057157829003601f168201915b5050505050905090565b336000818152600b602090815260408083206001600160a01b0387168085529252808320859055519192909160008051602061236a833981519152906105df908690611d42565b60405180910390a35060015b92915050565b60085490565b6001600160a01b03166000908152600a602052604090205490565b6000826001600160a01b03811661062857600080fd5b6001600160a01b03811630141561063e57600080fd5b6001600160a01b0385166000908152600b6020908152604080832033845290915290205461066c90846112b7565b6001600160a01b0386166000908152600b602090815260408083203384529091528120919091556009546106a19085906112c3565b6001600160a01b0387166000908152600a60205260409020549091506106c790826112b7565b6001600160a01b038088166000908152600a602052604080822093909355908716815220546106f690826112cf565b6001600160a01b038087166000818152600a6020526040908190209390935591519088169060008051602061234a83398151915290610736908890611d42565b60405180910390a350600195945050505050565b60009081526020819052604090206001015490565b6107688261074a565b610771816112db565b61077b83836112ec565b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b600990565b6000467f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6107d5610506565b805160209182012060408051808201825260018152603160f81b908401525161082593927fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6918691309101611d7f565b6040516020818303038152906040528051906020012091505090565b61084961130e565b6001600160a01b0316816001600160a01b0316146108825760405162461bcd60e51b81526004016108799061206d565b60405180910390fd5b61088c8282611312565b5050565b336000908152600b602090815260408083206001600160a01b03861684529091528120546108be90836112cf565b336000818152600b602090815260408083206001600160a01b0389168085529252918290208490559051909260008051602061236a833981519152916105df9190611d42565b6109307f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661041461130e565b61094c5760405162461bcd60e51b815260040161087990611f69565b61088c8282611334565b61096761096161130e565b826113cc565b50565b6009546001600160a01b0382166000908152600a602052604081205490916104fe91906111ec565b61099a611491565b6109a460006114d0565b565b604051806040016040528060018152602001603160f81b81525081565b6109d5826109cf61130e565b83611522565b61088c82826113cc565b6000610a0d7f5fde63b561377d1441afa201ff619faac2ff8fed70a7fbdbe7a5cb07768c0b7561041461130e565b610a295760405162461bcd60e51b815260040161087990611e73565b81610a7157827f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f2600854604051610a609190611d42565b60405180910390a2506008546105eb565b6000821215610a9757610a8f610a868361156c565b600854906112b7565b600855610aa8565b600854610aa490836112cf565b6008555b6008546001600160801b031015610ac5576001600160801b036008555b600854610b0490610ad86009600a612173565b610ae690636322c973612241565b610af2906000196122ef565b610afe90600019612260565b906111ec565b60095560085460405184917f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f291610b3b9190611d42565b60405180910390a25060085492915050565b6001600160a01b03166000908152600c602052604090205490565b7f5fde63b561377d1441afa201ff619faac2ff8fed70a7fbdbe7a5cb07768c0b7581565b6000816001600160a01b038116610ba257600080fd5b6001600160a01b038116301415610bb857600080fd5b6001600160a01b0384166000908152600a6020526040812054600954909190610be29083906111ec565b6001600160a01b0387166000908152600b60209081526040808320338452909152902054909150610c1390826112b7565b6001600160a01b038088166000818152600b60209081526040808320338452825280832095909555918152600a90915282812081905590871681522054610c5a90836112cf565b6001600160a01b038087166000818152600a6020526040908190209390935591519088169060008051602061234a83398151915290610736908590611d42565b6007546001600160a01b031690565b6000828152600160205260408120610cc19083611596565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b606060068054610515906122ba565b600081565b6000816001600160a01b038116610d1b57600080fd5b6001600160a01b038116301415610d3157600080fd5b336000908152600a6020526040812054600954909190610d529083906111ec565b336000908152600a60205260408082208290556001600160a01b0388168252902054909150610d8190836112cf565b6001600160a01b0386166000818152600a602052604090819020929092559051339060008051602061234a83398151915290610dbe908590611d42565b60405180910390a36001935050505b50919050565b336000908152600b602090815260408083206001600160a01b038616845290915281205480831015610e0e57610e0981846112b7565b610e11565b60005b336000818152600b602090815260408083206001600160a01b038a168085529252918290208490559051909260008051602061236a83398151915291610e579190611d42565b60405180910390a35060019392505050565b6000826001600160a01b038116610e7f57600080fd5b6001600160a01b038116301415610e9557600080fd5b6000610eac600954856112c390919063ffffffff16565b336000908152600a6020526040902054909150610ec990826112b7565b336000908152600a6020526040808220929092556001600160a01b03871681522054610ef590826112cf565b6001600160a01b0386166000818152600a602052604090819020929092559051339060008051602061234a83398151915290610f32908890611d42565b60405180910390a3506001949350505050565b6000610f536009600a612173565b610f6190636322c973612241565b610f6d906000196122ef565b610f7990600019612260565b905090565b60008181526001602052604081206104fe906115a2565b83421115610fa257600080fd5b6001600160a01b0387166000908152600c60209081526040808320549051909291610ff9917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918c918c918c9188918d9101611d4b565b604051602081830303815290604052805190602001209050600061101b6107a9565b8260405160200161102d929190611c93565b604051602081830303815290604052805190602001209050600181878787604051600081526020016040526040516110689493929190611dab565b6020604051602081039080840390855afa15801561108a573d6000803e3d6000fd5b505050602060405103516001600160a01b03168a6001600160a01b0316146110b157600080fd5b6110bc8360016112cf565b6001600160a01b03808c166000818152600c6020908152604080832095909555600b8152848220938e168083529390528390208b9055915190919060008051602061236a83398151915290611112908c90611d42565b60405180910390a350505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6111538261074a565b61115c816112db565b61077b8383611312565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6111bd611491565b6001600160a01b0381166111e35760405162461bcd60e51b815260040161087990611eaa565b610967816114d0565b6000610cc18284612119565b6112028282610cc8565b61088c576000828152602081815260408083206001600160a01b03851684529091529020805460ff1916600117905561123961130e565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610cc1836001600160a01b0384166115ad565b60006001600160e01b03198216637965db0b60e01b14806104fe57506104fe826115f7565b6000610cc18284612260565b6000610cc18284612241565b6000610cc18284612101565b610967816112e761130e565b611610565b6112f682826111f8565b600082815260016020526040902061077b908261127d565b3390565b61131c8282611669565b600082815260016020526040902061077b90826116ec565b6001600160a01b03821661135a5760405162461bcd60e51b8152600401610879906120bc565b6113666000838361077b565b80600460008282546113789190612101565b90915550506001600160a01b0382166000818152600260205260408082208054850190555160008051602061234a833981519152906113b8908590611d42565b60405180910390a361088c6000838361077b565b6001600160a01b0382166113f25760405162461bcd60e51b815260040161087990611fe8565b6113fe8260008361077b565b6001600160a01b038216600090815260026020526040902054818110156114375760405162461bcd60e51b815260040161087990611e31565b6001600160a01b03831660008181526002602052604080822085850390556004805486900390555190919060008051602061234a8339815191529061147d908690611d42565b60405180910390a361077b8360008461077b565b61149961130e565b6001600160a01b03166114aa610c9a565b6001600160a01b0316146109a45760405162461bcd60e51b815260040161087990611fb3565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061152e8484611166565b9050600019811461156657818110156115595760405162461bcd60e51b815260040161087990611f32565b6115668484848403611701565b50505050565b6000600160ff1b82141561157f57600080fd5b6000821261158d57816104fe565b6104fe82612303565b6000610cc183836117a3565b60006104fe826117db565b60006115b983836117df565b6115ef575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105eb565b5060006105eb565b6001600160e01b031981166301ffc9a760e01b14919050565b61161a8282610cc8565b61088c57611627816117f7565b611632836020611809565b604051602001611643929190611cae565b60408051601f198184030181529082905262461bcd60e51b825261087991600401611dc9565b6116738282610cc8565b1561088c576000828152602081815260408083206001600160a01b03851684529091529020805460ff191690556116a861130e565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000610cc1836001600160a01b0384166119bb565b6001600160a01b0383166117275760405162461bcd60e51b815260040161087990612029565b6001600160a01b03821661174d5760405162461bcd60e51b815260040161087990611ef0565b6001600160a01b03808416600081815260036020908152604080832094871680845294909152908190208490555160008051602061236a83398151915290611796908590611d42565b60405180910390a3505050565b60008260000182815481106117c857634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b5490565b60009081526001919091016020526040902054151590565b60606104fe6001600160a01b03831660145b60606000611818836002612241565b611823906002612101565b67ffffffffffffffff81111561184957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611873576020820181803683370190505b509050600360fc1b8160008151811061189c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106118d957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006118fd846002612241565b611908906001612101565b90505b600181111561199c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061194a57634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061196e57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93611995816122a3565b905061190b565b508315610cc15760405162461bcd60e51b815260040161087990611dfc565b60008181526001830160205260408120548015611ace5760006119df600183612260565b85549091506000906119f390600190612260565b9050818114611a74576000866000018281548110611a2157634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110611a5257634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611a9357634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105eb565b60009150506105eb565b80356001600160a01b038116811461050157600080fd5b600060208284031215611b00578081fd5b610cc182611ad8565b60008060408385031215611b1b578081fd5b611b2483611ad8565b9150611b3260208401611ad8565b90509250929050565b600080600060608486031215611b4f578081fd5b611b5884611ad8565b9250611b6660208501611ad8565b9150604084013590509250925092565b600080600080600080600060e0888a031215611b90578283fd5b611b9988611ad8565b9650611ba760208901611ad8565b95506040880135945060608801359350608088013560ff81168114611bca578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611bf9578182fd5b611c0283611ad8565b946020939093013593505050565b600060208284031215611c21578081fd5b5035919050565b60008060408385031215611c3a578182fd5b82359150611b3260208401611ad8565b60008060408385031215611c5c578182fd5b50508035926020909101359150565b600060208284031215611c7c578081fd5b81356001600160e01b031981168114610cc1578182fd5b61190160f01b81526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351611ce6816017850160208801612277565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611d17816028840160208801612277565b01602801949350505050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152611de8816040850160208701612277565b601f01601f19169190910160400192915050565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526022908201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604082015261636560f01b606082015260800190565b60208082526017908201527f4d7573742068617665207265626173657220726f6c652e000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601d908201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604082015260600190565b6020808252602a908201527f45524332305072657365743a206d7573742068617665206d696e74657220726f6040820152691b19481d1bc81b5a5b9d60b21b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b60ff91909116815260200190565b600082198211156121145761211461231d565b500190565b60008261212857612128612333565b500490565b80825b600180861161213f575061216a565b8187048211156121515761215161231d565b8086161561215e57918102915b9490941c938002612130565b94509492505050565b6000610cc1600019848460008261218c57506001610cc1565b8161219957506000610cc1565b81600181146121af57600281146121b9576121e6565b6001915050610cc1565b60ff8411156121ca576121ca61231d565b6001841b9150848211156121e0576121e061231d565b50610cc1565b5060208310610133831016604e8410600b8410161715612219575081810a838111156122145761221461231d565b610cc1565b612226848484600161212d565b8086048211156122385761223861231d565b02949350505050565b600081600019048311821515161561225b5761225b61231d565b500290565b6000828210156122725761227261231d565b500390565b60005b8381101561229257818101518382015260200161227a565b838111156115665750506000910152565b6000816122b2576122b261231d565b506000190190565b6002810460018216806122ce57607f821691505b60208210811415610dcd57634e487b7160e01b600052602260045260246000fd5b6000826122fe576122fe612333565b500690565b6000600160ff1b8214156123195761231961231d565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a2646970667358221220e58d7b44695cb4af7b253bc4408820eac6d096e6ff88c0599163bc14300794d564736f6c63430008000033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80637a43e23f1161013b578063a457c2d7116100b8578063d53913931161007c578063d539139314610490578063d547741f14610498578063dd62ed3e146104ab578063e1b11da4146104be578063f2fde38b146104c65761023d565b8063a457c2d71461043c578063a9059cbb1461044f578063b1bf962d14610462578063ca15c8731461046a578063d505accf1461047d5761023d565b80639010d07c116100ff5780639010d07c146103f357806391d148541461040657806395d89b4114610419578063a217fddf14610421578063a3a7e7f3146104295761023d565b80637a43e23f1461039d5780637ecebe00146103b057806383eb70e5146103c357806384d4b410146103cb5780638da5cb5b146103de5761023d565b8063313ce567116101c957806342966c681161018d57806342966c681461035457806370a0823114610367578063715018a61461037a578063781603761461038257806379cc67901461038a5761023d565b8063313ce567146102fe5780633644e5151461031357806336568abe1461031b578063395093511461032e57806340c10f19146103415761023d565b80631da24f3e116102105780631da24f3e146102a857806323b872dd146102bb578063248a9ca3146102ce5780632f2ff15d146102e157806330adf81f146102f65761023d565b806301ffc9a71461024257806306fdde031461026b578063095ea7b31461028057806318160ddd14610293575b600080fd5b610255610250366004611c6b565b6104d9565b6040516102629190611d37565b60405180910390f35b610273610506565b6040516102629190611dc9565b61025561028e366004611be7565b610598565b61029b6105f1565b6040516102629190611d42565b61029b6102b6366004611aef565b6105f7565b6102556102c9366004611b3b565b610612565b61029b6102dc366004611c10565b61074a565b6102f46102ef366004611c28565b61075f565b005b61029b610780565b6103066107a4565b60405161026291906120f3565b61029b6107a9565b6102f4610329366004611c28565b610841565b61025561033c366004611be7565b610890565b6102f461034f366004611be7565b610904565b6102f4610362366004611c10565b610956565b61029b610375366004611aef565b61096a565b6102f4610992565b6102736109a6565b6102f4610398366004611be7565b6109c3565b61029b6103ab366004611c4a565b6109df565b61029b6103be366004611aef565b610b4d565b61029b610b68565b6102556103d9366004611b09565b610b8c565b6103e6610c9a565b6040516102629190611d23565b6103e6610401366004611c4a565b610ca9565b610255610414366004611c28565b610cc8565b610273610cf1565b61029b610d00565b610255610437366004611aef565b610d05565b61025561044a366004611be7565b610dd3565b61025561045d366004611be7565b610e69565b61029b610f45565b61029b610478366004611c10565b610f7e565b6102f461048b366004611b76565b610f95565b61029b611126565b6102f46104a6366004611c28565b61114a565b61029b6104b9366004611b09565b611166565b61029b611191565b6102f46104d4366004611aef565b6111b5565b60006001600160e01b03198216635a05180f60e01b14806104fe57506104fe82611292565b90505b919050565b606060058054610515906122ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610541906122ba565b801561058e5780601f106105635761010080835404028352916020019161058e565b820191906000526020600020905b81548152906001019060200180831161057157829003601f168201915b5050505050905090565b336000818152600b602090815260408083206001600160a01b0387168085529252808320859055519192909160008051602061236a833981519152906105df908690611d42565b60405180910390a35060015b92915050565b60085490565b6001600160a01b03166000908152600a602052604090205490565b6000826001600160a01b03811661062857600080fd5b6001600160a01b03811630141561063e57600080fd5b6001600160a01b0385166000908152600b6020908152604080832033845290915290205461066c90846112b7565b6001600160a01b0386166000908152600b602090815260408083203384529091528120919091556009546106a19085906112c3565b6001600160a01b0387166000908152600a60205260409020549091506106c790826112b7565b6001600160a01b038088166000908152600a602052604080822093909355908716815220546106f690826112cf565b6001600160a01b038087166000818152600a6020526040908190209390935591519088169060008051602061234a83398151915290610736908890611d42565b60405180910390a350600195945050505050565b60009081526020819052604090206001015490565b6107688261074a565b610771816112db565b61077b83836112ec565b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b600990565b6000467f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6107d5610506565b805160209182012060408051808201825260018152603160f81b908401525161082593927fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6918691309101611d7f565b6040516020818303038152906040528051906020012091505090565b61084961130e565b6001600160a01b0316816001600160a01b0316146108825760405162461bcd60e51b81526004016108799061206d565b60405180910390fd5b61088c8282611312565b5050565b336000908152600b602090815260408083206001600160a01b03861684529091528120546108be90836112cf565b336000818152600b602090815260408083206001600160a01b0389168085529252918290208490559051909260008051602061236a833981519152916105df9190611d42565b6109307f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661041461130e565b61094c5760405162461bcd60e51b815260040161087990611f69565b61088c8282611334565b61096761096161130e565b826113cc565b50565b6009546001600160a01b0382166000908152600a602052604081205490916104fe91906111ec565b61099a611491565b6109a460006114d0565b565b604051806040016040528060018152602001603160f81b81525081565b6109d5826109cf61130e565b83611522565b61088c82826113cc565b6000610a0d7f5fde63b561377d1441afa201ff619faac2ff8fed70a7fbdbe7a5cb07768c0b7561041461130e565b610a295760405162461bcd60e51b815260040161087990611e73565b81610a7157827f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f2600854604051610a609190611d42565b60405180910390a2506008546105eb565b6000821215610a9757610a8f610a868361156c565b600854906112b7565b600855610aa8565b600854610aa490836112cf565b6008555b6008546001600160801b031015610ac5576001600160801b036008555b600854610b0490610ad86009600a612173565b610ae690636322c973612241565b610af2906000196122ef565b610afe90600019612260565b906111ec565b60095560085460405184917f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f291610b3b9190611d42565b60405180910390a25060085492915050565b6001600160a01b03166000908152600c602052604090205490565b7f5fde63b561377d1441afa201ff619faac2ff8fed70a7fbdbe7a5cb07768c0b7581565b6000816001600160a01b038116610ba257600080fd5b6001600160a01b038116301415610bb857600080fd5b6001600160a01b0384166000908152600a6020526040812054600954909190610be29083906111ec565b6001600160a01b0387166000908152600b60209081526040808320338452909152902054909150610c1390826112b7565b6001600160a01b038088166000818152600b60209081526040808320338452825280832095909555918152600a90915282812081905590871681522054610c5a90836112cf565b6001600160a01b038087166000818152600a6020526040908190209390935591519088169060008051602061234a83398151915290610736908590611d42565b6007546001600160a01b031690565b6000828152600160205260408120610cc19083611596565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b606060068054610515906122ba565b600081565b6000816001600160a01b038116610d1b57600080fd5b6001600160a01b038116301415610d3157600080fd5b336000908152600a6020526040812054600954909190610d529083906111ec565b336000908152600a60205260408082208290556001600160a01b0388168252902054909150610d8190836112cf565b6001600160a01b0386166000818152600a602052604090819020929092559051339060008051602061234a83398151915290610dbe908590611d42565b60405180910390a36001935050505b50919050565b336000908152600b602090815260408083206001600160a01b038616845290915281205480831015610e0e57610e0981846112b7565b610e11565b60005b336000818152600b602090815260408083206001600160a01b038a168085529252918290208490559051909260008051602061236a83398151915291610e579190611d42565b60405180910390a35060019392505050565b6000826001600160a01b038116610e7f57600080fd5b6001600160a01b038116301415610e9557600080fd5b6000610eac600954856112c390919063ffffffff16565b336000908152600a6020526040902054909150610ec990826112b7565b336000908152600a6020526040808220929092556001600160a01b03871681522054610ef590826112cf565b6001600160a01b0386166000818152600a602052604090819020929092559051339060008051602061234a83398151915290610f32908890611d42565b60405180910390a3506001949350505050565b6000610f536009600a612173565b610f6190636322c973612241565b610f6d906000196122ef565b610f7990600019612260565b905090565b60008181526001602052604081206104fe906115a2565b83421115610fa257600080fd5b6001600160a01b0387166000908152600c60209081526040808320549051909291610ff9917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918c918c918c9188918d9101611d4b565b604051602081830303815290604052805190602001209050600061101b6107a9565b8260405160200161102d929190611c93565b604051602081830303815290604052805190602001209050600181878787604051600081526020016040526040516110689493929190611dab565b6020604051602081039080840390855afa15801561108a573d6000803e3d6000fd5b505050602060405103516001600160a01b03168a6001600160a01b0316146110b157600080fd5b6110bc8360016112cf565b6001600160a01b03808c166000818152600c6020908152604080832095909555600b8152848220938e168083529390528390208b9055915190919060008051602061236a83398151915290611112908c90611d42565b60405180910390a350505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6111538261074a565b61115c816112db565b61077b8383611312565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6111bd611491565b6001600160a01b0381166111e35760405162461bcd60e51b815260040161087990611eaa565b610967816114d0565b6000610cc18284612119565b6112028282610cc8565b61088c576000828152602081815260408083206001600160a01b03851684529091529020805460ff1916600117905561123961130e565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610cc1836001600160a01b0384166115ad565b60006001600160e01b03198216637965db0b60e01b14806104fe57506104fe826115f7565b6000610cc18284612260565b6000610cc18284612241565b6000610cc18284612101565b610967816112e761130e565b611610565b6112f682826111f8565b600082815260016020526040902061077b908261127d565b3390565b61131c8282611669565b600082815260016020526040902061077b90826116ec565b6001600160a01b03821661135a5760405162461bcd60e51b8152600401610879906120bc565b6113666000838361077b565b80600460008282546113789190612101565b90915550506001600160a01b0382166000818152600260205260408082208054850190555160008051602061234a833981519152906113b8908590611d42565b60405180910390a361088c6000838361077b565b6001600160a01b0382166113f25760405162461bcd60e51b815260040161087990611fe8565b6113fe8260008361077b565b6001600160a01b038216600090815260026020526040902054818110156114375760405162461bcd60e51b815260040161087990611e31565b6001600160a01b03831660008181526002602052604080822085850390556004805486900390555190919060008051602061234a8339815191529061147d908690611d42565b60405180910390a361077b8360008461077b565b61149961130e565b6001600160a01b03166114aa610c9a565b6001600160a01b0316146109a45760405162461bcd60e51b815260040161087990611fb3565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061152e8484611166565b9050600019811461156657818110156115595760405162461bcd60e51b815260040161087990611f32565b6115668484848403611701565b50505050565b6000600160ff1b82141561157f57600080fd5b6000821261158d57816104fe565b6104fe82612303565b6000610cc183836117a3565b60006104fe826117db565b60006115b983836117df565b6115ef575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105eb565b5060006105eb565b6001600160e01b031981166301ffc9a760e01b14919050565b61161a8282610cc8565b61088c57611627816117f7565b611632836020611809565b604051602001611643929190611cae565b60408051601f198184030181529082905262461bcd60e51b825261087991600401611dc9565b6116738282610cc8565b1561088c576000828152602081815260408083206001600160a01b03851684529091529020805460ff191690556116a861130e565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000610cc1836001600160a01b0384166119bb565b6001600160a01b0383166117275760405162461bcd60e51b815260040161087990612029565b6001600160a01b03821661174d5760405162461bcd60e51b815260040161087990611ef0565b6001600160a01b03808416600081815260036020908152604080832094871680845294909152908190208490555160008051602061236a83398151915290611796908590611d42565b60405180910390a3505050565b60008260000182815481106117c857634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b5490565b60009081526001919091016020526040902054151590565b60606104fe6001600160a01b03831660145b60606000611818836002612241565b611823906002612101565b67ffffffffffffffff81111561184957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611873576020820181803683370190505b509050600360fc1b8160008151811061189c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106118d957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006118fd846002612241565b611908906001612101565b90505b600181111561199c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061194a57634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061196e57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93611995816122a3565b905061190b565b508315610cc15760405162461bcd60e51b815260040161087990611dfc565b60008181526001830160205260408120548015611ace5760006119df600183612260565b85549091506000906119f390600190612260565b9050818114611a74576000866000018281548110611a2157634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110611a5257634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611a9357634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105eb565b60009150506105eb565b80356001600160a01b038116811461050157600080fd5b600060208284031215611b00578081fd5b610cc182611ad8565b60008060408385031215611b1b578081fd5b611b2483611ad8565b9150611b3260208401611ad8565b90509250929050565b600080600060608486031215611b4f578081fd5b611b5884611ad8565b9250611b6660208501611ad8565b9150604084013590509250925092565b600080600080600080600060e0888a031215611b90578283fd5b611b9988611ad8565b9650611ba760208901611ad8565b95506040880135945060608801359350608088013560ff81168114611bca578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611bf9578182fd5b611c0283611ad8565b946020939093013593505050565b600060208284031215611c21578081fd5b5035919050565b60008060408385031215611c3a578182fd5b82359150611b3260208401611ad8565b60008060408385031215611c5c578182fd5b50508035926020909101359150565b600060208284031215611c7c578081fd5b81356001600160e01b031981168114610cc1578182fd5b61190160f01b81526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351611ce6816017850160208801612277565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611d17816028840160208801612277565b01602801949350505050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152611de8816040850160208701612277565b601f01601f19169190910160400192915050565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526022908201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604082015261636560f01b606082015260800190565b60208082526017908201527f4d7573742068617665207265626173657220726f6c652e000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601d908201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604082015260600190565b6020808252602a908201527f45524332305072657365743a206d7573742068617665206d696e74657220726f6040820152691b19481d1bc81b5a5b9d60b21b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b60ff91909116815260200190565b600082198211156121145761211461231d565b500190565b60008261212857612128612333565b500490565b80825b600180861161213f575061216a565b8187048211156121515761215161231d565b8086161561215e57918102915b9490941c938002612130565b94509492505050565b6000610cc1600019848460008261218c57506001610cc1565b8161219957506000610cc1565b81600181146121af57600281146121b9576121e6565b6001915050610cc1565b60ff8411156121ca576121ca61231d565b6001841b9150848211156121e0576121e061231d565b50610cc1565b5060208310610133831016604e8410600b8410161715612219575081810a838111156122145761221461231d565b610cc1565b612226848484600161212d565b8086048211156122385761223861231d565b02949350505050565b600081600019048311821515161561225b5761225b61231d565b500290565b6000828210156122725761227261231d565b500390565b60005b8381101561229257818101518382015260200161227a565b838111156115665750506000910152565b6000816122b2576122b261231d565b506000190190565b6002810460018216806122ce57607f821691505b60208210811415610dcd57634e487b7160e01b600052602260045260246000fd5b6000826122fe576122fe612333565b500690565b6000600160ff1b8214156123195761231961231d565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a2646970667358221220e58d7b44695cb4af7b253bc4408820eac6d096e6ff88c0599163bc14300794d564736f6c63430008000033
Deployed Bytecode Sourcemap
83026:13669:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55349:214;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59365:100;;;:::i;:::-;;;;;;;:::i;93905:221::-;;;;;;:::i;:::-;;:::i;88534:100::-;;;:::i;:::-;;;;;;;:::i;89016:113::-;;;;;;:::i;:::-;;:::i;92085:498::-;;;;;;:::i;:::-;;:::i;50871:131::-;;;;;;:::i;:::-;;:::i;51312:147::-;;;;;;:::i;:::-;;:::i;:::-;;85981:170;;;:::i;86639:92::-;;;:::i;:::-;;;;;;;:::i;89691:465::-;;;:::i;52456:218::-;;;;;;:::i;:::-;;:::i;94499:342::-;;;;;;:::i;:::-;;:::i;72336:193::-;;;;;;:::i;:::-;;:::i;71189:91::-;;;;;;:::i;:::-;;:::i;88755:136::-;;;;;;:::i;:::-;;:::i;74472:103::-;;;:::i;85755:44::-;;;:::i;71599:164::-;;;;;;:::i;:::-;;:::i;86999:1462::-;;;;;;:::i;:::-;;:::i;89395:97::-;;;;;;:::i;:::-;;:::i;72021:64::-;;;:::i;92796:467::-;;;;;;:::i;:::-;;:::i;73824:87::-;;;:::i;:::-;;;;;;;:::i;56162:153::-;;;;;;:::i;:::-;;:::i;49344:147::-;;;;;;:::i;:::-;;:::i;59584:104::-;;;:::i;48449:49::-;;;:::i;90995:370::-;;;;;;:::i;:::-;;:::i;95103:428::-;;;;;;:::i;:::-;;:::i;90382:410::-;;;;;;:::i;:::-;;:::i;89197:97::-;;;:::i;56489:142::-;;;;;;:::i;:::-;;:::i;95921:771::-;;;;;;:::i;:::-;;:::i;71952:62::-;;;:::i;51752:149::-;;;;;;:::i;:::-;;:::i;91672:151::-;;;;;;:::i;:::-;;:::i;85806:168::-;;;:::i;74730:201::-;;;;;;:::i;:::-;;:::i;55349:214::-;55434:4;-1:-1:-1;;;;;;55458:57:0;;-1:-1:-1;;;55458:57:0;;:97;;;55519:36;55543:11;55519:23;:36::i;:::-;55451:104;;55349:214;;;;:::o;59365:100::-;59419:13;59452:5;59445:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59365:100;:::o;93905:221::-;94014:10;93979:4;93996:29;;;:17;:29;;;;;;;;-1:-1:-1;;;;;93996:38:0;;;;;;;;;;:46;;;94060:36;93979:4;;93996:38;;-1:-1:-1;;;;;;;;;;;94060:36:0;;;94037:5;;94060:36;:::i;:::-;;;;;;;;-1:-1:-1;94114:4:0;93905:221;;;;;:::o;88534:100::-;88614:12;;88534:100;:::o;89016:113::-;-1:-1:-1;;;;;89104:17:0;89077:7;89104:17;;;:12;:17;;;;;;;89016:113::o;92085:498::-;92226:4;92213:2;-1:-1:-1;;;;;84613:18:0;;84605:27;;;;;;-1:-1:-1;;;;;84651:19:0;;84665:4;84651:19;;84643:28;;;;;;-1:-1:-1;;;;;92281:23:0;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;92305:10:::1;92281:35:::0;;;;;;;;:46:::1;::::0;92321:5;92281:39:::1;:46::i;:::-;-1:-1:-1::0;;;;;92243:23:0;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;92267:10:::1;92243:35:::0;;;;;;;:84;;;;92369:16:::1;::::0;92359:27:::1;::::0;:5;;:9:::1;:27::i;:::-;-1:-1:-1::0;;;;;92418:18:0;::::1;;::::0;;;:12:::1;:18;::::0;;;;;92340:46;;-1:-1:-1;92418:32:0::1;::::0;92340:46;92418:22:::1;:32::i;:::-;-1:-1:-1::0;;;;;92397:18:0;;::::1;;::::0;;;:12:::1;:18;::::0;;;;;:53;;;;92480:16;;::::1;::::0;;;;:30:::1;::::0;92501:8;92480:20:::1;:30::i;:::-;-1:-1:-1::0;;;;;92461:16:0;;::::1;;::::0;;;:12:::1;:16;::::0;;;;;;:49;;;;92528:25;;;;::::1;::::0;-1:-1:-1;;;;;;;;;;;92528:25:0;::::1;::::0;92547:5;;92528:25:::1;:::i;:::-;;;;;;;;-1:-1:-1::0;92571:4:0::1;::::0;92085:498;-1:-1:-1;;;;;92085:498:0:o;50871:131::-;50945:7;50972:12;;;;;;;;;;:22;;;;50871:131::o;51312:147::-;51395:18;51408:4;51395:12;:18::i;:::-;48940:16;48951:4;48940:10;:16::i;:::-;51426:25:::1;51437:4;51443:7;51426:10;:25::i;:::-;51312:147:::0;;;:::o;85981:170::-;86032:119;85981:170;:::o;86639:92::-;86722:1;86639:92;:::o;89691:465::-;89740:7;89821:9;85855:119;89984:6;:4;:6::i;:::-;89968:24;;;;;;;90031:15;;;;;;;;;;;-1:-1:-1;;;90031:15:0;;;;89899:234;;;;90015:33;;90071:7;;90109:4;;89899:234;;:::i;:::-;;;;;;;;;;;;;89871:277;;;;;;89851:297;;;89691:465;:::o;52456:218::-;52563:12;:10;:12::i;:::-;-1:-1:-1;;;;;52552:23:0;:7;-1:-1:-1;;;;;52552:23:0;;52544:83;;;;-1:-1:-1;;;52544:83:0;;;;;;;:::i;:::-;;;;;;;;;52640:26;52652:4;52658:7;52640:11;:26::i;:::-;52456:218;;:::o;94499:342::-;94664:10;94588:4;94646:29;;;:17;:29;;;;;;;;-1:-1:-1;;;;;94646:38:0;;;;;;;;;;:78;;94703:10;94646:42;:78::i;:::-;94623:10;94605:29;;;;:17;:29;;;;;;;;-1:-1:-1;;;;;94605:38:0;;;;;;;;;;;:119;;;94742:69;;94605:38;;-1:-1:-1;;;;;;;;;;;94742:69:0;;;94605:119;94742:69;:::i;72336:193::-;72412:34;71990:24;72433:12;:10;:12::i;72412:34::-;72404:89;;;;-1:-1:-1;;;72404:89:0;;;;;;;:::i;:::-;72504:17;72510:2;72514:6;72504:5;:17::i;71189:91::-;71245:27;71251:12;:10;:12::i;:::-;71265:6;71245:5;:27::i;:::-;71189:91;:::o;88755:136::-;88866:16;;-1:-1:-1;;;;;88844:17:0;;88817:7;88844:17;;;:12;:17;;;;;;88817:7;;88844:39;;:17;:21;:39::i;74472:103::-;73710:13;:11;:13::i;:::-;74537:30:::1;74564:1;74537:18;:30::i;:::-;74472:103::o:0;85755:44::-;;;;;;;;;;;;;;-1:-1:-1;;;85755:44:0;;;;:::o;71599:164::-;71676:46;71692:7;71701:12;:10;:12::i;:::-;71715:6;71676:15;:46::i;:::-;71733:22;71739:7;71748:6;71733:5;:22::i;86999:1462::-;87086:7;87119:35;72060:25;87141:12;:10;:12::i;87119:35::-;87111:71;;;;-1:-1:-1;;;87111:71:0;;;;;;;:::i;:::-;87199:16;87195:118;;87247:5;87237:30;87254:12;;87237:30;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;87289:12:0;;87282:19;;87195:118;87343:1;87329:11;:15;87325:193;;;87376:44;87401:17;:11;:15;:17::i;:::-;87376:12;;;:16;:44::i;:::-;87361:12;:59;87325:193;;;87468:12;;:38;;87493:11;87468:16;:38::i;:::-;87453:12;:53;87325:193;87534:12;;-1:-1:-1;;;;;;87530:83:0;;;-1:-1:-1;;;;;87576:12:0;:25;87530:83;87659:12;;87644:28;;84871:12;84735:1;84871:2;:12;:::i;:::-;84858:25;;:10;:25;:::i;:::-;85120:38;;-1:-1:-1;;85120:38:0;:::i;:::-;85105:54;;-1:-1:-1;;85105:54:0;:::i;:::-;87644:14;;:28::i;:::-;87625:16;:47;88410:12;;88393:30;;88403:5;;88393:30;;;;88410:12;88393:30;:::i;:::-;;;;;;;;-1:-1:-1;88441:12:0;;86999:1462;;;;:::o;89395:97::-;-1:-1:-1;;;;;89472:12:0;89445:7;89472:12;;;:7;:12;;;;;;;89395:97::o;72021:64::-;72060:25;72021:64;:::o;92796:467::-;92884:4;92871:2;-1:-1:-1;;;;;84613:18:0;;84605:27;;;;;;-1:-1:-1;;;;;84651:19:0;;84665:4;84651:19;;84643:28;;;;;;-1:-1:-1;;;;;92920:18:0;::::1;92901:16;92920:18:::0;;;:12:::1;:18;::::0;;;;;92978:16:::1;::::0;92920:18;;92901:16;92965:30:::1;::::0;92920:18;;92965:12:::1;:30::i;:::-;-1:-1:-1::0;;;;;93046:23:0;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;93070:10:::1;93046:35:::0;;;;;;;;92949:46;;-1:-1:-1;93046:46:0::1;::::0;92949;93046:39:::1;:46::i;:::-;-1:-1:-1::0;;;;;93008:23:0;;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;93032:10:::1;93008:35:::0;;;;;;;:84;;;;93112:18;;;:12:::1;:18:::0;;;;;;93105:25;;;93160:16;;::::1;::::0;;;;:30:::1;::::0;93181:8;93160:20:::1;:30::i;:::-;-1:-1:-1::0;;;;;93141:16:0;;::::1;;::::0;;;:12:::1;:16;::::0;;;;;;:49;;;;93208:25;;;;::::1;::::0;-1:-1:-1;;;;;;;;;;;93208:25:0;::::1;::::0;93227:5;;93208:25:::1;:::i;73824:87::-:0;73897:6;;-1:-1:-1;;;;;73897:6:0;73824:87;:::o;56162:153::-;56252:7;56279:18;;;:12;:18;;;;;:28;;56301:5;56279:21;:28::i;:::-;56272:35;56162:153;-1:-1:-1;;;56162:153:0:o;49344:147::-;49430:4;49454:12;;;;;;;;;;;-1:-1:-1;;;;;49454:29:0;;;;;;;;;;;;;;;49344:147::o;59584:104::-;59640:13;59673:7;59666:14;;;;;:::i;48449:49::-;48494:4;48449:49;:::o;90995:370::-;91065:4;91052:2;-1:-1:-1;;;;;84613:18:0;;84605:27;;;;;;-1:-1:-1;;;;;84651:19:0;;84665:4;84651:19;;84643:28;;;;;;91114:10:::1;91082:16;91101:24:::0;;;:12:::1;:24;::::0;;;;;91165:16:::1;::::0;91101:24;;91082:16;91152:30:::1;::::0;91101:24;;91152:12:::1;:30::i;:::-;91215:10;91202:24;::::0;;;:12:::1;:24;::::0;;;;;91195:31;;;-1:-1:-1;;;;;91256:16:0;::::1;::::0;;;;;91136:46;;-1:-1:-1;91256:30:0::1;::::0;91277:8;91256:20:::1;:30::i;:::-;-1:-1:-1::0;;;;;91237:16:0;::::1;;::::0;;;:12:::1;:16;::::0;;;;;;:49;;;;91304:31;;91313:10:::1;::::0;-1:-1:-1;;;;;;;;;;;91304:31:0;::::1;::::0;91329:5;;91304:31:::1;:::i;:::-;;;;;;;;91353:4;91346:11;;;;84682:1;90995:370:::0;;;;:::o;95103:428::-;95251:10;95197:4;95233:29;;;:17;:29;;;;;;;;-1:-1:-1;;;;;95233:38:0;;;;;;;;;;95324:27;;;;95323:91;;95385:29;:8;95398:15;95385:12;:29::i;:::-;95323:91;;;95368:1;95323:91;95300:10;95282:29;;;;:17;:29;;;;;;;;-1:-1:-1;;;;;95282:38:0;;;;;;;;;;;:132;;;95432:69;;95282:38;;-1:-1:-1;;;;;;;;;;;95432:69:0;;;95282:132;95432:69;:::i;:::-;;;;;;;;-1:-1:-1;95519:4:0;;95103:428;-1:-1:-1;;;95103:428:0:o;90382:410::-;90507:4;90485:2;-1:-1:-1;;;;;84613:18:0;;84605:27;;;;;;-1:-1:-1;;;;;84651:19:0;;84665:4;84651:19;;84643:28;;;;;;90529:16:::1;90548:27;90558:16;;90548:5;:9;;:27;;;;:::i;:::-;90628:10;90615:24;::::0;;;:12:::1;:24;::::0;;;;;90529:46;;-1:-1:-1;90615:38:0::1;::::0;90529:46;90615:28:::1;:38::i;:::-;90601:10;90588:24;::::0;;;:12:::1;:24;::::0;;;;;:65;;;;-1:-1:-1;;;;;90683:16:0;::::1;::::0;;;;:30:::1;::::0;90704:8;90683:20:::1;:30::i;:::-;-1:-1:-1::0;;;;;90664:16:0;::::1;;::::0;;;:12:::1;:16;::::0;;;;;;:49;;;;90731:31;;90740:10:::1;::::0;-1:-1:-1;;;;;;;;;;;90731:31:0;::::1;::::0;90756:5;;90731:31:::1;:::i;:::-;;;;;;;;-1:-1:-1::0;90780:4:0::1;::::0;90382:410;-1:-1:-1;;;;90382:410:0:o;89197:97::-;89249:7;84871:12;84735:1;84871:2;:12;:::i;:::-;84858:25;;:10;:25;:::i;:::-;85120:38;;-1:-1:-1;;85120:38:0;:::i;:::-;85105:54;;-1:-1:-1;;85105:54:0;:::i;:::-;89269:17;;89197:97;:::o;56489:142::-;56569:7;56596:18;;;:12;:18;;;;;:27;;:25;:27::i;95921:771::-;96148:8;96129:15;:27;;96121:36;;;;;;-1:-1:-1;;;;;96191:14:0;;96170:18;96191:14;;;:7;:14;;;;;;;;;96267:72;;96191:14;;96170:18;96267:72;;86032:119;;96199:5;;96302:7;;96311:5;;96191:14;;96330:8;;96267:72;;:::i;:::-;;;;;;;;;;;;;96243:107;;;;;;96216:134;;96361:14;96431:18;:16;:18::i;:::-;96451:16;96402:66;;;;;;;;;:::i;:::-;;;;;;;;;;;;;96378:101;;;;;;96361:118;;96509:26;96519:6;96527:1;96530;96533;96509:26;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;96500:35:0;:5;-1:-1:-1;;;;;96500:35:0;;96492:44;;;;;;96566:17;:10;96581:1;96566:14;:17::i;:::-;-1:-1:-1;;;;;96549:14:0;;;;;;;:7;:14;;;;;;;;:34;;;;96596:17;:24;;;;;:33;;;;;;;;;;;;:41;;;96653:31;;96596:33;;96549:14;-1:-1:-1;;;;;;;;;;;96653:31:0;;;96632:5;;96653:31;:::i;:::-;;;;;;;;95921:771;;;;;;;;;;:::o;71952:62::-;71990:24;71952:62;:::o;51752:149::-;51836:18;51849:4;51836:12;:18::i;:::-;48940:16;48951:4;48940:10;:16::i;:::-;51867:26:::1;51879:4;51885:7;51867:11;:26::i;91672:151::-:0;-1:-1:-1;;;;;91781:25:0;;;91754:7;91781:25;;;:17;:25;;;;;;;;:34;;;;;;;;;;;;;91672:151::o;85806:168::-;85855:119;85806:168;:::o;74730:201::-;73710:13;:11;:13::i;:::-;-1:-1:-1;;;;;74819:22:0;::::1;74811:73;;;;-1:-1:-1::0;;;74811:73:0::1;;;;;;;:::i;:::-;74895:28;74914:8;74895:18;:28::i;79355:98::-:0;79413:7;79440:5;79444:1;79440;:5;:::i;54053:238::-;54137:22;54145:4;54151:7;54137;:22::i;:::-;54132:152;;54176:6;:12;;;;;;;;;;;-1:-1:-1;;;;;54176:29:0;;;;;;;;;:36;;-1:-1:-1;;54176:36:0;54208:4;54176:36;;;54259:12;:10;:12::i;:::-;-1:-1:-1;;;;;54232:40:0;54250:7;-1:-1:-1;;;;;54232:40:0;54244:4;54232:40;;;;;;;;;;54053:238;;:::o;15185:152::-;15255:4;15279:50;15284:3;-1:-1:-1;;;;;15304:23:0;;15279:4;:50::i;49048:204::-;49133:4;-1:-1:-1;;;;;;49157:47:0;;-1:-1:-1;;;49157:47:0;;:87;;;49208:36;49232:11;49208:23;:36::i;78599:98::-;78657:7;78684:5;78688:1;78684;:5;:::i;78956:98::-;79014:7;79041:5;79045:1;79041;:5;:::i;78218:98::-;78276:7;78303:5;78307:1;78303;:5;:::i;49795:105::-;49862:30;49873:4;49879:12;:10;:12::i;:::-;49862:10;:30::i;56724:169::-;56812:31;56829:4;56835:7;56812:16;:31::i;:::-;56854:18;;;;:12;:18;;;;;:31;;56877:7;56854:22;:31::i;46204:98::-;46284:10;46204:98;:::o;56987:174::-;57076:32;57094:4;57100:7;57076:17;:32::i;:::-;57119:18;;;;:12;:18;;;;;:34;;57145:7;57119:25;:34::i;65975:548::-;-1:-1:-1;;;;;66059:21:0;;66051:65;;;;-1:-1:-1;;;66051:65:0;;;;;;;:::i;:::-;66129:49;66158:1;66162:7;66171:6;66129:20;:49::i;:::-;66207:6;66191:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;66362:18:0;;;;;;:9;:18;;;;;;:28;;;;;;66417:37;-1:-1:-1;;;;;;;;;;;66417:37:0;;;66384:6;;66417:37;:::i;:::-;;;;;;;;66467:48;66495:1;66499:7;66508:6;66467:19;:48::i;66856:675::-;-1:-1:-1;;;;;66940:21:0;;66932:67;;;;-1:-1:-1;;;66932:67:0;;;;;;;:::i;:::-;67012:49;67033:7;67050:1;67054:6;67012:20;:49::i;:::-;-1:-1:-1;;;;;67099:18:0;;67074:22;67099:18;;;:9;:18;;;;;;67136:24;;;;67128:71;;;;-1:-1:-1;;;67128:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;67235:18:0;;;;;;:9;:18;;;;;;67256:23;;;67235:44;;67374:12;:22;;;;;;;67425:37;67235:18;;;-1:-1:-1;;;;;;;;;;;67425:37:0;;;67273:6;;67425:37;:::i;:::-;;;;;;;;67475:48;67495:7;67512:1;67516:6;67475:19;:48::i;73989:132::-;74064:12;:10;:12::i;:::-;-1:-1:-1;;;;;74053:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;74053:23:0;;74045:68;;;;-1:-1:-1;;;74045:68:0;;;;;;;:::i;75091:191::-;75184:6;;;-1:-1:-1;;;;;75201:17:0;;;-1:-1:-1;;;;;;75201:17:0;;;;;;;75234:40;;75184:6;;;75201:17;75184:6;;75234:40;;75165:16;;75234:40;75091:191;;:::o;68640:453::-;68775:24;68802:25;68812:5;68819:7;68802:9;:25::i;:::-;68775:52;;-1:-1:-1;;68842:16:0;:37;68838:248;;68924:6;68904:16;:26;;68896:68;;;;-1:-1:-1;;;68896:68:0;;;;;;;:::i;:::-;69008:51;69017:5;69024:7;69052:6;69033:16;:25;69008:8;:51::i;:::-;68640:453;;;;:::o;4909:129::-;4955:6;-1:-1:-1;;;4982:15:0;;;4974:24;;;;;;5020:1;5016;:5;:14;;5029:1;5016:14;;;5024:2;5025:1;5024:2;:::i;16481:158::-;16555:7;16606:22;16610:3;16622:5;16606:3;:22::i;16010:117::-;16073:7;16100:19;16108:3;16100:7;:19::i;8916:414::-;8979:4;9001:21;9011:3;9016:5;9001:9;:21::i;:::-;8996:327;;-1:-1:-1;9039:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;9222:18;;9200:19;;;:12;;;:19;;;;;;:40;;;;9255:11;;8996:327;-1:-1:-1;9306:5:0;9299:12;;21866:157;-1:-1:-1;;;;;;21975:40:0;;-1:-1:-1;;;21975:40:0;21866:157;;;:::o;50190:492::-;50279:22;50287:4;50293:7;50279;:22::i;:::-;50274:401;;50467:28;50487:7;50467:19;:28::i;:::-;50568:38;50596:4;50603:2;50568:19;:38::i;:::-;50372:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;50372:257:0;;;;;;;;;;-1:-1:-1;;;50318:345:0;;;;;;;:::i;54471:239::-;54555:22;54563:4;54569:7;54555;:22::i;:::-;54551:152;;;54626:5;54594:12;;;;;;;;;;;-1:-1:-1;;;;;54594:29:0;;;;;;;;;:37;;-1:-1:-1;;54594:37:0;;;54678:12;:10;:12::i;:::-;-1:-1:-1;;;;;54651:40:0;54669:7;-1:-1:-1;;;;;54651:40:0;54663:4;54651:40;;;;;;;;;;54471:239;;:::o;15513:158::-;15586:4;15610:53;15618:3;-1:-1:-1;;;;;15638:23:0;;15610:7;:53::i;67969:380::-;-1:-1:-1;;;;;68105:19:0;;68097:68;;;;-1:-1:-1;;;68097:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68184:21:0;;68176:68;;;;-1:-1:-1;;;68176:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68257:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;68309:32;-1:-1:-1;;;;;;;;;;;68309:32:0;;;68287:6;;68309:32;:::i;:::-;;;;;;;;67969:380;;;:::o;11690:120::-;11757:7;11784:3;:11;;11796:5;11784:18;;;;;;-1:-1:-1;;;11784:18:0;;;;;;;;;;;;;;;;;11777:25;;11690:120;;;;:::o;11227:109::-;11310:18;;11227:109::o;11012:129::-;11085:4;11109:19;;;:12;;;;;:19;;;;;;:24;;;11012:129::o;37177:151::-;37235:13;37268:52;-1:-1:-1;;;;;37280:22:0;;35332:2;36573:447;36648:13;36674:19;36706:10;36710:6;36706:1;:10;:::i;:::-;:14;;36719:1;36706:14;:::i;:::-;36696:25;;;;;;-1:-1:-1;;;36696:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36696:25:0;;36674:47;;-1:-1:-1;;;36732:6:0;36739:1;36732:9;;;;;;-1:-1:-1;;;36732:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;36732:15:0;;;;;;;;;-1:-1:-1;;;36758:6:0;36765:1;36758:9;;;;;;-1:-1:-1;;;36758:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;36758:15:0;;;;;;;;-1:-1:-1;36789:9:0;36801:10;36805:6;36801:1;:10;:::i;:::-;:14;;36814:1;36801:14;:::i;:::-;36789:26;;36784:131;36821:1;36817;:5;36784:131;;;-1:-1:-1;;;36865:5:0;36873:3;36865:11;36856:21;;;;;-1:-1:-1;;;36856:21:0;;;;;;;;;;;;36844:6;36851:1;36844:9;;;;;;-1:-1:-1;;;36844:9:0;;;;;;;;;;;;:33;-1:-1:-1;;;;;36844:33:0;;;;;;;;-1:-1:-1;36902:1:0;36892:11;;;;;36824:3;;;:::i;:::-;;;36784:131;;;-1:-1:-1;36933:10:0;;36925:55;;;;-1:-1:-1;;;36925:55:0;;;;;;;:::i;9506:1420::-;9572:4;9711:19;;;:12;;;:19;;;;;;9747:15;;9743:1176;;10122:21;10146:14;10159:1;10146:10;:14;:::i;:::-;10195:18;;10122:38;;-1:-1:-1;10175:17:0;;10195:22;;10216:1;;10195:22;:::i;:::-;10175:42;;10251:13;10238:9;:26;10234:405;;10285:17;10305:3;:11;;10317:9;10305:22;;;;;;-1:-1:-1;;;10305:22:0;;;;;;;;;;;;;;;;;10285:42;;10459:9;10430:3;:11;;10442:13;10430:26;;;;;;-1:-1:-1;;;10430:26:0;;;;;;;;;;;;;;;;;;;;:38;;;;10544:23;;;:12;;;:23;;;;;:36;;;10234:405;10720:17;;:3;;:17;;;-1:-1:-1;;;10720:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;10815:3;:12;;:19;10828:5;10815:19;;;;;;;;;;;10808:26;;;10858:4;10851:11;;;;;;;9743:1176;10902:5;10895:12;;;;;14:175:1;84:20;;-1:-1:-1;;;;;133:31:1;;123:42;;113:2;;179:1;176;169:12;194:198;;306:2;294:9;285:7;281:23;277:32;274:2;;;327:6;319;312:22;274:2;355:31;376:9;355:31;:::i;397:274::-;;;526:2;514:9;505:7;501:23;497:32;494:2;;;547:6;539;532:22;494:2;575:31;596:9;575:31;:::i;:::-;565:41;;625:40;661:2;650:9;646:18;625:40;:::i;:::-;615:50;;484:187;;;;;:::o;676:342::-;;;;822:2;810:9;801:7;797:23;793:32;790:2;;;843:6;835;828:22;790:2;871:31;892:9;871:31;:::i;:::-;861:41;;921:40;957:2;946:9;942:18;921:40;:::i;:::-;911:50;;1008:2;997:9;993:18;980:32;970:42;;780:238;;;;;:::o;1023:717::-;;;;;;;;1235:3;1223:9;1214:7;1210:23;1206:33;1203:2;;;1257:6;1249;1242:22;1203:2;1285:31;1306:9;1285:31;:::i;:::-;1275:41;;1335:40;1371:2;1360:9;1356:18;1335:40;:::i;:::-;1325:50;;1422:2;1411:9;1407:18;1394:32;1384:42;;1473:2;1462:9;1458:18;1445:32;1435:42;;1527:3;1516:9;1512:19;1499:33;1572:4;1565:5;1561:16;1554:5;1551:27;1541:2;;1597:6;1589;1582:22;1541:2;1193:547;;;;-1:-1:-1;1193:547:1;;;;1625:5;1677:3;1662:19;;1649:33;;-1:-1:-1;1729:3:1;1714:19;;;1701:33;;1193:547;-1:-1:-1;;1193:547:1:o;1745:266::-;;;1874:2;1862:9;1853:7;1849:23;1845:32;1842:2;;;1895:6;1887;1880:22;1842:2;1923:31;1944:9;1923:31;:::i;:::-;1913:41;2001:2;1986:18;;;;1973:32;;-1:-1:-1;;;1832:179:1:o;2016:190::-;;2128:2;2116:9;2107:7;2103:23;2099:32;2096:2;;;2149:6;2141;2134:22;2096:2;-1:-1:-1;2177:23:1;;2086:120;-1:-1:-1;2086:120:1:o;2211:266::-;;;2340:2;2328:9;2319:7;2315:23;2311:32;2308:2;;;2361:6;2353;2346:22;2308:2;2402:9;2389:23;2379:33;;2431:40;2467:2;2456:9;2452:18;2431:40;:::i;2482:258::-;;;2611:2;2599:9;2590:7;2586:23;2582:32;2579:2;;;2632:6;2624;2617:22;2579:2;-1:-1:-1;;2660:23:1;;;2730:2;2715:18;;;2702:32;;-1:-1:-1;2569:171:1:o;2745:306::-;;2856:2;2844:9;2835:7;2831:23;2827:32;2824:2;;;2877:6;2869;2862:22;2824:2;2908:23;;-1:-1:-1;;;;;;2960:32:1;;2950:43;;2940:2;;3012:6;3004;2997:22;3513:392;-1:-1:-1;;;3771:27:1;;3823:1;3814:11;;3807:27;;;;3859:2;3850:12;;3843:28;3896:2;3887:12;;3761:144::o;3910:786::-;;4321:25;4316:3;4309:38;4376:6;4370:13;4392:62;4447:6;4442:2;4437:3;4433:12;4426:4;4418:6;4414:17;4392:62;:::i;:::-;-1:-1:-1;;;4513:2:1;4473:16;;;4505:11;;;4498:40;4563:13;;4585:63;4563:13;4634:2;4626:11;;4619:4;4607:17;;4585:63;:::i;:::-;4668:17;4687:2;4664:26;;4299:397;-1:-1:-1;;;;4299:397:1:o;4701:203::-;-1:-1:-1;;;;;4865:32:1;;;;4847:51;;4835:2;4820:18;;4802:102::o;4909:187::-;5074:14;;5067:22;5049:41;;5037:2;5022:18;;5004:92::o;5101:177::-;5247:25;;;5235:2;5220:18;;5202:76::o;5283:591::-;5570:25;;;-1:-1:-1;;;;;5669:15:1;;;5664:2;5649:18;;5642:43;5721:15;;;;5716:2;5701:18;;5694:43;5768:2;5753:18;;5746:34;5811:3;5796:19;;5789:35;;;;5622:3;5840:19;;5833:35;5557:3;5542:19;;5524:350::o;5879:489::-;6138:25;;;6194:2;6179:18;;6172:34;;;;6237:2;6222:18;;6215:34;;;;6280:2;6265:18;;6258:34;-1:-1:-1;;;;;6329:32:1;6323:3;6308:19;;6301:61;6125:3;6110:19;;6092:276::o;6373:398::-;6600:25;;;6673:4;6661:17;;;;6656:2;6641:18;;6634:45;6710:2;6695:18;;6688:34;6753:2;6738:18;;6731:34;6587:3;6572:19;;6554:217::o;6776:383::-;;6925:2;6914:9;6907:21;6957:6;6951:13;7000:6;6995:2;6984:9;6980:18;6973:34;7016:66;7075:6;7070:2;7059:9;7055:18;7050:2;7042:6;7038:15;7016:66;:::i;:::-;7143:2;7122:15;-1:-1:-1;;7118:29:1;7103:45;;;;7150:2;7099:54;;6897:262;-1:-1:-1;;6897:262:1:o;7164:356::-;7366:2;7348:21;;;7385:18;;;7378:30;7444:34;7439:2;7424:18;;7417:62;7511:2;7496:18;;7338:182::o;7525:398::-;7727:2;7709:21;;;7766:2;7746:18;;;7739:30;7805:34;7800:2;7785:18;;7778:62;-1:-1:-1;;;7871:2:1;7856:18;;7849:32;7913:3;7898:19;;7699:224::o;7928:347::-;8130:2;8112:21;;;8169:2;8149:18;;;8142:30;8208:25;8203:2;8188:18;;8181:53;8266:2;8251:18;;8102:173::o;8280:402::-;8482:2;8464:21;;;8521:2;8501:18;;;8494:30;8560:34;8555:2;8540:18;;8533:62;-1:-1:-1;;;8626:2:1;8611:18;;8604:36;8672:3;8657:19;;8454:228::o;8687:398::-;8889:2;8871:21;;;8928:2;8908:18;;;8901:30;8967:34;8962:2;8947:18;;8940:62;-1:-1:-1;;;9033:2:1;9018:18;;9011:32;9075:3;9060:19;;8861:224::o;9090:353::-;9292:2;9274:21;;;9331:2;9311:18;;;9304:30;9370:31;9365:2;9350:18;;9343:59;9434:2;9419:18;;9264:179::o;9448:406::-;9650:2;9632:21;;;9689:2;9669:18;;;9662:30;9728:34;9723:2;9708:18;;9701:62;-1:-1:-1;;;9794:2:1;9779:18;;9772:40;9844:3;9829:19;;9622:232::o;9859:356::-;10061:2;10043:21;;;10080:18;;;10073:30;10139:34;10134:2;10119:18;;10112:62;10206:2;10191:18;;10033:182::o;10220:397::-;10422:2;10404:21;;;10461:2;10441:18;;;10434:30;10500:34;10495:2;10480:18;;10473:62;-1:-1:-1;;;10566:2:1;10551:18;;10544:31;10607:3;10592:19;;10394:223::o;10622:400::-;10824:2;10806:21;;;10863:2;10843:18;;;10836:30;10902:34;10897:2;10882:18;;10875:62;-1:-1:-1;;;10968:2:1;10953:18;;10946:34;11012:3;10997:19;;10796:226::o;11027:411::-;11229:2;11211:21;;;11268:2;11248:18;;;11241:30;11307:34;11302:2;11287:18;;11280:62;-1:-1:-1;;;11373:2:1;11358:18;;11351:45;11428:3;11413:19;;11201:237::o;11443:355::-;11645:2;11627:21;;;11684:2;11664:18;;;11657:30;11723:33;11718:2;11703:18;;11696:61;11789:2;11774:18;;11617:181::o;11985:184::-;12157:4;12145:17;;;;12127:36;;12115:2;12100:18;;12082:87::o;12174:128::-;;12245:1;12241:6;12238:1;12235:13;12232:2;;;12251:18;;:::i;:::-;-1:-1:-1;12287:9:1;;12222:80::o;12307:120::-;;12373:1;12363:2;;12378:18;;:::i;:::-;-1:-1:-1;12412:9:1;;12353:74::o;12432:453::-;12528:6;12551:5;12565:314;12614:1;12651:2;12641:8;12638:16;12628:2;;12658:5;;;12628:2;12699:4;12694:3;12690:14;12684:4;12681:24;12678:2;;;12708:18;;:::i;:::-;12758:2;12748:8;12744:17;12741:2;;;12773:16;;;;12741:2;12852:17;;;;;12812:15;;12565:314;;;12509:376;;;;;;;:::o;12890:139::-;;12979:44;-1:-1:-1;;13006:8:1;13000:4;13034:922;13118:8;13108:2;;-1:-1:-1;13159:1:1;13173:5;;13108:2;13207:4;13197:2;;-1:-1:-1;13244:1:1;13258:5;;13197:2;13289:4;13307:1;13302:59;;;;13375:1;13370:183;;;;13282:271;;13302:59;13332:1;13323:10;;13346:5;;;13370:183;13407:3;13397:8;13394:17;13391:2;;;13414:18;;:::i;:::-;13470:1;13460:8;13456:16;13447:25;;13498:3;13491:5;13488:14;13485:2;;;13505:18;;:::i;:::-;13538:5;;;13282:271;;13637:2;13627:8;13624:16;13618:3;13612:4;13609:13;13605:36;13599:2;13589:8;13586:16;13581:2;13575:4;13572:12;13568:35;13565:77;13562:2;;;-1:-1:-1;13674:19:1;;;13709:14;;;13706:2;;;13726:18;;:::i;:::-;13759:5;;13562:2;13806:42;13844:3;13834:8;13828:4;13825:1;13806:42;:::i;:::-;13881:6;13876:3;13872:16;13863:7;13860:29;13857:2;;;13892:18;;:::i;:::-;13930:20;;13098:858;-1:-1:-1;;;;13098:858:1:o;13961:168::-;;14067:1;14063;14059:6;14055:14;14052:1;14049:21;14044:1;14037:9;14030:17;14026:45;14023:2;;;14074:18;;:::i;:::-;-1:-1:-1;14114:9:1;;14013:116::o;14134:125::-;;14202:1;14199;14196:8;14193:2;;;14207:18;;:::i;:::-;-1:-1:-1;14244:9:1;;14183:76::o;14264:258::-;14336:1;14346:113;14360:6;14357:1;14354:13;14346:113;;;14436:11;;;14430:18;14417:11;;;14410:39;14382:2;14375:10;14346:113;;;14477:6;14474:1;14471:13;14468:2;;;-1:-1:-1;;14512:1:1;14494:16;;14487:27;14317:205::o;14527:136::-;;14594:5;14584:2;;14603:18;;:::i;:::-;-1:-1:-1;;;14639:18:1;;14574:89::o;14668:380::-;14753:1;14743:12;;14800:1;14790:12;;;14811:2;;14865:4;14857:6;14853:17;14843:27;;14811:2;14918;14910:6;14907:14;14887:18;14884:38;14881:2;;;14964:10;14959:3;14955:20;14952:1;14945:31;14999:4;14996:1;14989:15;15027:4;15024:1;15017:15;15053:112;;15111:1;15101:2;;15116:18;;:::i;:::-;-1:-1:-1;15150:9:1;;15091:74::o;15170:138::-;;-1:-1:-1;;;15226:22:1;;15223:2;;;15251:18;;:::i;:::-;15287:15;;15213:95::o;15313:127::-;15374:10;15369:3;15365:20;15362:1;15355:31;15405:4;15402:1;15395:15;15429:4;15426:1;15419:15;15445:127;15506:10;15501:3;15497:20;15494:1;15487:31;15537:4;15534:1;15527:15;15561:4;15558:1;15551:15
Swarm Source
ipfs://e58d7b44695cb4af7b253bc4408820eac6d096e6ff88c0599163bc14300794d5
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.