Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 10,542 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Enter Markets | 10154968 | 2 hrs ago | IN | 0 ETH | 0.00002421 | ||||
Enter Markets | 10154956 | 2 hrs ago | IN | 0 ETH | 0.00002324 | ||||
Enter Markets | 10154939 | 2 hrs ago | IN | 0 ETH | 0.00002463 | ||||
Enter Markets | 10154901 | 2 hrs ago | IN | 0 ETH | 0.00002167 | ||||
Enter Markets | 10146568 | 9 hrs ago | IN | 0 ETH | 0.00000772 | ||||
Enter Markets | 10146551 | 9 hrs ago | IN | 0 ETH | 0.00000773 | ||||
Enter Markets | 10146546 | 9 hrs ago | IN | 0 ETH | 0.00000754 | ||||
Enter Markets | 10146540 | 9 hrs ago | IN | 0 ETH | 0.00000787 | ||||
Enter Markets | 10143569 | 11 hrs ago | IN | 0 ETH | 0.00000885 | ||||
Enter Markets | 10143550 | 11 hrs ago | IN | 0 ETH | 0.00000923 | ||||
Enter Markets | 10143434 | 11 hrs ago | IN | 0 ETH | 0.0000094 | ||||
Enter Markets | 10143361 | 11 hrs ago | IN | 0 ETH | 0.00000954 | ||||
Enter Markets | 10132471 | 20 hrs ago | IN | 0 ETH | 0.00001344 | ||||
Enter Markets | 10127033 | 25 hrs ago | IN | 0 ETH | 0.00001122 | ||||
Enter Markets | 10125994 | 26 hrs ago | IN | 0 ETH | 0.00001082 | ||||
Enter Markets | 10125988 | 26 hrs ago | IN | 0 ETH | 0.00001081 | ||||
Enter Markets | 10125936 | 26 hrs ago | IN | 0 ETH | 0.00001011 | ||||
Enter Markets | 10125925 | 26 hrs ago | IN | 0 ETH | 0.00001082 | ||||
Enter Markets | 10121717 | 29 hrs ago | IN | 0 ETH | 0.00000772 | ||||
Enter Markets | 10121690 | 29 hrs ago | IN | 0 ETH | 0.00000774 | ||||
Enter Markets | 10121636 | 29 hrs ago | IN | 0 ETH | 0.000008 | ||||
Enter Markets | 10121618 | 29 hrs ago | IN | 0 ETH | 0.00000863 | ||||
Enter Markets | 10120902 | 30 hrs ago | IN | 0 ETH | 0.00000794 | ||||
Enter Markets | 10120870 | 30 hrs ago | IN | 0 ETH | 0.00000769 | ||||
Enter Markets | 10120861 | 30 hrs ago | IN | 0 ETH | 0.00000839 |
Loading...
Loading
Contract Name:
Comptroller
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at scrollscan.com on 2023-10-18 */ /** *Submitted for verification at scrollscan.com on 2023-10-17 */ // SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.4; library SignatureLib { uint256 constant ECDSA_SIG_R_BS = 32; uint256 constant ECDSA_SIG_S_BS = 32; function recoverSignerAddress(bytes32 signedHash, uint256 signatureCalldataNegativeOffset) internal pure returns (address) { bytes32 r; bytes32 s; uint8 v; assembly { let signatureCalldataStartPos := sub(calldatasize(), signatureCalldataNegativeOffset) r := calldataload(signatureCalldataStartPos) signatureCalldataStartPos := add(signatureCalldataStartPos, ECDSA_SIG_R_BS) s := calldataload(signatureCalldataStartPos) signatureCalldataStartPos := add(signatureCalldataStartPos, ECDSA_SIG_S_BS) v := byte(0, calldataload(signatureCalldataStartPos)) // last byte of the signature memory array } return ecrecover(signedHash, v, r, s); } } // File: @redstone-finance/evm-connector/contracts/libs/BitmapLib.sol pragma solidity ^0.8.4; library BitmapLib { function setBitInBitmap(uint256 bitmap, uint256 bitIndex) internal pure returns (uint256) { return bitmap | (1 << bitIndex); } function getBitFromBitmap(uint256 bitmap, uint256 bitIndex) internal pure returns (bool) { uint256 bitAtIndex = bitmap & (1 << bitIndex); return bitAtIndex > 0; } } // File: @redstone-finance/evm-connector/contracts/core/RedstoneConstants.sol pragma solidity ^0.8.4; /** * @title The base contract with helpful constants * @author The Redstone Oracles team * @dev It mainly contains redstone-related values, which improve readability * of other contracts (e.g. CalldataExtractor and RedstoneConsumerBase) */ contract RedstoneConstants { // === Abbreviations === // BS - Bytes size // PTR - Pointer (memory location) // SIG - Signature // Solidity and YUL constants uint256 internal constant STANDARD_SLOT_BS = 32; uint256 internal constant FREE_MEMORY_PTR = 0x40; uint256 internal constant BYTES_ARR_LEN_VAR_BS = 32; uint256 internal constant FUNCTION_SIGNATURE_BS = 4; uint256 internal constant REVERT_MSG_OFFSET = 68; // Revert message structure described here: https://ethereum.stackexchange.com/a/66173/106364 uint256 internal constant STRING_ERR_MESSAGE_MASK = 0x08c379a000000000000000000000000000000000000000000000000000000000; // RedStone protocol consts uint256 internal constant SIG_BS = 65; uint256 internal constant TIMESTAMP_BS = 6; uint256 internal constant DATA_PACKAGES_COUNT_BS = 2; uint256 internal constant DATA_POINTS_COUNT_BS = 3; uint256 internal constant DATA_POINT_VALUE_BYTE_SIZE_BS = 4; uint256 internal constant DATA_POINT_SYMBOL_BS = 32; uint256 internal constant DEFAULT_DATA_POINT_VALUE_BS = 32; uint256 internal constant UNSIGNED_METADATA_BYTE_SIZE_BS = 3; uint256 internal constant REDSTONE_MARKER_BS = 9; // byte size of 0x000002ed57011e0000 uint256 internal constant REDSTONE_MARKER_MASK = 0x0000000000000000000000000000000000000000000000000002ed57011e0000; // Derived values (based on consts) uint256 internal constant TIMESTAMP_NEGATIVE_OFFSET_IN_DATA_PACKAGE_WITH_STANDARD_SLOT_BS = 104; // SIG_BS + DATA_POINTS_COUNT_BS + DATA_POINT_VALUE_BYTE_SIZE_BS + STANDARD_SLOT_BS uint256 internal constant DATA_PACKAGE_WITHOUT_DATA_POINTS_BS = 78; // DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS + SIG_BS uint256 internal constant DATA_PACKAGE_WITHOUT_DATA_POINTS_AND_SIG_BS = 13; // DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS uint256 internal constant REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS = 41; // REDSTONE_MARKER_BS + STANDARD_SLOT_BS // Error messages error CalldataOverOrUnderFlow(); error IncorrectUnsignedMetadataSize(); error InsufficientNumberOfUniqueSigners(uint256 receivedSignersCount, uint256 requiredSignersCount); error EachSignerMustProvideTheSameValue(); error EmptyCalldataPointersArr(); error InvalidCalldataPointer(); error CalldataMustHaveValidPayload(); error SignerNotAuthorised(address receivedSigner); } // File: @openzeppelin/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: @redstone-finance/evm-connector/contracts/core/CalldataExtractor.sol pragma solidity ^0.8.4; /** * @title The base contract with the main logic of data extraction from calldata * @author The Redstone Oracles team * @dev This contract was created to reuse the same logic in the RedstoneConsumerBase * and the ProxyConnector contracts */ contract CalldataExtractor is RedstoneConstants { using SafeMath for uint256; function _extractByteSizeOfUnsignedMetadata() internal pure returns (uint256) { // Checking if the calldata ends with the RedStone marker bool hasValidRedstoneMarker; assembly { let calldataLast32Bytes := calldataload(sub(calldatasize(), STANDARD_SLOT_BS)) hasValidRedstoneMarker := eq( REDSTONE_MARKER_MASK, and(calldataLast32Bytes, REDSTONE_MARKER_MASK) ) } if (!hasValidRedstoneMarker) { revert CalldataMustHaveValidPayload(); } // Using uint24, because unsigned metadata byte size number has 3 bytes uint24 unsignedMetadataByteSize; if (REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS > msg.data.length) { revert CalldataOverOrUnderFlow(); } assembly { unsignedMetadataByteSize := calldataload( sub(calldatasize(), REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS) ) } uint256 calldataNegativeOffset = unsignedMetadataByteSize + UNSIGNED_METADATA_BYTE_SIZE_BS + REDSTONE_MARKER_BS; if (calldataNegativeOffset + DATA_PACKAGES_COUNT_BS > msg.data.length) { revert IncorrectUnsignedMetadataSize(); } return calldataNegativeOffset; } // We return uint16, because unsigned metadata byte size number has 2 bytes function _extractDataPackagesCountFromCalldata(uint256 calldataNegativeOffset) internal pure returns (uint16 dataPackagesCount) { uint256 calldataNegativeOffsetWithStandardSlot = calldataNegativeOffset + STANDARD_SLOT_BS; if (calldataNegativeOffsetWithStandardSlot > msg.data.length) { revert CalldataOverOrUnderFlow(); } assembly { dataPackagesCount := calldataload( sub(calldatasize(), calldataNegativeOffsetWithStandardSlot) ) } return dataPackagesCount; } function _extractDataPointValueAndDataFeedId( uint256 calldataNegativeOffsetForDataPackage, uint256 defaultDataPointValueByteSize, uint256 dataPointIndex ) internal pure virtual returns (bytes32 dataPointDataFeedId, uint256 dataPointValue) { uint256 negativeOffsetToDataPoints = calldataNegativeOffsetForDataPackage + DATA_PACKAGE_WITHOUT_DATA_POINTS_BS; uint256 dataPointNegativeOffset = negativeOffsetToDataPoints.add( (1 + dataPointIndex).mul((defaultDataPointValueByteSize + DATA_POINT_SYMBOL_BS)) ); uint256 dataPointCalldataOffset = msg.data.length.sub(dataPointNegativeOffset); assembly { dataPointDataFeedId := calldataload(dataPointCalldataOffset) dataPointValue := calldataload(add(dataPointCalldataOffset, DATA_POINT_SYMBOL_BS)) } } function _extractDataPointsDetailsForDataPackage(uint256 calldataNegativeOffsetForDataPackage) internal pure returns (uint256 dataPointsCount, uint256 eachDataPointValueByteSize) { // Using uint24, because data points count byte size number has 3 bytes uint24 dataPointsCount_; // Using uint32, because data point value byte size has 4 bytes uint32 eachDataPointValueByteSize_; // Extract data points count uint256 negativeCalldataOffset = calldataNegativeOffsetForDataPackage + SIG_BS; uint256 calldataOffset = msg.data.length.sub(negativeCalldataOffset + STANDARD_SLOT_BS); assembly { dataPointsCount_ := calldataload(calldataOffset) } // Extract each data point value size calldataOffset = calldataOffset.sub(DATA_POINTS_COUNT_BS); assembly { eachDataPointValueByteSize_ := calldataload(calldataOffset) } // Prepare returned values dataPointsCount = dataPointsCount_; eachDataPointValueByteSize = eachDataPointValueByteSize_; } } // File: @redstone-finance/evm-connector/contracts/libs/NumericArrayLib.sol pragma solidity ^0.8.4; library NumericArrayLib { // This function sort array in memory using bubble sort algorithm, // which performs even better than quick sort for small arrays uint256 constant BYTES_ARR_LEN_VAR_BS = 32; uint256 constant UINT256_VALUE_BS = 32; error CanNotPickMedianOfEmptyArray(); // This function modifies the array function pickMedian(uint256[] memory arr) internal pure returns (uint256) { if (arr.length == 0) { revert CanNotPickMedianOfEmptyArray(); } sort(arr); uint256 middleIndex = arr.length / 2; if (arr.length % 2 == 0) { uint256 sum = SafeMath.add(arr[middleIndex - 1], arr[middleIndex]); return sum / 2; } else { return arr[middleIndex]; } } function sort(uint256[] memory arr) internal pure { assembly { let arrLength := mload(arr) let valuesPtr := add(arr, BYTES_ARR_LEN_VAR_BS) let endPtr := add(valuesPtr, mul(arrLength, UINT256_VALUE_BS)) for { let arrIPtr := valuesPtr } lt(arrIPtr, endPtr) { arrIPtr := add(arrIPtr, UINT256_VALUE_BS) // arrIPtr += 32 } { for { let arrJPtr := valuesPtr } lt(arrJPtr, arrIPtr) { arrJPtr := add(arrJPtr, UINT256_VALUE_BS) // arrJPtr += 32 } { let arrI := mload(arrIPtr) let arrJ := mload(arrJPtr) if lt(arrI, arrJ) { mstore(arrIPtr, arrJ) mstore(arrJPtr, arrI) } } } } } } // File: @redstone-finance/evm-connector/contracts/core/RedstoneDefaultsLib.sol pragma solidity ^0.8.4; /** * @title Default implementations of virtual redstone consumer base functions * @author The Redstone Oracles team */ library RedstoneDefaultsLib { uint256 constant DEFAULT_MAX_DATA_TIMESTAMP_DELAY_SECONDS = 3 minutes; uint256 constant DEFAULT_MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 1 minutes; error TimestampFromTooLongFuture(uint256 receivedTimestampSeconds, uint256 blockTimestamp); error TimestampIsTooOld(uint256 receivedTimestampSeconds, uint256 blockTimestamp); function validateTimestamp(uint256 receivedTimestampMilliseconds) internal view { // Getting data timestamp from future seems quite unlikely // But we've already spent too much time with different cases // Where block.timestamp was less than dataPackage.timestamp. // Some blockchains may case this problem as well. // That's why we add MAX_BLOCK_TIMESTAMP_DELAY // and allow data "from future" but with a small delay uint256 receivedTimestampSeconds = receivedTimestampMilliseconds / 1000; if (block.timestamp < receivedTimestampSeconds) { if ((receivedTimestampSeconds - block.timestamp) > DEFAULT_MAX_DATA_TIMESTAMP_AHEAD_SECONDS) { revert TimestampFromTooLongFuture(receivedTimestampSeconds, block.timestamp); } } else if ((block.timestamp - receivedTimestampSeconds) > DEFAULT_MAX_DATA_TIMESTAMP_DELAY_SECONDS) { revert TimestampIsTooOld(receivedTimestampSeconds, block.timestamp); } } function aggregateValues(uint256[] memory values) internal pure returns (uint256) { return NumericArrayLib.pickMedian(values); } } // File: @redstone-finance/evm-connector/contracts/core/RedstoneConsumerBase.sol pragma solidity ^0.8.4; /** * @title The base contract with the main Redstone logic * @author The Redstone Oracles team * @dev Do not use this contract directly in consumer contracts, take a * look at `RedstoneConsumerNumericBase` and `RedstoneConsumerBytesBase` instead */ abstract contract RedstoneConsumerBase is CalldataExtractor { using SafeMath for uint256; /* ========== VIRTUAL FUNCTIONS (MAY BE OVERRIDDEN IN CHILD CONTRACTS) ========== */ /** * @dev This function must be implemented by the child consumer contract. * It should return a unique index for a given signer address if the signer * is authorised, otherwise it should revert * @param receivedSigner The address of a signer, recovered from ECDSA signature * @return Unique index for a signer in the range [0..255] */ function getAuthorisedSignerIndex(address receivedSigner) public view virtual returns (uint8); /** * @dev This function may be overridden by the child consumer contract. * It should validate the timestamp against the current time (block.timestamp) * It should revert with a helpful message if the timestamp is not valid * @param receivedTimestampMilliseconds Timestamp extracted from calldata */ function validateTimestamp(uint256 receivedTimestampMilliseconds) public view virtual { RedstoneDefaultsLib.validateTimestamp(receivedTimestampMilliseconds); } /** * @dev This function should be overridden by the child consumer contract. * @return The minimum required value of unique authorised signers */ function getUniqueSignersThreshold() public view virtual returns (uint8) { return 1; } /** * @dev This function may be overridden by the child consumer contract. * It should aggregate values from different signers to a single uint value. * By default, it calculates the median value * @param values An array of uint256 values from different signers * @return Result of the aggregation in the form of a single number */ function aggregateValues(uint256[] memory values) public view virtual returns (uint256) { return RedstoneDefaultsLib.aggregateValues(values); } /* ========== FUNCTIONS WITH IMPLEMENTATION (CAN NOT BE OVERRIDDEN) ========== */ /** * @dev This is an internal helpful function for secure extraction oracle values * from the tx calldata. Security is achieved by signatures verification, timestamp * validation, and aggregating values from different authorised signers into a * single numeric value. If any of the required conditions (e.g. too old timestamp or * insufficient number of authorised signers) do not match, the function will revert. * * Note! You should not call this function in a consumer contract. You can use * `getOracleNumericValuesFromTxMsg` or `getOracleNumericValueFromTxMsg` instead. * * @param dataFeedIds An array of unique data feed identifiers * @return An array of the extracted and verified oracle values in the same order * as they are requested in dataFeedIds array */ function _securelyExtractOracleValuesFromTxMsg(bytes32[] memory dataFeedIds) internal view returns (uint256[] memory) { // Initializing helpful variables and allocating memory uint256[] memory uniqueSignerCountForDataFeedIds = new uint256[](dataFeedIds.length); uint256[] memory signersBitmapForDataFeedIds = new uint256[](dataFeedIds.length); uint256[][] memory valuesForDataFeeds = new uint256[][](dataFeedIds.length); for (uint256 i = 0; i < dataFeedIds.length; i++) { // The line below is commented because newly allocated arrays are filled with zeros // But we left it for better readability // signersBitmapForDataFeedIds[i] = 0; // <- setting to an empty bitmap valuesForDataFeeds[i] = new uint256[](getUniqueSignersThreshold()); } // Extracting the number of data packages from calldata uint256 calldataNegativeOffset = _extractByteSizeOfUnsignedMetadata(); uint256 dataPackagesCount = _extractDataPackagesCountFromCalldata(calldataNegativeOffset); calldataNegativeOffset += DATA_PACKAGES_COUNT_BS; // Saving current free memory pointer uint256 freeMemPtr; assembly { freeMemPtr := mload(FREE_MEMORY_PTR) } // Data packages extraction in a loop for (uint256 dataPackageIndex = 0; dataPackageIndex < dataPackagesCount; dataPackageIndex++) { // Extract data package details and update calldata offset uint256 dataPackageByteSize = _extractDataPackage( dataFeedIds, uniqueSignerCountForDataFeedIds, signersBitmapForDataFeedIds, valuesForDataFeeds, calldataNegativeOffset ); calldataNegativeOffset += dataPackageByteSize; // Shifting memory pointer back to the "safe" value assembly { mstore(FREE_MEMORY_PTR, freeMemPtr) } } // Validating numbers of unique signers and calculating aggregated values for each dataFeedId return _getAggregatedValues(valuesForDataFeeds, uniqueSignerCountForDataFeedIds); } /** * @dev This is a private helpful function, which extracts data for a data package based * on the given negative calldata offset, verifies them, and in the case of successful * verification updates the corresponding data package values in memory * * @param dataFeedIds an array of unique data feed identifiers * @param uniqueSignerCountForDataFeedIds an array with the numbers of unique signers * for each data feed * @param signersBitmapForDataFeedIds an array of signer bitmaps for data feeds * @param valuesForDataFeeds 2-dimensional array, valuesForDataFeeds[i][j] contains * j-th value for the i-th data feed * @param calldataNegativeOffset negative calldata offset for the given data package * * @return An array of the aggregated values */ function _extractDataPackage( bytes32[] memory dataFeedIds, uint256[] memory uniqueSignerCountForDataFeedIds, uint256[] memory signersBitmapForDataFeedIds, uint256[][] memory valuesForDataFeeds, uint256 calldataNegativeOffset ) private view returns (uint256) { uint256 signerIndex; ( uint256 dataPointsCount, uint256 eachDataPointValueByteSize ) = _extractDataPointsDetailsForDataPackage(calldataNegativeOffset); // We use scopes to resolve problem with too deep stack { uint48 extractedTimestamp; address signerAddress; bytes32 signedHash; bytes memory signedMessage; uint256 signedMessageBytesCount; signedMessageBytesCount = dataPointsCount.mul(eachDataPointValueByteSize + DATA_POINT_SYMBOL_BS) + DATA_PACKAGE_WITHOUT_DATA_POINTS_AND_SIG_BS; //DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS uint256 timestampCalldataOffset = msg.data.length.sub( calldataNegativeOffset + TIMESTAMP_NEGATIVE_OFFSET_IN_DATA_PACKAGE_WITH_STANDARD_SLOT_BS); uint256 signedMessageCalldataOffset = msg.data.length.sub( calldataNegativeOffset + SIG_BS + signedMessageBytesCount); assembly { // Extracting the signed message signedMessage := extractBytesFromCalldata( signedMessageCalldataOffset, signedMessageBytesCount ) // Hashing the signed message signedHash := keccak256(add(signedMessage, BYTES_ARR_LEN_VAR_BS), signedMessageBytesCount) // Extracting timestamp extractedTimestamp := calldataload(timestampCalldataOffset) function initByteArray(bytesCount) -> ptr { ptr := mload(FREE_MEMORY_PTR) mstore(ptr, bytesCount) ptr := add(ptr, BYTES_ARR_LEN_VAR_BS) mstore(FREE_MEMORY_PTR, add(ptr, bytesCount)) } function extractBytesFromCalldata(offset, bytesCount) -> extractedBytes { let extractedBytesStartPtr := initByteArray(bytesCount) calldatacopy( extractedBytesStartPtr, offset, bytesCount ) extractedBytes := sub(extractedBytesStartPtr, BYTES_ARR_LEN_VAR_BS) } } // Validating timestamp validateTimestamp(extractedTimestamp); // Verifying the off-chain signature against on-chain hashed data signerAddress = SignatureLib.recoverSignerAddress( signedHash, calldataNegativeOffset + SIG_BS ); signerIndex = getAuthorisedSignerIndex(signerAddress); } // Updating helpful arrays { bytes32 dataPointDataFeedId; uint256 dataPointValue; for (uint256 dataPointIndex = 0; dataPointIndex < dataPointsCount; dataPointIndex++) { // Extracting data feed id and value for the current data point (dataPointDataFeedId, dataPointValue) = _extractDataPointValueAndDataFeedId( calldataNegativeOffset, eachDataPointValueByteSize, dataPointIndex ); for ( uint256 dataFeedIdIndex = 0; dataFeedIdIndex < dataFeedIds.length; dataFeedIdIndex++ ) { if (dataPointDataFeedId == dataFeedIds[dataFeedIdIndex]) { uint256 bitmapSignersForDataFeedId = signersBitmapForDataFeedIds[dataFeedIdIndex]; if ( !BitmapLib.getBitFromBitmap(bitmapSignersForDataFeedId, signerIndex) && /* current signer was not counted for current dataFeedId */ uniqueSignerCountForDataFeedIds[dataFeedIdIndex] < getUniqueSignersThreshold() ) { // Increase unique signer counter uniqueSignerCountForDataFeedIds[dataFeedIdIndex]++; // Add new value valuesForDataFeeds[dataFeedIdIndex][ uniqueSignerCountForDataFeedIds[dataFeedIdIndex] - 1 ] = dataPointValue; // Update signers bitmap signersBitmapForDataFeedIds[dataFeedIdIndex] = BitmapLib.setBitInBitmap( bitmapSignersForDataFeedId, signerIndex ); } // Breaking, as there couldn't be several indexes for the same feed ID break; } } } } // Return total data package byte size return DATA_PACKAGE_WITHOUT_DATA_POINTS_BS + (eachDataPointValueByteSize + DATA_POINT_SYMBOL_BS) * dataPointsCount; } /** * @dev This is a private helpful function, which aggregates values from different * authorised signers for the given arrays of values for each data feed * * @param valuesForDataFeeds 2-dimensional array, valuesForDataFeeds[i][j] contains * j-th value for the i-th data feed * @param uniqueSignerCountForDataFeedIds an array with the numbers of unique signers * for each data feed * * @return An array of the aggregated values */ function _getAggregatedValues( uint256[][] memory valuesForDataFeeds, uint256[] memory uniqueSignerCountForDataFeedIds ) private view returns (uint256[] memory) { uint256[] memory aggregatedValues = new uint256[](valuesForDataFeeds.length); uint256 uniqueSignersThreshold = getUniqueSignersThreshold(); for (uint256 dataFeedIndex = 0; dataFeedIndex < valuesForDataFeeds.length; dataFeedIndex++) { if (uniqueSignerCountForDataFeedIds[dataFeedIndex] < uniqueSignersThreshold) { revert InsufficientNumberOfUniqueSigners( uniqueSignerCountForDataFeedIds[dataFeedIndex], uniqueSignersThreshold); } uint256 aggregatedValueForDataFeedId = aggregateValues(valuesForDataFeeds[dataFeedIndex]); aggregatedValues[dataFeedIndex] = aggregatedValueForDataFeedId; } return aggregatedValues; } } // File: @redstone-finance/evm-connector/contracts/core/RedstoneConsumerNumericBase.sol pragma solidity ^0.8.4; /** * @title The base contract for Redstone consumers' contracts that allows to * securely calculate numeric redstone oracle values * @author The Redstone Oracles team * @dev This contract can extend other contracts to allow them * securely fetch Redstone oracle data from transactions calldata */ abstract contract RedstoneConsumerNumericBase is RedstoneConsumerBase { error GetDataServiceIdNotImplemented(); function getDataServiceId() public view virtual returns (string memory) { revert GetDataServiceIdNotImplemented(); } /** * @dev This function can be used in a consumer contract to securely extract an * oracle value for a given data feed id. Security is achieved by * signatures verification, timestamp validation, and aggregating values * from different authorised signers into a single numeric value. If any of the * required conditions do not match, the function will revert. * Note! This function expects that tx calldata contains redstone payload in the end * Learn more about redstone payload here: https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/evm-connector#readme * @param dataFeedId bytes32 value that uniquely identifies the data feed * @return Extracted and verified numeric oracle value for the given data feed id */ function getOracleNumericValueFromTxMsg(bytes32 dataFeedId) internal view virtual returns (uint256) { bytes32[] memory dataFeedIds = new bytes32[](1); dataFeedIds[0] = dataFeedId; return getOracleNumericValuesFromTxMsg(dataFeedIds)[0]; } /** * @dev This function can be used in a consumer contract to securely extract several * numeric oracle values for a given array of data feed ids. Security is achieved by * signatures verification, timestamp validation, and aggregating values * from different authorised signers into a single numeric value. If any of the * required conditions do not match, the function will revert. * Note! This function expects that tx calldata contains redstone payload in the end * Learn more about redstone payload here: https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/evm-connector#readme * @param dataFeedIds An array of unique data feed identifiers * @return An array of the extracted and verified oracle values in the same order * as they are requested in the dataFeedIds array */ function getOracleNumericValuesFromTxMsg(bytes32[] memory dataFeedIds) internal view virtual returns (uint256[] memory) { return _securelyExtractOracleValuesFromTxMsg(dataFeedIds); } /** * @dev This function works similarly to the `getOracleNumericValuesFromTxMsg` with the * only difference that it allows to request oracle data for an array of data feeds * that may contain duplicates * * @param dataFeedIdsWithDuplicates An array of data feed identifiers (duplicates are allowed) * @return An array of the extracted and verified oracle values in the same order * as they are requested in the dataFeedIdsWithDuplicates array */ function getOracleNumericValuesWithDuplicatesFromTxMsg(bytes32[] memory dataFeedIdsWithDuplicates) internal view returns (uint256[] memory) { // Building an array without duplicates bytes32[] memory dataFeedIdsWithoutDuplicates = new bytes32[](dataFeedIdsWithDuplicates.length); bool alreadyIncluded; uint256 uniqueDataFeedIdsCount = 0; for (uint256 indexWithDup = 0; indexWithDup < dataFeedIdsWithDuplicates.length; indexWithDup++) { // Checking if current element is already included in `dataFeedIdsWithoutDuplicates` alreadyIncluded = false; for (uint256 indexWithoutDup = 0; indexWithoutDup < uniqueDataFeedIdsCount; indexWithoutDup++) { if (dataFeedIdsWithoutDuplicates[indexWithoutDup] == dataFeedIdsWithDuplicates[indexWithDup]) { alreadyIncluded = true; break; } } // Adding if not included if (!alreadyIncluded) { dataFeedIdsWithoutDuplicates[uniqueDataFeedIdsCount] = dataFeedIdsWithDuplicates[indexWithDup]; uniqueDataFeedIdsCount++; } } // Overriding dataFeedIdsWithoutDuplicates.length // Equivalent to: dataFeedIdsWithoutDuplicates.length = uniqueDataFeedIdsCount; assembly { mstore(dataFeedIdsWithoutDuplicates, uniqueDataFeedIdsCount) } // Requesting oracle values (without duplicates) uint256[] memory valuesWithoutDuplicates = getOracleNumericValuesFromTxMsg(dataFeedIdsWithoutDuplicates); // Preparing result values array uint256[] memory valuesWithDuplicates = new uint256[](dataFeedIdsWithDuplicates.length); for (uint256 indexWithDup = 0; indexWithDup < dataFeedIdsWithDuplicates.length; indexWithDup++) { for (uint256 indexWithoutDup = 0; indexWithoutDup < dataFeedIdsWithoutDuplicates.length; indexWithoutDup++) { if (dataFeedIdsWithDuplicates[indexWithDup] == dataFeedIdsWithoutDuplicates[indexWithoutDup]) { valuesWithDuplicates[indexWithDup] = valuesWithoutDuplicates[indexWithoutDup]; break; } } } return valuesWithDuplicates; } } // File: @redstone-finance/evm-connector/contracts/data-services/PrimaryProdDataServiceConsumerBase.sol pragma solidity ^0.8.4; contract PrimaryProdDataServiceConsumerBase is RedstoneConsumerNumericBase { function getDataServiceId() public view virtual override returns (string memory) { return "redstone-primary-prod"; } function getUniqueSignersThreshold() public view virtual override returns (uint8) { return 3; } function getAuthorisedSignerIndex( address signerAddress ) public view virtual override returns (uint8) { if (signerAddress == 0x8BB8F32Df04c8b654987DAaeD53D6B6091e3B774) { return 0; } else if (signerAddress == 0xdEB22f54738d54976C4c0fe5ce6d408E40d88499) { return 1; } else if (signerAddress == 0x51Ce04Be4b3E32572C4Ec9135221d0691Ba7d202) { return 2; } else if (signerAddress == 0xDD682daEC5A90dD295d14DA4b0bec9281017b5bE) { return 3; } else if (signerAddress == 0x9c5AE89C4Af6aA32cE58588DBaF90d18a855B6de) { return 4; } else { revert SignerNotAuthorised(signerAddress); } } } // File: ComptrollerRedstone.sol pragma solidity ^0.8.10; abstract contract ComptrollerInterface { bool public constant isComptroller = true; function enterMarkets(address[] calldata cTokens) virtual external returns (uint[] memory); function exitMarket(address cToken) virtual external returns (uint); function mintAllowed(address cToken, address minter, uint mintAmount) virtual external returns (uint); function mintVerify(address cToken, address minter, uint mintAmount, uint mintTokens) virtual external; function redeemAllowed(address cToken, address redeemer, uint redeemTokens) virtual external returns (uint); function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) virtual external; function borrowAllowed(address cToken, address borrower, uint borrowAmount) virtual external returns (uint); function borrowVerify(address cToken, address borrower, uint borrowAmount) virtual external; function repayBorrowAllowed( address cToken, address payer, address borrower, uint repayAmount) virtual external returns (uint); function repayBorrowVerify( address cToken, address payer, address borrower, uint repayAmount, uint borrowerIndex) virtual external; function liquidateBorrowAllowed( address cTokenBorrowed, address cTokenCollateral, address liquidator, address borrower, uint repayAmount) virtual external returns (uint); function liquidateBorrowVerify( address cTokenBorrowed, address cTokenCollateral, address liquidator, address borrower, uint repayAmount, uint seizeTokens) virtual external; function seizeAllowed( address cTokenCollateral, address cTokenBorrowed, address liquidator, address borrower, uint seizeTokens) virtual external returns (uint); function seizeVerify( address cTokenCollateral, address cTokenBorrowed, address liquidator, address borrower, uint seizeTokens) virtual external; function transferAllowed(address cToken, address src, address dst, uint transferTokens) virtual external returns (uint); function transferVerify(address cToken, address src, address dst, uint transferTokens) virtual external; function liquidateCalculateSeizeTokens( address cTokenBorrowed, address cTokenCollateral, uint repayAmount) virtual external view returns (uint, uint); } abstract contract InterestRateModel { bool public constant isInterestRateModel = true; function getBorrowRate(uint cash, uint borrows, uint reserves) virtual external view returns (uint); function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) virtual external view returns (uint); } interface EIP20NonStandardInterface { function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256 balance); function transfer(address dst, uint256 amount) external; function transferFrom(address src, address dst, uint256 amount) external; function approve(address spender, uint256 amount) external returns (bool success); function allowance(address owner, address spender) external view returns (uint256 remaining); event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); } contract ComptrollerErrorReporter { enum Error { NO_ERROR, UNAUTHORIZED, COMPTROLLER_MISMATCH, INSUFFICIENT_SHORTFALL, INSUFFICIENT_LIQUIDITY, INVALID_CLOSE_FACTOR, INVALID_COLLATERAL_FACTOR, INVALID_LIQUIDATION_INCENTIVE, MARKET_NOT_ENTERED, MARKET_NOT_LISTED, MARKET_ALREADY_LISTED, MATH_ERROR, NONZERO_BORROW_BALANCE, PRICE_ERROR, REJECTION, SNAPSHOT_ERROR, TOO_MANY_ASSETS, TOO_MUCH_REPAY } enum FailureInfo { ACCEPT_ADMIN_PENDING_ADMIN_CHECK, ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK, EXIT_MARKET_BALANCE_OWED, EXIT_MARKET_REJECTION, SET_CLOSE_FACTOR_OWNER_CHECK, SET_CLOSE_FACTOR_VALIDATION, SET_COLLATERAL_FACTOR_OWNER_CHECK, SET_COLLATERAL_FACTOR_NO_EXISTS, SET_COLLATERAL_FACTOR_VALIDATION, SET_COLLATERAL_FACTOR_WITHOUT_PRICE, SET_IMPLEMENTATION_OWNER_CHECK, SET_LIQUIDATION_INCENTIVE_OWNER_CHECK, SET_LIQUIDATION_INCENTIVE_VALIDATION, SET_MAX_ASSETS_OWNER_CHECK, SET_PENDING_ADMIN_OWNER_CHECK, SET_PENDING_IMPLEMENTATION_OWNER_CHECK, SET_PRICE_ORACLE_OWNER_CHECK, SUPPORT_MARKET_EXISTS, SUPPORT_MARKET_OWNER_CHECK, SET_PAUSE_GUARDIAN_OWNER_CHECK } event Failure(uint error, uint info, uint detail); function fail(Error err, FailureInfo info) internal returns (uint) { emit Failure(uint(err), uint(info), 0); return uint(err); } function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) { emit Failure(uint(err), uint(info), opaqueError); return uint(err); } } contract TokenErrorReporter { uint public constant NO_ERROR = 0; error TransferComptrollerRejection(uint256 errorCode); error TransferNotAllowed(); error TransferNotEnough(); error TransferTooMuch(); error MintComptrollerRejection(uint256 errorCode); error MintFreshnessCheck(); error RedeemComptrollerRejection(uint256 errorCode); error RedeemFreshnessCheck(); error RedeemTransferOutNotPossible(); error BorrowComptrollerRejection(uint256 errorCode); error BorrowFreshnessCheck(); error BorrowCashNotAvailable(); error RepayBorrowComptrollerRejection(uint256 errorCode); error RepayBorrowFreshnessCheck(); error LiquidateComptrollerRejection(uint256 errorCode); error LiquidateFreshnessCheck(); error LiquidateCollateralFreshnessCheck(); error LiquidateAccrueBorrowInterestFailed(uint256 errorCode); error LiquidateAccrueCollateralInterestFailed(uint256 errorCode); error LiquidateLiquidatorIsBorrower(); error LiquidateCloseAmountIsZero(); error LiquidateCloseAmountIsUintMax(); error LiquidateRepayBorrowFreshFailed(uint256 errorCode); error LiquidateSeizeComptrollerRejection(uint256 errorCode); error LiquidateSeizeLiquidatorIsBorrower(); error AcceptAdminPendingAdminCheck(); error SetComptrollerOwnerCheck(); error SetPendingAdminOwnerCheck(); error SetReserveFactorAdminCheck(); error SetReserveFactorFreshCheck(); error SetReserveFactorBoundsCheck(); error AddReservesFactorFreshCheck(uint256 actualAddAmount); error ReduceReservesAdminCheck(); error ReduceReservesFreshCheck(); error ReduceReservesCashNotAvailable(); error ReduceReservesCashValidation(); error SetInterestRateModelOwnerCheck(); error SetInterestRateModelFreshCheck(); } contract CTokenStorage { bool internal _notEntered; string public name; string public symbol; uint8 public decimals; uint internal constant borrowRateMaxMantissa = 0.0005e16; uint internal constant reserveFactorMaxMantissa = 1e18; address payable public admin; address payable public pendingAdmin; ComptrollerInterface public comptroller; InterestRateModel public interestRateModel; uint internal initialExchangeRateMantissa; uint public reserveFactorMantissa; uint public accrualBlockNumber; uint public borrowIndex; uint public totalBorrows; uint public totalReserves; uint public totalSupply; mapping (address => uint) internal accountTokens; mapping (address => mapping (address => uint)) internal transferAllowances; struct BorrowSnapshot { uint principal; uint interestIndex; } mapping(address => BorrowSnapshot) internal accountBorrows; uint public constant protocolSeizeShareMantissa = 2.8e16; } abstract contract CTokenInterface is CTokenStorage { bool public constant isCToken = true; event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows); event Mint(address minter, uint mintAmount, uint mintTokens); event Redeem(address redeemer, uint redeemAmount, uint redeemTokens); event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows); event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows); event LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address cTokenCollateral, uint seizeTokens); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); event NewAdmin(address oldAdmin, address newAdmin); event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller); event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel); event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa); event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves); event ReservesReduced(address admin, uint reduceAmount, uint newTotalReserves); event Transfer(address indexed from, address indexed to, uint amount); event Approval(address indexed owner, address indexed spender, uint amount); function transfer(address dst, uint amount) virtual external returns (bool); function transferFrom(address src, address dst, uint amount) virtual external returns (bool); function approve(address spender, uint amount) virtual external returns (bool); function allowance(address owner, address spender) virtual external view returns (uint); function balanceOf(address owner) virtual external view returns (uint); function balanceOfUnderlying(address owner) virtual external returns (uint); function getAccountSnapshot(address account) virtual external view returns (uint, uint, uint, uint); function borrowRatePerBlock() virtual external view returns (uint); function supplyRatePerBlock() virtual external view returns (uint); function totalBorrowsCurrent() virtual external returns (uint); function borrowBalanceCurrent(address account) virtual external returns (uint); function borrowBalanceStored(address account) virtual external view returns (uint); function exchangeRateCurrent() virtual external returns (uint); function exchangeRateStored() virtual external view returns (uint); function getCash() virtual external view returns (uint); function accrueInterest() virtual external returns (uint); function seize(address liquidator, address borrower, uint seizeTokens) virtual external returns (uint); function _setPendingAdmin(address payable newPendingAdmin) virtual external returns (uint); function _acceptAdmin() virtual external returns (uint); function _setComptroller(ComptrollerInterface newComptroller) virtual external returns (uint); function _setReserveFactor(uint newReserveFactorMantissa) virtual external returns (uint); function _reduceReserves(uint reduceAmount) virtual external returns (uint); function _setInterestRateModel(InterestRateModel newInterestRateModel) virtual external returns (uint); } contract CErc20Storage { address public underlying; } abstract contract CErc20Interface is CErc20Storage { function mint(uint mintAmount) virtual external returns (uint); function redeem(uint redeemTokens) virtual external returns (uint); function redeemUnderlying(uint redeemAmount) virtual external returns (uint); function borrow(uint borrowAmount) virtual external returns (uint); function repayBorrow(uint repayAmount) virtual external returns (uint); function repayBorrowBehalf(address borrower, uint repayAmount) virtual external returns (uint); function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) virtual external returns (uint); function sweepToken(EIP20NonStandardInterface token) virtual external; function _addReserves(uint addAmount) virtual external returns (uint); } contract CDelegationStorage { address public implementation; } abstract contract CDelegatorInterface is CDelegationStorage { event NewImplementation(address oldImplementation, address newImplementation); function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData) virtual external; } abstract contract CDelegateInterface is CDelegationStorage { function _becomeImplementation(bytes memory data) virtual external; function _resignImplementation() virtual external; } interface EIP20Interface { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256 balance); function transfer(address dst, uint256 amount) external returns (bool success); function transferFrom(address src, address dst, uint256 amount) external returns (bool success); function approve(address spender, uint256 amount) external returns (bool success); function allowance(address owner, address spender) external view returns (uint256 remaining); event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); } contract ExponentialNoError { uint constant expScale = 1e18; uint constant doubleScale = 1e36; uint constant halfExpScale = expScale/2; uint constant mantissaOne = expScale; struct Exp { uint mantissa; } struct Double { uint mantissa; } function truncate(Exp memory exp) pure internal returns (uint) { return exp.mantissa / expScale; } function mul_ScalarTruncate(Exp memory a, uint scalar) pure internal returns (uint) { Exp memory product = mul_(a, scalar); return truncate(product); } function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (uint) { Exp memory product = mul_(a, scalar); return add_(truncate(product), addend); } function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa < right.mantissa; } function lessThanOrEqualExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa <= right.mantissa; } function greaterThanExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa > right.mantissa; } function isZeroExp(Exp memory value) pure internal returns (bool) { return value.mantissa == 0; } function safe224(uint n, string memory errorMessage) pure internal returns (uint224) { require(n < 2**224, errorMessage); return uint224(n); } function safe32(uint n, string memory errorMessage) pure internal returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function add_(Exp memory a, Exp memory b) pure internal returns (Exp memory) { return Exp({mantissa: add_(a.mantissa, b.mantissa)}); } function add_(Double memory a, Double memory b) pure internal returns (Double memory) { return Double({mantissa: add_(a.mantissa, b.mantissa)}); } function add_(uint a, uint b) pure internal returns (uint) { return a + b; } function sub_(Exp memory a, Exp memory b) pure internal returns (Exp memory) { return Exp({mantissa: sub_(a.mantissa, b.mantissa)}); } function sub_(Double memory a, Double memory b) pure internal returns (Double memory) { return Double({mantissa: sub_(a.mantissa, b.mantissa)}); } function sub_(uint a, uint b) pure internal returns (uint) { return a - b; } function mul_(Exp memory a, Exp memory b) pure internal returns (Exp memory) { return Exp({mantissa: mul_(a.mantissa, b.mantissa) / expScale}); } function mul_(Exp memory a, uint b) pure internal returns (Exp memory) { return Exp({mantissa: mul_(a.mantissa, b)}); } function mul_(uint a, Exp memory b) pure internal returns (uint) { return mul_(a, b.mantissa) / expScale; } function mul_(Double memory a, Double memory b) pure internal returns (Double memory) { return Double({mantissa: mul_(a.mantissa, b.mantissa) / doubleScale}); } function mul_(Double memory a, uint b) pure internal returns (Double memory) { return Double({mantissa: mul_(a.mantissa, b)}); } function mul_(uint a, Double memory b) pure internal returns (uint) { return mul_(a, b.mantissa) / doubleScale; } function mul_(uint a, uint b) pure internal returns (uint) { return a * b; } function div_(Exp memory a, Exp memory b) pure internal returns (Exp memory) { return Exp({mantissa: div_(mul_(a.mantissa, expScale), b.mantissa)}); } function div_(Exp memory a, uint b) pure internal returns (Exp memory) { return Exp({mantissa: div_(a.mantissa, b)}); } function div_(uint a, Exp memory b) pure internal returns (uint) { return div_(mul_(a, expScale), b.mantissa); } function div_(Double memory a, Double memory b) pure internal returns (Double memory) { return Double({mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa)}); } function div_(Double memory a, uint b) pure internal returns (Double memory) { return Double({mantissa: div_(a.mantissa, b)}); } function div_(uint a, Double memory b) pure internal returns (uint) { return div_(mul_(a, doubleScale), b.mantissa); } function div_(uint a, uint b) pure internal returns (uint) { return a / b; } function fraction(uint a, uint b) pure internal returns (Double memory) { return Double({mantissa: div_(mul_(a, doubleScale), b)}); } } abstract contract CToken is CTokenInterface, ExponentialNoError, TokenErrorReporter { function initialize(ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, string memory symbol_, uint8 decimals_) public { require(msg.sender == admin, "only admin may initialize the market"); require(accrualBlockNumber == 0 && borrowIndex == 0, "market may only be initialized once"); initialExchangeRateMantissa = initialExchangeRateMantissa_; require(initialExchangeRateMantissa > 0, "initial exchange rate must be greater than zero."); uint err = _setComptroller(comptroller_); require(err == NO_ERROR, "setting comptroller failed"); accrualBlockNumber = getBlockNumber(); borrowIndex = mantissaOne; err = _setInterestRateModelFresh(interestRateModel_); require(err == NO_ERROR, "setting interest rate model failed"); name = name_; symbol = symbol_; decimals = decimals_; _notEntered = true; } function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) { uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens); if (allowed != 0) { revert TransferComptrollerRejection(allowed); } if (src == dst) { revert TransferNotAllowed(); } uint startingAllowance = 0; if (spender == src) { startingAllowance = type(uint).max; } else { startingAllowance = transferAllowances[src][spender]; } uint allowanceNew = startingAllowance - tokens; uint srcTokensNew = accountTokens[src] - tokens; uint dstTokensNew = accountTokens[dst] + tokens; accountTokens[src] = srcTokensNew; accountTokens[dst] = dstTokensNew; if (startingAllowance != type(uint).max) { transferAllowances[src][spender] = allowanceNew; } emit Transfer(src, dst, tokens); return NO_ERROR; } function transfer(address dst, uint256 amount) override external nonReentrant returns (bool) { return transferTokens(msg.sender, msg.sender, dst, amount) == NO_ERROR; } function transferFrom(address src, address dst, uint256 amount) override external nonReentrant returns (bool) { return transferTokens(msg.sender, src, dst, amount) == NO_ERROR; } function approve(address spender, uint256 amount) override external returns (bool) { address src = msg.sender; transferAllowances[src][spender] = amount; emit Approval(src, spender, amount); return true; } function allowance(address owner, address spender) override external view returns (uint256) { return transferAllowances[owner][spender]; } function balanceOf(address owner) override external view returns (uint256) { return accountTokens[owner]; } function balanceOfUnderlying(address owner) override external returns (uint) { Exp memory exchangeRate = Exp({mantissa: exchangeRateCurrent()}); return mul_ScalarTruncate(exchangeRate, accountTokens[owner]); } function getAccountSnapshot(address account) override external view returns (uint, uint, uint, uint) { return ( NO_ERROR, accountTokens[account], borrowBalanceStoredInternal(account), exchangeRateStoredInternal() ); } function getBlockNumber() virtual internal view returns (uint) { return block.number; } function borrowRatePerBlock() override external view returns (uint) { return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves); } function supplyRatePerBlock() override external view returns (uint) { return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa); } function totalBorrowsCurrent() override external nonReentrant returns (uint) { accrueInterest(); return totalBorrows; } function borrowBalanceCurrent(address account) override external nonReentrant returns (uint) { accrueInterest(); return borrowBalanceStored(account); } function borrowBalanceStored(address account) override public view returns (uint) { return borrowBalanceStoredInternal(account); } function borrowBalanceStoredInternal(address account) internal view returns (uint) { BorrowSnapshot storage borrowSnapshot = accountBorrows[account]; if (borrowSnapshot.principal == 0) { return 0; } uint principalTimesIndex = borrowSnapshot.principal * borrowIndex; return principalTimesIndex / borrowSnapshot.interestIndex; } function exchangeRateCurrent() override public nonReentrant returns (uint) { accrueInterest(); return exchangeRateStored(); } function exchangeRateStored() override public view returns (uint) { return exchangeRateStoredInternal(); } function exchangeRateStoredInternal() virtual internal view returns (uint) { uint _totalSupply = totalSupply; if (_totalSupply == 0) { return initialExchangeRateMantissa; } else { uint totalCash = getCashPrior(); uint cashPlusBorrowsMinusReserves = totalCash + totalBorrows - totalReserves; uint exchangeRate = cashPlusBorrowsMinusReserves * expScale / _totalSupply; return exchangeRate; } } function getCash() override external view returns (uint) { return getCashPrior(); } function accrueInterest() virtual override public returns (uint) { uint currentBlockNumber = getBlockNumber(); uint accrualBlockNumberPrior = accrualBlockNumber; if (accrualBlockNumberPrior == currentBlockNumber) { return NO_ERROR; } uint cashPrior = getCashPrior(); uint borrowsPrior = totalBorrows; uint reservesPrior = totalReserves; uint borrowIndexPrior = borrowIndex; uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior); require(borrowRateMantissa <= borrowRateMaxMantissa, "borrow rate is absurdly high"); uint blockDelta = currentBlockNumber - accrualBlockNumberPrior; Exp memory simpleInterestFactor = mul_(Exp({mantissa: borrowRateMantissa}), blockDelta); uint interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior); uint totalBorrowsNew = interestAccumulated + borrowsPrior; uint totalReservesNew = mul_ScalarTruncateAddUInt(Exp({mantissa: reserveFactorMantissa}), interestAccumulated, reservesPrior); uint borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior); accrualBlockNumber = currentBlockNumber; borrowIndex = borrowIndexNew; totalBorrows = totalBorrowsNew; totalReserves = totalReservesNew; emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew); return NO_ERROR; } function mintInternal(uint mintAmount) internal nonReentrant { accrueInterest(); mintFresh(msg.sender, mintAmount); } function mintFresh(address minter, uint mintAmount) internal { uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount); if (allowed != 0) { revert MintComptrollerRejection(allowed); } if (accrualBlockNumber != getBlockNumber()) { revert MintFreshnessCheck(); } Exp memory exchangeRate = Exp({mantissa: exchangeRateStoredInternal()}); uint actualMintAmount = doTransferIn(minter, mintAmount); uint mintTokens = div_(actualMintAmount, exchangeRate); totalSupply = totalSupply + mintTokens; accountTokens[minter] = accountTokens[minter] + mintTokens; emit Mint(minter, actualMintAmount, mintTokens); emit Transfer(address(this), minter, mintTokens); } function redeemInternal(uint redeemTokens) internal nonReentrant { accrueInterest(); redeemFresh(payable(msg.sender), redeemTokens, 0); } function redeemUnderlyingInternal(uint redeemAmount) internal nonReentrant { accrueInterest(); redeemFresh(payable(msg.sender), 0, redeemAmount); } function redeemFresh(address payable redeemer, uint redeemTokensIn, uint redeemAmountIn) internal { require(redeemTokensIn == 0 || redeemAmountIn == 0, "one of redeemTokensIn or redeemAmountIn must be zero"); Exp memory exchangeRate = Exp({mantissa: exchangeRateStoredInternal() }); uint redeemTokens; uint redeemAmount; if (redeemTokensIn > 0) { redeemTokens = redeemTokensIn; redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokensIn); } else { redeemTokens = div_(redeemAmountIn, exchangeRate); redeemAmount = redeemAmountIn; } uint allowed = comptroller.redeemAllowed(address(this), redeemer, redeemTokens); if (allowed != 0) { revert RedeemComptrollerRejection(allowed); } if (accrualBlockNumber != getBlockNumber()) { revert RedeemFreshnessCheck(); } if (getCashPrior() < redeemAmount) { revert RedeemTransferOutNotPossible(); } totalSupply = totalSupply - redeemTokens; accountTokens[redeemer] = accountTokens[redeemer] - redeemTokens; doTransferOut(redeemer, redeemAmount); emit Transfer(redeemer, address(this), redeemTokens); emit Redeem(redeemer, redeemAmount, redeemTokens); comptroller.redeemVerify(address(this), redeemer, redeemAmount, redeemTokens); } function borrowInternal(uint borrowAmount) internal nonReentrant { accrueInterest(); borrowFresh(payable(msg.sender), borrowAmount); } function borrowFresh(address payable borrower, uint borrowAmount) internal { uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount); if (allowed != 0) { revert BorrowComptrollerRejection(allowed); } if (accrualBlockNumber != getBlockNumber()) { revert BorrowFreshnessCheck(); } if (getCashPrior() < borrowAmount) { revert BorrowCashNotAvailable(); } uint accountBorrowsPrev = borrowBalanceStoredInternal(borrower); uint accountBorrowsNew = accountBorrowsPrev + borrowAmount; uint totalBorrowsNew = totalBorrows + borrowAmount; accountBorrows[borrower].principal = accountBorrowsNew; accountBorrows[borrower].interestIndex = borrowIndex; totalBorrows = totalBorrowsNew; doTransferOut(borrower, borrowAmount); emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew); } function repayBorrowInternal(uint repayAmount) internal nonReentrant { accrueInterest(); repayBorrowFresh(msg.sender, msg.sender, repayAmount); } function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant { accrueInterest(); repayBorrowFresh(msg.sender, borrower, repayAmount); } function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint) { uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount); if (allowed != 0) { revert RepayBorrowComptrollerRejection(allowed); } if (accrualBlockNumber != getBlockNumber()) { revert RepayBorrowFreshnessCheck(); } uint accountBorrowsPrev = borrowBalanceStoredInternal(borrower); uint repayAmountFinal = repayAmount == type(uint).max ? accountBorrowsPrev : repayAmount; uint actualRepayAmount = doTransferIn(payer, repayAmountFinal); uint accountBorrowsNew = accountBorrowsPrev - actualRepayAmount; uint totalBorrowsNew = totalBorrows - actualRepayAmount; accountBorrows[borrower].principal = accountBorrowsNew; accountBorrows[borrower].interestIndex = borrowIndex; totalBorrows = totalBorrowsNew; emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew); return actualRepayAmount; } function liquidateBorrowInternal(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) internal nonReentrant { accrueInterest(); uint error = cTokenCollateral.accrueInterest(); if (error != NO_ERROR) { revert LiquidateAccrueCollateralInterestFailed(error); } liquidateBorrowFresh(msg.sender, borrower, repayAmount, cTokenCollateral); } function liquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CTokenInterface cTokenCollateral) internal { uint allowed = comptroller.liquidateBorrowAllowed(address(this), address(cTokenCollateral), liquidator, borrower, repayAmount); if (allowed != 0) { revert LiquidateComptrollerRejection(allowed); } if (accrualBlockNumber != getBlockNumber()) { revert LiquidateFreshnessCheck(); } if (cTokenCollateral.accrualBlockNumber() != getBlockNumber()) { revert LiquidateCollateralFreshnessCheck(); } if (borrower == liquidator) { revert LiquidateLiquidatorIsBorrower(); } if (repayAmount == 0) { revert LiquidateCloseAmountIsZero(); } if (repayAmount == type(uint).max) { revert LiquidateCloseAmountIsUintMax(); } uint actualRepayAmount = repayBorrowFresh(liquidator, borrower, repayAmount); (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(address(this), address(cTokenCollateral), actualRepayAmount); require(amountSeizeError == NO_ERROR, "LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED"); require(cTokenCollateral.balanceOf(borrower) >= seizeTokens, "LIQUIDATE_SEIZE_TOO_MUCH"); if (address(cTokenCollateral) == address(this)) { seizeInternal(address(this), liquidator, borrower, seizeTokens); } else { require(cTokenCollateral.seize(liquidator, borrower, seizeTokens) == NO_ERROR, "token seizure failed"); } emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(cTokenCollateral), seizeTokens); } function seize(address liquidator, address borrower, uint seizeTokens) override external nonReentrant returns (uint) { seizeInternal(msg.sender, liquidator, borrower, seizeTokens); return NO_ERROR; } function seizeInternal(address seizerToken, address liquidator, address borrower, uint seizeTokens) internal { uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens); if (allowed != 0) { revert LiquidateSeizeComptrollerRejection(allowed); } if (borrower == liquidator) { revert LiquidateSeizeLiquidatorIsBorrower(); } uint protocolSeizeTokens = mul_(seizeTokens, Exp({mantissa: protocolSeizeShareMantissa})); uint liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens; Exp memory exchangeRate = Exp({mantissa: exchangeRateStoredInternal()}); uint protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens); uint totalReservesNew = totalReserves + protocolSeizeAmount; totalReserves = totalReservesNew; totalSupply = totalSupply - protocolSeizeTokens; accountTokens[borrower] = accountTokens[borrower] - seizeTokens; accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens; emit Transfer(borrower, liquidator, liquidatorSeizeTokens); emit Transfer(borrower, address(this), protocolSeizeTokens); emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew); } function _setPendingAdmin(address payable newPendingAdmin) override external returns (uint) { if (msg.sender != admin) { revert SetPendingAdminOwnerCheck(); } address oldPendingAdmin = pendingAdmin; pendingAdmin = newPendingAdmin; emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin); return NO_ERROR; } function _acceptAdmin() override external returns (uint) { if (msg.sender != pendingAdmin || msg.sender == address(0)) { revert AcceptAdminPendingAdminCheck(); } address oldAdmin = admin; address oldPendingAdmin = pendingAdmin; admin = pendingAdmin; pendingAdmin = payable(address(0)); emit NewAdmin(oldAdmin, admin); emit NewPendingAdmin(oldPendingAdmin, pendingAdmin); return NO_ERROR; } function _setComptroller(ComptrollerInterface newComptroller) override public returns (uint) { if (msg.sender != admin) { revert SetComptrollerOwnerCheck(); } ComptrollerInterface oldComptroller = comptroller; require(newComptroller.isComptroller(), "marker method returned false"); comptroller = newComptroller; emit NewComptroller(oldComptroller, newComptroller); return NO_ERROR; } function _setReserveFactor(uint newReserveFactorMantissa) override external nonReentrant returns (uint) { accrueInterest(); return _setReserveFactorFresh(newReserveFactorMantissa); } function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) { if (msg.sender != admin) { revert SetReserveFactorAdminCheck(); } if (accrualBlockNumber != getBlockNumber()) { revert SetReserveFactorFreshCheck(); } if (newReserveFactorMantissa > reserveFactorMaxMantissa) { revert SetReserveFactorBoundsCheck(); } uint oldReserveFactorMantissa = reserveFactorMantissa; reserveFactorMantissa = newReserveFactorMantissa; emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa); return NO_ERROR; } function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) { accrueInterest(); _addReservesFresh(addAmount); return NO_ERROR; } function _addReservesFresh(uint addAmount) internal returns (uint, uint) { uint totalReservesNew; uint actualAddAmount; if (accrualBlockNumber != getBlockNumber()) { revert AddReservesFactorFreshCheck(actualAddAmount); } actualAddAmount = doTransferIn(msg.sender, addAmount); totalReservesNew = totalReserves + actualAddAmount; totalReserves = totalReservesNew; emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew); return (NO_ERROR, actualAddAmount); } function _reduceReserves(uint reduceAmount) override external nonReentrant returns (uint) { accrueInterest(); return _reduceReservesFresh(reduceAmount); } function _reduceReservesFresh(uint reduceAmount) internal returns (uint) { uint totalReservesNew; if (msg.sender != admin) { revert ReduceReservesAdminCheck(); } if (accrualBlockNumber != getBlockNumber()) { revert ReduceReservesFreshCheck(); } if (getCashPrior() < reduceAmount) { revert ReduceReservesCashNotAvailable(); } if (reduceAmount > totalReserves) { revert ReduceReservesCashValidation(); } totalReservesNew = totalReserves - reduceAmount; totalReserves = totalReservesNew; doTransferOut(admin, reduceAmount); emit ReservesReduced(admin, reduceAmount, totalReservesNew); return NO_ERROR; } function _setInterestRateModel(InterestRateModel newInterestRateModel) override public returns (uint) { accrueInterest(); return _setInterestRateModelFresh(newInterestRateModel); } function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) { InterestRateModel oldInterestRateModel; if (msg.sender != admin) { revert SetInterestRateModelOwnerCheck(); } if (accrualBlockNumber != getBlockNumber()) { revert SetInterestRateModelFreshCheck(); } oldInterestRateModel = interestRateModel; require(newInterestRateModel.isInterestRateModel(), "marker method returned false"); interestRateModel = newInterestRateModel; emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel); return NO_ERROR; } function getCashPrior() virtual internal view returns (uint); function doTransferIn(address from, uint amount) virtual internal returns (uint); function doTransferOut(address payable to, uint amount) virtual internal; modifier nonReentrant() { require(_notEntered, "re-entered"); _notEntered = false; _; _notEntered = true; } } contract UnitrollerAdminStorage { address public admin; address public pendingAdmin; address public comptrollerImplementation; address public pendingComptrollerImplementation; } contract ComptrollerV1Storage is UnitrollerAdminStorage { uint public closeFactorMantissa; uint public liquidationIncentiveMantissa; uint public maxAssets; mapping(address => CToken[]) public accountAssets; } contract ComptrollerV2Storage is ComptrollerV1Storage { struct Market { bool isListed; uint collateralFactorMantissa; mapping(address => bool) accountMembership; bool isComped; } mapping(address => Market) public markets; address public pauseGuardian; bool public _mintGuardianPaused; bool public _borrowGuardianPaused; bool public transferGuardianPaused; bool public seizeGuardianPaused; mapping(address => bool) public mintGuardianPaused; mapping(address => bool) public borrowGuardianPaused; } contract ComptrollerV3Storage is ComptrollerV2Storage { struct CompMarketState { uint224 index; uint32 block; } CToken[] public allMarkets; uint public compRate; mapping(address => uint) public compSpeeds; mapping(address => CompMarketState) public compSupplyState; mapping(address => CompMarketState) public compBorrowState; mapping(address => mapping(address => uint)) public compSupplierIndex; mapping(address => mapping(address => uint)) public compBorrowerIndex; mapping(address => uint) public compAccrued; } contract ComptrollerV4Storage is ComptrollerV3Storage { address public borrowCapGuardian; mapping(address => uint) public borrowCaps; } contract ComptrollerV5Storage is ComptrollerV4Storage { mapping(address => uint) public compContributorSpeeds; mapping(address => uint) public lastContributorBlock; } contract ComptrollerV6Storage is ComptrollerV5Storage { mapping(address => uint) public compBorrowSpeeds; mapping(address => uint) public compSupplySpeeds; } contract ComptrollerV7Storage is ComptrollerV6Storage { bool public proposal65FixExecuted; mapping(address => uint) public compReceivable; } contract Unitroller is UnitrollerAdminStorage, ComptrollerErrorReporter { event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation); event NewImplementation(address oldImplementation, address newImplementation); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); event NewAdmin(address oldAdmin, address newAdmin); constructor() public { admin = msg.sender; } function _setPendingImplementation(address newPendingImplementation) public returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK); } address oldPendingImplementation = pendingComptrollerImplementation; pendingComptrollerImplementation = newPendingImplementation; emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation); return uint(Error.NO_ERROR); } function _acceptImplementation() public returns (uint) { if (msg.sender != pendingComptrollerImplementation || pendingComptrollerImplementation == address(0)) { return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK); } address oldImplementation = comptrollerImplementation; address oldPendingImplementation = pendingComptrollerImplementation; comptrollerImplementation = pendingComptrollerImplementation; pendingComptrollerImplementation = address(0); emit NewImplementation(oldImplementation, comptrollerImplementation); emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation); return uint(Error.NO_ERROR); } function _setPendingAdmin(address newPendingAdmin) public returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK); } address oldPendingAdmin = pendingAdmin; pendingAdmin = newPendingAdmin; emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin); return uint(Error.NO_ERROR); } function _acceptAdmin() public returns (uint) { if (msg.sender != pendingAdmin || msg.sender == address(0)) { return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK); } address oldAdmin = admin; address oldPendingAdmin = pendingAdmin; admin = pendingAdmin; pendingAdmin = address(0); emit NewAdmin(oldAdmin, admin); emit NewPendingAdmin(oldPendingAdmin, pendingAdmin); return uint(Error.NO_ERROR); } fallback() payable external { (bool success, ) = comptrollerImplementation.delegatecall(msg.data); assembly { let free_mem_ptr := mload(0x40) returndatacopy(free_mem_ptr, 0, returndatasize()) switch success case 0 { revert(free_mem_ptr, returndatasize()) } default { return(free_mem_ptr, returndatasize()) } } } } interface CompLike { function delegate(address delegatee) external; } contract CErc20 is CToken, CErc20Interface { function initialize(address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, string memory symbol_, uint8 decimals_) public { super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_); underlying = underlying_; EIP20Interface(underlying).totalSupply(); } function mint(uint mintAmount) override external returns (uint) { mintInternal(mintAmount); return NO_ERROR; } function redeem(uint redeemTokens) override external returns (uint) { redeemInternal(redeemTokens); return NO_ERROR; } function redeemUnderlying(uint redeemAmount) override external returns (uint) { redeemUnderlyingInternal(redeemAmount); return NO_ERROR; } function borrow(uint borrowAmount) override external returns (uint) { borrowInternal(borrowAmount); return NO_ERROR; } function repayBorrow(uint repayAmount) override external returns (uint) { repayBorrowInternal(repayAmount); return NO_ERROR; } function repayBorrowBehalf(address borrower, uint repayAmount) override external returns (uint) { repayBorrowBehalfInternal(borrower, repayAmount); return NO_ERROR; } function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) override external returns (uint) { liquidateBorrowInternal(borrower, repayAmount, cTokenCollateral); return NO_ERROR; } function sweepToken(EIP20NonStandardInterface token) override external { require(msg.sender == admin, "CErc20::sweepToken: only admin can sweep tokens"); require(address(token) != underlying, "CErc20::sweepToken: can not sweep underlying token"); uint256 balance = token.balanceOf(address(this)); token.transfer(admin, balance); } function _addReserves(uint addAmount) override external returns (uint) { return _addReservesInternal(addAmount); } function getCashPrior() virtual override internal view returns (uint) { EIP20Interface token = EIP20Interface(underlying); return token.balanceOf(address(this)); } function doTransferIn(address from, uint amount) virtual override internal returns (uint) { address underlying_ = underlying; EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying_); uint balanceBefore = EIP20Interface(underlying_).balanceOf(address(this)); token.transferFrom(from, address(this), amount); bool success; assembly { switch returndatasize() case 0 { success := not(0) } case 32 { returndatacopy(0, 0, 32) success := mload(0) } default { revert(0, 0) } } require(success, "TOKEN_TRANSFER_IN_FAILED"); uint balanceAfter = EIP20Interface(underlying_).balanceOf(address(this)); return balanceAfter - balanceBefore; } function doTransferOut(address payable to, uint amount) virtual override internal { EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying); token.transfer(to, amount); bool success; assembly { switch returndatasize() case 0 { success := not(0) } case 32 { returndatacopy(0, 0, 32) success := mload(0) } default { revert(0, 0) } } require(success, "TOKEN_TRANSFER_OUT_FAILED"); } function _delegateCompLikeTo(address compLikeDelegatee) external { require(msg.sender == admin, "only the admin may set the comp-like delegate"); CompLike(underlying).delegate(compLikeDelegatee); } } contract Comptroller is ComptrollerV7Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError, PrimaryProdDataServiceConsumerBase { event MarketListed(CToken cToken); event MarketEntered(CToken cToken, address account); event MarketExited(CToken cToken, address account); event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian); event ActionPaused(string action, bool pauseState); event ActionPaused(CToken cToken, string action, bool pauseState); event CompBorrowSpeedUpdated(CToken indexed cToken, uint newSpeed); event CompSupplySpeedUpdated(CToken indexed cToken, uint newSpeed); event ContributorCompSpeedUpdated(address indexed contributor, uint newSpeed); event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); event NewBorrowCap(CToken indexed cToken, uint newBorrowCap); event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian); event CompGranted(address recipient, uint amount); event CompAccruedAdjusted(address indexed user, uint oldCompAccrued, uint newCompAccrued); event CompReceivableUpdated(address indexed user, uint oldCompReceivable, uint newCompReceivable); uint224 public constant compInitialIndex = 1e36; uint internal constant closeFactorMinMantissa = 0.05e18; uint internal constant closeFactorMaxMantissa = 0.9e18; uint internal constant collateralFactorMaxMantissa = 0.9e18; constructor() { admin = msg.sender; } function getAssetsIn(address account) external view returns (CToken[] memory) { CToken[] memory assetsIn = accountAssets[account]; return assetsIn; } function checkMembership(address account, CToken cToken) external view returns (bool) { return markets[address(cToken)].accountMembership[account]; } function enterMarkets(address[] memory cTokens) override public returns (uint[] memory) { uint len = cTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { CToken cToken = CToken(cTokens[i]); results[i] = uint(addToMarketInternal(cToken, msg.sender)); } return results; } function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { Market storage marketToJoin = markets[address(cToken)]; if (!marketToJoin.isListed) { return Error.MARKET_NOT_LISTED; } if (marketToJoin.accountMembership[borrower] == true) { return Error.NO_ERROR; } marketToJoin.accountMembership[borrower] = true; accountAssets[borrower].push(cToken); emit MarketEntered(cToken, borrower); return Error.NO_ERROR; } function exitMarket(address cTokenAddress) override external returns (uint) { CToken cToken = CToken(cTokenAddress); (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); if (amountOwed != 0) { return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED); } uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } Market storage marketToExit = markets[address(cToken)]; if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } delete marketToExit.accountMembership[msg.sender]; CToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { if (userAssetList[i] == cToken) { assetIndex = i; break; } } assert(assetIndex < len); CToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.pop(); emit MarketExited(cToken, msg.sender); return uint(Error.NO_ERROR); } function mintAllowed(address cToken, address minter, uint mintAmount) override external returns (uint) { require(!mintGuardianPaused[cToken], "mint is paused"); minter; mintAmount; if (!markets[cToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } return uint(Error.NO_ERROR); } function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) override external { cToken; minter; actualMintAmount; mintTokens; if (false) { maxAssets = maxAssets; } } function redeemAllowed(address cToken, address redeemer, uint redeemTokens) override external returns (uint) { uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } return uint(Error.NO_ERROR); } function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { if (!markets[cToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } if (!markets[cToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } if (shortfall > 0) { return uint(Error.INSUFFICIENT_LIQUIDITY); } return uint(Error.NO_ERROR); } function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) override external { cToken; redeemer; if (redeemTokens == 0 && redeemAmount > 0) { revert("redeemTokens zero"); } } function getUnderlyingPrice(CToken cToken) public view returns (uint) { uint256 ethPrice; bytes32 asset; if (keccak256(abi.encodePacked(cToken.symbol())) == keccak256(abi.encodePacked("cETH"))) { ethPrice = getOracleNumericValueFromTxMsg(bytes32("ETH")); } else if (keccak256(abi.encodePacked(cToken.symbol())) == keccak256(abi.encodePacked("cWETH"))) { ethPrice = getOracleNumericValueFromTxMsg(bytes32("ETH")); } else if (keccak256(abi.encodePacked(cToken.symbol())) == keccak256(abi.encodePacked("cUSDC"))) { ethPrice = getOracleNumericValueFromTxMsg(bytes32("USDC")) * 1e12; } else if (keccak256(abi.encodePacked(cToken.symbol())) == keccak256(abi.encodePacked("cUSDT"))) { ethPrice = getOracleNumericValueFromTxMsg(bytes32("USDT")) * 1e12; } else if (keccak256(abi.encodePacked(cToken.symbol())) == keccak256(abi.encodePacked("cWBTC"))) { ethPrice = getOracleNumericValueFromTxMsg(bytes32("BTC")) * 1e10; } else { string memory underlyingSymbol = EIP20Interface(address(CErc20(address(cToken)).underlying())).symbol(); bytes32 result; bytes memory tempEmptyStringTest = bytes(underlyingSymbol); if (tempEmptyStringTest.length == 0) { result = 0x0; } assembly { result := mload(add(underlyingSymbol, 32)) } asset = bytes32(result); ethPrice = getOracleNumericValueFromTxMsg(asset); } return ethPrice; } function borrowAllowed(address cToken, address borrower, uint borrowAmount) override external returns (uint) { require(!borrowGuardianPaused[cToken], "borrow is paused"); if (!markets[cToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } if (!markets[cToken].accountMembership[borrower]) { require(msg.sender == cToken, "sender must be cToken"); Error err = addToMarketInternal(CToken(msg.sender), borrower); if (err != Error.NO_ERROR) { return uint(err); } assert(markets[cToken].accountMembership[borrower]); } if (getUnderlyingPrice(CToken(cToken)) == 0) { return uint(Error.PRICE_ERROR); } uint borrowCap = borrowCaps[cToken]; if (borrowCap != 0) { uint totalBorrows = CToken(cToken).totalBorrows(); uint nextTotalBorrows = add_(totalBorrows, borrowAmount); require(nextTotalBorrows < borrowCap, "market borrow cap reached"); } (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } if (shortfall > 0) { return uint(Error.INSUFFICIENT_LIQUIDITY); } return uint(Error.NO_ERROR); } function borrowVerify(address cToken, address borrower, uint borrowAmount) override external { cToken; borrower; borrowAmount; if (false) { maxAssets = maxAssets; } } function repayBorrowAllowed( address cToken, address payer, address borrower, uint repayAmount) override external returns (uint) { payer; borrower; repayAmount; if (!markets[cToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } return uint(Error.NO_ERROR); } function repayBorrowVerify( address cToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) override external { cToken; payer; borrower; actualRepayAmount; borrowerIndex; if (false) { maxAssets = maxAssets; } } function liquidateBorrowAllowed( address cTokenBorrowed, address cTokenCollateral, address liquidator, address borrower, uint repayAmount) override external returns (uint) { liquidator; if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); if (isDeprecated(CToken(cTokenBorrowed))) { require(borrowBalance >= repayAmount, "Can not repay more than the total borrow"); } else { (Error err, , uint shortfall) = getAccountLiquidityInternal(borrower); if (err != Error.NO_ERROR) { return uint(err); } if (shortfall == 0) { return uint(Error.INSUFFICIENT_SHORTFALL); } uint maxClose = mul_ScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (repayAmount > maxClose) { return uint(Error.TOO_MUCH_REPAY); } } return uint(Error.NO_ERROR); } function liquidateBorrowVerify( address cTokenBorrowed, address cTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) override external { cTokenBorrowed; cTokenCollateral; liquidator; borrower; actualRepayAmount; seizeTokens; if (false) { maxAssets = maxAssets; } } function seizeAllowed( address cTokenCollateral, address cTokenBorrowed, address liquidator, address borrower, uint seizeTokens) override external returns (uint) { require(!seizeGuardianPaused, "seize is paused"); seizeTokens; if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } return uint(Error.NO_ERROR); } function seizeVerify( address cTokenCollateral, address cTokenBorrowed, address liquidator, address borrower, uint seizeTokens) override external { cTokenCollateral; cTokenBorrowed; liquidator; borrower; seizeTokens; if (false) { maxAssets = maxAssets; } } function transferAllowed(address cToken, address src, address dst, uint transferTokens) override external returns (uint) { require(!transferGuardianPaused, "transfer is paused"); uint allowed = redeemAllowedInternal(cToken, src, transferTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } return uint(Error.NO_ERROR); } function transferVerify(address cToken, address src, address dst, uint transferTokens) override external { cToken; src; dst; transferTokens; if (false) { maxAssets = maxAssets; } } struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; uint cTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; Exp collateralFactor; Exp exchangeRate; Exp oraclePrice; Exp tokensToDenom; } function getAccountLiquidity(address account) public view returns (uint, uint, uint) { (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(address(0)), 0, 0); return (uint(err), liquidity, shortfall); } function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { return getHypotheticalAccountLiquidityInternal(account, CToken(address(0)), 0, 0); } function getHypotheticalAccountLiquidity( address account, address cTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } function getHypotheticalAccountLiquidityInternal( address account, CToken cTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { AccountLiquidityLocalVars memory vars; uint oErr; CToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { CToken asset = assets[i]; (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { return (Error.SNAPSHOT_ERROR, 0, 0); } vars.collateralFactor = Exp({mantissa: markets[address(asset)].collateralFactorMantissa}); vars.exchangeRate = Exp({mantissa: vars.exchangeRateMantissa}); vars.oraclePriceMantissa = getUnderlyingPrice(asset); if (vars.oraclePriceMantissa == 0) { return (Error.PRICE_ERROR, 0, 0); } vars.oraclePrice = Exp({mantissa: vars.oraclePriceMantissa}); vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice); vars.sumCollateral = mul_ScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, vars.borrowBalance, vars.sumBorrowPlusEffects); if (asset == cTokenModify) { vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, borrowAmount, vars.sumBorrowPlusEffects); } } if (vars.sumCollateral > vars.sumBorrowPlusEffects) { return (Error.NO_ERROR, vars.sumCollateral - vars.sumBorrowPlusEffects, 0); } else { return (Error.NO_ERROR, 0, vars.sumBorrowPlusEffects - vars.sumCollateral); } } function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) override external view returns (uint, uint) { uint priceBorrowedMantissa = getUnderlyingPrice(CToken(cTokenBorrowed)); uint priceCollateralMantissa = getUnderlyingPrice(CToken(cTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); uint seizeTokens; Exp memory numerator; Exp memory denominator; Exp memory ratio; numerator = mul_(Exp({mantissa: liquidationIncentiveMantissa}), Exp({mantissa: priceBorrowedMantissa})); denominator = mul_(Exp({mantissa: priceCollateralMantissa}), Exp({mantissa: exchangeRateMantissa})); ratio = div_(numerator, denominator); seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount); return (uint(Error.NO_ERROR), seizeTokens); } function _setCloseFactor(uint newCloseFactorMantissa) external returns (uint) { require(msg.sender == admin, "only admin can set close factor"); uint oldCloseFactorMantissa = closeFactorMantissa; closeFactorMantissa = newCloseFactorMantissa; emit NewCloseFactor(oldCloseFactorMantissa, closeFactorMantissa); return uint(Error.NO_ERROR); } function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } Market storage market = markets[address(cToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } Exp memory newCollateralFactorExp = Exp({mantissa: newCollateralFactorMantissa}); Exp memory highLimit = Exp({mantissa: collateralFactorMaxMantissa}); if (lessThanExp(highLimit, newCollateralFactorExp)) { return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION); } if (newCollateralFactorMantissa != 0 && getUnderlyingPrice(cToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } uint oldCollateralFactorMantissa = market.collateralFactorMantissa; market.collateralFactorMantissa = newCollateralFactorMantissa; emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } function _setLiquidationIncentive(uint newLiquidationIncentiveMantissa) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_LIQUIDATION_INCENTIVE_OWNER_CHECK); } uint oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa; liquidationIncentiveMantissa = newLiquidationIncentiveMantissa; emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa); return uint(Error.NO_ERROR); } function _supportMarket(CToken cToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } if (markets[address(cToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } cToken.isCToken(); Market storage newMarket = markets[address(cToken)]; newMarket.isListed = true; newMarket.isComped = false; newMarket.collateralFactorMantissa = 0; _addMarketInternal(address(cToken)); _initializeMarket(address(cToken)); emit MarketListed(cToken); return uint(Error.NO_ERROR); } function _addMarketInternal(address cToken) internal { for (uint i = 0; i < allMarkets.length; i ++) { require(allMarkets[i] != CToken(cToken), "market already added"); } allMarkets.push(CToken(cToken)); } function _initializeMarket(address cToken) internal { uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits"); CompMarketState storage supplyState = compSupplyState[cToken]; CompMarketState storage borrowState = compBorrowState[cToken]; if (supplyState.index == 0) { supplyState.index = compInitialIndex; } if (borrowState.index == 0) { borrowState.index = compInitialIndex; } supplyState.block = borrowState.block = blockNumber; } function _setMarketBorrowCaps(CToken[] calldata cTokens, uint[] calldata newBorrowCaps) external { require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps"); uint numMarkets = cTokens.length; uint numBorrowCaps = newBorrowCaps.length; require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input"); for(uint i = 0; i < numMarkets; i++) { borrowCaps[address(cTokens[i])] = newBorrowCaps[i]; emit NewBorrowCap(cTokens[i], newBorrowCaps[i]); } } function _setBorrowCapGuardian(address newBorrowCapGuardian) external { require(msg.sender == admin, "only admin can set borrow cap guardian"); address oldBorrowCapGuardian = borrowCapGuardian; borrowCapGuardian = newBorrowCapGuardian; emit NewBorrowCapGuardian(oldBorrowCapGuardian, newBorrowCapGuardian); } function _setPauseGuardian(address newPauseGuardian) public returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_PAUSE_GUARDIAN_OWNER_CHECK); } address oldPauseGuardian = pauseGuardian; pauseGuardian = newPauseGuardian; emit NewPauseGuardian(oldPauseGuardian, pauseGuardian); return uint(Error.NO_ERROR); } function _setMintPaused(CToken cToken, bool state) public returns (bool) { require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); mintGuardianPaused[address(cToken)] = state; emit ActionPaused(cToken, "Mint", state); return state; } function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); borrowGuardianPaused[address(cToken)] = state; emit ActionPaused(cToken, "Borrow", state); return state; } function _setTransferPaused(bool state) public returns (bool) { require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); transferGuardianPaused = state; emit ActionPaused("Transfer", state); return state; } function _setSeizePaused(bool state) public returns (bool) { require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); seizeGuardianPaused = state; emit ActionPaused("Seize", state); return state; } function _become(Unitroller unitroller) public { require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); require(unitroller._acceptImplementation() == 0, "change not authorized"); } function fixBadAccruals(address[] calldata affectedUsers, uint[] calldata amounts) external { require(msg.sender == admin, "Only admin can call this function"); require(!proposal65FixExecuted, "Already executed this one-off function"); require(affectedUsers.length == amounts.length, "Invalid input"); address user; uint currentAccrual; uint amountToSubtract; uint newAccrual; for (uint i = 0; i < affectedUsers.length; ++i) { user = affectedUsers[i]; currentAccrual = compAccrued[user]; amountToSubtract = amounts[i]; if (amountToSubtract > currentAccrual) { uint accountReceivable = amountToSubtract - currentAccrual; uint oldReceivable = compReceivable[user]; uint newReceivable = add_(oldReceivable, accountReceivable); compReceivable[user] = newReceivable; emit CompReceivableUpdated(user, oldReceivable, newReceivable); amountToSubtract = currentAccrual; } if (amountToSubtract > 0) { compAccrued[user] = newAccrual = sub_(currentAccrual, amountToSubtract); emit CompAccruedAdjusted(user, currentAccrual, newAccrual); } } proposal65FixExecuted = true; } function adminOrInitializing() internal view returns (bool) { return msg.sender == admin || msg.sender == comptrollerImplementation; } function getAllMarkets() public view returns (CToken[] memory) { return allMarkets; } function isDeprecated(CToken cToken) public view returns (bool) { return markets[address(cToken)].collateralFactorMantissa == 0 && borrowGuardianPaused[address(cToken)] == true && cToken.reserveFactorMantissa() == 1e18 ; } function getBlockNumber() virtual public view returns (uint) { return block.number; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CalldataMustHaveValidPayload","type":"error"},{"inputs":[],"name":"CalldataOverOrUnderFlow","type":"error"},{"inputs":[],"name":"CanNotPickMedianOfEmptyArray","type":"error"},{"inputs":[],"name":"EachSignerMustProvideTheSameValue","type":"error"},{"inputs":[],"name":"EmptyCalldataPointersArr","type":"error"},{"inputs":[],"name":"GetDataServiceIdNotImplemented","type":"error"},{"inputs":[],"name":"IncorrectUnsignedMetadataSize","type":"error"},{"inputs":[{"internalType":"uint256","name":"receivedSignersCount","type":"uint256"},{"internalType":"uint256","name":"requiredSignersCount","type":"uint256"}],"name":"InsufficientNumberOfUniqueSigners","type":"error"},{"inputs":[],"name":"InvalidCalldataPointer","type":"error"},{"inputs":[{"internalType":"address","name":"receivedSigner","type":"address"}],"name":"SignerNotAuthorised","type":"error"},{"inputs":[{"internalType":"uint256","name":"receivedTimestampSeconds","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"TimestampFromTooLongFuture","type":"error"},{"inputs":[{"internalType":"uint256","name":"receivedTimestampSeconds","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"TimestampIsTooOld","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"action","type":"string"},{"indexed":false,"internalType":"bool","name":"pauseState","type":"bool"}],"name":"ActionPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"string","name":"action","type":"string"},{"indexed":false,"internalType":"bool","name":"pauseState","type":"bool"}],"name":"ActionPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCompAccrued","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCompAccrued","type":"uint256"}],"name":"CompAccruedAdjusted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSpeed","type":"uint256"}],"name":"CompBorrowSpeedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CompGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCompReceivable","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCompReceivable","type":"uint256"}],"name":"CompReceivableUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSpeed","type":"uint256"}],"name":"CompSupplySpeedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSpeed","type":"uint256"}],"name":"ContributorCompSpeedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"compDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compBorrowIndex","type":"uint256"}],"name":"DistributedBorrowerComp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":false,"internalType":"uint256","name":"compDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compSupplyIndex","type":"uint256"}],"name":"DistributedSupplierComp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"Failure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketEntered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketExited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"MarketListed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newBorrowCap","type":"uint256"}],"name":"NewBorrowCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldBorrowCapGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newBorrowCapGuardian","type":"address"}],"name":"NewBorrowCapGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCloseFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCloseFactorMantissa","type":"uint256"}],"name":"NewCloseFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCollateralFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralFactorMantissa","type":"uint256"}],"name":"NewCollateralFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLiquidationIncentiveMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLiquidationIncentiveMantissa","type":"uint256"}],"name":"NewLiquidationIncentive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPauseGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newPauseGuardian","type":"address"}],"name":"NewPauseGuardian","type":"event"},{"inputs":[{"internalType":"contract Unitroller","name":"unitroller","type":"address"}],"name":"_become","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_borrowGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_mintGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newBorrowCapGuardian","type":"address"}],"name":"_setBorrowCapGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"_setBorrowPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCloseFactorMantissa","type":"uint256"}],"name":"_setCloseFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"newCollateralFactorMantissa","type":"uint256"}],"name":"_setCollateralFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLiquidationIncentiveMantissa","type":"uint256"}],"name":"_setLiquidationIncentive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CToken[]","name":"cTokens","type":"address[]"},{"internalType":"uint256[]","name":"newBorrowCaps","type":"uint256[]"}],"name":"_setMarketBorrowCaps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"_setMintPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauseGuardian","type":"address"}],"name":"_setPauseGuardian","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"_setSeizePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"_setTransferPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"_supportMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountAssets","outputs":[{"internalType":"contract CToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"aggregateValues","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allMarkets","outputs":[{"internalType":"contract CToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"borrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"borrowCapGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowCaps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"borrowVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeFactorMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compBorrowSpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compBorrowState","outputs":[{"internalType":"uint224","name":"index","type":"uint224"},{"internalType":"uint32","name":"block","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"compBorrowerIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compContributorSpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"compInitialIndex","outputs":[{"internalType":"uint224","name":"","type":"uint224"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"compRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compReceivable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compSpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"compSupplierIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compSupplySpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compSupplyState","outputs":[{"internalType":"uint224","name":"index","type":"uint224"},{"internalType":"uint32","name":"block","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptrollerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"cTokens","type":"address[]"}],"name":"enterMarkets","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenAddress","type":"address"}],"name":"exitMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"affectedUsers","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"fixBadAccruals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllMarkets","outputs":[{"internalType":"contract CToken[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAssetsIn","outputs":[{"internalType":"contract CToken[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signerAddress","type":"address"}],"name":"getAuthorisedSignerIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDataServiceId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"cTokenModify","type":"address"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"getHypotheticalAccountLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"getUnderlyingPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUniqueSignersThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isComptroller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"isDeprecated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastContributorBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"liquidateBorrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"liquidateBorrowVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"}],"name":"liquidateCalculateSeizeTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidationIncentiveMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"markets","outputs":[{"internalType":"bool","name":"isListed","type":"bool"},{"internalType":"uint256","name":"collateralFactorMantissa","type":"uint256"},{"internalType":"bool","name":"isComped","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"mintAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"actualMintAmount","type":"uint256"},{"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"mintVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingComptrollerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposal65FixExecuted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeemAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeemVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"payer","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"repayBorrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"payer","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"},{"internalType":"uint256","name":"borrowerIndex","type":"uint256"}],"name":"repayBorrowVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"seizeAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seizeGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"seizeVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"transferTokens","type":"uint256"}],"name":"transferAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"transferTokens","type":"uint256"}],"name":"transferVerify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"receivedTimestampMilliseconds","type":"uint256"}],"name":"validateTimestamp","outputs":[],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b03191633179055614d58806100326000396000f3fe608060405234801561001057600080fd5b506004361061045e5760003560e01c806387f763031161024c578063c274583a11610146578063e6653f3d116100c3578063f4a433c011610087578063f4a433c014610bc9578063f50b2efe14610be9578063f851a44014610bfc578063f90c492414610c0f578063fc57d4df14610c1657600080fd5b8063e6653f3d14610b79578063e875544614610b8d578063eabe7d9114610b96578063ede4edd014610ba9578063f00a7a9214610bbc57600080fd5b8063d02f73511161010a578063d02f735114610b1a578063da3d454c14610b2d578063dce1544914610b40578063dcfbc0c714610b53578063e4028eee14610b6657600080fd5b8063c274583a14610a50578063c299823814610a87578063c488847b14610aa7578063ca0af04314610acf578063cc7ebdc414610afa57600080fd5b8063a7f0e231116101d4578063b21be7fd11610198578063b21be7fd146109cc578063b24ebfcc146109f7578063bb82aa5e14610a0a578063bdcdc25814610a1d578063bea6b8b814610a3057600080fd5b8063a7f0e23114610959578063aa90075414610987578063abfceffc14610990578063ac0b0bb7146109b0578063b0772d0b146109c457600080fd5b8063929fe9a11161021b578063929fe9a1146108c957806394543c151461090a57806394b2294b1461091d578063986ab83814610926578063a76b3fda1461094657600080fd5b806387f76303146108175780638c57804e1461082b5780638e8f294b146108635780638ebf6364146108b657600080fd5b80634a5844321161035d5780635f5af1aa116102e55780636b79c38d116102a95780636b79c38d146107475780636d154ea5146107a35780636d35bf91146107c6578063731f0c2b146107d457806385b7beb8146107f757600080fd5b80635f5af1aa146106e05780635fc7e71e146106f3578063607ef6c1146107065780636a56947e146107195780636aa875b51461072757600080fd5b80634fd42e171161032c5780634fd42e171461068157806351dff9891461069457806352d84d1e146106a75780635c778605146106ba5780635ec88c79146106cd57600080fd5b80634a584432146106175780634ada90af146106375780634e79238f146106405780634ef4c3e11461066e57600080fd5b806326782247116103eb5780633c94786f116103af5780633c94786f146105ae5780633ce142f5146105c257806341c728b9146105e757806342cbb15c146105fb57806347ef3b3b1461060157600080fd5b8063267822471461054f5780632d70db7814610562578063317b0b7714610575578063391957d7146105885780633bcf7ec11461059b57600080fd5b80631d7b33d7116104325780631d7b33d7146104bb5780631ededc91146104e957806321af4569146104fe57806324008a621461052957806324a3d6221461053c57600080fd5b80627e3dd21461046357806316b95e8f1461048057806318c882a5146104955780631d504dc6146104a8575b600080fd5b61046b600181565b60405190151581526020015b60405180910390f35b61049361048e36600461444d565b610c29565b005b61046b6104a33660046144dc565b610ed2565b6104936104b6366004614515565b61100b565b6104db6104c9366004614515565b600e6020526000908152604090205481565b604051908152602001610477565b6104936104f7366004614532565b5050505050565b601454610511906001600160a01b031681565b6040516001600160a01b039091168152602001610477565b6104db61053736600461458d565b611189565b600954610511906001600160a01b031681565b600154610511906001600160a01b031681565b61046b6105703660046145de565b6111bd565b6104db6105833660046145fb565b6112ad565b610493610596366004614515565b611354565b61046b6105a93660046144dc565b61141e565b60095461046b90600160a01b900460ff1681565b6105d56105d0366004614515565b611548565b60405160ff9091168152602001610477565b6104936105f5366004614614565b50505050565b436104db565b61049361060f36600461465a565b505050505050565b6104db610625366004614515565b60156020526000908152604090205481565b6104db60055481565b61065361064e366004614614565b61164a565b60408051938452602084019290925290820152606001610477565b6104db61067c3660046146c8565b61168a565b6104db61068f3660046145fb565b611718565b6104936106a2366004614614565b611775565b6105116106b53660046145fb565b6117c4565b6104936106c83660046146c8565b505050565b6106536106db366004614515565b6117ee565b6104db6106ee366004614515565b611829565b6104db610701366004614709565b6118a2565b61049361071436600461444d565b611a74565b6104936105f536600461458d565b6104db610735366004614515565b60196020526000908152604090205481565b61077f610755366004614515565b600f602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b604080516001600160e01b03909316835263ffffffff909116602083015201610477565b61046b6107b1366004614515565b600b6020526000908152604090205460ff1681565b6104936104f7366004614709565b61046b6107e2366004614515565b600a6020526000908152604090205460ff1681565b6104db610805366004614515565b601b6020526000908152604090205481565b60095461046b90600160b01b900460ff1681565b61077f610839366004614515565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b610897610871366004614515565b60086020526000908152604090208054600182015460039092015460ff91821692911683565b6040805193151584526020840192909252151590820152606001610477565b61046b6108c43660046145de565b611c52565b61046b6108d736600461476d565b6001600160a01b038082166000908152600860209081526040808320938616835260029093019052205460ff1692915050565b61046b610918366004614515565b611d39565b6104db60065481565b6104db610934366004614515565b60166020526000908152604090205481565b6104db610954366004614515565b611df8565b61096f6ec097ce7bc90715b34b9f100000000081565b6040516001600160e01b039091168152602001610477565b6104db600d5481565b6109a361099e366004614515565b611f2a565b604051610477919061479b565b60095461046b90600160b81b900460ff1681565b6109a3611fa0565b6104db6109da36600461476d565b601160209081526000928352604080842090915290825290205481565b6104db610a05366004614853565b612002565b600254610511906001600160a01b031681565b6104db610a2b36600461458d565b61200d565b6104db610a3e366004614515565b60176020526000908152604090205481565b60408051808201825260158152741c99591cdd1bdb994b5c1c9a5b585c9e4b5c1c9bd9605a1b602082015290516104779190614902565b610a9a610a95366004614935565b612087565b60405161047791906149c4565b610aba610ab53660046146c8565b61214f565b60408051928352602083019190915201610477565b6104db610add36600461476d565b601260209081526000928352604080842090915290825290205481565b6104db610b08366004614515565b60136020526000908152604090205481565b6104db610b28366004614709565b61229b565b6104db610b3b3660046146c8565b612419565b610511610b4e3660046149fc565b6126fc565b600354610511906001600160a01b031681565b6104db610b743660046149fc565b612734565b60095461046b90600160a81b900460ff1681565b6104db60045481565b6104db610ba43660046146c8565b612860565b6104db610bb7366004614515565b612888565b601a5461046b9060ff1681565b6104db610bd7366004614515565b60186020526000908152604090205481565b610493610bf73660046145fb565b612be3565b600054610511906001600160a01b031681565b60036105d5565b6104db610c24366004614515565b612bec565b6000546001600160a01b03163314610c925760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6044820152603760f91b60648201526084015b60405180910390fd5b601a5460ff1615610cf45760405162461bcd60e51b815260206004820152602660248201527f416c72656164792065786563757465642074686973206f6e652d6f66662066756044820152653731ba34b7b760d11b6064820152608401610c89565b828114610d335760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60008060008060005b87811015610eba57888882818110610d5657610d56614a28565b9050602002016020810190610d6b9190614515565b6001600160a01b0381166000908152601360205260409020549095509350868682818110610d9b57610d9b614a28565b90506020020135925083831115610e3f576000610db88585614a54565b6001600160a01b0387166000908152601b6020526040812054919250610dde8284613109565b6001600160a01b0389166000818152601b6020908152604091829020849055815186815290810184905292935090917f17fea09d9a7ca41b2f9f9118f18f44848a62e9c70d55dd4385131eb2cf1b7e47910160405180910390a28695505050505b8215610eaa57610e4f8484613115565b6001600160a01b038616600081815260136020908152604091829020849055815188815290810184905292945090917f4a5c134e28b537a76546993ea37f3b60d9190476df7356d3842aa40902e20f04910160405180910390a25b610eb381614a67565b9050610d3c565b5050601a805460ff1916600117905550505050505050565b6001600160a01b03821660009081526008602052604081205460ff16610f0a5760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b0316331480610f2d57506000546001600160a01b031633145b610f495760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480610f6457506001821515145b610f805760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600b6020908152604091829020805460ff19168615159081179091558251938452606091840182905260069184019190915265426f72726f7760d01b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a0015b60405180910390a150805b92915050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190614b3f565b6001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b815260206004820152602760248201527f6f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676560448201526620627261696e7360c81b6064820152608401610c89565b806001600160a01b031663c1e803346040518163ffffffff1660e01b81526004016020604051808303816000875af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190614b5c565b156111865760405162461bcd60e51b815260206004820152601560248201527418da185b99d9481b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610c89565b50565b6001600160a01b03841660009081526008602052604081205460ff166111b1575060096111b5565b5060005b949350505050565b6009546000906001600160a01b03163314806111e357506000546001600160a01b031633145b6111ff5760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b031633148061121a57506001821515145b6112365760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b81b0260ff60b81b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600590820152645365697a6560d81b6060820152901515602082015260800190565b60405180910390a15090565b600080546001600160a01b031633146113085760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f72006044820152606401610c89565b600480549083905560408051828152602081018590527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a160005b9392505050565b6000546001600160a01b031633146113bd5760405162461bcd60e51b815260206004820152602660248201527f6f6e6c792061646d696e2063616e2073657420626f72726f772063617020677560448201526530b93234b0b760d11b6064820152608401610c89565b601480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29910160405180910390a15050565b6001600160a01b03821660009081526008602052604081205460ff166114565760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b031633148061147957506000546001600160a01b031633145b6114955760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b03163314806114b057506001821515145b6114cc5760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600a6020908152604091829020805460ff19168615159081179091558251938452606091840182905260049184019190915263135a5b9d60e21b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a001610ffa565b60006001600160a01b038216738bb8f32df04c8b654987daaed53d6b6091e3b7740361157657506000919050565b6001600160a01b03821673deb22f54738d54976c4c0fe5ce6d408e40d88499036115a257506001919050565b6001600160a01b0382167351ce04be4b3e32572c4ec9135221d0691ba7d202036115ce57506002919050565b6001600160a01b03821673dd682daec5a90dd295d14da4b0bec9281017b5be036115fa57506003919050565b6001600160a01b038216739c5ae89c4af6aa32ce58588dbaf90d18a855b6de0361162657506004919050565b6040516303b1166f60e61b81526001600160a01b0383166004820152602401610c89565b60008060008060008061165f8a8a8a8a613121565b92509250925082601181111561167757611677614b75565b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600a602052604081205460ff16156116e45760405162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661170e5760095b905061134d565b6000949350505050565b600080546001600160a01b03163314611737576110056001600b6133f4565b600580549083905560408051828152602081018590527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec13169101611342565b801580156117835750600082115b156105f55760405162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b6044820152606401610c89565b600c81815481106117d457600080fd5b6000918252602090912001546001600160a01b0316905081565b600080600080600080611805876000806000613121565b92509250925082601181111561181d5761181d614b75565b97919650945092505050565b600080546001600160a01b0316331461184857611005600160136133f4565b600980546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9101611342565b6001600160a01b03851660009081526008602052604081205460ff1615806118e357506001600160a01b03851660009081526008602052604090205460ff16155b156118f25760095b9050611a6b565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908816906395dd919390602401602060405180830381865afa15801561193c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190614b5c565b905061196b87611d39565b156119d657828110156119d15760405162461bcd60e51b815260206004820152602860248201527f43616e206e6f74207265706179206d6f7265207468616e2074686520746f74616044820152676c20626f72726f7760c01b6064820152608401610c89565b611a65565b6000806119e28661346d565b919350909150600090508260118111156119fe576119fe614b75565b14611a1f57816011811115611a1557611a15614b75565b9350505050611a6b565b80600003611a2e576003611a15565b6000611a4a60405180602001604052806004548152508561348d565b905080861115611a61576011945050505050611a6b565b5050505b60009150505b95945050505050565b6000546001600160a01b0316331480611a9757506014546001600160a01b031633145b611b015760405162461bcd60e51b815260206004820152603560248201527f6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616044820152746e2063616e2073657420626f72726f77206361707360581b6064820152608401610c89565b82818115801590611b1157508082145b611b4d5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60005b82811015611c4957848482818110611b6a57611b6a614a28565b9050602002013560156000898985818110611b8757611b87614a28565b9050602002016020810190611b9c9190614515565b6001600160a01b03168152602081019190915260400160002055868682818110611bc857611bc8614a28565b9050602002016020810190611bdd9190614515565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611c1957611c19614a28565b90506020020135604051611c2f91815260200190565b60405180910390a280611c4181614a67565b915050611b50565b50505050505050565b6009546000906001600160a01b0316331480611c7857506000546001600160a01b031633145b611c945760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480611caf57506001821515145b611ccb5760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b01b0260ff60b01b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600890820152672a3930b739b332b960c11b6060820152901515602082015260800190565b6001600160a01b038116600090815260086020526040812060010154158015611d7f57506001600160a01b0382166000908152600b602052604090205460ff1615156001145b80156110055750816001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de89190614b5c565b670de0b6b3a76400001492915050565b600080546001600160a01b03163314611e1757611005600160126133f4565b6001600160a01b03821660009081526008602052604090205460ff1615611e4457611005600a60116133f4565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea69190614b8b565b506001600160a01b03821660009081526008602052604081208054600160ff1991821681178355600383018054909216909155810191909155611ee8836134a5565b611ef18361358d565b6040516001600160a01b03841681527fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90602001611342565b6001600160a01b0381166000908152600760209081526040808320805482518185028101850190935280835260609493830182828015611f9357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f75575b5093979650505050505050565b6060600c805480602002602001604051908101604052809291908181526020018280548015611ff857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611fda575b5050505050905090565b600061100582613689565b600954600090600160b01b900460ff161561205f5760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b6044820152606401610c89565b600061206c868685613694565b9050801561207b5790506111b5565b60009695505050505050565b805160609060008167ffffffffffffffff8111156120a7576120a76147e8565b6040519080825280602002602001820160405280156120d0578160200160208202803683370190505b50905060005b828110156121475760008582815181106120f2576120f2614a28565b60200260200101519050612106813361374c565b601181111561211757612117614b75565b83838151811061212957612129614a28565b6020908102919091010152508061213f81614a67565b9150506120d6565b509392505050565b600080600061215d86612bec565b9050600061216a86612bec565b9050811580612177575080155b1561218b57600d6000935093505050612293565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef9190614b5c565b905060006122096040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260055481528451928301909452888252919261224591613840565b925061226d604051806020016040528088815250604051806020016040528088815250613840565b91506122798383613888565b9050612285818b61348d565b600099509750505050505050505b935093915050565b600954600090600160b81b900460ff16156122ea5760405162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b6044820152606401610c89565b6001600160a01b03861660009081526008602052604090205460ff16158061232b57506001600160a01b03851660009081526008602052604090205460ff16155b156123375760096118eb565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614b3f565b6001600160a01b0316866001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190614b3f565b6001600160a01b03161461207b5760026118eb565b6001600160a01b0383166000908152600b602052604081205460ff16156124755760405162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661249c576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff1661259957336001600160a01b0385161461251d5760405162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329031aa37b5b2b760591b6044820152606401610c89565b6000612529338561374c565b9050600081601181111561253f5761253f614b75565b1461255e5780601181111561255657612556614b75565b91505061134d565b6001600160a01b038086166000908152600860209081526040808320938816835260029093019052205460ff1661259757612597614ba8565b505b6125a284612bec565b6000036125b057600d611707565b6001600160a01b0384166000908152601560205260409020548015612695576000856001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190614b5c565b905060006126418286613109565b90508281106126925760405162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f77206361702072656163686564000000000000006044820152606401610c89565b50505b6000806126a58688600088613121565b919350909150600090508260118111156126c1576126c1614b75565b146126e2578160118111156126d8576126d8614b75565b935050505061134d565b80156126ef5760046126d8565b6000979650505050505050565b6007602052816000526040600020818154811061271857600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080546001600160a01b0316331461275a57612753600160066133f4565b9050611005565b6001600160a01b0383166000908152600860205260409020805460ff1661278f57612787600960076133f4565b915050611005565b60408051602080820183528582528251908101909252670c7d713b49da00008252906127bd81835190511090565b156127d8576127ce600660086133f4565b9350505050611005565b84158015906127ed57506127eb86612bec565b155b156127fe576127ce600d60096133f4565b60018301805490869055604080516001600160a01b0389168152602081018390529081018790527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a160005b979650505050505050565b60008061286e858585613694565b9050801561287d57905061134d565b600095945050505050565b6040516361bfb47160e11b815233600482015260009082908290819081906001600160a01b0385169063c37f68e290602401608060405180830381865afa1580156128d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fb9190614bbe565b50925092509250826000146129605760405162461bcd60e51b815260206004820152602560248201527f657869744d61726b65743a206765744163636f756e74536e617073686f742066604482015264185a5b195960da1b6064820152608401610c89565b801561297c57612972600c60026133f4565b9695505050505050565b6000612989873385613694565b9050801561299e57612855600e6003836138c2565b6001600160a01b0385166000908152600860209081526040808320338452600281019092529091205460ff166129dd5760005b98975050505050505050565b3360009081526002820160209081526040808320805460ff191690556007825280832080548251818502810185019093528083529192909190830182828015612a4f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a31575b5050835193945083925060009150505b82811015612ab357896001600160a01b0316848281518110612a8357612a83614a28565b60200260200101516001600160a01b031603612aa157809150612ab3565b80612aab81614a67565b915050612a5f565b50818110612ac357612ac3614ba8565b33600090815260076020526040902080548190612ae290600190614a54565b81548110612af257612af2614a28565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110612b2257612b22614a28565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480612b6057612b60614bf4565b600082815260209020810160001990810180546001600160a01b03191690550190556040517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90612bc9908c9033906001600160a01b0392831681529116602082015260400190565b60405180910390a160009c9b505050505050505050505050565b6111868161393a565b6000806000604051602001612c0b90630c68aa8960e31b815260040190565b60405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c5f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c879190810190614c0a565b604051602001612c979190614c9e565b6040516020818303038152906040528051906020012003612cc857612cc16208aa8960eb1b6139be565b9150613102565b604051640c6ae8aa8960db1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d589190810190614c0a565b604051602001612d689190614c9e565b6040516020818303038152906040528051906020012003612d9257612cc16208aa8960eb1b6139be565b60405164635553444360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612dfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e229190810190614c0a565b604051602001612e329190614c9e565b6040516020818303038152906040528051906020012003612e6c57612e5d635553444360e01b6139be565b612cc19064e8d4a51000614cba565b6040516418d554d11560da1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612efc9190810190614c0a565b604051602001612f0c9190614c9e565b6040516020818303038152906040528051906020012003612f3757612e5d631554d11560e21b6139be565b60405164635742544360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fc79190810190614c0a565b604051602001612fd79190614c9e565b6040516020818303038152906040528051906020012003613010576130016242544360e81b6139be565b612cc1906402540be400614cba565b6000846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130749190614b3f565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156130b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130d99190810190614c0a565b905060008082905080516000036130ef57600091505b60208301519150819350612855846139be565b5092915050565b600061134d8284614cd1565b600061134d8284614a54565b600080600061312e61435f565b6001600160a01b03881660009081526007602090815260408083208054825181850281018501909352808352849383018282801561319557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613177575b5050505050905060005b815181101561339e5760008282815181106131bc576131bc614a28565b60209081029190910101516040516361bfb47160e11b81526001600160a01b038e811660048301529192509082169063c37f68e290602401608060405180830381865afa158015613211573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132359190614bbe565b6080890152606088015260408701529350831561326157600f6000809750975097505050505050611680565b60408051602080820183526001600160a01b03841660009081526008825283902060010154825260c088019190915281519081019091526080860151815260e08601526132ad81612bec565b60a086018190526000036132d057600d6000809750975097505050505050611680565b604080516020810190915260a0860151815261010086015260c085015160e086015161330a916132ff91613840565b866101000151613840565b610120860181905260408601518651613324929190613a2e565b855261010085015160608601516020870151613341929190613a2e565b60208601526001600160a01b03808c169082160361338b5761336d8561012001518b8760200151613a2e565b60208601819052610100860151613385918b90613a2e565b60208601525b508061339681614a67565b91505061319f565b506020830151835111156133cf57602083015183516000916133bf91614a54565b6000955095509550505050611680565b600080846000015185602001516133e69190614a54565b955095509550505050611680565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561342957613429614b75565b83601381111561343b5761343b614b75565b60408051928352602083019190915260009082015260600160405180910390a182601181111561134d5761134d614b75565b6000806000613480846000806000613121565b9250925092509193909250565b60008061349a8484613a4f565b90506111b581613a77565b60005b600c5481101561353a57816001600160a01b0316600c82815481106134cf576134cf614a28565b6000918252602090912001546001600160a01b0316036135285760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08185b1c9958591e48185919195960621b6044820152606401610c89565b8061353281614a67565b9150506134a8565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b0392909216919091179055565b60006135ce436040518060400160405280601c81526020017f626c6f636b206e756d6265722065786365656473203332206269747300000000815250613a8f565b6001600160a01b0383166000908152600f60209081526040808320601090925282208154939450909290916001600160e01b03909116900361362a5781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b031660000361365c5780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b600061100582613abf565b6001600160a01b03831660009081526008602052604081205460ff166136bb576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff166136f3576000611707565b6000806137038587866000613121565b9193509091506000905082601181111561371f5761371f614b75565b1461373f5781601181111561373657613736614b75565b9250505061134d565b801561207b576004613736565b6001600160a01b0382166000908152600860205260408120805460ff16613777576009915050611005565b6001600160a01b038316600090815260028201602052604090205460ff1615156001036137a8576000915050611005565b6001600160a01b03838116600081815260028401602090815260408083208054600160ff199091168117909155600783528184208054918201815584529282902090920180546001600160a01b031916948916948517905581519384528301919091527f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5910160405180910390a15060009392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061387586600001518660000151613b7a565b61387f9190614cfa565b90529392505050565b604080516020810190915260008152604051806020016040528061387f6138bb8660000151670de0b6b3a7640000613b7a565b8551613b86565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460118111156138f7576138f7614b75565b84601381111561390957613909614b75565b604080519283526020830191909152810184905260600160405180910390a18360118111156111b5576111b5614b75565b60006139486103e883614cfa565b90508042101561398a57603c61395e4283614a54565b11156139865760405163b6b0916d60e01b815260048101829052426024820152604401610c89565b5050565b60b46139968242614a54565b111561398657604051630321d0b560e01b815260048101829052426024820152604401610c89565b6040805160018082528183019092526000918291906020808301908036833701905050905082816000815181106139f7576139f7614a28565b602002602001018181525050613a0c81613b92565b600081518110613a1e57613a1e614a28565b6020026020010151915050919050565b600080613a3b8585613a4f565b9050611a6b613a4982613a77565b84613109565b604080516020810190915260008152604051806020016040528061387f856000015185613b7a565b805160009061100590670de0b6b3a764000090614cfa565b6000816401000000008410613ab75760405162461bcd60e51b8152600401610c899190614902565b509192915050565b60008151600003613ae357604051639e198af960e01b815260040160405180910390fd5b613aec82613b9d565b600060028351613afc9190614cfa565b905060028351613b0c9190614d0e565b600003613b68576000613b5b84613b24600185614a54565b81518110613b3457613b34614a28565b6020026020010151858481518110613b4e57613b4e614a28565b6020026020010151613109565b90506111b5600282614cfa565b828181518110613a1e57613a1e614a28565b600061134d8284614cba565b600061134d8284614cfa565b606061100582613be5565b8051602082016020820281019150805b828110156105f557815b81811015613bdc578151815180821015613bd2578084528183525b5050602001613bb7565b50602001613bad565b60606000825167ffffffffffffffff811115613c0357613c036147e8565b604051908082528060200260200182016040528015613c2c578160200160208202803683370190505b5090506000835167ffffffffffffffff811115613c4b57613c4b6147e8565b604051908082528060200260200182016040528015613c74578160200160208202803683370190505b5090506000845167ffffffffffffffff811115613c9357613c936147e8565b604051908082528060200260200182016040528015613cc657816020015b6060815260200190600190039081613cb15790505b50905060005b8551811015613d245760408051600380825260808201909252906020820160608036833701905050828281518110613d0657613d06614a28565b60200260200101819052508080613d1c90614a67565b915050613ccc565b506000613d2f613d9e565b90506000613d3c82613e45565b61ffff169050613d4d600283614cd1565b60405190925060005b82811015613d93576000613d6d8a89898989613e7f565b9050613d798186614cd1565b945082604052508080613d8b90614a67565b915050613d56565b506129d1848761411f565b60006602ed57011e0000601f1936013581161480613dcf576040516373bb264f60e11b815260040160405180910390fd5b60003660291115613df357604051632bcb7bc560e11b815260040160405180910390fd5b5060281936013560006009613e0e600362ffffff8516614cd1565b613e189190614cd1565b905036613e26600283614cd1565b111561134d5760405163c30a7bd760e01b815260040160405180910390fd5b600080613e53602084614cd1565b905036811115613e7657604051632bcb7bc560e11b815260040160405180910390fd5b36033592915050565b600080600080613e8e85614238565b909250905060008080606081600d613eb1613eaa602089614cd1565b8990613b7a565b613ebb9190614cd1565b90506000613ed4613ecd60688d614cd1565b3690613115565b90506000613ef183613ee760418f614cd1565b613ecd9190614cd1565b9050613efd8382613f10565b9350826020850120945081359650613f34565b60408051838152602081850181019092526000910183838237601f19019392505050565b613f458765ffffffffffff16612be3565b613f5985613f5460418f614cd1565b614288565b9550613f6486611548565b60ff1699505050505050505060008060005b848110156140ec57613f89888583614300565b909350915060005b8c518110156140d9578c8181518110613fac57613fac614a28565b602002602001015184036140c75760008b8281518110613fce57613fce614a28565b60200260200101519050613fe781896001901b16151590565b1580156140105750600360ff168d838151811061400657614006614a28565b6020026020010151105b156140c1578c828151811061402757614027614a28565b60200260200101805180919061403c90614a67565b81525050838b838151811061405357614053614a28565b602002602001015160018f858151811061406f5761406f614a28565b60200260200101516140819190614a54565b8151811061409157614091614a28565b60209081029190910101526001881b81178c83815181106140b4576140b4614a28565b6020026020010181815250505b506140d9565b806140d181614a67565b915050613f91565b50806140e481614a67565b915050613f76565b505050816020826140fd9190614cd1565b6141079190614cba565b61411290604e614cd1565b9998505050505050505050565b60606000835167ffffffffffffffff81111561413d5761413d6147e8565b604051908082528060200260200182016040528015614166578160200160208202803683370190505b509050600360005b855181101561422e578185828151811061418a5761418a614a28565b602002602001015110156141d7578481815181106141aa576141aa614a28565b602002602001015182604051632b13aef560e01b8152600401610c89929190918252602082015260400190565b60006141fb8783815181106141ee576141ee614a28565b6020026020010151612002565b90508084838151811061421057614210614a28565b6020908102919091010152508061422681614a67565b91505061416e565b5090949350505050565b600080808080614249604187614cd1565b9050600061425b613ecd602084614cd1565b80359450905061426c816003613115565b62ffffff9490941697933563ffffffff16965092945050505050565b60408051600080825260208083018085528690523685900380850135831a948401859052803560608501819052910135608084018190529193909260019060a0016020604051602081039080840390855afa1580156142eb573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000808061430f604e87614cd1565b9050600061433c614335614324602089614cd1565b61432f886001614cd1565b90613b7a565b8390613109565b9050600061434a3683613115565b80359960209091013598509650505050505050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016143ab6040518060200160405280600081525090565b81526020016143c66040518060200160405280600081525090565b81526020016143e16040518060200160405280600081525090565b81526020016143fc6040518060200160405280600081525090565b905290565b60008083601f84011261441357600080fd5b50813567ffffffffffffffff81111561442b57600080fd5b6020830191508360208260051b850101111561444657600080fd5b9250929050565b6000806000806040858703121561446357600080fd5b843567ffffffffffffffff8082111561447b57600080fd5b61448788838901614401565b909650945060208701359150808211156144a057600080fd5b506144ad87828801614401565b95989497509550505050565b6001600160a01b038116811461118657600080fd5b801515811461118657600080fd5b600080604083850312156144ef57600080fd5b82356144fa816144b9565b9150602083013561450a816144ce565b809150509250929050565b60006020828403121561452757600080fd5b813561134d816144b9565b600080600080600060a0868803121561454a57600080fd5b8535614555816144b9565b94506020860135614565816144b9565b93506040860135614575816144b9565b94979396509394606081013594506080013592915050565b600080600080608085870312156145a357600080fd5b84356145ae816144b9565b935060208501356145be816144b9565b925060408501356145ce816144b9565b9396929550929360600135925050565b6000602082840312156145f057600080fd5b813561134d816144ce565b60006020828403121561460d57600080fd5b5035919050565b6000806000806080858703121561462a57600080fd5b8435614635816144b9565b93506020850135614645816144b9565b93969395505050506040820135916060013590565b60008060008060008060c0878903121561467357600080fd5b863561467e816144b9565b9550602087013561468e816144b9565b9450604087013561469e816144b9565b935060608701356146ae816144b9565b9598949750929560808101359460a0909101359350915050565b6000806000606084860312156146dd57600080fd5b83356146e8816144b9565b925060208401356146f8816144b9565b929592945050506040919091013590565b600080600080600060a0868803121561472157600080fd5b853561472c816144b9565b9450602086013561473c816144b9565b9350604086013561474c816144b9565b9250606086013561475c816144b9565b949793965091946080013592915050565b6000806040838503121561478057600080fd5b823561478b816144b9565b9150602083013561450a816144b9565b6020808252825182820181905260009190848201906040850190845b818110156147dc5783516001600160a01b0316835292840192918401916001016147b7565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614827576148276147e8565b604052919050565b600067ffffffffffffffff821115614849576148496147e8565b5060051b60200190565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b80356148a161489c8261482f565b6147fe565b81815260059190911b820183019083810190878311156148c057600080fd5b928401925b82841015612855578335825292840192908401906148c5565b60005b838110156148f95781810151838201526020016148e1565b50506000910152565b60208152600082518060208401526149218160408501602087016148de565b601f01601f19169190910160400192915050565b6000602080838503121561494857600080fd5b823567ffffffffffffffff81111561495f57600080fd5b8301601f8101851361497057600080fd5b803561497e61489c8261482f565b81815260059190911b8201830190838101908783111561499d57600080fd5b928401925b828410156128555783356149b5816144b9565b825292840192908401906149a2565b6020808252825182820181905260009190848201906040850190845b818110156147dc578351835292840192918401916001016149e0565b60008060408385031215614a0f57600080fd5b8235614a1a816144b9565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561100557611005614a3e565b600060018201614a7957614a79614a3e565b5060010190565b60208082526028908201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6040820152671d081b1a5cdd195960c21b606082015260800190565b60208082526027908201527f6f6e6c7920706175736520677561726469616e20616e642061646d696e2063616040820152666e20706175736560c81b606082015260800190565b6020808252601690820152756f6e6c792061646d696e2063616e20756e706175736560501b604082015260600190565b600060208284031215614b5157600080fd5b815161134d816144b9565b600060208284031215614b6e57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614b9d57600080fd5b815161134d816144ce565b634e487b7160e01b600052600160045260246000fd5b60008060008060808587031215614bd457600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614c1c57600080fd5b815167ffffffffffffffff80821115614c3457600080fd5b818401915084601f830112614c4857600080fd5b815181811115614c5a57614c5a6147e8565b614c6d601f8201601f19166020016147fe565b9150808252856020828501011115614c8457600080fd5b614c958160208401602086016148de565b50949350505050565b60008251614cb08184602087016148de565b9190910192915050565b808202811582820484141761100557611005614a3e565b8082018082111561100557611005614a3e565b634e487b7160e01b600052601260045260246000fd5b600082614d0957614d09614ce4565b500490565b600082614d1d57614d1d614ce4565b50069056fea2646970667358221220bafd5e6394cb5564fc079ac4bc62f2bead18ad908f73aa6a16a21b14bd82f29564736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061045e5760003560e01c806387f763031161024c578063c274583a11610146578063e6653f3d116100c3578063f4a433c011610087578063f4a433c014610bc9578063f50b2efe14610be9578063f851a44014610bfc578063f90c492414610c0f578063fc57d4df14610c1657600080fd5b8063e6653f3d14610b79578063e875544614610b8d578063eabe7d9114610b96578063ede4edd014610ba9578063f00a7a9214610bbc57600080fd5b8063d02f73511161010a578063d02f735114610b1a578063da3d454c14610b2d578063dce1544914610b40578063dcfbc0c714610b53578063e4028eee14610b6657600080fd5b8063c274583a14610a50578063c299823814610a87578063c488847b14610aa7578063ca0af04314610acf578063cc7ebdc414610afa57600080fd5b8063a7f0e231116101d4578063b21be7fd11610198578063b21be7fd146109cc578063b24ebfcc146109f7578063bb82aa5e14610a0a578063bdcdc25814610a1d578063bea6b8b814610a3057600080fd5b8063a7f0e23114610959578063aa90075414610987578063abfceffc14610990578063ac0b0bb7146109b0578063b0772d0b146109c457600080fd5b8063929fe9a11161021b578063929fe9a1146108c957806394543c151461090a57806394b2294b1461091d578063986ab83814610926578063a76b3fda1461094657600080fd5b806387f76303146108175780638c57804e1461082b5780638e8f294b146108635780638ebf6364146108b657600080fd5b80634a5844321161035d5780635f5af1aa116102e55780636b79c38d116102a95780636b79c38d146107475780636d154ea5146107a35780636d35bf91146107c6578063731f0c2b146107d457806385b7beb8146107f757600080fd5b80635f5af1aa146106e05780635fc7e71e146106f3578063607ef6c1146107065780636a56947e146107195780636aa875b51461072757600080fd5b80634fd42e171161032c5780634fd42e171461068157806351dff9891461069457806352d84d1e146106a75780635c778605146106ba5780635ec88c79146106cd57600080fd5b80634a584432146106175780634ada90af146106375780634e79238f146106405780634ef4c3e11461066e57600080fd5b806326782247116103eb5780633c94786f116103af5780633c94786f146105ae5780633ce142f5146105c257806341c728b9146105e757806342cbb15c146105fb57806347ef3b3b1461060157600080fd5b8063267822471461054f5780632d70db7814610562578063317b0b7714610575578063391957d7146105885780633bcf7ec11461059b57600080fd5b80631d7b33d7116104325780631d7b33d7146104bb5780631ededc91146104e957806321af4569146104fe57806324008a621461052957806324a3d6221461053c57600080fd5b80627e3dd21461046357806316b95e8f1461048057806318c882a5146104955780631d504dc6146104a8575b600080fd5b61046b600181565b60405190151581526020015b60405180910390f35b61049361048e36600461444d565b610c29565b005b61046b6104a33660046144dc565b610ed2565b6104936104b6366004614515565b61100b565b6104db6104c9366004614515565b600e6020526000908152604090205481565b604051908152602001610477565b6104936104f7366004614532565b5050505050565b601454610511906001600160a01b031681565b6040516001600160a01b039091168152602001610477565b6104db61053736600461458d565b611189565b600954610511906001600160a01b031681565b600154610511906001600160a01b031681565b61046b6105703660046145de565b6111bd565b6104db6105833660046145fb565b6112ad565b610493610596366004614515565b611354565b61046b6105a93660046144dc565b61141e565b60095461046b90600160a01b900460ff1681565b6105d56105d0366004614515565b611548565b60405160ff9091168152602001610477565b6104936105f5366004614614565b50505050565b436104db565b61049361060f36600461465a565b505050505050565b6104db610625366004614515565b60156020526000908152604090205481565b6104db60055481565b61065361064e366004614614565b61164a565b60408051938452602084019290925290820152606001610477565b6104db61067c3660046146c8565b61168a565b6104db61068f3660046145fb565b611718565b6104936106a2366004614614565b611775565b6105116106b53660046145fb565b6117c4565b6104936106c83660046146c8565b505050565b6106536106db366004614515565b6117ee565b6104db6106ee366004614515565b611829565b6104db610701366004614709565b6118a2565b61049361071436600461444d565b611a74565b6104936105f536600461458d565b6104db610735366004614515565b60196020526000908152604090205481565b61077f610755366004614515565b600f602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b604080516001600160e01b03909316835263ffffffff909116602083015201610477565b61046b6107b1366004614515565b600b6020526000908152604090205460ff1681565b6104936104f7366004614709565b61046b6107e2366004614515565b600a6020526000908152604090205460ff1681565b6104db610805366004614515565b601b6020526000908152604090205481565b60095461046b90600160b01b900460ff1681565b61077f610839366004614515565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b610897610871366004614515565b60086020526000908152604090208054600182015460039092015460ff91821692911683565b6040805193151584526020840192909252151590820152606001610477565b61046b6108c43660046145de565b611c52565b61046b6108d736600461476d565b6001600160a01b038082166000908152600860209081526040808320938616835260029093019052205460ff1692915050565b61046b610918366004614515565b611d39565b6104db60065481565b6104db610934366004614515565b60166020526000908152604090205481565b6104db610954366004614515565b611df8565b61096f6ec097ce7bc90715b34b9f100000000081565b6040516001600160e01b039091168152602001610477565b6104db600d5481565b6109a361099e366004614515565b611f2a565b604051610477919061479b565b60095461046b90600160b81b900460ff1681565b6109a3611fa0565b6104db6109da36600461476d565b601160209081526000928352604080842090915290825290205481565b6104db610a05366004614853565b612002565b600254610511906001600160a01b031681565b6104db610a2b36600461458d565b61200d565b6104db610a3e366004614515565b60176020526000908152604090205481565b60408051808201825260158152741c99591cdd1bdb994b5c1c9a5b585c9e4b5c1c9bd9605a1b602082015290516104779190614902565b610a9a610a95366004614935565b612087565b60405161047791906149c4565b610aba610ab53660046146c8565b61214f565b60408051928352602083019190915201610477565b6104db610add36600461476d565b601260209081526000928352604080842090915290825290205481565b6104db610b08366004614515565b60136020526000908152604090205481565b6104db610b28366004614709565b61229b565b6104db610b3b3660046146c8565b612419565b610511610b4e3660046149fc565b6126fc565b600354610511906001600160a01b031681565b6104db610b743660046149fc565b612734565b60095461046b90600160a81b900460ff1681565b6104db60045481565b6104db610ba43660046146c8565b612860565b6104db610bb7366004614515565b612888565b601a5461046b9060ff1681565b6104db610bd7366004614515565b60186020526000908152604090205481565b610493610bf73660046145fb565b612be3565b600054610511906001600160a01b031681565b60036105d5565b6104db610c24366004614515565b612bec565b6000546001600160a01b03163314610c925760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6044820152603760f91b60648201526084015b60405180910390fd5b601a5460ff1615610cf45760405162461bcd60e51b815260206004820152602660248201527f416c72656164792065786563757465642074686973206f6e652d6f66662066756044820152653731ba34b7b760d11b6064820152608401610c89565b828114610d335760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60008060008060005b87811015610eba57888882818110610d5657610d56614a28565b9050602002016020810190610d6b9190614515565b6001600160a01b0381166000908152601360205260409020549095509350868682818110610d9b57610d9b614a28565b90506020020135925083831115610e3f576000610db88585614a54565b6001600160a01b0387166000908152601b6020526040812054919250610dde8284613109565b6001600160a01b0389166000818152601b6020908152604091829020849055815186815290810184905292935090917f17fea09d9a7ca41b2f9f9118f18f44848a62e9c70d55dd4385131eb2cf1b7e47910160405180910390a28695505050505b8215610eaa57610e4f8484613115565b6001600160a01b038616600081815260136020908152604091829020849055815188815290810184905292945090917f4a5c134e28b537a76546993ea37f3b60d9190476df7356d3842aa40902e20f04910160405180910390a25b610eb381614a67565b9050610d3c565b5050601a805460ff1916600117905550505050505050565b6001600160a01b03821660009081526008602052604081205460ff16610f0a5760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b0316331480610f2d57506000546001600160a01b031633145b610f495760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480610f6457506001821515145b610f805760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600b6020908152604091829020805460ff19168615159081179091558251938452606091840182905260069184019190915265426f72726f7760d01b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a0015b60405180910390a150805b92915050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190614b3f565b6001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b815260206004820152602760248201527f6f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676560448201526620627261696e7360c81b6064820152608401610c89565b806001600160a01b031663c1e803346040518163ffffffff1660e01b81526004016020604051808303816000875af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190614b5c565b156111865760405162461bcd60e51b815260206004820152601560248201527418da185b99d9481b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610c89565b50565b6001600160a01b03841660009081526008602052604081205460ff166111b1575060096111b5565b5060005b949350505050565b6009546000906001600160a01b03163314806111e357506000546001600160a01b031633145b6111ff5760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b031633148061121a57506001821515145b6112365760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b81b0260ff60b81b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600590820152645365697a6560d81b6060820152901515602082015260800190565b60405180910390a15090565b600080546001600160a01b031633146113085760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f72006044820152606401610c89565b600480549083905560408051828152602081018590527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a160005b9392505050565b6000546001600160a01b031633146113bd5760405162461bcd60e51b815260206004820152602660248201527f6f6e6c792061646d696e2063616e2073657420626f72726f772063617020677560448201526530b93234b0b760d11b6064820152608401610c89565b601480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29910160405180910390a15050565b6001600160a01b03821660009081526008602052604081205460ff166114565760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b031633148061147957506000546001600160a01b031633145b6114955760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b03163314806114b057506001821515145b6114cc5760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600a6020908152604091829020805460ff19168615159081179091558251938452606091840182905260049184019190915263135a5b9d60e21b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a001610ffa565b60006001600160a01b038216738bb8f32df04c8b654987daaed53d6b6091e3b7740361157657506000919050565b6001600160a01b03821673deb22f54738d54976c4c0fe5ce6d408e40d88499036115a257506001919050565b6001600160a01b0382167351ce04be4b3e32572c4ec9135221d0691ba7d202036115ce57506002919050565b6001600160a01b03821673dd682daec5a90dd295d14da4b0bec9281017b5be036115fa57506003919050565b6001600160a01b038216739c5ae89c4af6aa32ce58588dbaf90d18a855b6de0361162657506004919050565b6040516303b1166f60e61b81526001600160a01b0383166004820152602401610c89565b60008060008060008061165f8a8a8a8a613121565b92509250925082601181111561167757611677614b75565b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600a602052604081205460ff16156116e45760405162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661170e5760095b905061134d565b6000949350505050565b600080546001600160a01b03163314611737576110056001600b6133f4565b600580549083905560408051828152602081018590527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec13169101611342565b801580156117835750600082115b156105f55760405162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b6044820152606401610c89565b600c81815481106117d457600080fd5b6000918252602090912001546001600160a01b0316905081565b600080600080600080611805876000806000613121565b92509250925082601181111561181d5761181d614b75565b97919650945092505050565b600080546001600160a01b0316331461184857611005600160136133f4565b600980546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9101611342565b6001600160a01b03851660009081526008602052604081205460ff1615806118e357506001600160a01b03851660009081526008602052604090205460ff16155b156118f25760095b9050611a6b565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908816906395dd919390602401602060405180830381865afa15801561193c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190614b5c565b905061196b87611d39565b156119d657828110156119d15760405162461bcd60e51b815260206004820152602860248201527f43616e206e6f74207265706179206d6f7265207468616e2074686520746f74616044820152676c20626f72726f7760c01b6064820152608401610c89565b611a65565b6000806119e28661346d565b919350909150600090508260118111156119fe576119fe614b75565b14611a1f57816011811115611a1557611a15614b75565b9350505050611a6b565b80600003611a2e576003611a15565b6000611a4a60405180602001604052806004548152508561348d565b905080861115611a61576011945050505050611a6b565b5050505b60009150505b95945050505050565b6000546001600160a01b0316331480611a9757506014546001600160a01b031633145b611b015760405162461bcd60e51b815260206004820152603560248201527f6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616044820152746e2063616e2073657420626f72726f77206361707360581b6064820152608401610c89565b82818115801590611b1157508082145b611b4d5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60005b82811015611c4957848482818110611b6a57611b6a614a28565b9050602002013560156000898985818110611b8757611b87614a28565b9050602002016020810190611b9c9190614515565b6001600160a01b03168152602081019190915260400160002055868682818110611bc857611bc8614a28565b9050602002016020810190611bdd9190614515565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611c1957611c19614a28565b90506020020135604051611c2f91815260200190565b60405180910390a280611c4181614a67565b915050611b50565b50505050505050565b6009546000906001600160a01b0316331480611c7857506000546001600160a01b031633145b611c945760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480611caf57506001821515145b611ccb5760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b01b0260ff60b01b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600890820152672a3930b739b332b960c11b6060820152901515602082015260800190565b6001600160a01b038116600090815260086020526040812060010154158015611d7f57506001600160a01b0382166000908152600b602052604090205460ff1615156001145b80156110055750816001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de89190614b5c565b670de0b6b3a76400001492915050565b600080546001600160a01b03163314611e1757611005600160126133f4565b6001600160a01b03821660009081526008602052604090205460ff1615611e4457611005600a60116133f4565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea69190614b8b565b506001600160a01b03821660009081526008602052604081208054600160ff1991821681178355600383018054909216909155810191909155611ee8836134a5565b611ef18361358d565b6040516001600160a01b03841681527fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90602001611342565b6001600160a01b0381166000908152600760209081526040808320805482518185028101850190935280835260609493830182828015611f9357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f75575b5093979650505050505050565b6060600c805480602002602001604051908101604052809291908181526020018280548015611ff857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611fda575b5050505050905090565b600061100582613689565b600954600090600160b01b900460ff161561205f5760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b6044820152606401610c89565b600061206c868685613694565b9050801561207b5790506111b5565b60009695505050505050565b805160609060008167ffffffffffffffff8111156120a7576120a76147e8565b6040519080825280602002602001820160405280156120d0578160200160208202803683370190505b50905060005b828110156121475760008582815181106120f2576120f2614a28565b60200260200101519050612106813361374c565b601181111561211757612117614b75565b83838151811061212957612129614a28565b6020908102919091010152508061213f81614a67565b9150506120d6565b509392505050565b600080600061215d86612bec565b9050600061216a86612bec565b9050811580612177575080155b1561218b57600d6000935093505050612293565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef9190614b5c565b905060006122096040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260055481528451928301909452888252919261224591613840565b925061226d604051806020016040528088815250604051806020016040528088815250613840565b91506122798383613888565b9050612285818b61348d565b600099509750505050505050505b935093915050565b600954600090600160b81b900460ff16156122ea5760405162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b6044820152606401610c89565b6001600160a01b03861660009081526008602052604090205460ff16158061232b57506001600160a01b03851660009081526008602052604090205460ff16155b156123375760096118eb565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614b3f565b6001600160a01b0316866001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190614b3f565b6001600160a01b03161461207b5760026118eb565b6001600160a01b0383166000908152600b602052604081205460ff16156124755760405162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661249c576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff1661259957336001600160a01b0385161461251d5760405162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329031aa37b5b2b760591b6044820152606401610c89565b6000612529338561374c565b9050600081601181111561253f5761253f614b75565b1461255e5780601181111561255657612556614b75565b91505061134d565b6001600160a01b038086166000908152600860209081526040808320938816835260029093019052205460ff1661259757612597614ba8565b505b6125a284612bec565b6000036125b057600d611707565b6001600160a01b0384166000908152601560205260409020548015612695576000856001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190614b5c565b905060006126418286613109565b90508281106126925760405162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f77206361702072656163686564000000000000006044820152606401610c89565b50505b6000806126a58688600088613121565b919350909150600090508260118111156126c1576126c1614b75565b146126e2578160118111156126d8576126d8614b75565b935050505061134d565b80156126ef5760046126d8565b6000979650505050505050565b6007602052816000526040600020818154811061271857600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080546001600160a01b0316331461275a57612753600160066133f4565b9050611005565b6001600160a01b0383166000908152600860205260409020805460ff1661278f57612787600960076133f4565b915050611005565b60408051602080820183528582528251908101909252670c7d713b49da00008252906127bd81835190511090565b156127d8576127ce600660086133f4565b9350505050611005565b84158015906127ed57506127eb86612bec565b155b156127fe576127ce600d60096133f4565b60018301805490869055604080516001600160a01b0389168152602081018390529081018790527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a160005b979650505050505050565b60008061286e858585613694565b9050801561287d57905061134d565b600095945050505050565b6040516361bfb47160e11b815233600482015260009082908290819081906001600160a01b0385169063c37f68e290602401608060405180830381865afa1580156128d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fb9190614bbe565b50925092509250826000146129605760405162461bcd60e51b815260206004820152602560248201527f657869744d61726b65743a206765744163636f756e74536e617073686f742066604482015264185a5b195960da1b6064820152608401610c89565b801561297c57612972600c60026133f4565b9695505050505050565b6000612989873385613694565b9050801561299e57612855600e6003836138c2565b6001600160a01b0385166000908152600860209081526040808320338452600281019092529091205460ff166129dd5760005b98975050505050505050565b3360009081526002820160209081526040808320805460ff191690556007825280832080548251818502810185019093528083529192909190830182828015612a4f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a31575b5050835193945083925060009150505b82811015612ab357896001600160a01b0316848281518110612a8357612a83614a28565b60200260200101516001600160a01b031603612aa157809150612ab3565b80612aab81614a67565b915050612a5f565b50818110612ac357612ac3614ba8565b33600090815260076020526040902080548190612ae290600190614a54565b81548110612af257612af2614a28565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110612b2257612b22614a28565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480612b6057612b60614bf4565b600082815260209020810160001990810180546001600160a01b03191690550190556040517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90612bc9908c9033906001600160a01b0392831681529116602082015260400190565b60405180910390a160009c9b505050505050505050505050565b6111868161393a565b6000806000604051602001612c0b90630c68aa8960e31b815260040190565b60405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c5f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c879190810190614c0a565b604051602001612c979190614c9e565b6040516020818303038152906040528051906020012003612cc857612cc16208aa8960eb1b6139be565b9150613102565b604051640c6ae8aa8960db1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d589190810190614c0a565b604051602001612d689190614c9e565b6040516020818303038152906040528051906020012003612d9257612cc16208aa8960eb1b6139be565b60405164635553444360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612dfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e229190810190614c0a565b604051602001612e329190614c9e565b6040516020818303038152906040528051906020012003612e6c57612e5d635553444360e01b6139be565b612cc19064e8d4a51000614cba565b6040516418d554d11560da1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612efc9190810190614c0a565b604051602001612f0c9190614c9e565b6040516020818303038152906040528051906020012003612f3757612e5d631554d11560e21b6139be565b60405164635742544360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fc79190810190614c0a565b604051602001612fd79190614c9e565b6040516020818303038152906040528051906020012003613010576130016242544360e81b6139be565b612cc1906402540be400614cba565b6000846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130749190614b3f565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156130b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130d99190810190614c0a565b905060008082905080516000036130ef57600091505b60208301519150819350612855846139be565b5092915050565b600061134d8284614cd1565b600061134d8284614a54565b600080600061312e61435f565b6001600160a01b03881660009081526007602090815260408083208054825181850281018501909352808352849383018282801561319557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613177575b5050505050905060005b815181101561339e5760008282815181106131bc576131bc614a28565b60209081029190910101516040516361bfb47160e11b81526001600160a01b038e811660048301529192509082169063c37f68e290602401608060405180830381865afa158015613211573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132359190614bbe565b6080890152606088015260408701529350831561326157600f6000809750975097505050505050611680565b60408051602080820183526001600160a01b03841660009081526008825283902060010154825260c088019190915281519081019091526080860151815260e08601526132ad81612bec565b60a086018190526000036132d057600d6000809750975097505050505050611680565b604080516020810190915260a0860151815261010086015260c085015160e086015161330a916132ff91613840565b866101000151613840565b610120860181905260408601518651613324929190613a2e565b855261010085015160608601516020870151613341929190613a2e565b60208601526001600160a01b03808c169082160361338b5761336d8561012001518b8760200151613a2e565b60208601819052610100860151613385918b90613a2e565b60208601525b508061339681614a67565b91505061319f565b506020830151835111156133cf57602083015183516000916133bf91614a54565b6000955095509550505050611680565b600080846000015185602001516133e69190614a54565b955095509550505050611680565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561342957613429614b75565b83601381111561343b5761343b614b75565b60408051928352602083019190915260009082015260600160405180910390a182601181111561134d5761134d614b75565b6000806000613480846000806000613121565b9250925092509193909250565b60008061349a8484613a4f565b90506111b581613a77565b60005b600c5481101561353a57816001600160a01b0316600c82815481106134cf576134cf614a28565b6000918252602090912001546001600160a01b0316036135285760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08185b1c9958591e48185919195960621b6044820152606401610c89565b8061353281614a67565b9150506134a8565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b0392909216919091179055565b60006135ce436040518060400160405280601c81526020017f626c6f636b206e756d6265722065786365656473203332206269747300000000815250613a8f565b6001600160a01b0383166000908152600f60209081526040808320601090925282208154939450909290916001600160e01b03909116900361362a5781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b031660000361365c5780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b600061100582613abf565b6001600160a01b03831660009081526008602052604081205460ff166136bb576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff166136f3576000611707565b6000806137038587866000613121565b9193509091506000905082601181111561371f5761371f614b75565b1461373f5781601181111561373657613736614b75565b9250505061134d565b801561207b576004613736565b6001600160a01b0382166000908152600860205260408120805460ff16613777576009915050611005565b6001600160a01b038316600090815260028201602052604090205460ff1615156001036137a8576000915050611005565b6001600160a01b03838116600081815260028401602090815260408083208054600160ff199091168117909155600783528184208054918201815584529282902090920180546001600160a01b031916948916948517905581519384528301919091527f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5910160405180910390a15060009392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061387586600001518660000151613b7a565b61387f9190614cfa565b90529392505050565b604080516020810190915260008152604051806020016040528061387f6138bb8660000151670de0b6b3a7640000613b7a565b8551613b86565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460118111156138f7576138f7614b75565b84601381111561390957613909614b75565b604080519283526020830191909152810184905260600160405180910390a18360118111156111b5576111b5614b75565b60006139486103e883614cfa565b90508042101561398a57603c61395e4283614a54565b11156139865760405163b6b0916d60e01b815260048101829052426024820152604401610c89565b5050565b60b46139968242614a54565b111561398657604051630321d0b560e01b815260048101829052426024820152604401610c89565b6040805160018082528183019092526000918291906020808301908036833701905050905082816000815181106139f7576139f7614a28565b602002602001018181525050613a0c81613b92565b600081518110613a1e57613a1e614a28565b6020026020010151915050919050565b600080613a3b8585613a4f565b9050611a6b613a4982613a77565b84613109565b604080516020810190915260008152604051806020016040528061387f856000015185613b7a565b805160009061100590670de0b6b3a764000090614cfa565b6000816401000000008410613ab75760405162461bcd60e51b8152600401610c899190614902565b509192915050565b60008151600003613ae357604051639e198af960e01b815260040160405180910390fd5b613aec82613b9d565b600060028351613afc9190614cfa565b905060028351613b0c9190614d0e565b600003613b68576000613b5b84613b24600185614a54565b81518110613b3457613b34614a28565b6020026020010151858481518110613b4e57613b4e614a28565b6020026020010151613109565b90506111b5600282614cfa565b828181518110613a1e57613a1e614a28565b600061134d8284614cba565b600061134d8284614cfa565b606061100582613be5565b8051602082016020820281019150805b828110156105f557815b81811015613bdc578151815180821015613bd2578084528183525b5050602001613bb7565b50602001613bad565b60606000825167ffffffffffffffff811115613c0357613c036147e8565b604051908082528060200260200182016040528015613c2c578160200160208202803683370190505b5090506000835167ffffffffffffffff811115613c4b57613c4b6147e8565b604051908082528060200260200182016040528015613c74578160200160208202803683370190505b5090506000845167ffffffffffffffff811115613c9357613c936147e8565b604051908082528060200260200182016040528015613cc657816020015b6060815260200190600190039081613cb15790505b50905060005b8551811015613d245760408051600380825260808201909252906020820160608036833701905050828281518110613d0657613d06614a28565b60200260200101819052508080613d1c90614a67565b915050613ccc565b506000613d2f613d9e565b90506000613d3c82613e45565b61ffff169050613d4d600283614cd1565b60405190925060005b82811015613d93576000613d6d8a89898989613e7f565b9050613d798186614cd1565b945082604052508080613d8b90614a67565b915050613d56565b506129d1848761411f565b60006602ed57011e0000601f1936013581161480613dcf576040516373bb264f60e11b815260040160405180910390fd5b60003660291115613df357604051632bcb7bc560e11b815260040160405180910390fd5b5060281936013560006009613e0e600362ffffff8516614cd1565b613e189190614cd1565b905036613e26600283614cd1565b111561134d5760405163c30a7bd760e01b815260040160405180910390fd5b600080613e53602084614cd1565b905036811115613e7657604051632bcb7bc560e11b815260040160405180910390fd5b36033592915050565b600080600080613e8e85614238565b909250905060008080606081600d613eb1613eaa602089614cd1565b8990613b7a565b613ebb9190614cd1565b90506000613ed4613ecd60688d614cd1565b3690613115565b90506000613ef183613ee760418f614cd1565b613ecd9190614cd1565b9050613efd8382613f10565b9350826020850120945081359650613f34565b60408051838152602081850181019092526000910183838237601f19019392505050565b613f458765ffffffffffff16612be3565b613f5985613f5460418f614cd1565b614288565b9550613f6486611548565b60ff1699505050505050505060008060005b848110156140ec57613f89888583614300565b909350915060005b8c518110156140d9578c8181518110613fac57613fac614a28565b602002602001015184036140c75760008b8281518110613fce57613fce614a28565b60200260200101519050613fe781896001901b16151590565b1580156140105750600360ff168d838151811061400657614006614a28565b6020026020010151105b156140c1578c828151811061402757614027614a28565b60200260200101805180919061403c90614a67565b81525050838b838151811061405357614053614a28565b602002602001015160018f858151811061406f5761406f614a28565b60200260200101516140819190614a54565b8151811061409157614091614a28565b60209081029190910101526001881b81178c83815181106140b4576140b4614a28565b6020026020010181815250505b506140d9565b806140d181614a67565b915050613f91565b50806140e481614a67565b915050613f76565b505050816020826140fd9190614cd1565b6141079190614cba565b61411290604e614cd1565b9998505050505050505050565b60606000835167ffffffffffffffff81111561413d5761413d6147e8565b604051908082528060200260200182016040528015614166578160200160208202803683370190505b509050600360005b855181101561422e578185828151811061418a5761418a614a28565b602002602001015110156141d7578481815181106141aa576141aa614a28565b602002602001015182604051632b13aef560e01b8152600401610c89929190918252602082015260400190565b60006141fb8783815181106141ee576141ee614a28565b6020026020010151612002565b90508084838151811061421057614210614a28565b6020908102919091010152508061422681614a67565b91505061416e565b5090949350505050565b600080808080614249604187614cd1565b9050600061425b613ecd602084614cd1565b80359450905061426c816003613115565b62ffffff9490941697933563ffffffff16965092945050505050565b60408051600080825260208083018085528690523685900380850135831a948401859052803560608501819052910135608084018190529193909260019060a0016020604051602081039080840390855afa1580156142eb573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000808061430f604e87614cd1565b9050600061433c614335614324602089614cd1565b61432f886001614cd1565b90613b7a565b8390613109565b9050600061434a3683613115565b80359960209091013598509650505050505050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016143ab6040518060200160405280600081525090565b81526020016143c66040518060200160405280600081525090565b81526020016143e16040518060200160405280600081525090565b81526020016143fc6040518060200160405280600081525090565b905290565b60008083601f84011261441357600080fd5b50813567ffffffffffffffff81111561442b57600080fd5b6020830191508360208260051b850101111561444657600080fd5b9250929050565b6000806000806040858703121561446357600080fd5b843567ffffffffffffffff8082111561447b57600080fd5b61448788838901614401565b909650945060208701359150808211156144a057600080fd5b506144ad87828801614401565b95989497509550505050565b6001600160a01b038116811461118657600080fd5b801515811461118657600080fd5b600080604083850312156144ef57600080fd5b82356144fa816144b9565b9150602083013561450a816144ce565b809150509250929050565b60006020828403121561452757600080fd5b813561134d816144b9565b600080600080600060a0868803121561454a57600080fd5b8535614555816144b9565b94506020860135614565816144b9565b93506040860135614575816144b9565b94979396509394606081013594506080013592915050565b600080600080608085870312156145a357600080fd5b84356145ae816144b9565b935060208501356145be816144b9565b925060408501356145ce816144b9565b9396929550929360600135925050565b6000602082840312156145f057600080fd5b813561134d816144ce565b60006020828403121561460d57600080fd5b5035919050565b6000806000806080858703121561462a57600080fd5b8435614635816144b9565b93506020850135614645816144b9565b93969395505050506040820135916060013590565b60008060008060008060c0878903121561467357600080fd5b863561467e816144b9565b9550602087013561468e816144b9565b9450604087013561469e816144b9565b935060608701356146ae816144b9565b9598949750929560808101359460a0909101359350915050565b6000806000606084860312156146dd57600080fd5b83356146e8816144b9565b925060208401356146f8816144b9565b929592945050506040919091013590565b600080600080600060a0868803121561472157600080fd5b853561472c816144b9565b9450602086013561473c816144b9565b9350604086013561474c816144b9565b9250606086013561475c816144b9565b949793965091946080013592915050565b6000806040838503121561478057600080fd5b823561478b816144b9565b9150602083013561450a816144b9565b6020808252825182820181905260009190848201906040850190845b818110156147dc5783516001600160a01b0316835292840192918401916001016147b7565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614827576148276147e8565b604052919050565b600067ffffffffffffffff821115614849576148496147e8565b5060051b60200190565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b80356148a161489c8261482f565b6147fe565b81815260059190911b820183019083810190878311156148c057600080fd5b928401925b82841015612855578335825292840192908401906148c5565b60005b838110156148f95781810151838201526020016148e1565b50506000910152565b60208152600082518060208401526149218160408501602087016148de565b601f01601f19169190910160400192915050565b6000602080838503121561494857600080fd5b823567ffffffffffffffff81111561495f57600080fd5b8301601f8101851361497057600080fd5b803561497e61489c8261482f565b81815260059190911b8201830190838101908783111561499d57600080fd5b928401925b828410156128555783356149b5816144b9565b825292840192908401906149a2565b6020808252825182820181905260009190848201906040850190845b818110156147dc578351835292840192918401916001016149e0565b60008060408385031215614a0f57600080fd5b8235614a1a816144b9565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561100557611005614a3e565b600060018201614a7957614a79614a3e565b5060010190565b60208082526028908201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6040820152671d081b1a5cdd195960c21b606082015260800190565b60208082526027908201527f6f6e6c7920706175736520677561726469616e20616e642061646d696e2063616040820152666e20706175736560c81b606082015260800190565b6020808252601690820152756f6e6c792061646d696e2063616e20756e706175736560501b604082015260600190565b600060208284031215614b5157600080fd5b815161134d816144b9565b600060208284031215614b6e57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614b9d57600080fd5b815161134d816144ce565b634e487b7160e01b600052600160045260246000fd5b60008060008060808587031215614bd457600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614c1c57600080fd5b815167ffffffffffffffff80821115614c3457600080fd5b818401915084601f830112614c4857600080fd5b815181811115614c5a57614c5a6147e8565b614c6d601f8201601f19166020016147fe565b9150808252856020828501011115614c8457600080fd5b614c958160208401602086016148de565b50949350505050565b60008251614cb08184602087016148de565b9190910192915050565b808202811582820484141761100557611005614a3e565b8082018082111561100557611005614a3e565b634e487b7160e01b600052601260045260246000fd5b600082614d0957614d09614ce4565b500490565b600082614d1d57614d1d614ce4565b50069056fea2646970667358221220bafd5e6394cb5564fc079ac4bc62f2bead18ad908f73aa6a16a21b14bd82f29564736f6c63430008120033
Deployed Bytecode Sourcemap
89114:28162:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37584:41;;37621:4;37584:41;;;;;179:14:1;;172:22;154:41;;142:2;127:18;37584:41:0;;;;;;;;115200:1411;;;;;;:::i;:::-;;:::i;:::-;;113678:509;;;;;;:::i;:::-;;:::i;114958:234::-;;;;;;:::i;:::-;;:::i;80166:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2718:25:1;;;2706:2;2691:18;80166:42:0;2572:177:1;99696:369:0;;;;;;:::i;:::-;;;;;;;80621:32;;;;;-1:-1:-1;;;;;80621:32:0;;;;;;-1:-1:-1;;;;;3614:32:1;;;3596:51;;3584:2;3569:18;80621:32:0;3450:203:1;99310:378:0;;;;;;:::i;:::-;;:::i;79642:28::-;;;;;-1:-1:-1;;;;;79642:28:0;;;78969:27;;;;;-1:-1:-1;;;;;78969:27:0;;;114581:369;;;;;;:::i;:::-;;:::i;107914:391::-;;;;;;:::i;:::-;;:::i;112371:355::-;;;;;;:::i;:::-;;:::i;113167:503::-;;;;;;:::i;:::-;;:::i;79677:31::-;;;;;-1:-1:-1;;;79677:31:0;;;;;;36801:662;;;;;;:::i;:::-;;:::i;:::-;;;4888:4:1;4876:17;;;4858:36;;4846:2;4831:18;36801:662:0;4716:184:1;94408:273:0;;;;;;:::i;:::-;;;;;;117174:99;117253:12;117174:99;;101290:457;;;;;;:::i;:::-;;;;;;;;80662:42;;;;;;:::i;:::-;;;;;;;;;;;;;;79214:40;;;;;;104330:408;;;;;;:::i;:::-;;:::i;:::-;;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;6583:18;;;6576:34;6487:2;6472:18;104330:408:0;6297:319:1;94036:364:0;;;;;;:::i;:::-;;:::i;109612:552::-;;;;;;:::i;:::-;;:::i;95714:267::-;;;;;;:::i;:::-;;:::i;80102:26::-;;;;;;:::i;:::-;;:::i;99069:233::-;;;;;;:::i;:::-;;;;;103841:277;;;;;;:::i;:::-;;:::i;112734:425::-;;;;;;:::i;:::-;;:::i;100073:1209::-;;;;;;:::i;:::-;;:::i;111760:603::-;;;;;;:::i;:::-;;:::i;103222:256::-;;;;;;:::i;81017:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;80217:58;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80217:58:0;;;-1:-1:-1;;;80217:58:0;;;;;;;;;;-1:-1:-1;;;;;9081:32:1;;;9063:51;;9162:10;9150:23;;;9145:2;9130:18;;9123:51;9036:18;80217:58:0;8891:289:1;79891:52:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;102418:386;;;;;;:::i;79834:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;81178:46;;;;;;:::i;:::-;;;;;;;;;;;;;;79755:34;;;;;-1:-1:-1;;;79755:34:0;;;;;;80284:58;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80284:58:0;;;-1:-1:-1;;;80284:58:0;;;;;;79592:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9400:14:1;;9393:22;9375:41;;9447:2;9432:18;;9425:34;;;;9502:14;9495:22;9475:18;;;9468:50;9363:2;9348:18;79592:41:0;9185:339:1;114195:378:0;;;;;;:::i;:::-;;:::i;91374:163::-;;;;;;:::i;:::-;-1:-1:-1;;;;;91478:24:0;;;91454:4;91478:24;;;:7;:24;;;;;;;;:51;;;;;:42;;;;:51;;;;;;91374:163;;;;;116882:284;;;;;;:::i;:::-;;:::i;79263:21::-;;;;;;80775:53;;;;;;:::i;:::-;;;;;;;;;;;;;;110172:745;;;;;;:::i;:::-;;:::i;90879:47::-;;90922:4;90879:47;;;;;-1:-1:-1;;;;;10392:32:1;;;10374:51;;10362:2;10347:18;90879:47:0;10228:203:1;80137:20:0;;;;;;91192:174;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;79796:31::-;;;;;-1:-1:-1;;;79796:31:0;;;;;;116775:99;;;:::i;80351:69::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;20964:151;;;;;;:::i;:::-;;:::i;79005:40::-;;;;;-1:-1:-1;;;;;79005:40:0;;;102812:402;;;;;;:::i;:::-;;:::i;80837:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;36562:124;36650:30;;;;;;;;;;;-1:-1:-1;;;36650:30:0;;;;36562:124;;;;36650:30;36562:124;:::i;91545:388::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;106831:1075::-;;;;;;:::i;:::-;;:::i;:::-;;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;;15438:18;106831:1075:0;15291:248:1;80429:69:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;80507:43;;;;;;:::i;:::-;;;;;;;;;;;;;;101755:655;;;;;;:::i;:::-;;:::i;97618:1443::-;;;;;;:::i;:::-;;:::i;79293:49::-;;;;;;:::i;:::-;;:::i;79054:47::-;;;;;-1:-1:-1;;;;;79054:47:0;;;108313:1291;;;;;;:::i;:::-;;:::i;79715:33::-;;;;;-1:-1:-1;;;79715:33:0;;;;;;79174:31;;;;;;94689:324;;;;;;:::i;:::-;;:::i;92514:1514::-;;;;;;:::i;:::-;;:::i;81136:33::-;;;;;;;;;80960:48;;;;;;:::i;:::-;;;;;;;;;;;;;;20170:167;;;;;;:::i;:::-;;:::i;78940:20::-;;;;;-1:-1:-1;;;;;78940:20:0;;;36692:103;36788:1;36692:103;;95989:1621;;;;;;:::i;:::-;;:::i;115200:1411::-;115325:5;;-1:-1:-1;;;;;115325:5:0;115311:10;:19;115303:65;;;;-1:-1:-1;;;115303:65:0;;16417:2:1;115303:65:0;;;16399:21:1;16456:2;16436:18;;;16429:30;16495:34;16475:18;;;16468:62;-1:-1:-1;;;16546:18:1;;;16539:31;16587:19;;115303:65:0;;;;;;;;;115389:21;;;;115388:22;115380:73;;;;-1:-1:-1;;;115380:73:0;;16819:2:1;115380:73:0;;;16801:21:1;16858:2;16838:18;;;16831:30;16897:34;16877:18;;;16870:62;-1:-1:-1;;;16948:18:1;;;16941:36;16994:19;;115380:73:0;16617:402:1;115380:73:0;115473:38;;;115465:64;;;;-1:-1:-1;;;115465:64:0;;17226:2:1;115465:64:0;;;17208:21:1;17265:2;17245:18;;;17238:30;-1:-1:-1;;;17284:18:1;;;17277:43;17337:18;;115465:64:0;17024:337:1;115465:64:0;115542:12;115565:19;115595:21;115627:15;115660:6;115655:907;115672:24;;;115655:907;;;115725:13;;115739:1;115725:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;115773:17:0;;;;;;:11;:17;;;;;;115718:23;;-1:-1:-1;115773:17:0;-1:-1:-1;115826:7:0;;115834:1;115826:10;;;;;;;:::i;:::-;;;;;;;115807:29;;115876:14;115857:16;:33;115853:469;;;115913:22;115938:33;115957:14;115938:16;:33;:::i;:::-;-1:-1:-1;;;;;116014:20:0;;115993:18;116014:20;;;:14;:20;;;;;;115913:58;;-1:-1:-1;116074:38:0;116014:20;115913:58;116074:4;:38::i;:::-;-1:-1:-1;;;;;116133:20:0;;;;;;:14;:20;;;;;;;;;:36;;;116195:57;;15465:25:1;;;15506:18;;;15499:34;;;116133:36:0;;-1:-1:-1;116133:20:0;;116195:57;;15438:18:1;116195:57:0;;;;;;;116292:14;116273:33;;115892:430;;;115853:469;116342:20;;116338:213;;116418:38;116423:14;116439:16;116418:4;:38::i;:::-;-1:-1:-1;;;;;116385:17:0;;;;;;:11;:17;;;;;;;;;:71;;;116482:53;;15465:25:1;;;15506:18;;;15499:34;;;116385:71:0;;-1:-1:-1;116385:17:0;;116482:53;;15438:18:1;116482:53:0;;;;;;;116338:213;115698:3;;;:::i;:::-;;;115655:907;;;-1:-1:-1;;116574:21:0;:28;;-1:-1:-1;;116574:28:0;116598:4;116574:28;;;-1:-1:-1;;;;;;;115200:1411:0:o;113678:509::-;-1:-1:-1;;;;;113772:24:0;;113747:4;113772:24;;;:7;:24;;;;;:33;;;113764:86;;;;-1:-1:-1;;;113764:86:0;;;;;;;:::i;:::-;113883:13;;-1:-1:-1;;;;;113883:13:0;113869:10;:27;;:50;;-1:-1:-1;113914:5:0;;-1:-1:-1;;;;;113914:5:0;113900:10;:19;113869:50;113861:102;;;;-1:-1:-1;;;113861:102:0;;;;;;;:::i;:::-;113996:5;;-1:-1:-1;;;;;113996:5:0;113982:10;:19;;:36;;-1:-1:-1;114014:4:0;114005:13;;;;113982:36;113974:71;;;;-1:-1:-1;;;113974:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;114058:37:0;;;;;;:20;:37;;;;;;;;;:45;;-1:-1:-1;;114058:45:0;;;;;;;;;;114119:37;;19320:51:1;;;19407:2;19387:18;;;19380:30;;;19446:1;19426:18;;;19419:29;;;;-1:-1:-1;;;19479:3:1;19464:19;;19457:37;19546:18;;;19539:50;114119:37:0;;19358:3:1;19511:19;114119:37:0;;;;;;;;-1:-1:-1;114174:5:0;113678:509;;;;;:::o;114958:234::-;115038:10;-1:-1:-1;;;;;115038:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;115024:32:0;:10;-1:-1:-1;;;;;115024:32:0;;115016:84;;;;-1:-1:-1;;;115016:84:0;;20066:2:1;115016:84:0;;;20048:21:1;20105:2;20085:18;;;20078:30;20144:34;20124:18;;;20117:62;-1:-1:-1;;;20195:18:1;;;20188:37;20242:19;;115016:84:0;19864:403:1;115016:84:0;115119:10;-1:-1:-1;;;;;115119:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;115111:73;;;;-1:-1:-1;;;115111:73:0;;20663:2:1;115111:73:0;;;20645:21:1;20702:2;20682:18;;;20675:30;-1:-1:-1;;;20721:18:1;;;20714:51;20782:18;;115111:73:0;20461:345:1;115111:73:0;114958:234;:::o;99310:378::-;-1:-1:-1;;;;;99552:15:0;;99469:4;99552:15;;;:7;:15;;;;;:24;;;99547:94;;-1:-1:-1;99605:23:0;99593:36;;99547:94;-1:-1:-1;99665:14:0;99310:378;;;;;;;:::o;114581:369::-;114673:13;;114634:4;;-1:-1:-1;;;;;114673:13:0;114659:10;:27;;:50;;-1:-1:-1;114704:5:0;;-1:-1:-1;;;;;114704:5:0;114690:10;:19;114659:50;114651:102;;;;-1:-1:-1;;;114651:102:0;;;;;;;:::i;:::-;114786:5;;-1:-1:-1;;;;;114786:5:0;114772:10;:19;;:36;;-1:-1:-1;114804:4:0;114795:13;;;;114772:36;114764:71;;;;-1:-1:-1;;;114764:71:0;;;;;;;:::i;:::-;114848:19;:27;;;;;-1:-1:-1;;;114848:27:0;-1:-1:-1;;;;114848:27:0;;;;;;114891:28;;;;;;114870:5;;21167:2:1;21149:21;;;21206:1;21186:18;;;21179:29;-1:-1:-1;;;21239:2:1;21224:18;;21217:35;21333:14;;21326:22;21319:4;21304:20;;21297:52;21284:3;21269:19;;20943:412;114891:28:0;;;;;;;;-1:-1:-1;114937:5:0;114581:369::o;107914:391::-;107986:4;108024:5;;-1:-1:-1;;;;;108024:5:0;108010:10;:19;108002:63;;;;-1:-1:-1;;;108002:63:0;;21562:2:1;108002:63:0;;;21544:21:1;21601:2;21581:18;;;21574:30;21640:33;21620:18;;;21613:61;21691:18;;108002:63:0;21360:355:1;108002:63:0;108108:19;;;108138:44;;;;108198:59;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;108198:59:0;;15438:18:1;108198:59:0;;;;;;;;108282:14;108277:20;108270:27;107914:391;-1:-1:-1;;;107914:391:0:o;112371:355::-;112474:5;;-1:-1:-1;;;;;112474:5:0;112460:10;:19;112452:70;;;;-1:-1:-1;;;112452:70:0;;21922:2:1;112452:70:0;;;21904:21:1;21961:2;21941:18;;;21934:30;22000:34;21980:18;;;21973:62;-1:-1:-1;;;22051:18:1;;;22044:36;22097:19;;112452:70:0;21720:402:1;112452:70:0;112566:17;;;-1:-1:-1;;;;;112596:40:0;;;-1:-1:-1;;;;;;112596:40:0;;;;;;;112654:64;;;112566:17;;;;22339:34:1;;;22404:2;22389:18;;22382:43;;;;112654:64:0;;22274:18:1;112654:64:0;;;;;;;112441:285;112371:355;:::o;113167:503::-;-1:-1:-1;;;;;113259:24:0;;113234:4;113259:24;;;:7;:24;;;;;:33;;;113251:86;;;;-1:-1:-1;;;113251:86:0;;;;;;;:::i;:::-;113370:13;;-1:-1:-1;;;;;113370:13:0;113356:10;:27;;:50;;-1:-1:-1;113401:5:0;;-1:-1:-1;;;;;113401:5:0;113387:10;:19;113356:50;113348:102;;;;-1:-1:-1;;;113348:102:0;;;;;;;:::i;:::-;113483:5;;-1:-1:-1;;;;;113483:5:0;113469:10;:19;;:36;;-1:-1:-1;113501:4:0;113492:13;;;;113469:36;113461:71;;;;-1:-1:-1;;;113461:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113545:35:0;;;;;;:18;:35;;;;;;;;;:43;;-1:-1:-1;;113545:43:0;;;;;;;;;;113604:35;;22685:51:1;;;22772:2;22752:18;;;22745:30;;;22811:1;22791:18;;;22784:29;;;;-1:-1:-1;;;22844:3:1;22829:19;;22822:35;22909:18;;;22902:50;113604:35:0;;22723:3:1;22874:19;113604:35:0;22436:522:1;36801:662:0;36906:5;-1:-1:-1;;;;;36924:59:0;;36941:42;36924:59;36920:538;;-1:-1:-1;37001:1:0;;36801:662;-1:-1:-1;36801:662:0:o;36920:538::-;-1:-1:-1;;;;;37020:59:0;;37037:42;37020:59;37016:442;;-1:-1:-1;37097:1:0;;36801:662;-1:-1:-1;36801:662:0:o;37016:442::-;-1:-1:-1;;;;;37116:59:0;;37133:42;37116:59;37112:346;;-1:-1:-1;37193:1:0;;36801:662;-1:-1:-1;36801:662:0:o;37112:346::-;-1:-1:-1;;;;;37212:59:0;;37229:42;37212:59;37208:250;;-1:-1:-1;37289:1:0;;36801:662;-1:-1:-1;36801:662:0:o;37208:250::-;-1:-1:-1;;;;;37308:59:0;;37325:42;37308:59;37304:154;;-1:-1:-1;37385:1:0;;36801:662;-1:-1:-1;36801:662:0:o;37304:154::-;37416:34;;-1:-1:-1;;;37416:34:0;;-1:-1:-1;;;;;3614:32:1;;37416:34:0;;;3596:51:1;3569:18;;37416:34:0;3450:203:1;104330:408:0;104506:4;104512;104518;104536:9;104547:14;104563;104581:98;104621:7;104637:12;104652;104666;104581:39;:98::i;:::-;104535:144;;;;;;104703:3;104698:9;;;;;;;;:::i;:::-;104690:40;-1:-1:-1;104709:9:0;;-1:-1:-1;104720:9:0;-1:-1:-1;;104330:408:0;;;;;;;;;:::o;94036:364::-;-1:-1:-1;;;;;94161:26:0;;94133:4;94161:26;;;:18;:26;;;;;;;;94160:27;94152:54;;;;-1:-1:-1;;;94152:54:0;;23165:2:1;94152:54:0;;;23147:21:1;23204:2;23184:18;;;23177:30;-1:-1:-1;;;23223:18:1;;;23216:44;23277:18;;94152:54:0;22963:338:1;94152:54:0;-1:-1:-1;;;;;94264:15:0;;;;;;:7;:15;;;;;:24;;;94259:94;;94317:23;94312:29;94305:36;;;;94259:94;94377:14;94365:27;94036:364;-1:-1:-1;;;;94036:364:0:o;109612:552::-;109702:4;109739:5;;-1:-1:-1;;;;;109739:5:0;109725:10;:19;109721:134;;109768:75;109773:18;109793:49;109768:4;:75::i;109721:134::-;109906:28;;;109947:62;;;;110027:89;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;110027:89:0;;15438:18:1;110027:89:0;15291:248:1;95714:267:0;95881:17;;:37;;;;;95917:1;95902:12;:16;95881:37;95877:97;;;95935:27;;-1:-1:-1;;;95935:27:0;;23508:2:1;95935:27:0;;;23490:21:1;23547:2;23527:18;;;23520:30;-1:-1:-1;;;23566:18:1;;;23559:47;23623:18;;95935:27:0;23306:341:1;80102:26:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80102:26:0;;-1:-1:-1;80102:26:0;:::o;103841:277::-;103908:4;103914;103920;103938:9;103949:14;103965;103983:74;104023:7;104047:1;104052;104055;103983:39;:74::i;:::-;103937:120;;;;;;104083:3;104078:9;;;;;;;;:::i;:::-;104070:40;104089:9;;-1:-1:-1;104089:9:0;-1:-1:-1;103841:277:0;-1:-1:-1;;;103841:277:0:o;112734:425::-;112803:4;112838:5;;-1:-1:-1;;;;;112838:5:0;112824:10;:19;112820:127;;112867:68;112872:18;112892:42;112867:4;:68::i;112820:127::-;112986:13;;;-1:-1:-1;;;;;113012:32:0;;;-1:-1:-1;;;;;;113012:32:0;;;;;;;113062:49;;;112986:13;;;;22339:34:1;;;22404:2;22389:18;;22382:43;;;;113062:49:0;;22274:18:1;113062:49:0;22127:304:1;100073:1209:0;-1:-1:-1;;;;;100331:23:0;;100284:4;100331:23;;;:7;:23;;;;;:32;;;100330:33;;:72;;-1:-1:-1;;;;;;100368:25:0;;;;;;:7;:25;;;;;:34;;;100367:35;100330:72;100326:141;;;100431:23;100426:29;100419:36;;;;100326:141;100500:52;;-1:-1:-1;;;100500:52:0;;-1:-1:-1;;;;;3614:32:1;;;100500:52:0;;;3596:51:1;100479:18:0;;100500:42;;;;;;3569:18:1;;100500:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100479:73;;100569:36;100589:14;100569:12;:36::i;:::-;100565:672;;;100647:11;100630:13;:28;;100622:81;;;;-1:-1:-1;;;100622:81:0;;23854:2:1;100622:81:0;;;23836:21:1;23893:2;23873:18;;;23866:30;23932:34;23912:18;;;23905:62;-1:-1:-1;;;23983:18:1;;;23976:38;24031:19;;100622:81:0;23652:404:1;100622:81:0;100565:672;;;100739:9;100752:14;100770:37;100798:8;100770:27;:37::i;:::-;100738:69;;-1:-1:-1;100738:69:0;;-1:-1:-1;100833:14:0;;-1:-1:-1;100826:3:0;:21;;;;;;;;:::i;:::-;;100822:78;;100880:3;100875:9;;;;;;;;:::i;:::-;100868:16;;;;;;;100822:78;100920:9;100933:1;100920:14;100916:96;;100967:28;100962:34;;100916:96;101028:13;101044:71;101063:36;;;;;;;;101078:19;;101063:36;;;101101:13;101044:18;:71::i;:::-;101028:87;;101148:8;101134:11;:22;101130:96;;;101189:20;101177:33;;;;;;;;101130:96;100721:516;;;100565:672;101259:14;101247:27;;;100073:1209;;;;;;;;:::o;111760:603::-;111887:5;;-1:-1:-1;;;;;111887:5:0;111873:10;:19;;:54;;-1:-1:-1;111910:17:0;;-1:-1:-1;;;;;111910:17:0;111896:10;:31;111873:54;111865:120;;;;-1:-1:-1;;;111865:120:0;;24263:2:1;111865:120:0;;;24245:21:1;24302:2;24282:18;;;24275:30;24341:34;24321:18;;;24314:62;-1:-1:-1;;;24392:18:1;;;24385:51;24453:19;;111865:120:0;24061:417:1;111865:120:0;112016:7;112062:13;112103:15;;;;;:46;;;112136:13;112122:10;:27;112103:46;112095:72;;;;-1:-1:-1;;;112095:72:0;;24685:2:1;112095:72:0;;;24667:21:1;24724:2;24704:18;;;24697:30;-1:-1:-1;;;24743:18:1;;;24736:43;24796:18;;112095:72:0;24483:337:1;112095:72:0;112184:6;112180:176;112200:10;112196:1;:14;112180:176;;;112266:13;;112280:1;112266:16;;;;;;;:::i;:::-;;;;;;;112232:10;:31;112251:7;;112259:1;112251:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;112232:31:0;;;;;;;;;;;;-1:-1:-1;112232:31:0;:50;112315:7;;112323:1;112315:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;112302:42:0;;112327:13;;112341:1;112327:16;;;;;;;:::i;:::-;;;;;;;112302:42;;;;2718:25:1;;2706:2;2691:18;;2572:177;112302:42:0;;;;;;;;112212:3;;;;:::i;:::-;;;;112180:176;;;;111857:506;;111760:603;;;;:::o;114195:378::-;114290:13;;114251:4;;-1:-1:-1;;;;;114290:13:0;114276:10;:27;;:50;;-1:-1:-1;114321:5:0;;-1:-1:-1;;;;;114321:5:0;114307:10;:19;114276:50;114268:102;;;;-1:-1:-1;;;114268:102:0;;;;;;;:::i;:::-;114403:5;;-1:-1:-1;;;;;114403:5:0;114389:10;:19;;:36;;-1:-1:-1;114421:4:0;114412:13;;;;114389:36;114381:71;;;;-1:-1:-1;;;114381:71:0;;;;;;;:::i;:::-;114465:22;:30;;;;;-1:-1:-1;;;114465:30:0;-1:-1:-1;;;;114465:30:0;;;;;;114511:31;;;;;;114490:5;;25049:2:1;25031:21;;;25088:1;25068:18;;;25061:29;-1:-1:-1;;;25121:2:1;25106:18;;25099:38;25218:14;;25211:22;25204:4;25189:20;;25182:52;25169:3;25154:19;;24825:415;116882:284:0;-1:-1:-1;;;;;116977:24:0;;116940:4;116977:24;;;:7;:24;;;;;:49;;;:54;:116;;;;-1:-1:-1;;;;;;117048:37:0;;;;;;:20;:37;;;;;;;;:45;;:37;:45;116977:116;:171;;;;;117110:6;-1:-1:-1;;;;;117110:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117144:4;117110:38;116957:191;116882:284;-1:-1:-1;;116882:284:0:o;110172:745::-;110229:4;110264:5;;-1:-1:-1;;;;;110264:5:0;110250:10;:19;110246:123;;110293:64;110298:18;110318:38;110293:4;:64::i;110246:123::-;-1:-1:-1;;;;;110385:24:0;;;;;;:7;:24;;;;;:33;;;110381:141;;;110442:68;110447:27;110476:33;110442:4;:68::i;110381:141::-;110534:6;-1:-1:-1;;;;;110534:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;110592:24:0;;110565;110592;;;:7;:24;;;;;110627:25;;110648:4;-1:-1:-1;;110627:25:0;;;;;;;110663:18;;;:26;;;;;;;;110700:34;;:38;;;;110751:35;110592:24;110751:18;:35::i;:::-;110797:34;110823:6;110797:17;:34::i;:::-;110849:20;;-1:-1:-1;;;;;3614:32:1;;3596:51;;110849:20:0;;3584:2:1;3569:18;110849:20:0;3450:203:1;91192:174:0;-1:-1:-1;;;;;91308:22:0;;91281:24;91308:22;;;:13;:22;;;;;;;;91281:49;;;;;;;;;;;;;;;;;91253:15;;91281:24;:49;;91308:22;91281:49;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;91281:49:0;;;;;;;;;;;;;;;;-1:-1:-1;91281:49:0;;91192:174;-1:-1:-1;;;;;;;91192:174:0:o;116775:99::-;116821:15;116856:10;116849:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;116849:17:0;;;;;;;;;;;;;;;;;;;;;;;116775:99;:::o;20964:151::-;21043:7;21066:43;21102:6;21066:35;:43::i;102812:402::-;102955:22;;102927:4;;-1:-1:-1;;;102955:22:0;;;;102954:23;102946:54;;;;-1:-1:-1;;;102946:54:0;;25697:2:1;102946:54:0;;;25679:21:1;25736:2;25716:18;;;25709:30;-1:-1:-1;;;25755:18:1;;;25748:48;25813:18;;102946:54:0;25495:342:1;102946:54:0;103013:12;103028:50;103050:6;103058:3;103063:14;103028:21;:50::i;:::-;103013:65;-1:-1:-1;103093:31:0;;103089:78;;103148:7;-1:-1:-1;103141:14:0;;103089:78;103191:14;103179:27;102812:402;-1:-1:-1;;;;;;102812:402:0:o;91545:388::-;91655:14;;91618:13;;91644:8;91655:14;91706:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91706:15:0;;91682:39;;91737:6;91732:167;91753:3;91749:1;:7;91732:167;;;91778:13;91801:7;91809:1;91801:10;;;;;;;;:::i;:::-;;;;;;;91778:34;;91847:39;91867:6;91875:10;91847:19;:39::i;:::-;91842:45;;;;;;;;:::i;:::-;91829:7;91837:1;91829:10;;;;;;;;:::i;:::-;;;;;;;;;;:58;-1:-1:-1;91758:3:0;;;;:::i;:::-;;;;91732:167;;;-1:-1:-1;91918:7:0;91545:388;-1:-1:-1;;;91545:388:0:o;106831:1075::-;106976:4;106982;107001:26;107030:42;107056:14;107030:18;:42::i;:::-;107001:71;;107083:28;107114:44;107140:16;107114:18;:44::i;:::-;107083:75;-1:-1:-1;107173:26:0;;;:58;;-1:-1:-1;107203:28:0;;107173:58;107169:126;;;107261:17;107281:1;107248:35;;;;;;;;107169:126;107307:25;107342:16;-1:-1:-1;;;;;107335:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107307:73;;107392:16;107419:20;-1:-1:-1;;;;;;;;;;;;;;107419:20:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;107529:45:0;;;;;;;107544:28;;107529:45;;107576:38;;;;;;;;;;;-1:-1:-1;;107524:91:0;;:4;:91::i;:::-;107512:103;;107640:85;107645:40;;;;;;;;107660:23;107645:40;;;107687:37;;;;;;;;107702:20;107687:37;;;107640:4;:85::i;:::-;107626:99;;107744:28;107749:9;107760:11;107744:4;:28::i;:::-;107736:36;;107799:44;107818:5;107825:17;107799:18;:44::i;:::-;107869:14;;-1:-1:-1;107785:58:0;-1:-1:-1;;;;;;;;106831:1075:0;;;;;;;:::o;101755:655::-;101984:19;;101956:4;;-1:-1:-1;;;101984:19:0;;;;101983:20;101975:48;;;;-1:-1:-1;;;101975:48:0;;26044:2:1;101975:48:0;;;26026:21:1;26083:2;26063:18;;;26056:30;-1:-1:-1;;;26102:18:1;;;26095:45;26157:18;;101975:48:0;25842:339:1;101975:48:0;-1:-1:-1;;;;;102065:25:0;;;;;;:7;:25;;;;;:34;;;102064:35;;:72;;-1:-1:-1;;;;;;102104:23:0;;;;;;:7;:23;;;;;:32;;;102103:33;102064:72;102060:141;;;102165:23;102160:29;;102060:141;102266:14;-1:-1:-1;;;;;102259:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102217:78:0;102224:16;-1:-1:-1;;;;;102217:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102217:78:0;;102213:150;;102324:26;102319:32;;97618:1443;-1:-1:-1;;;;;97749:28:0;;97721:4;97749:28;;;:20;:28;;;;;;;;97748:29;97740:58;;;;-1:-1:-1;;;97740:58:0;;26681:2:1;97740:58:0;;;26663:21:1;26720:2;26700:18;;;26693:30;-1:-1:-1;;;26739:18:1;;;26732:46;26795:18;;97740:58:0;26479:340:1;97740:58:0;-1:-1:-1;;;;;97816:15:0;;;;;;:7;:15;;;;;:24;;;97811:94;;97869:23;97864:29;;97811:94;-1:-1:-1;;;;;97922:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;97917:371;;97992:10;-1:-1:-1;;;;;97992:20:0;;;97984:54;;;;-1:-1:-1;;;97984:54:0;;27026:2:1;97984:54:0;;;27008:21:1;27065:2;27045:18;;;27038:30;-1:-1:-1;;;27084:18:1;;;27077:51;27145:18;;97984:54:0;26824:345:1;97984:54:0;98055:9;98067:49;98094:10;98107:8;98067:19;:49::i;:::-;98055:61;-1:-1:-1;98142:14:0;98135:3;:21;;;;;;;;:::i;:::-;;98131:78;;98189:3;98184:9;;;;;;;;:::i;:::-;98177:16;;;;;98131:78;-1:-1:-1;;;;;98232:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;98225:51;;;;:::i;:::-;97967:321;97917:371;98304:34;98330:6;98304:18;:34::i;:::-;98342:1;98304:39;98300:102;;98372:17;98367:23;;98300:102;-1:-1:-1;;;;;98431:18:0;;98414:14;98431:18;;;:10;:18;;;;;;98466:14;;98462:248;;98497:17;98524:6;-1:-1:-1;;;;;98517:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98497:49;;98561:21;98585:32;98590:12;98604;98585:4;:32::i;:::-;98561:56;;98659:9;98640:16;:28;98632:66;;;;-1:-1:-1;;;98632:66:0;;27508:2:1;98632:66:0;;;27490:21:1;27547:2;27527:18;;;27520:30;27586:27;27566:18;;;27559:55;27631:18;;98632:66:0;27306:349:1;98632:66:0;98482:228;;98462:248;98723:9;98736:14;98754:82;98794:8;98811:6;98820:1;98823:12;98754:39;:82::i;:::-;98722:114;;-1:-1:-1;98722:114:0;;-1:-1:-1;98858:14:0;;-1:-1:-1;98851:3:0;:21;;;;;;;;:::i;:::-;;98847:70;;98901:3;98896:9;;;;;;;;:::i;:::-;98889:16;;;;;;;98847:70;98931:13;;98927:87;;98973:28;98968:34;;98927:87;99038:14;99026:27;97618:1443;-1:-1:-1;;;;;;;97618:1443:0:o;79293:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;79293:49:0;;-1:-1:-1;79293:49:0;;-1:-1:-1;79293:49:0:o;108313:1291::-;108410:4;108447:5;;-1:-1:-1;;;;;108447:5:0;108433:10;:19;108429:130;;108476:71;108481:18;108501:45;108476:4;:71::i;:::-;108469:78;;;;108429:130;-1:-1:-1;;;;;108595:24:0;;108571:21;108595:24;;;:7;:24;;;;;108635:15;;;;108630:130;;108674:74;108679:23;108704:43;108674:4;:74::i;:::-;108667:81;;;;;108630:130;108808:44;;;;;;;;;;;;108888;;;;;;;;91117:6;108888:44;;108808;108947:46;108888:44;108808;52722:14;52706:13;;:30;;52603:141;108947:46;108943:169;;;109017:83;109022:31;109055:44;109017:4;:83::i;:::-;109010:90;;;;;;;108943:169;109128:32;;;;;:67;;;109164:26;109183:6;109164:18;:26::i;:::-;:31;109128:67;109124:179;;;109219:72;109224:17;109243:47;109219:4;:72::i;109124:179::-;109350:31;;;;;109392:61;;;;109471:85;;;-1:-1:-1;;;;;27895:32:1;;27877:51;;27959:2;27944:18;;27937:34;;;27987:18;;;27980:34;;;109471:85:0;;27865:2:1;27850:18;109471:85:0;;;;;;;109581:14;109576:20;109569:27;108313:1291;-1:-1:-1;;;;;;;108313:1291:0:o;94689:324::-;94792:4;94809:12;94824:53;94846:6;94854:8;94864:12;94824:21;:53::i;:::-;94809:68;-1:-1:-1;94892:31:0;;94888:78;;94947:7;-1:-1:-1;94940:14:0;;94888:78;94990:14;94978:27;94689:324;-1:-1:-1;;;;;94689:324:0:o;92514:1514::-;92701:37;;-1:-1:-1;;;92701:37:0;;92727:10;92701:37;;;3596:51:1;92584:4:0;;92624:13;;92584:4;;;;;;-1:-1:-1;;;;;92701:25:0;;;;;3569:18:1;;92701:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92651:87;;;;;;;92757:4;92765:1;92757:9;92749:59;;;;-1:-1:-1;;;92749:59:0;;28600:2:1;92749:59:0;;;28582:21:1;28639:2;28619:18;;;28612:30;28678:34;28658:18;;;28651:62;-1:-1:-1;;;28729:18:1;;;28722:35;28774:19;;92749:59:0;28398:401:1;92749:59:0;92826:15;;92822:127;;92865:72;92870:28;92900:36;92865:4;:72::i;:::-;92858:79;92514:1514;-1:-1:-1;;;;;;92514:1514:0:o;92822:127::-;92961:12;92976:60;92998:13;93013:10;93025;92976:21;:60::i;:::-;92961:75;-1:-1:-1;93051:12:0;;93047:123;;93087:71;93098:15;93115:33;93150:7;93087:10;:71::i;93047:123::-;-1:-1:-1;;;;;93212:24:0;;93182:27;93212:24;;;:7;:24;;;;;;;;93285:10;93254:42;;:30;;;:42;;;;;;;;;93249:103;;93325:14;93320:20;93313:27;92514:1514;-1:-1:-1;;;;;;;;92514:1514:0:o;93249:103::-;93402:10;93371:42;;;;:30;;;:42;;;;;;;;93364:49;;-1:-1:-1;;93364:49:0;;;93458:13;:25;;;;;93426:57;;;;;;;;;;;;;;;;;;;93458:25;;93426:57;;;93458:25;93426:57;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93426:57:0;;;;;;;;;;;;;;;;-1:-1:-1;;93505:20:0;;93426:57;;-1:-1:-1;93505:20:0;;-1:-1:-1;93494:8:0;;-1:-1:-1;;93568:162:0;93589:3;93585:1;:7;93568:162;;;93638:6;-1:-1:-1;;;;;93618:26:0;:13;93632:1;93618:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;93618:26:0;;93614:105;;93678:1;93665:14;;93698:5;;93614:105;93594:3;;;;:::i;:::-;;;;93568:162;;;;93762:3;93749:10;:16;93742:24;;;;:::i;:::-;93823:10;93779:27;93809:25;;;:13;:25;;;;;93881:17;;93809:25;;93881:21;;93901:1;;93881:21;:::i;:::-;93870:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93870:33:0;93845:10;93856;93845:22;;;;;;;;:::i;:::-;;;;;;;;;:58;;;;;-1:-1:-1;;;;;93845:58:0;;;;;-1:-1:-1;;;;;93845:58:0;;;;;;93914:10;:16;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;93914:16:0;;;;;-1:-1:-1;;;;;;93914:16:0;;;;;;93948:32;;;;;;93961:6;;93969:10;;-1:-1:-1;;;;;22357:15:1;;;22339:34;;22409:15;;22404:2;22389:18;;22382:43;22289:2;22274:18;;22127:304;93948:32:0;;;;;;;;94005:14;93993:27;92514:1514;-1:-1:-1;;;;;;;;;;;;92514:1514:0:o;20170:167::-;20263:68;20301:29;20263:37;:68::i;95989:1621::-;96053:4;96070:16;96099:13;96185:24;;;;;;-1:-1:-1;;;29462:19:1;;29506:1;29497:11;;29260:254;96185:24:0;;;;;;;;;;;;;96175:35;;;;;;96154:6;-1:-1:-1;;;;;96154:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96154:15:0;;;;;;;;;;;;:::i;:::-;96137:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96127:44;;;;;;:83;96123:1454;;96238:46;-1:-1:-1;;;96238:30:0;:46::i;:::-;96227:57;;96123:1454;;;96364:25;;-1:-1:-1;;;96364:25:0;;;30739:20:1;30775:11;;96364:25:0;;;;;;;;;;;;96354:36;;;;;;96333:6;-1:-1:-1;;;;;96333:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96333:15:0;;;;;;;;;;;;:::i;:::-;96316:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96306:44;;;;;;:84;96302:1275;;96418:46;-1:-1:-1;;;96418:30:0;:46::i;96302:1275::-;96544:25;;-1:-1:-1;;;96544:25:0;;;30999:20:1;31035:11;;96544:25:0;;;;;;;;;;;;96534:36;;;;;;96513:6;-1:-1:-1;;;;;96513:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96513:15:0;;;;;;;;;;;;:::i;:::-;96496:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96486:44;;;;;;:84;96482:1095;;96598:47;-1:-1:-1;;;96598:30:0;:47::i;:::-;:54;;96648:4;96598:54;:::i;96482:1095::-;96732:25;;-1:-1:-1;;;96732:25:0;;;31432:20:1;31468:11;;96732:25:0;;;;;;;;;;;;96722:36;;;;;;96701:6;-1:-1:-1;;;;;96701:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96701:15:0;;;;;;;;;;;;:::i;:::-;96684:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96674:44;;;;;;:84;96670:907;;96786:47;-1:-1:-1;;;96786:30:0;:47::i;96670:907::-;96920:25;;-1:-1:-1;;;96920:25:0;;;31692:20:1;31728:11;;96920:25:0;;;;;;;;;;;;96910:36;;;;;;96889:6;-1:-1:-1;;;;;96889:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96889:15:0;;;;;;;;;;;;:::i;:::-;96872:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96862:44;;;;;;:84;96858:719;;96974:46;-1:-1:-1;;;96974:30:0;:46::i;:::-;:53;;97023:4;96974:53;:::i;96858:719::-;97060:30;97131:6;-1:-1:-1;;;;;97116:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;97093:68:0;;:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;97093:70:0;;;;;;;;;;;;:::i;:::-;97060:103;;97178:14;97207:32;97248:16;97207:58;;97284:19;:26;97314:1;97284:31;97280:84;;97345:3;;-1:-1:-1;97280:84:0;97444:2;97426:16;97422:25;97416:32;97406:42;;97493:6;97477:23;;97528:37;97559:5;97528:30;:37::i;96858:719::-;-1:-1:-1;97594:8:0;95989:1621;-1:-1:-1;;95989:1621:0:o;53846:90::-;53899:4;53923:5;53927:1;53923;:5;:::i;54268:90::-;54321:4;54345:5;54349:1;54345;:5;:::i;104746:2077::-;104931:5;104938:4;104944;104963:37;;:::i;:::-;-1:-1:-1;;;;;105059:22:0;;105012:9;105059:22;;;:13;:22;;;;;;;;105034:47;;;;;;;;;;;;;;;;;105012:9;;105034:47;;105059:22;105034:47;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105034:47:0;;;;;;;;;;;;;;;;;;;;;;;105097:6;105092:1452;105113:6;:13;105109:1;:17;105092:1452;;;105148:12;105163:6;105170:1;105163:9;;;;;;;;:::i;:::-;;;;;;;;;;;105265:33;;-1:-1:-1;;;105265:33:0;;-1:-1:-1;;;;;3614:32:1;;;105265:33:0;;;3596:51:1;105163:9:0;;-1:-1:-1;105265:24:0;;;;;;3569:18:1;;105265:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105236:25;;;105189:109;105216:18;;;105189:109;105196:18;;;105189:109;;-1:-1:-1;105317:9:0;;105313:86;;105356:20;105378:1;105381;105348:35;;;;;;;;;;;;;105313:86;105437:65;;;;;;;;;-1:-1:-1;;;;;105452:23:0;;-1:-1:-1;105452:23:0;;;:7;:23;;;;;:48;;;105437:65;;105413:21;;;:89;;;;105537:42;;;;;;;;-1:-1:-1;;;105552:25:0;105537:42;;105517:17;;;:62;105623:25;105468:5;105623:18;:25::i;:::-;105596:24;;;:52;;;105695:1;105667:29;105663:102;;105725:17;105744:1;105747;105717:32;;;;;;;;;;;;;105663:102;105798:41;;;;;;;;;105813:24;;;;105798:41;;105779:16;;;:60;105887:21;;;;105910:17;;;;105877:70;;105882:46;;:4;:46::i;:::-;105930:4;:16;;;105877:4;:70::i;:::-;105856:18;;;:91;;;106031:18;;;;106051;;105985:85;;105856:91;106031:18;105985:25;:85::i;:::-;105964:106;;106141:16;;;;106159:18;;;;106179:25;;;;106115:90;;106141:16;106159:18;106115:25;:90::i;:::-;106087:25;;;:118;-1:-1:-1;;;;;106226:21:0;;;;;;;106222:311;;106298:86;106324:4;:18;;;106344:12;106358:4;:25;;;106298;:86::i;:::-;106270:25;;;:114;;;106459:16;;;;106433:84;;106477:12;;106433:25;:84::i;:::-;106405:25;;;:112;106222:311;-1:-1:-1;105128:3:0;;;;:::i;:::-;;;;105092:1452;;;-1:-1:-1;106581:25:0;;;;106560:18;;:46;106556:260;;;106668:25;;;;106647:18;;106631:14;;106647:46;;;:::i;:::-;106695:1;106623:74;;;;;;;;;;;106556:260;106738:14;106754:1;106785:4;:18;;;106757:4;:25;;;:46;;;;:::i;:::-;106730:74;;;;;;;;;;;42657:153;42718:4;42740:33;42753:3;42748:9;;;;;;;;:::i;:::-;42764:4;42759:10;;;;;;;;:::i;:::-;42740:33;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;42771:1:0;6583:18:1;;;6576:34;6487:2;6472:18;42740:33:0;;;;;;;42798:3;42793:9;;;;;;;;:::i;104126:196::-;104203:5;104210:4;104216;104240:74;104280:7;104304:1;104309;104312;104240:39;:74::i;:::-;104233:81;;;;;;104126:196;;;;;:::o;52205:174::-;52283:4;52300:18;52321:15;52326:1;52329:6;52321:4;:15::i;:::-;52300:36;;52354:17;52363:7;52354:8;:17::i;110925:250::-;110994:6;110989:137;111010:10;:17;111006:21;;110989:137;;;111082:6;-1:-1:-1;;;;;111058:31:0;:10;111069:1;111058:13;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;111058:13:0;:31;111050:64;;;;-1:-1:-1;;;111050:64:0;;32414:2:1;111050:64:0;;;32396:21:1;32453:2;32433:18;;;32426:30;-1:-1:-1;;;32472:18:1;;;32465:50;32532:18;;111050:64:0;32212:344:1;111050:64:0;111029:4;;;;:::i;:::-;;;;110989:137;;;-1:-1:-1;111136:10:0;:31;;;;;;;-1:-1:-1;111136:31:0;;;;;;;;-1:-1:-1;;;;;;111136:31:0;-1:-1:-1;;;;;111136:31:0;;;;;;;;;;110925:250::o;111183:569::-;111246:18;111267:56;117253:12;111267:56;;;;;;;;;;;;;;;;;:6;:56::i;:::-;-1:-1:-1;;;;;111374:23:0;;111336:35;111374:23;;;:15;:23;;;;;;;;111446:15;:23;;;;;111486:17;;111246:77;;-1:-1:-1;111374:23:0;;111446;;-1:-1:-1;;;;;111486:17:0;;;:22;;111482:93;;111527:36;;-1:-1:-1;;;;;;111527:36:0;90922:4;111527:36;;;111482:93;111591:17;;-1:-1:-1;;;;;111591:17:0;;:22;111587:93;;111632:36;;-1:-1:-1;;;;;;111632:36:0;90922:4;111632:36;;;111587:93;111713:31;;;;;;-1:-1:-1;;;111713:31:0;-1:-1:-1;;;;;111713:31:0;;;;;;;;111693:51;;;;;;;;;;-1:-1:-1;111183:569:0:o;18663:136::-;18736:7;18759:34;18786:6;18759:26;:34::i;95021:685::-;-1:-1:-1;;;;;95150:15:0;;95128:4;95150:15;;;:7;:15;;;;;:24;;;95145:94;;95203:23;95198:29;;95145:94;-1:-1:-1;;;;;95256:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;95251:104;;95328:14;95323:20;;95251:104;95368:9;95381:14;95399:82;95439:8;95456:6;95465:12;95479:1;95399:39;:82::i;:::-;95367:114;;-1:-1:-1;95367:114:0;;-1:-1:-1;95503:14:0;;-1:-1:-1;95496:3:0;:21;;;;;;;;:::i;:::-;;95492:70;;95546:3;95541:9;;;;;;;;:::i;:::-;95534:16;;;;;;95492:70;95576:13;;95572:87;;95618:28;95613:34;;91941:565;-1:-1:-1;;;;;92069:24:0;;92021:5;92069:24;;;:7;:24;;;;;92111:21;;;;92106:87;;92158:23;92151:30;;;;;92106:87;-1:-1:-1;;;;;92209:40:0;;;;;;:30;;;:40;;;;;;;;:48;;:40;:48;92205:104;;92283:14;92276:21;;;;;92205:104;-1:-1:-1;;;;;92321:40:0;;;;;;;:30;;;:40;;;;;;;;:47;;92364:4;-1:-1:-1;;92321:47:0;;;;;;;;92379:13;:23;;;;;:36;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;92379:36:0;;;;;;;;;92433:31;;22339:34:1;;;22389:18;;22382:43;;;;92433:31:0;;22274:18:1;92433:31:0;;;;;;;-1:-1:-1;92484:14:0;;91941:565;-1:-1:-1;;;91941:565:0:o;54366:159::-;-1:-1:-1;;;;;;;;;;;;54461:56:0;;;;;;;;51837:4;54476:28;54481:1;:10;;;54493:1;:10;;;54476:4;:28::i;:::-;:39;;;;:::i;:::-;54461:56;;54454:63;54366:159;-1:-1:-1;;;54366:159:0:o;55368:164::-;-1:-1:-1;;;;;;;;;;;;55463:61:0;;;;;;;;55478:44;55483:26;55488:1;:10;;;51837:4;55483;:26::i;:::-;55511:10;;55478:4;:44::i;42818:187::-;42903:4;42925:43;42938:3;42933:9;;;;;;;;:::i;:::-;42949:4;42944:10;;;;;;;;:::i;:::-;42925:43;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;6583:18;;6576:34;;;6487:2;6472:18;42925:43:0;;;;;;;42993:3;42988:9;;;;;;;;:::i;17682:975::-;18135:32;18170:36;18202:4;18170:29;:36;:::i;:::-;18135:71;;18237:24;18219:15;:42;18215:437;;;17483:9;18277:42;18304:15;18277:24;:42;:::i;:::-;18276:87;18272:190;;;18383:69;;-1:-1:-1;;;18383:69:0;;;;;15465:25:1;;;18436:15:0;15506:18:1;;;15499:34;15438:18;;18383:69:0;15291:248:1;18272:190:0;17762:895;17682:975;:::o;18215:437::-;17409:9;18480:42;18498:24;18480:15;:42;:::i;:::-;18479:87;18475:177;;;18584:60;;-1:-1:-1;;;18584:60:0;;;;;15465:25:1;;;18628:15:0;15506:18:1;;;15499:34;15438:18;;18584:60:0;15291:248:1;32370:278:0;32531:16;;;32545:1;32531:16;;;;;;;;;32481:7;;;;32531:16;;;;;;;;;;;;-1:-1:-1;32531:16:0;32500:47;;32571:10;32554:11;32566:1;32554:14;;;;;;;;:::i;:::-;;;;;;:27;;;;;32595:44;32627:11;32595:31;:44::i;:::-;32640:1;32595:47;;;;;;;;:::i;:::-;;;;;;;32588:54;;;32370:278;;;:::o;52387:208::-;52485:4;52502:18;52523:15;52528:1;52531:6;52523:4;:15::i;:::-;52502:36;;52556:31;52561:17;52570:7;52561:8;:17::i;:::-;52580:6;52556:4;:31::i;54533:133::-;-1:-1:-1;;;;;;;;;;;;54622:36:0;;;;;;;;54637:19;54642:1;:10;;;54654:1;54637:4;:19::i;52083:114::-;52166:12;;52140:4;;52166:23;;51837:4;;52166:23;:::i;53353:161::-;53428:6;53466:12;53459:5;53455:9;;53447:32;;;;-1:-1:-1;;;53447:32:0;;;;;;;;:::i;:::-;-1:-1:-1;53504:1:0;;53353:161;-1:-1:-1;;53353:161:0:o;15883:403::-;15948:7;15968:3;:10;15982:1;15968:15;15964:75;;16001:30;;-1:-1:-1;;;16001:30:0;;;;;;;;;;;15964:75;16045:9;16050:3;16045:4;:9::i;:::-;16061:19;16096:1;16083:3;:10;:14;;;;:::i;:::-;16061:36;;16121:1;16108:3;:10;:14;;;;:::i;:::-;16126:1;16108:19;16104:177;;16138:11;16152:52;16165:3;16169:15;16183:1;16169:11;:15;:::i;:::-;16165:20;;;;;;;;:::i;:::-;;;;;;;16187:3;16191:11;16187:16;;;;;;;;:::i;:::-;;;;;;;16152:12;:52::i;:::-;16138:66;-1:-1:-1;16220:7:0;16226:1;16138:66;16220:7;:::i;16104:177::-;16257:3;16261:11;16257:16;;;;;;;;:::i;55270:90::-;55323:4;55347:5;55351:1;55347;:5;:::i;56292:90::-;56345:4;56369:5;56373:1;56369;:5;:::i;33509:213::-;33631:16;33666:50;33704:11;33666:37;:50::i;16292:774::-;16390:3;16384:10;16428:20;16423:3;16419:30;16501:16;16490:9;16486:32;16475:9;16471:48;16457:62;;16557:9;16527:527;16588:6;16579:7;16576:19;16527:527;;;16718:9;16686:359;16751:7;16742;16739:20;16686:359;;;16874:7;16868:14;16912:7;16906:14;16944:4;16938;16935:14;16932:102;;;16981:4;16972:7;16965:21;17016:4;17007:7;17000:21;16932:102;-1:-1:-1;;16797:16:0;16784:30;16686:359;;;-1:-1:-1;16631:16:0;16618:30;16527:527;;22032:2070;22147:16;22236:48;22301:11;:18;22287:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22287:33:0;;22236:84;;22327:44;22388:11;:18;22374:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22374:33:0;;22327:80;;22414:37;22470:11;:18;22454:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22414:75;;22501:9;22496:350;22520:11;:18;22516:1;:22;22496:350;;;22796:42;;;36788:1;22796:42;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22796:42:0;22772:18;22791:1;22772:21;;;;;;;;:::i;:::-;;;;;;:66;;;;22540:3;;;;;:::i;:::-;;;;22496:350;;;;22915:30;22948:36;:34;:36::i;:::-;22915:69;;22991:25;23019:61;23057:22;23019:37;:61::i;:::-;22991:89;;;-1:-1:-1;23087:48:0;2638:1;23087:48;;:::i;:::-;23250:15;23244:22;23087:48;;-1:-1:-1;23187:18:0;23324:585;23378:17;23359:16;:36;23324:585;;;23492:27;23522:192;23552:11;23574:31;23616:27;23654:18;23683:22;23522:19;:192::i;:::-;23492:222;-1:-1:-1;23723:45:0;23492:222;23723:45;;:::i;:::-;;;23882:10;23865:15;23858:35;23847:55;23397:18;;;;;:::i;:::-;;;;23324:585;;;;24023:73;24044:18;24064:31;24023:20;:73::i;11718:1200::-;11787:7;12099:20;-1:-1:-1;;11962:14:0;11958:37;11945:51;12074:46;;12030:99;;12142:83;;12187:30;;-1:-1:-1;;;12187:30:0;;;;;;;;;;;12142:83;12310:31;12395:8;3752:2;12352:58;12348:113;;;12428:25;;-1:-1:-1;;;12428:25:0;;;;;;;;;;;12348:113;-1:-1:-1;;;12540:14:0;12536:61;12513:93;12619:30;2994:1;12652:64;2941:1;12652:64;;;;:::i;:::-;:92;;;;:::i;:::-;12619:125;-1:-1:-1;12805:8:0;12755:47;2638:1;12619:125;12755:47;:::i;:::-;:65;12751:126;;;12838:31;;-1:-1:-1;;;12838:31:0;;;;;;;;;;;13003:540;13120:24;;13205:41;2023:2;13205:22;:41;:::i;:::-;13156:90;-1:-1:-1;13298:8:0;13257:56;;13253:111;;;13331:25;;-1:-1:-1;;;13331:25:0;;;;;;;;;;;13253:111;13436:14;13432:59;13409:91;;13003:540;-1:-1:-1;;13003:540:0:o;24917:4605::-;25195:7;25211:19;25248:23;25280:34;25324:63;25364:22;25324:39;:63::i;:::-;25239:148;;-1:-1:-1;25239:148:0;-1:-1:-1;25466:25:0;;;25557:26;25466:25;3605:2;25660:70;25680:49;2812:2;25239:148;25680:49;:::i;:::-;25660:15;;:19;:70::i;:::-;:125;;;;:::i;:::-;25634:151;-1:-1:-1;25866:31:0;25900:119;25930:88;3290:3;25930:22;:88;:::i;:::-;25900:8;;:19;:119::i;:::-;25866:153;-1:-1:-1;26030:35:0;26068:88;26132:23;26098:31;2533:2;26098:22;:31;:::i;:::-;:57;;;;:::i;26068:88::-;26030:126;;26246:111;26323:23;26283:27;26246:111;:::i;:::-;26229:128;;26474:23;26451:20;26436:13;26432:40;26422:76;26408:90;;26578:23;26565:37;26543:59;;26614:236;;26862:350;26682:15;26676:22;;26710:23;;;26761:20;26818;;;;;26794:45;;;26919:14;;26752:30;27099:10;27078:6;27041:22;27014:108;-1:-1:-1;;27152:49:0;;26862:350;-1:-1:-1;;;26862:350:0:o;:::-;27262:37;27280:18;27262:37;;:17;:37::i;:::-;27399:105;27443:10;27464:31;2533:2;27464:22;:31;:::i;:::-;27399:33;:105::i;:::-;27383:121;;27527:39;27552:13;27527:24;:39::i;:::-;27513:53;;;;25457:2117;;;;;;;27623:27;27659:22;27695;27690:1632;27740:15;27723:14;:32;27690:1632;;;27899:147;27947:22;27982:26;28021:14;27899:35;:147::i;:::-;27859:187;;-1:-1:-1;27859:187:0;-1:-1:-1;28076:23:0;28059:1254;28134:11;:18;28116:15;:36;28059:1254;;;28234:11;28246:15;28234:28;;;;;;;;:::i;:::-;;;;;;;28211:19;:51;28207:1095;;28279:34;28316:27;28344:15;28316:44;;;;;;;;:::i;:::-;;;;;;;28279:81;;28398:67;28425:26;28453:11;1382:1;:13;;1372:24;1410:14;;;1255:175;28398:67;28397:68;:225;;;;-1:-1:-1;36788:1:0;28544:78;;:31;28576:15;28544:48;;;;;;;;:::i;:::-;;;;;;;:78;28397:225;28377:806;;;28704:31;28736:15;28704:48;;;;;;;;:::i;:::-;;;;;;:50;;;;;;;;:::i;:::-;;;;;28931:14;28805:18;28824:15;28805:35;;;;;;;;:::i;:::-;;;;;;;28910:1;28859:31;28891:15;28859:48;;;;;;;;:::i;:::-;;;;;;;:52;;;;:::i;:::-;28805:123;;;;;;;;:::i;:::-;;;;;;;;;;:140;1229:1;:13;;1219:24;;29004:27;29032:15;29004:44;;;;;;;;:::i;:::-;;;;;;:163;;;;;28377:806;29283:5;;;28207:1095;28165:17;;;;:::i;:::-;;;;28059:1254;;;-1:-1:-1;27757:16:0;;;;:::i;:::-;;;;27690:1632;;;;27614:1715;;29501:15;2812:2;29441:26;:49;;;;:::i;:::-;29440:76;;;;:::i;:::-;29395:121;;3446:2;29395:121;:::i;:::-;29381:135;24917:4605;-1:-1:-1;;;;;;;;;24917:4605:0:o;30004:880::-;30160:16;30185:33;30235:18;:25;30221:40;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30221:40:0;-1:-1:-1;30185:76:0;-1:-1:-1;36788:1:0;30268:30;30337:510;30385:18;:25;30369:13;:41;30337:510;;;30491:22;30442:31;30474:13;30442:46;;;;;;;;:::i;:::-;;;;;;;:71;30438:233;;;30579:31;30611:13;30579:46;;;;;;;;:::i;:::-;;;;;;;30638:22;30533:128;;-1:-1:-1;;;30533:128:0;;;;;;;;15465:25:1;;;15521:2;15506:18;;15499:34;15453:2;15438:18;;15291:248;30438:233:0;30679:36;30718:50;30734:18;30753:13;30734:33;;;;;;;;:::i;:::-;;;;;;;30718:15;:50::i;:::-;30679:89;;30811:28;30777:16;30794:13;30777:31;;;;;;;;:::i;:::-;;;;;;;;;;:62;-1:-1:-1;30412:15:0;;;;:::i;:::-;;;;30337:510;;;-1:-1:-1;30862:16:0;;30004:880;-1:-1:-1;;;;30004:880:0:o;14370:1053::-;14503:23;;;;;14862:45;2533:2;14862:36;:45;:::i;:::-;14829:78;-1:-1:-1;14914:22:0;14939:62;14959:41;2023:2;14829:78;14959:41;:::i;14939:62::-;15046:28;;;-1:-1:-1;14914:87:0;-1:-1:-1;15149:40:0;14914:87;2693:1;15149:18;:40::i;:::-;15320:34;;;;;;15245:28;;15361:56;;;-1:-1:-1;15320:34:0;;-1:-1:-1;;;;;14370:1053:0:o;254:727::-;775:46;945:30;;383:7;945:30;;;671:14;945:30;;;;;;33162:25:1;;;503:14:0;499:52;;;775:46;;;842:39;834:48;;33203:18:1;;;33196:45;;;564:39:0;;33257:18:1;;;33250:34;;;640:46:0;;699:39;33300:18:1;;;33293:34;;;383:7:0;;564:39;;945:30;;33134:19:1;;945:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;945:30:0;;-1:-1:-1;;945:30:0;;;254:727;-1:-1:-1;;;;;;;254:727:0:o;13549:815::-;13754:27;;;13851:74;3446:2;13851:36;:74;:::i;:::-;13814:111;-1:-1:-1;13932:31:0;13966:126;14005:80;14031:52;2812:2;14031:29;:52;:::i;:::-;14006:18;14010:14;14006:1;:18;:::i;:::-;14005:24;;:80::i;:::-;13966:26;;:30;:126::i;:::-;13932:160;-1:-1:-1;14099:31:0;14133:44;:8;13932:160;14133:19;:44::i;:::-;14225:37;;;14330:20;14301:50;;;14288:64;;-1:-1:-1;13549:815:0;-1:-1:-1;;;;;;;13549:815:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;206:367:1:-;269:8;279:6;333:3;326:4;318:6;314:17;310:27;300:55;;351:1;348;341:12;300:55;-1:-1:-1;374:20:1;;417:18;406:30;;403:50;;;449:1;446;439:12;403:50;486:4;478:6;474:17;462:29;;546:3;539:4;529:6;526:1;522:14;514:6;510:27;506:38;503:47;500:67;;;563:1;560;553:12;500:67;206:367;;;;;:::o;578:773::-;700:6;708;716;724;777:2;765:9;756:7;752:23;748:32;745:52;;;793:1;790;783:12;745:52;833:9;820:23;862:18;903:2;895:6;892:14;889:34;;;919:1;916;909:12;889:34;958:70;1020:7;1011:6;1000:9;996:22;958:70;:::i;:::-;1047:8;;-1:-1:-1;932:96:1;-1:-1:-1;1135:2:1;1120:18;;1107:32;;-1:-1:-1;1151:16:1;;;1148:36;;;1180:1;1177;1170:12;1148:36;;1219:72;1283:7;1272:8;1261:9;1257:24;1219:72;:::i;:::-;578:773;;;;-1:-1:-1;1310:8:1;-1:-1:-1;;;;578:773:1:o;1356:139::-;-1:-1:-1;;;;;1439:31:1;;1429:42;;1419:70;;1485:1;1482;1475:12;1500:118;1586:5;1579:13;1572:21;1565:5;1562:32;1552:60;;1608:1;1605;1598:12;1623:405;1703:6;1711;1764:2;1752:9;1743:7;1739:23;1735:32;1732:52;;;1780:1;1777;1770:12;1732:52;1819:9;1806:23;1838:39;1871:5;1838:39;:::i;:::-;1896:5;-1:-1:-1;1953:2:1;1938:18;;1925:32;1966:30;1925:32;1966:30;:::i;:::-;2015:7;2005:17;;;1623:405;;;;;:::o;2033:274::-;2111:6;2164:2;2152:9;2143:7;2139:23;2135:32;2132:52;;;2180:1;2177;2170:12;2132:52;2219:9;2206:23;2238:39;2271:5;2238:39;:::i;2754:691::-;2849:6;2857;2865;2873;2881;2934:3;2922:9;2913:7;2909:23;2905:33;2902:53;;;2951:1;2948;2941:12;2902:53;2990:9;2977:23;3009:39;3042:5;3009:39;:::i;:::-;3067:5;-1:-1:-1;3124:2:1;3109:18;;3096:32;3137:41;3096:32;3137:41;:::i;:::-;3197:7;-1:-1:-1;3256:2:1;3241:18;;3228:32;3269:41;3228:32;3269:41;:::i;:::-;2754:691;;;;-1:-1:-1;3329:7:1;;3383:2;3368:18;;3355:32;;-1:-1:-1;3434:3:1;3419:19;3406:33;;2754:691;-1:-1:-1;;2754:691:1:o;3658:622::-;3744:6;3752;3760;3768;3821:3;3809:9;3800:7;3796:23;3792:33;3789:53;;;3838:1;3835;3828:12;3789:53;3877:9;3864:23;3896:39;3929:5;3896:39;:::i;:::-;3954:5;-1:-1:-1;4011:2:1;3996:18;;3983:32;4024:41;3983:32;4024:41;:::i;:::-;4084:7;-1:-1:-1;4143:2:1;4128:18;;4115:32;4156:41;4115:32;4156:41;:::i;:::-;3658:622;;;;-1:-1:-1;4216:7:1;;4270:2;4255:18;4242:32;;-1:-1:-1;;3658:622:1:o;4285:241::-;4341:6;4394:2;4382:9;4373:7;4369:23;4365:32;4362:52;;;4410:1;4407;4400:12;4362:52;4449:9;4436:23;4468:28;4490:5;4468:28;:::i;4531:180::-;4590:6;4643:2;4631:9;4622:7;4618:23;4614:32;4611:52;;;4659:1;4656;4649:12;4611:52;-1:-1:-1;4682:23:1;;4531:180;-1:-1:-1;4531:180:1:o;4905:541::-;4991:6;4999;5007;5015;5068:3;5056:9;5047:7;5043:23;5039:33;5036:53;;;5085:1;5082;5075:12;5036:53;5124:9;5111:23;5143:39;5176:5;5143:39;:::i;:::-;5201:5;-1:-1:-1;5258:2:1;5243:18;;5230:32;5271:41;5230:32;5271:41;:::i;:::-;4905:541;;5331:7;;-1:-1:-1;;;;5385:2:1;5370:18;;5357:32;;5436:2;5421:18;5408:32;;4905:541::o;5451:841::-;5555:6;5563;5571;5579;5587;5595;5648:3;5636:9;5627:7;5623:23;5619:33;5616:53;;;5665:1;5662;5655:12;5616:53;5704:9;5691:23;5723:39;5756:5;5723:39;:::i;:::-;5781:5;-1:-1:-1;5838:2:1;5823:18;;5810:32;5851:41;5810:32;5851:41;:::i;:::-;5911:7;-1:-1:-1;5970:2:1;5955:18;;5942:32;5983:41;5942:32;5983:41;:::i;:::-;6043:7;-1:-1:-1;6102:2:1;6087:18;;6074:32;6115:41;6074:32;6115:41;:::i;:::-;5451:841;;;;-1:-1:-1;5451:841:1;;6229:3;6214:19;;6201:33;;6281:3;6266:19;;;6253:33;;-1:-1:-1;5451:841:1;-1:-1:-1;;5451:841:1:o;6621:472::-;6698:6;6706;6714;6767:2;6755:9;6746:7;6742:23;6738:32;6735:52;;;6783:1;6780;6773:12;6735:52;6822:9;6809:23;6841:39;6874:5;6841:39;:::i;:::-;6899:5;-1:-1:-1;6956:2:1;6941:18;;6928:32;6969:41;6928:32;6969:41;:::i;:::-;6621:472;;7029:7;;-1:-1:-1;;;7083:2:1;7068:18;;;;7055:32;;6621:472::o;7321:772::-;7416:6;7424;7432;7440;7448;7501:3;7489:9;7480:7;7476:23;7472:33;7469:53;;;7518:1;7515;7508:12;7469:53;7557:9;7544:23;7576:39;7609:5;7576:39;:::i;:::-;7634:5;-1:-1:-1;7691:2:1;7676:18;;7663:32;7704:41;7663:32;7704:41;:::i;:::-;7764:7;-1:-1:-1;7823:2:1;7808:18;;7795:32;7836:41;7795:32;7836:41;:::i;:::-;7896:7;-1:-1:-1;7955:2:1;7940:18;;7927:32;7968:41;7927:32;7968:41;:::i;:::-;7321:772;;;;-1:-1:-1;7321:772:1;;8082:3;8067:19;8054:33;;7321:772;-1:-1:-1;;7321:772:1:o;9529:419::-;9612:6;9620;9673:2;9661:9;9652:7;9648:23;9644:32;9641:52;;;9689:1;9686;9679:12;9641:52;9728:9;9715:23;9747:39;9780:5;9747:39;:::i;:::-;9805:5;-1:-1:-1;9862:2:1;9847:18;;9834:32;9875:41;9834:32;9875:41;:::i;10436:673::-;10622:2;10674:21;;;10744:13;;10647:18;;;10766:22;;;10593:4;;10622:2;10845:15;;;;10819:2;10804:18;;;10593:4;10888:195;10902:6;10899:1;10896:13;10888:195;;;10967:13;;-1:-1:-1;;;;;10963:39:1;10951:52;;11058:15;;;;11023:12;;;;10999:1;10917:9;10888:195;;;-1:-1:-1;11100:3:1;;10436:673;-1:-1:-1;;;;;;10436:673:1:o;11523:127::-;11584:10;11579:3;11575:20;11572:1;11565:31;11615:4;11612:1;11605:15;11639:4;11636:1;11629:15;11655:275;11726:2;11720:9;11791:2;11772:13;;-1:-1:-1;;11768:27:1;11756:40;;11826:18;11811:34;;11847:22;;;11808:62;11805:88;;;11873:18;;:::i;:::-;11909:2;11902:22;11655:275;;-1:-1:-1;11655:275:1:o;11935:183::-;11995:4;12028:18;12020:6;12017:30;12014:56;;;12050:18;;:::i;:::-;-1:-1:-1;12095:1:1;12091:14;12107:4;12087:25;;11935:183::o;12123:891::-;12207:6;12238:2;12281;12269:9;12260:7;12256:23;12252:32;12249:52;;;12297:1;12294;12287:12;12249:52;12337:9;12324:23;12370:18;12362:6;12359:30;12356:50;;;12402:1;12399;12392:12;12356:50;12425:22;;12478:4;12470:13;;12466:27;-1:-1:-1;12456:55:1;;12507:1;12504;12497:12;12456:55;12543:2;12530:16;12566:60;12582:43;12622:2;12582:43;:::i;:::-;12566:60;:::i;:::-;12660:15;;;12742:1;12738:10;;;;12730:19;;12726:28;;;12691:12;;;;12766:19;;;12763:39;;;12798:1;12795;12788:12;12763:39;12822:11;;;;12842:142;12858:6;12853:3;12850:15;12842:142;;;12924:17;;12912:30;;12875:12;;;;12962;;;;12842:142;;13019:250;13104:1;13114:113;13128:6;13125:1;13122:13;13114:113;;;13204:11;;;13198:18;13185:11;;;13178:39;13150:2;13143:10;13114:113;;;-1:-1:-1;;13261:1:1;13243:16;;13236:27;13019:250::o;13274:396::-;13423:2;13412:9;13405:21;13386:4;13455:6;13449:13;13498:6;13493:2;13482:9;13478:18;13471:34;13514:79;13586:6;13581:2;13570:9;13566:18;13561:2;13553:6;13549:15;13514:79;:::i;:::-;13654:2;13633:15;-1:-1:-1;;13629:29:1;13614:45;;;;13661:2;13610:54;;13274:396;-1:-1:-1;;13274:396:1:o;13675:974::-;13759:6;13790:2;13833;13821:9;13812:7;13808:23;13804:32;13801:52;;;13849:1;13846;13839:12;13801:52;13889:9;13876:23;13922:18;13914:6;13911:30;13908:50;;;13954:1;13951;13944:12;13908:50;13977:22;;14030:4;14022:13;;14018:27;-1:-1:-1;14008:55:1;;14059:1;14056;14049:12;14008:55;14095:2;14082:16;14118:60;14134:43;14174:2;14134:43;:::i;14118:60::-;14212:15;;;14294:1;14290:10;;;;14282:19;;14278:28;;;14243:12;;;;14318:19;;;14315:39;;;14350:1;14347;14340:12;14315:39;14374:11;;;;14394:225;14410:6;14405:3;14402:15;14394:225;;;14490:3;14477:17;14507:39;14540:5;14507:39;:::i;:::-;14559:18;;14427:12;;;;14597;;;;14394:225;;14654:632;14825:2;14877:21;;;14947:13;;14850:18;;;14969:22;;;14796:4;;14825:2;15048:15;;;;15022:2;15007:18;;;14796:4;15091:169;15105:6;15102:1;15099:13;15091:169;;;15166:13;;15154:26;;15235:15;;;;15200:12;;;;15127:1;15120:9;15091:169;;15544:323;15612:6;15620;15673:2;15661:9;15652:7;15648:23;15644:32;15641:52;;;15689:1;15686;15679:12;15641:52;15728:9;15715:23;15747:39;15780:5;15747:39;:::i;:::-;15805:5;15857:2;15842:18;;;;15829:32;;-1:-1:-1;;;15544:323:1:o;17366:127::-;17427:10;17422:3;17418:20;17415:1;17408:31;17458:4;17455:1;17448:15;17482:4;17479:1;17472:15;17498:127;17559:10;17554:3;17550:20;17547:1;17540:31;17590:4;17587:1;17580:15;17614:4;17611:1;17604:15;17630:128;17697:9;;;17718:11;;;17715:37;;;17732:18;;:::i;17763:135::-;17802:3;17823:17;;;17820:43;;17843:18;;:::i;:::-;-1:-1:-1;17890:1:1;17879:13;;17763:135::o;17903:404::-;18105:2;18087:21;;;18144:2;18124:18;;;18117:30;18183:34;18178:2;18163:18;;18156:62;-1:-1:-1;;;18249:2:1;18234:18;;18227:38;18297:3;18282:19;;17903:404::o;18312:403::-;18514:2;18496:21;;;18553:2;18533:18;;;18526:30;18592:34;18587:2;18572:18;;18565:62;-1:-1:-1;;;18658:2:1;18643:18;;18636:37;18705:3;18690:19;;18312:403::o;18720:346::-;18922:2;18904:21;;;18961:2;18941:18;;;18934:30;-1:-1:-1;;;18995:2:1;18980:18;;18973:52;19057:2;19042:18;;18720:346::o;19600:259::-;19670:6;19723:2;19711:9;19702:7;19698:23;19694:32;19691:52;;;19739:1;19736;19729:12;19691:52;19771:9;19765:16;19790:39;19823:5;19790:39;:::i;20272:184::-;20342:6;20395:2;20383:9;20374:7;20370:23;20366:32;20363:52;;;20411:1;20408;20401:12;20363:52;-1:-1:-1;20434:16:1;;20272:184;-1:-1:-1;20272:184:1:o;20811:127::-;20872:10;20867:3;20863:20;20860:1;20853:31;20903:4;20900:1;20893:15;20927:4;20924:1;20917:15;25245:245;25312:6;25365:2;25353:9;25344:7;25340:23;25336:32;25333:52;;;25381:1;25378;25371:12;25333:52;25413:9;25407:16;25432:28;25454:5;25432:28;:::i;27174:127::-;27235:10;27230:3;27226:20;27223:1;27216:31;27266:4;27263:1;27256:15;27290:4;27287:1;27280:15;28025:368;28122:6;28130;28138;28146;28199:3;28187:9;28178:7;28174:23;28170:33;28167:53;;;28216:1;28213;28206:12;28167:53;-1:-1:-1;;28239:16:1;;28295:2;28280:18;;28274:25;28339:2;28324:18;;28318:25;28383:2;28368:18;;;28362:25;28239:16;;28274:25;;-1:-1:-1;28362:25:1;;-1:-1:-1;28025:368:1;-1:-1:-1;28025:368:1:o;28804:127::-;28865:10;28860:3;28856:20;28853:1;28846:31;28896:4;28893:1;28886:15;28920:4;28917:1;28910:15;29519:719;29599:6;29652:2;29640:9;29631:7;29627:23;29623:32;29620:52;;;29668:1;29665;29658:12;29620:52;29701:9;29695:16;29730:18;29771:2;29763:6;29760:14;29757:34;;;29787:1;29784;29777:12;29757:34;29825:6;29814:9;29810:22;29800:32;;29870:7;29863:4;29859:2;29855:13;29851:27;29841:55;;29892:1;29889;29882:12;29841:55;29921:2;29915:9;29943:2;29939;29936:10;29933:36;;;29949:18;;:::i;:::-;29991:53;30034:2;30015:13;;-1:-1:-1;;30011:27:1;30040:2;30007:36;29991:53;:::i;:::-;29978:66;;30067:2;30060:5;30053:17;30107:7;30102:2;30097;30093;30089:11;30085:20;30082:33;30079:53;;;30128:1;30125;30118:12;30079:53;30141:67;30205:2;30200;30193:5;30189:14;30184:2;30180;30176:11;30141:67;:::i;:::-;-1:-1:-1;30227:5:1;29519:719;-1:-1:-1;;;;29519:719:1:o;30243:289::-;30374:3;30412:6;30406:13;30428:66;30487:6;30482:3;30475:4;30467:6;30463:17;30428:66;:::i;:::-;30510:16;;;;;30243:289;-1:-1:-1;;30243:289:1:o;31057:168::-;31130:9;;;31161;;31178:15;;;31172:22;;31158:37;31148:71;;31199:18;;:::i;31750:125::-;31815:9;;;31836:10;;;31833:36;;;31849:18;;:::i;32561:127::-;32622:10;32617:3;32613:20;32610:1;32603:31;32653:4;32650:1;32643:15;32677:4;32674:1;32667:15;32693:120;32733:1;32759;32749:35;;32764:18;;:::i;:::-;-1:-1:-1;32798:9:1;;32693:120::o;32818:112::-;32850:1;32876;32866:35;;32881:18;;:::i;:::-;-1:-1:-1;32915:9:1;;32818:112::o
Swarm Source
ipfs://bafd5e6394cb5564fc079ac4bc62f2bead18ad908f73aa6a16a21b14bd82f295
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.