Source Code
Overview
ETH Balance
ETH Value
$0.00Latest 25 from a total of 433 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Exit Market | 12444302 | 387 days ago | IN | 0 ETH | 0.0000133 | ||||
| Exit Market | 12444294 | 387 days ago | IN | 0 ETH | 0.00002326 | ||||
| Exit Market | 12444232 | 387 days ago | IN | 0 ETH | 0.00002086 | ||||
| Exit Market | 12444225 | 387 days ago | IN | 0 ETH | 0.00002455 | ||||
| Exit Market | 12444174 | 387 days ago | IN | 0 ETH | 0.00001739 | ||||
| Enter Markets | 10808008 | 448 days ago | IN | 0 ETH | 0.00002052 | ||||
| Enter Markets | 10720223 | 451 days ago | IN | 0 ETH | 0.00001154 | ||||
| Enter Markets | 10720221 | 451 days ago | IN | 0 ETH | 0.00001173 | ||||
| Exit Market | 10409303 | 461 days ago | IN | 0 ETH | 0.00001388 | ||||
| Exit Market | 10408947 | 461 days ago | IN | 0 ETH | 0.00002247 | ||||
| Enter Markets | 10301605 | 464 days ago | IN | 0 ETH | 0.00000871 | ||||
| Enter Markets | 10206256 | 467 days ago | IN | 0 ETH | 0.00000938 | ||||
| Enter Markets | 10205292 | 467 days ago | IN | 0 ETH | 0.00000977 | ||||
| Enter Markets | 10185219 | 468 days ago | IN | 0 ETH | 0.0000153 | ||||
| Enter Markets | 10184401 | 468 days ago | IN | 0 ETH | 0.00001353 | ||||
| Enter Markets | 10184393 | 468 days ago | IN | 0 ETH | 0.00001461 | ||||
| Exit Market | 9801083 | 481 days ago | IN | 0 ETH | 0.00001424 | ||||
| Enter Markets | 9801059 | 481 days ago | IN | 0 ETH | 0.00000813 | ||||
| Exit Market | 9723997 | 483 days ago | IN | 0 ETH | 0.00001749 | ||||
| Exit Market | 9723713 | 483 days ago | IN | 0 ETH | 0.00001716 | ||||
| Enter Markets | 9347788 | 496 days ago | IN | 0 ETH | 0.00000643 | ||||
| Enter Markets | 9301197 | 498 days ago | IN | 0 ETH | 0.00000517 | ||||
| Enter Markets | 9301194 | 498 days ago | IN | 0 ETH | 0.00000556 | ||||
| Enter Markets | 9164889 | 503 days ago | IN | 0 ETH | 0.00000982 | ||||
| Enter Markets | 9164888 | 503 days ago | IN | 0 ETH | 0.00001106 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
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-28
*/
/**
*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
Contract ABI
API[{"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
608060405234801561001057600080fd5b50600080546001600160a01b03191633179055614d58806100326000396000f3fe608060405234801561001057600080fd5b506004361061045e5760003560e01c806387f763031161024c578063c274583a11610146578063e6653f3d116100c3578063f4a433c011610087578063f4a433c014610bc9578063f50b2efe14610be9578063f851a44014610bfc578063f90c492414610c0f578063fc57d4df14610c1657600080fd5b8063e6653f3d14610b79578063e875544614610b8d578063eabe7d9114610b96578063ede4edd014610ba9578063f00a7a9214610bbc57600080fd5b8063d02f73511161010a578063d02f735114610b1a578063da3d454c14610b2d578063dce1544914610b40578063dcfbc0c714610b53578063e4028eee14610b6657600080fd5b8063c274583a14610a50578063c299823814610a87578063c488847b14610aa7578063ca0af04314610acf578063cc7ebdc414610afa57600080fd5b8063a7f0e231116101d4578063b21be7fd11610198578063b21be7fd146109cc578063b24ebfcc146109f7578063bb82aa5e14610a0a578063bdcdc25814610a1d578063bea6b8b814610a3057600080fd5b8063a7f0e23114610959578063aa90075414610987578063abfceffc14610990578063ac0b0bb7146109b0578063b0772d0b146109c457600080fd5b8063929fe9a11161021b578063929fe9a1146108c957806394543c151461090a57806394b2294b1461091d578063986ab83814610926578063a76b3fda1461094657600080fd5b806387f76303146108175780638c57804e1461082b5780638e8f294b146108635780638ebf6364146108b657600080fd5b80634a5844321161035d5780635f5af1aa116102e55780636b79c38d116102a95780636b79c38d146107475780636d154ea5146107a35780636d35bf91146107c6578063731f0c2b146107d457806385b7beb8146107f757600080fd5b80635f5af1aa146106e05780635fc7e71e146106f3578063607ef6c1146107065780636a56947e146107195780636aa875b51461072757600080fd5b80634fd42e171161032c5780634fd42e171461068157806351dff9891461069457806352d84d1e146106a75780635c778605146106ba5780635ec88c79146106cd57600080fd5b80634a584432146106175780634ada90af146106375780634e79238f146106405780634ef4c3e11461066e57600080fd5b806326782247116103eb5780633c94786f116103af5780633c94786f146105ae5780633ce142f5146105c257806341c728b9146105e757806342cbb15c146105fb57806347ef3b3b1461060157600080fd5b8063267822471461054f5780632d70db7814610562578063317b0b7714610575578063391957d7146105885780633bcf7ec11461059b57600080fd5b80631d7b33d7116104325780631d7b33d7146104bb5780631ededc91146104e957806321af4569146104fe57806324008a621461052957806324a3d6221461053c57600080fd5b80627e3dd21461046357806316b95e8f1461048057806318c882a5146104955780631d504dc6146104a8575b600080fd5b61046b600181565b60405190151581526020015b60405180910390f35b61049361048e36600461444d565b610c29565b005b61046b6104a33660046144dc565b610ed2565b6104936104b6366004614515565b61100b565b6104db6104c9366004614515565b600e6020526000908152604090205481565b604051908152602001610477565b6104936104f7366004614532565b5050505050565b601454610511906001600160a01b031681565b6040516001600160a01b039091168152602001610477565b6104db61053736600461458d565b611189565b600954610511906001600160a01b031681565b600154610511906001600160a01b031681565b61046b6105703660046145de565b6111bd565b6104db6105833660046145fb565b6112ad565b610493610596366004614515565b611354565b61046b6105a93660046144dc565b61141e565b60095461046b90600160a01b900460ff1681565b6105d56105d0366004614515565b611548565b60405160ff9091168152602001610477565b6104936105f5366004614614565b50505050565b436104db565b61049361060f36600461465a565b505050505050565b6104db610625366004614515565b60156020526000908152604090205481565b6104db60055481565b61065361064e366004614614565b61164a565b60408051938452602084019290925290820152606001610477565b6104db61067c3660046146c8565b61168a565b6104db61068f3660046145fb565b611718565b6104936106a2366004614614565b611775565b6105116106b53660046145fb565b6117c4565b6104936106c83660046146c8565b505050565b6106536106db366004614515565b6117ee565b6104db6106ee366004614515565b611829565b6104db610701366004614709565b6118a2565b61049361071436600461444d565b611a74565b6104936105f536600461458d565b6104db610735366004614515565b60196020526000908152604090205481565b61077f610755366004614515565b600f602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b604080516001600160e01b03909316835263ffffffff909116602083015201610477565b61046b6107b1366004614515565b600b6020526000908152604090205460ff1681565b6104936104f7366004614709565b61046b6107e2366004614515565b600a6020526000908152604090205460ff1681565b6104db610805366004614515565b601b6020526000908152604090205481565b60095461046b90600160b01b900460ff1681565b61077f610839366004614515565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b610897610871366004614515565b60086020526000908152604090208054600182015460039092015460ff91821692911683565b6040805193151584526020840192909252151590820152606001610477565b61046b6108c43660046145de565b611c52565b61046b6108d736600461476d565b6001600160a01b038082166000908152600860209081526040808320938616835260029093019052205460ff1692915050565b61046b610918366004614515565b611d39565b6104db60065481565b6104db610934366004614515565b60166020526000908152604090205481565b6104db610954366004614515565b611df8565b61096f6ec097ce7bc90715b34b9f100000000081565b6040516001600160e01b039091168152602001610477565b6104db600d5481565b6109a361099e366004614515565b611f2a565b604051610477919061479b565b60095461046b90600160b81b900460ff1681565b6109a3611fa0565b6104db6109da36600461476d565b601160209081526000928352604080842090915290825290205481565b6104db610a05366004614853565b612002565b600254610511906001600160a01b031681565b6104db610a2b36600461458d565b61200d565b6104db610a3e366004614515565b60176020526000908152604090205481565b60408051808201825260158152741c99591cdd1bdb994b5c1c9a5b585c9e4b5c1c9bd9605a1b602082015290516104779190614902565b610a9a610a95366004614935565b612087565b60405161047791906149c4565b610aba610ab53660046146c8565b61214f565b60408051928352602083019190915201610477565b6104db610add36600461476d565b601260209081526000928352604080842090915290825290205481565b6104db610b08366004614515565b60136020526000908152604090205481565b6104db610b28366004614709565b61229b565b6104db610b3b3660046146c8565b612419565b610511610b4e3660046149fc565b6126fc565b600354610511906001600160a01b031681565b6104db610b743660046149fc565b612734565b60095461046b90600160a81b900460ff1681565b6104db60045481565b6104db610ba43660046146c8565b612860565b6104db610bb7366004614515565b612888565b601a5461046b9060ff1681565b6104db610bd7366004614515565b60186020526000908152604090205481565b610493610bf73660046145fb565b612be3565b600054610511906001600160a01b031681565b60036105d5565b6104db610c24366004614515565b612bec565b6000546001600160a01b03163314610c925760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6044820152603760f91b60648201526084015b60405180910390fd5b601a5460ff1615610cf45760405162461bcd60e51b815260206004820152602660248201527f416c72656164792065786563757465642074686973206f6e652d6f66662066756044820152653731ba34b7b760d11b6064820152608401610c89565b828114610d335760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60008060008060005b87811015610eba57888882818110610d5657610d56614a28565b9050602002016020810190610d6b9190614515565b6001600160a01b0381166000908152601360205260409020549095509350868682818110610d9b57610d9b614a28565b90506020020135925083831115610e3f576000610db88585614a54565b6001600160a01b0387166000908152601b6020526040812054919250610dde8284613109565b6001600160a01b0389166000818152601b6020908152604091829020849055815186815290810184905292935090917f17fea09d9a7ca41b2f9f9118f18f44848a62e9c70d55dd4385131eb2cf1b7e47910160405180910390a28695505050505b8215610eaa57610e4f8484613115565b6001600160a01b038616600081815260136020908152604091829020849055815188815290810184905292945090917f4a5c134e28b537a76546993ea37f3b60d9190476df7356d3842aa40902e20f04910160405180910390a25b610eb381614a67565b9050610d3c565b5050601a805460ff1916600117905550505050505050565b6001600160a01b03821660009081526008602052604081205460ff16610f0a5760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b0316331480610f2d57506000546001600160a01b031633145b610f495760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480610f6457506001821515145b610f805760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600b6020908152604091829020805460ff19168615159081179091558251938452606091840182905260069184019190915265426f72726f7760d01b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a0015b60405180910390a150805b92915050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190614b3f565b6001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b815260206004820152602760248201527f6f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676560448201526620627261696e7360c81b6064820152608401610c89565b806001600160a01b031663c1e803346040518163ffffffff1660e01b81526004016020604051808303816000875af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190614b5c565b156111865760405162461bcd60e51b815260206004820152601560248201527418da185b99d9481b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610c89565b50565b6001600160a01b03841660009081526008602052604081205460ff166111b1575060096111b5565b5060005b949350505050565b6009546000906001600160a01b03163314806111e357506000546001600160a01b031633145b6111ff5760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b031633148061121a57506001821515145b6112365760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b81b0260ff60b81b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600590820152645365697a6560d81b6060820152901515602082015260800190565b60405180910390a15090565b600080546001600160a01b031633146113085760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f72006044820152606401610c89565b600480549083905560408051828152602081018590527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a160005b9392505050565b6000546001600160a01b031633146113bd5760405162461bcd60e51b815260206004820152602660248201527f6f6e6c792061646d696e2063616e2073657420626f72726f772063617020677560448201526530b93234b0b760d11b6064820152608401610c89565b601480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29910160405180910390a15050565b6001600160a01b03821660009081526008602052604081205460ff166114565760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b031633148061147957506000546001600160a01b031633145b6114955760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b03163314806114b057506001821515145b6114cc5760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600a6020908152604091829020805460ff19168615159081179091558251938452606091840182905260049184019190915263135a5b9d60e21b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a001610ffa565b60006001600160a01b038216738bb8f32df04c8b654987daaed53d6b6091e3b7740361157657506000919050565b6001600160a01b03821673deb22f54738d54976c4c0fe5ce6d408e40d88499036115a257506001919050565b6001600160a01b0382167351ce04be4b3e32572c4ec9135221d0691ba7d202036115ce57506002919050565b6001600160a01b03821673dd682daec5a90dd295d14da4b0bec9281017b5be036115fa57506003919050565b6001600160a01b038216739c5ae89c4af6aa32ce58588dbaf90d18a855b6de0361162657506004919050565b6040516303b1166f60e61b81526001600160a01b0383166004820152602401610c89565b60008060008060008061165f8a8a8a8a613121565b92509250925082601181111561167757611677614b75565b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600a602052604081205460ff16156116e45760405162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661170e5760095b905061134d565b6000949350505050565b600080546001600160a01b03163314611737576110056001600b6133f4565b600580549083905560408051828152602081018590527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec13169101611342565b801580156117835750600082115b156105f55760405162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b6044820152606401610c89565b600c81815481106117d457600080fd5b6000918252602090912001546001600160a01b0316905081565b600080600080600080611805876000806000613121565b92509250925082601181111561181d5761181d614b75565b97919650945092505050565b600080546001600160a01b0316331461184857611005600160136133f4565b600980546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9101611342565b6001600160a01b03851660009081526008602052604081205460ff1615806118e357506001600160a01b03851660009081526008602052604090205460ff16155b156118f25760095b9050611a6b565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908816906395dd919390602401602060405180830381865afa15801561193c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190614b5c565b905061196b87611d39565b156119d657828110156119d15760405162461bcd60e51b815260206004820152602860248201527f43616e206e6f74207265706179206d6f7265207468616e2074686520746f74616044820152676c20626f72726f7760c01b6064820152608401610c89565b611a65565b6000806119e28661346d565b919350909150600090508260118111156119fe576119fe614b75565b14611a1f57816011811115611a1557611a15614b75565b9350505050611a6b565b80600003611a2e576003611a15565b6000611a4a60405180602001604052806004548152508561348d565b905080861115611a61576011945050505050611a6b565b5050505b60009150505b95945050505050565b6000546001600160a01b0316331480611a9757506014546001600160a01b031633145b611b015760405162461bcd60e51b815260206004820152603560248201527f6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616044820152746e2063616e2073657420626f72726f77206361707360581b6064820152608401610c89565b82818115801590611b1157508082145b611b4d5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60005b82811015611c4957848482818110611b6a57611b6a614a28565b9050602002013560156000898985818110611b8757611b87614a28565b9050602002016020810190611b9c9190614515565b6001600160a01b03168152602081019190915260400160002055868682818110611bc857611bc8614a28565b9050602002016020810190611bdd9190614515565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611c1957611c19614a28565b90506020020135604051611c2f91815260200190565b60405180910390a280611c4181614a67565b915050611b50565b50505050505050565b6009546000906001600160a01b0316331480611c7857506000546001600160a01b031633145b611c945760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480611caf57506001821515145b611ccb5760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b01b0260ff60b01b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600890820152672a3930b739b332b960c11b6060820152901515602082015260800190565b6001600160a01b038116600090815260086020526040812060010154158015611d7f57506001600160a01b0382166000908152600b602052604090205460ff1615156001145b80156110055750816001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de89190614b5c565b670de0b6b3a76400001492915050565b600080546001600160a01b03163314611e1757611005600160126133f4565b6001600160a01b03821660009081526008602052604090205460ff1615611e4457611005600a60116133f4565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea69190614b8b565b506001600160a01b03821660009081526008602052604081208054600160ff1991821681178355600383018054909216909155810191909155611ee8836134a5565b611ef18361358d565b6040516001600160a01b03841681527fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90602001611342565b6001600160a01b0381166000908152600760209081526040808320805482518185028101850190935280835260609493830182828015611f9357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f75575b5093979650505050505050565b6060600c805480602002602001604051908101604052809291908181526020018280548015611ff857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611fda575b5050505050905090565b600061100582613689565b600954600090600160b01b900460ff161561205f5760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b6044820152606401610c89565b600061206c868685613694565b9050801561207b5790506111b5565b60009695505050505050565b805160609060008167ffffffffffffffff8111156120a7576120a76147e8565b6040519080825280602002602001820160405280156120d0578160200160208202803683370190505b50905060005b828110156121475760008582815181106120f2576120f2614a28565b60200260200101519050612106813361374c565b601181111561211757612117614b75565b83838151811061212957612129614a28565b6020908102919091010152508061213f81614a67565b9150506120d6565b509392505050565b600080600061215d86612bec565b9050600061216a86612bec565b9050811580612177575080155b1561218b57600d6000935093505050612293565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef9190614b5c565b905060006122096040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260055481528451928301909452888252919261224591613840565b925061226d604051806020016040528088815250604051806020016040528088815250613840565b91506122798383613888565b9050612285818b61348d565b600099509750505050505050505b935093915050565b600954600090600160b81b900460ff16156122ea5760405162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b6044820152606401610c89565b6001600160a01b03861660009081526008602052604090205460ff16158061232b57506001600160a01b03851660009081526008602052604090205460ff16155b156123375760096118eb565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614b3f565b6001600160a01b0316866001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190614b3f565b6001600160a01b03161461207b5760026118eb565b6001600160a01b0383166000908152600b602052604081205460ff16156124755760405162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661249c576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff1661259957336001600160a01b0385161461251d5760405162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329031aa37b5b2b760591b6044820152606401610c89565b6000612529338561374c565b9050600081601181111561253f5761253f614b75565b1461255e5780601181111561255657612556614b75565b91505061134d565b6001600160a01b038086166000908152600860209081526040808320938816835260029093019052205460ff1661259757612597614ba8565b505b6125a284612bec565b6000036125b057600d611707565b6001600160a01b0384166000908152601560205260409020548015612695576000856001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190614b5c565b905060006126418286613109565b90508281106126925760405162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f77206361702072656163686564000000000000006044820152606401610c89565b50505b6000806126a58688600088613121565b919350909150600090508260118111156126c1576126c1614b75565b146126e2578160118111156126d8576126d8614b75565b935050505061134d565b80156126ef5760046126d8565b6000979650505050505050565b6007602052816000526040600020818154811061271857600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080546001600160a01b0316331461275a57612753600160066133f4565b9050611005565b6001600160a01b0383166000908152600860205260409020805460ff1661278f57612787600960076133f4565b915050611005565b60408051602080820183528582528251908101909252670c7d713b49da00008252906127bd81835190511090565b156127d8576127ce600660086133f4565b9350505050611005565b84158015906127ed57506127eb86612bec565b155b156127fe576127ce600d60096133f4565b60018301805490869055604080516001600160a01b0389168152602081018390529081018790527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a160005b979650505050505050565b60008061286e858585613694565b9050801561287d57905061134d565b600095945050505050565b6040516361bfb47160e11b815233600482015260009082908290819081906001600160a01b0385169063c37f68e290602401608060405180830381865afa1580156128d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fb9190614bbe565b50925092509250826000146129605760405162461bcd60e51b815260206004820152602560248201527f657869744d61726b65743a206765744163636f756e74536e617073686f742066604482015264185a5b195960da1b6064820152608401610c89565b801561297c57612972600c60026133f4565b9695505050505050565b6000612989873385613694565b9050801561299e57612855600e6003836138c2565b6001600160a01b0385166000908152600860209081526040808320338452600281019092529091205460ff166129dd5760005b98975050505050505050565b3360009081526002820160209081526040808320805460ff191690556007825280832080548251818502810185019093528083529192909190830182828015612a4f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a31575b5050835193945083925060009150505b82811015612ab357896001600160a01b0316848281518110612a8357612a83614a28565b60200260200101516001600160a01b031603612aa157809150612ab3565b80612aab81614a67565b915050612a5f565b50818110612ac357612ac3614ba8565b33600090815260076020526040902080548190612ae290600190614a54565b81548110612af257612af2614a28565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110612b2257612b22614a28565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480612b6057612b60614bf4565b600082815260209020810160001990810180546001600160a01b03191690550190556040517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90612bc9908c9033906001600160a01b0392831681529116602082015260400190565b60405180910390a160009c9b505050505050505050505050565b6111868161393a565b6000806000604051602001612c0b90630c68aa8960e31b815260040190565b60405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c5f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c879190810190614c0a565b604051602001612c979190614c9e565b6040516020818303038152906040528051906020012003612cc857612cc16208aa8960eb1b6139be565b9150613102565b604051640c6ae8aa8960db1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d589190810190614c0a565b604051602001612d689190614c9e565b6040516020818303038152906040528051906020012003612d9257612cc16208aa8960eb1b6139be565b60405164635553444360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612dfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e229190810190614c0a565b604051602001612e329190614c9e565b6040516020818303038152906040528051906020012003612e6c57612e5d635553444360e01b6139be565b612cc19064e8d4a51000614cba565b6040516418d554d11560da1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612efc9190810190614c0a565b604051602001612f0c9190614c9e565b6040516020818303038152906040528051906020012003612f3757612e5d631554d11560e21b6139be565b60405164635742544360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fc79190810190614c0a565b604051602001612fd79190614c9e565b6040516020818303038152906040528051906020012003613010576130016242544360e81b6139be565b612cc1906402540be400614cba565b6000846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130749190614b3f565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156130b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130d99190810190614c0a565b905060008082905080516000036130ef57600091505b60208301519150819350612855846139be565b5092915050565b600061134d8284614cd1565b600061134d8284614a54565b600080600061312e61435f565b6001600160a01b03881660009081526007602090815260408083208054825181850281018501909352808352849383018282801561319557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613177575b5050505050905060005b815181101561339e5760008282815181106131bc576131bc614a28565b60209081029190910101516040516361bfb47160e11b81526001600160a01b038e811660048301529192509082169063c37f68e290602401608060405180830381865afa158015613211573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132359190614bbe565b6080890152606088015260408701529350831561326157600f6000809750975097505050505050611680565b60408051602080820183526001600160a01b03841660009081526008825283902060010154825260c088019190915281519081019091526080860151815260e08601526132ad81612bec565b60a086018190526000036132d057600d6000809750975097505050505050611680565b604080516020810190915260a0860151815261010086015260c085015160e086015161330a916132ff91613840565b866101000151613840565b610120860181905260408601518651613324929190613a2e565b855261010085015160608601516020870151613341929190613a2e565b60208601526001600160a01b03808c169082160361338b5761336d8561012001518b8760200151613a2e565b60208601819052610100860151613385918b90613a2e565b60208601525b508061339681614a67565b91505061319f565b506020830151835111156133cf57602083015183516000916133bf91614a54565b6000955095509550505050611680565b600080846000015185602001516133e69190614a54565b955095509550505050611680565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561342957613429614b75565b83601381111561343b5761343b614b75565b60408051928352602083019190915260009082015260600160405180910390a182601181111561134d5761134d614b75565b6000806000613480846000806000613121565b9250925092509193909250565b60008061349a8484613a4f565b90506111b581613a77565b60005b600c5481101561353a57816001600160a01b0316600c82815481106134cf576134cf614a28565b6000918252602090912001546001600160a01b0316036135285760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08185b1c9958591e48185919195960621b6044820152606401610c89565b8061353281614a67565b9150506134a8565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b0392909216919091179055565b60006135ce436040518060400160405280601c81526020017f626c6f636b206e756d6265722065786365656473203332206269747300000000815250613a8f565b6001600160a01b0383166000908152600f60209081526040808320601090925282208154939450909290916001600160e01b03909116900361362a5781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b031660000361365c5780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b600061100582613abf565b6001600160a01b03831660009081526008602052604081205460ff166136bb576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff166136f3576000611707565b6000806137038587866000613121565b9193509091506000905082601181111561371f5761371f614b75565b1461373f5781601181111561373657613736614b75565b9250505061134d565b801561207b576004613736565b6001600160a01b0382166000908152600860205260408120805460ff16613777576009915050611005565b6001600160a01b038316600090815260028201602052604090205460ff1615156001036137a8576000915050611005565b6001600160a01b03838116600081815260028401602090815260408083208054600160ff199091168117909155600783528184208054918201815584529282902090920180546001600160a01b031916948916948517905581519384528301919091527f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5910160405180910390a15060009392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061387586600001518660000151613b7a565b61387f9190614cfa565b90529392505050565b604080516020810190915260008152604051806020016040528061387f6138bb8660000151670de0b6b3a7640000613b7a565b8551613b86565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460118111156138f7576138f7614b75565b84601381111561390957613909614b75565b604080519283526020830191909152810184905260600160405180910390a18360118111156111b5576111b5614b75565b60006139486103e883614cfa565b90508042101561398a57603c61395e4283614a54565b11156139865760405163b6b0916d60e01b815260048101829052426024820152604401610c89565b5050565b60b46139968242614a54565b111561398657604051630321d0b560e01b815260048101829052426024820152604401610c89565b6040805160018082528183019092526000918291906020808301908036833701905050905082816000815181106139f7576139f7614a28565b602002602001018181525050613a0c81613b92565b600081518110613a1e57613a1e614a28565b6020026020010151915050919050565b600080613a3b8585613a4f565b9050611a6b613a4982613a77565b84613109565b604080516020810190915260008152604051806020016040528061387f856000015185613b7a565b805160009061100590670de0b6b3a764000090614cfa565b6000816401000000008410613ab75760405162461bcd60e51b8152600401610c899190614902565b509192915050565b60008151600003613ae357604051639e198af960e01b815260040160405180910390fd5b613aec82613b9d565b600060028351613afc9190614cfa565b905060028351613b0c9190614d0e565b600003613b68576000613b5b84613b24600185614a54565b81518110613b3457613b34614a28565b6020026020010151858481518110613b4e57613b4e614a28565b6020026020010151613109565b90506111b5600282614cfa565b828181518110613a1e57613a1e614a28565b600061134d8284614cba565b600061134d8284614cfa565b606061100582613be5565b8051602082016020820281019150805b828110156105f557815b81811015613bdc578151815180821015613bd2578084528183525b5050602001613bb7565b50602001613bad565b60606000825167ffffffffffffffff811115613c0357613c036147e8565b604051908082528060200260200182016040528015613c2c578160200160208202803683370190505b5090506000835167ffffffffffffffff811115613c4b57613c4b6147e8565b604051908082528060200260200182016040528015613c74578160200160208202803683370190505b5090506000845167ffffffffffffffff811115613c9357613c936147e8565b604051908082528060200260200182016040528015613cc657816020015b6060815260200190600190039081613cb15790505b50905060005b8551811015613d245760408051600380825260808201909252906020820160608036833701905050828281518110613d0657613d06614a28565b60200260200101819052508080613d1c90614a67565b915050613ccc565b506000613d2f613d9e565b90506000613d3c82613e45565b61ffff169050613d4d600283614cd1565b60405190925060005b82811015613d93576000613d6d8a89898989613e7f565b9050613d798186614cd1565b945082604052508080613d8b90614a67565b915050613d56565b506129d1848761411f565b60006602ed57011e0000601f1936013581161480613dcf576040516373bb264f60e11b815260040160405180910390fd5b60003660291115613df357604051632bcb7bc560e11b815260040160405180910390fd5b5060281936013560006009613e0e600362ffffff8516614cd1565b613e189190614cd1565b905036613e26600283614cd1565b111561134d5760405163c30a7bd760e01b815260040160405180910390fd5b600080613e53602084614cd1565b905036811115613e7657604051632bcb7bc560e11b815260040160405180910390fd5b36033592915050565b600080600080613e8e85614238565b909250905060008080606081600d613eb1613eaa602089614cd1565b8990613b7a565b613ebb9190614cd1565b90506000613ed4613ecd60688d614cd1565b3690613115565b90506000613ef183613ee760418f614cd1565b613ecd9190614cd1565b9050613efd8382613f10565b9350826020850120945081359650613f34565b60408051838152602081850181019092526000910183838237601f19019392505050565b613f458765ffffffffffff16612be3565b613f5985613f5460418f614cd1565b614288565b9550613f6486611548565b60ff1699505050505050505060008060005b848110156140ec57613f89888583614300565b909350915060005b8c518110156140d9578c8181518110613fac57613fac614a28565b602002602001015184036140c75760008b8281518110613fce57613fce614a28565b60200260200101519050613fe781896001901b16151590565b1580156140105750600360ff168d838151811061400657614006614a28565b6020026020010151105b156140c1578c828151811061402757614027614a28565b60200260200101805180919061403c90614a67565b81525050838b838151811061405357614053614a28565b602002602001015160018f858151811061406f5761406f614a28565b60200260200101516140819190614a54565b8151811061409157614091614a28565b60209081029190910101526001881b81178c83815181106140b4576140b4614a28565b6020026020010181815250505b506140d9565b806140d181614a67565b915050613f91565b50806140e481614a67565b915050613f76565b505050816020826140fd9190614cd1565b6141079190614cba565b61411290604e614cd1565b9998505050505050505050565b60606000835167ffffffffffffffff81111561413d5761413d6147e8565b604051908082528060200260200182016040528015614166578160200160208202803683370190505b509050600360005b855181101561422e578185828151811061418a5761418a614a28565b602002602001015110156141d7578481815181106141aa576141aa614a28565b602002602001015182604051632b13aef560e01b8152600401610c89929190918252602082015260400190565b60006141fb8783815181106141ee576141ee614a28565b6020026020010151612002565b90508084838151811061421057614210614a28565b6020908102919091010152508061422681614a67565b91505061416e565b5090949350505050565b600080808080614249604187614cd1565b9050600061425b613ecd602084614cd1565b80359450905061426c816003613115565b62ffffff9490941697933563ffffffff16965092945050505050565b60408051600080825260208083018085528690523685900380850135831a948401859052803560608501819052910135608084018190529193909260019060a0016020604051602081039080840390855afa1580156142eb573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000808061430f604e87614cd1565b9050600061433c614335614324602089614cd1565b61432f886001614cd1565b90613b7a565b8390613109565b9050600061434a3683613115565b80359960209091013598509650505050505050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016143ab6040518060200160405280600081525090565b81526020016143c66040518060200160405280600081525090565b81526020016143e16040518060200160405280600081525090565b81526020016143fc6040518060200160405280600081525090565b905290565b60008083601f84011261441357600080fd5b50813567ffffffffffffffff81111561442b57600080fd5b6020830191508360208260051b850101111561444657600080fd5b9250929050565b6000806000806040858703121561446357600080fd5b843567ffffffffffffffff8082111561447b57600080fd5b61448788838901614401565b909650945060208701359150808211156144a057600080fd5b506144ad87828801614401565b95989497509550505050565b6001600160a01b038116811461118657600080fd5b801515811461118657600080fd5b600080604083850312156144ef57600080fd5b82356144fa816144b9565b9150602083013561450a816144ce565b809150509250929050565b60006020828403121561452757600080fd5b813561134d816144b9565b600080600080600060a0868803121561454a57600080fd5b8535614555816144b9565b94506020860135614565816144b9565b93506040860135614575816144b9565b94979396509394606081013594506080013592915050565b600080600080608085870312156145a357600080fd5b84356145ae816144b9565b935060208501356145be816144b9565b925060408501356145ce816144b9565b9396929550929360600135925050565b6000602082840312156145f057600080fd5b813561134d816144ce565b60006020828403121561460d57600080fd5b5035919050565b6000806000806080858703121561462a57600080fd5b8435614635816144b9565b93506020850135614645816144b9565b93969395505050506040820135916060013590565b60008060008060008060c0878903121561467357600080fd5b863561467e816144b9565b9550602087013561468e816144b9565b9450604087013561469e816144b9565b935060608701356146ae816144b9565b9598949750929560808101359460a0909101359350915050565b6000806000606084860312156146dd57600080fd5b83356146e8816144b9565b925060208401356146f8816144b9565b929592945050506040919091013590565b600080600080600060a0868803121561472157600080fd5b853561472c816144b9565b9450602086013561473c816144b9565b9350604086013561474c816144b9565b9250606086013561475c816144b9565b949793965091946080013592915050565b6000806040838503121561478057600080fd5b823561478b816144b9565b9150602083013561450a816144b9565b6020808252825182820181905260009190848201906040850190845b818110156147dc5783516001600160a01b0316835292840192918401916001016147b7565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614827576148276147e8565b604052919050565b600067ffffffffffffffff821115614849576148496147e8565b5060051b60200190565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b80356148a161489c8261482f565b6147fe565b81815260059190911b820183019083810190878311156148c057600080fd5b928401925b82841015612855578335825292840192908401906148c5565b60005b838110156148f95781810151838201526020016148e1565b50506000910152565b60208152600082518060208401526149218160408501602087016148de565b601f01601f19169190910160400192915050565b6000602080838503121561494857600080fd5b823567ffffffffffffffff81111561495f57600080fd5b8301601f8101851361497057600080fd5b803561497e61489c8261482f565b81815260059190911b8201830190838101908783111561499d57600080fd5b928401925b828410156128555783356149b5816144b9565b825292840192908401906149a2565b6020808252825182820181905260009190848201906040850190845b818110156147dc578351835292840192918401916001016149e0565b60008060408385031215614a0f57600080fd5b8235614a1a816144b9565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561100557611005614a3e565b600060018201614a7957614a79614a3e565b5060010190565b60208082526028908201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6040820152671d081b1a5cdd195960c21b606082015260800190565b60208082526027908201527f6f6e6c7920706175736520677561726469616e20616e642061646d696e2063616040820152666e20706175736560c81b606082015260800190565b6020808252601690820152756f6e6c792061646d696e2063616e20756e706175736560501b604082015260600190565b600060208284031215614b5157600080fd5b815161134d816144b9565b600060208284031215614b6e57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614b9d57600080fd5b815161134d816144ce565b634e487b7160e01b600052600160045260246000fd5b60008060008060808587031215614bd457600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614c1c57600080fd5b815167ffffffffffffffff80821115614c3457600080fd5b818401915084601f830112614c4857600080fd5b815181811115614c5a57614c5a6147e8565b614c6d601f8201601f19166020016147fe565b9150808252856020828501011115614c8457600080fd5b614c958160208401602086016148de565b50949350505050565b60008251614cb08184602087016148de565b9190910192915050565b808202811582820484141761100557611005614a3e565b8082018082111561100557611005614a3e565b634e487b7160e01b600052601260045260246000fd5b600082614d0957614d09614ce4565b500490565b600082614d1d57614d1d614ce4565b50069056fea2646970667358221220a58e7b3a602b383375b9890cf1561943f1fa328f230a4df9fda104da731ded4364736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061045e5760003560e01c806387f763031161024c578063c274583a11610146578063e6653f3d116100c3578063f4a433c011610087578063f4a433c014610bc9578063f50b2efe14610be9578063f851a44014610bfc578063f90c492414610c0f578063fc57d4df14610c1657600080fd5b8063e6653f3d14610b79578063e875544614610b8d578063eabe7d9114610b96578063ede4edd014610ba9578063f00a7a9214610bbc57600080fd5b8063d02f73511161010a578063d02f735114610b1a578063da3d454c14610b2d578063dce1544914610b40578063dcfbc0c714610b53578063e4028eee14610b6657600080fd5b8063c274583a14610a50578063c299823814610a87578063c488847b14610aa7578063ca0af04314610acf578063cc7ebdc414610afa57600080fd5b8063a7f0e231116101d4578063b21be7fd11610198578063b21be7fd146109cc578063b24ebfcc146109f7578063bb82aa5e14610a0a578063bdcdc25814610a1d578063bea6b8b814610a3057600080fd5b8063a7f0e23114610959578063aa90075414610987578063abfceffc14610990578063ac0b0bb7146109b0578063b0772d0b146109c457600080fd5b8063929fe9a11161021b578063929fe9a1146108c957806394543c151461090a57806394b2294b1461091d578063986ab83814610926578063a76b3fda1461094657600080fd5b806387f76303146108175780638c57804e1461082b5780638e8f294b146108635780638ebf6364146108b657600080fd5b80634a5844321161035d5780635f5af1aa116102e55780636b79c38d116102a95780636b79c38d146107475780636d154ea5146107a35780636d35bf91146107c6578063731f0c2b146107d457806385b7beb8146107f757600080fd5b80635f5af1aa146106e05780635fc7e71e146106f3578063607ef6c1146107065780636a56947e146107195780636aa875b51461072757600080fd5b80634fd42e171161032c5780634fd42e171461068157806351dff9891461069457806352d84d1e146106a75780635c778605146106ba5780635ec88c79146106cd57600080fd5b80634a584432146106175780634ada90af146106375780634e79238f146106405780634ef4c3e11461066e57600080fd5b806326782247116103eb5780633c94786f116103af5780633c94786f146105ae5780633ce142f5146105c257806341c728b9146105e757806342cbb15c146105fb57806347ef3b3b1461060157600080fd5b8063267822471461054f5780632d70db7814610562578063317b0b7714610575578063391957d7146105885780633bcf7ec11461059b57600080fd5b80631d7b33d7116104325780631d7b33d7146104bb5780631ededc91146104e957806321af4569146104fe57806324008a621461052957806324a3d6221461053c57600080fd5b80627e3dd21461046357806316b95e8f1461048057806318c882a5146104955780631d504dc6146104a8575b600080fd5b61046b600181565b60405190151581526020015b60405180910390f35b61049361048e36600461444d565b610c29565b005b61046b6104a33660046144dc565b610ed2565b6104936104b6366004614515565b61100b565b6104db6104c9366004614515565b600e6020526000908152604090205481565b604051908152602001610477565b6104936104f7366004614532565b5050505050565b601454610511906001600160a01b031681565b6040516001600160a01b039091168152602001610477565b6104db61053736600461458d565b611189565b600954610511906001600160a01b031681565b600154610511906001600160a01b031681565b61046b6105703660046145de565b6111bd565b6104db6105833660046145fb565b6112ad565b610493610596366004614515565b611354565b61046b6105a93660046144dc565b61141e565b60095461046b90600160a01b900460ff1681565b6105d56105d0366004614515565b611548565b60405160ff9091168152602001610477565b6104936105f5366004614614565b50505050565b436104db565b61049361060f36600461465a565b505050505050565b6104db610625366004614515565b60156020526000908152604090205481565b6104db60055481565b61065361064e366004614614565b61164a565b60408051938452602084019290925290820152606001610477565b6104db61067c3660046146c8565b61168a565b6104db61068f3660046145fb565b611718565b6104936106a2366004614614565b611775565b6105116106b53660046145fb565b6117c4565b6104936106c83660046146c8565b505050565b6106536106db366004614515565b6117ee565b6104db6106ee366004614515565b611829565b6104db610701366004614709565b6118a2565b61049361071436600461444d565b611a74565b6104936105f536600461458d565b6104db610735366004614515565b60196020526000908152604090205481565b61077f610755366004614515565b600f602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b604080516001600160e01b03909316835263ffffffff909116602083015201610477565b61046b6107b1366004614515565b600b6020526000908152604090205460ff1681565b6104936104f7366004614709565b61046b6107e2366004614515565b600a6020526000908152604090205460ff1681565b6104db610805366004614515565b601b6020526000908152604090205481565b60095461046b90600160b01b900460ff1681565b61077f610839366004614515565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b610897610871366004614515565b60086020526000908152604090208054600182015460039092015460ff91821692911683565b6040805193151584526020840192909252151590820152606001610477565b61046b6108c43660046145de565b611c52565b61046b6108d736600461476d565b6001600160a01b038082166000908152600860209081526040808320938616835260029093019052205460ff1692915050565b61046b610918366004614515565b611d39565b6104db60065481565b6104db610934366004614515565b60166020526000908152604090205481565b6104db610954366004614515565b611df8565b61096f6ec097ce7bc90715b34b9f100000000081565b6040516001600160e01b039091168152602001610477565b6104db600d5481565b6109a361099e366004614515565b611f2a565b604051610477919061479b565b60095461046b90600160b81b900460ff1681565b6109a3611fa0565b6104db6109da36600461476d565b601160209081526000928352604080842090915290825290205481565b6104db610a05366004614853565b612002565b600254610511906001600160a01b031681565b6104db610a2b36600461458d565b61200d565b6104db610a3e366004614515565b60176020526000908152604090205481565b60408051808201825260158152741c99591cdd1bdb994b5c1c9a5b585c9e4b5c1c9bd9605a1b602082015290516104779190614902565b610a9a610a95366004614935565b612087565b60405161047791906149c4565b610aba610ab53660046146c8565b61214f565b60408051928352602083019190915201610477565b6104db610add36600461476d565b601260209081526000928352604080842090915290825290205481565b6104db610b08366004614515565b60136020526000908152604090205481565b6104db610b28366004614709565b61229b565b6104db610b3b3660046146c8565b612419565b610511610b4e3660046149fc565b6126fc565b600354610511906001600160a01b031681565b6104db610b743660046149fc565b612734565b60095461046b90600160a81b900460ff1681565b6104db60045481565b6104db610ba43660046146c8565b612860565b6104db610bb7366004614515565b612888565b601a5461046b9060ff1681565b6104db610bd7366004614515565b60186020526000908152604090205481565b610493610bf73660046145fb565b612be3565b600054610511906001600160a01b031681565b60036105d5565b6104db610c24366004614515565b612bec565b6000546001600160a01b03163314610c925760405162461bcd60e51b815260206004820152602160248201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6044820152603760f91b60648201526084015b60405180910390fd5b601a5460ff1615610cf45760405162461bcd60e51b815260206004820152602660248201527f416c72656164792065786563757465642074686973206f6e652d6f66662066756044820152653731ba34b7b760d11b6064820152608401610c89565b828114610d335760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60008060008060005b87811015610eba57888882818110610d5657610d56614a28565b9050602002016020810190610d6b9190614515565b6001600160a01b0381166000908152601360205260409020549095509350868682818110610d9b57610d9b614a28565b90506020020135925083831115610e3f576000610db88585614a54565b6001600160a01b0387166000908152601b6020526040812054919250610dde8284613109565b6001600160a01b0389166000818152601b6020908152604091829020849055815186815290810184905292935090917f17fea09d9a7ca41b2f9f9118f18f44848a62e9c70d55dd4385131eb2cf1b7e47910160405180910390a28695505050505b8215610eaa57610e4f8484613115565b6001600160a01b038616600081815260136020908152604091829020849055815188815290810184905292945090917f4a5c134e28b537a76546993ea37f3b60d9190476df7356d3842aa40902e20f04910160405180910390a25b610eb381614a67565b9050610d3c565b5050601a805460ff1916600117905550505050505050565b6001600160a01b03821660009081526008602052604081205460ff16610f0a5760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b0316331480610f2d57506000546001600160a01b031633145b610f495760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480610f6457506001821515145b610f805760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600b6020908152604091829020805460ff19168615159081179091558251938452606091840182905260069184019190915265426f72726f7760d01b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a0015b60405180910390a150805b92915050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190614b3f565b6001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b815260206004820152602760248201527f6f6e6c7920756e6974726f6c6c65722061646d696e2063616e206368616e676560448201526620627261696e7360c81b6064820152608401610c89565b806001600160a01b031663c1e803346040518163ffffffff1660e01b81526004016020604051808303816000875af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190614b5c565b156111865760405162461bcd60e51b815260206004820152601560248201527418da185b99d9481b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610c89565b50565b6001600160a01b03841660009081526008602052604081205460ff166111b1575060096111b5565b5060005b949350505050565b6009546000906001600160a01b03163314806111e357506000546001600160a01b031633145b6111ff5760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b031633148061121a57506001821515145b6112365760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b81b0260ff60b81b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600590820152645365697a6560d81b6060820152901515602082015260800190565b60405180910390a15090565b600080546001600160a01b031633146113085760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792061646d696e2063616e2073657420636c6f736520666163746f72006044820152606401610c89565b600480549083905560408051828152602081018590527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a160005b9392505050565b6000546001600160a01b031633146113bd5760405162461bcd60e51b815260206004820152602660248201527f6f6e6c792061646d696e2063616e2073657420626f72726f772063617020677560448201526530b93234b0b760d11b6064820152608401610c89565b601480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527feda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29910160405180910390a15050565b6001600160a01b03821660009081526008602052604081205460ff166114565760405162461bcd60e51b8152600401610c8990614a80565b6009546001600160a01b031633148061147957506000546001600160a01b031633145b6114955760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b03163314806114b057506001821515145b6114cc5760405162461bcd60e51b8152600401610c8990614b0f565b6001600160a01b0383166000818152600a6020908152604091829020805460ff19168615159081179091558251938452606091840182905260049184019190915263135a5b9d60e21b6080840152908201527f71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b09060a001610ffa565b60006001600160a01b038216738bb8f32df04c8b654987daaed53d6b6091e3b7740361157657506000919050565b6001600160a01b03821673deb22f54738d54976c4c0fe5ce6d408e40d88499036115a257506001919050565b6001600160a01b0382167351ce04be4b3e32572c4ec9135221d0691ba7d202036115ce57506002919050565b6001600160a01b03821673dd682daec5a90dd295d14da4b0bec9281017b5be036115fa57506003919050565b6001600160a01b038216739c5ae89c4af6aa32ce58588dbaf90d18a855b6de0361162657506004919050565b6040516303b1166f60e61b81526001600160a01b0383166004820152602401610c89565b60008060008060008061165f8a8a8a8a613121565b92509250925082601181111561167757611677614b75565b95509093509150505b9450945094915050565b6001600160a01b0383166000908152600a602052604081205460ff16156116e45760405162461bcd60e51b815260206004820152600e60248201526d1b5a5b9d081a5cc81c185d5cd95960921b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661170e5760095b905061134d565b6000949350505050565b600080546001600160a01b03163314611737576110056001600b6133f4565b600580549083905560408051828152602081018590527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec13169101611342565b801580156117835750600082115b156105f55760405162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b6044820152606401610c89565b600c81815481106117d457600080fd5b6000918252602090912001546001600160a01b0316905081565b600080600080600080611805876000806000613121565b92509250925082601181111561181d5761181d614b75565b97919650945092505050565b600080546001600160a01b0316331461184857611005600160136133f4565b600980546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9101611342565b6001600160a01b03851660009081526008602052604081205460ff1615806118e357506001600160a01b03851660009081526008602052604090205460ff16155b156118f25760095b9050611a6b565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908816906395dd919390602401602060405180830381865afa15801561193c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190614b5c565b905061196b87611d39565b156119d657828110156119d15760405162461bcd60e51b815260206004820152602860248201527f43616e206e6f74207265706179206d6f7265207468616e2074686520746f74616044820152676c20626f72726f7760c01b6064820152608401610c89565b611a65565b6000806119e28661346d565b919350909150600090508260118111156119fe576119fe614b75565b14611a1f57816011811115611a1557611a15614b75565b9350505050611a6b565b80600003611a2e576003611a15565b6000611a4a60405180602001604052806004548152508561348d565b905080861115611a61576011945050505050611a6b565b5050505b60009150505b95945050505050565b6000546001600160a01b0316331480611a9757506014546001600160a01b031633145b611b015760405162461bcd60e51b815260206004820152603560248201527f6f6e6c792061646d696e206f7220626f72726f772063617020677561726469616044820152746e2063616e2073657420626f72726f77206361707360581b6064820152608401610c89565b82818115801590611b1157508082145b611b4d5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610c89565b60005b82811015611c4957848482818110611b6a57611b6a614a28565b9050602002013560156000898985818110611b8757611b87614a28565b9050602002016020810190611b9c9190614515565b6001600160a01b03168152602081019190915260400160002055868682818110611bc857611bc8614a28565b9050602002016020810190611bdd9190614515565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611c1957611c19614a28565b90506020020135604051611c2f91815260200190565b60405180910390a280611c4181614a67565b915050611b50565b50505050505050565b6009546000906001600160a01b0316331480611c7857506000546001600160a01b031633145b611c945760405162461bcd60e51b8152600401610c8990614ac8565b6000546001600160a01b0316331480611caf57506001821515145b611ccb5760405162461bcd60e51b8152600401610c8990614b0f565b60098054831515600160b01b0260ff60b01b199091161790556040517fef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0906112a19084906040808252600890820152672a3930b739b332b960c11b6060820152901515602082015260800190565b6001600160a01b038116600090815260086020526040812060010154158015611d7f57506001600160a01b0382166000908152600b602052604090205460ff1615156001145b80156110055750816001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de89190614b5c565b670de0b6b3a76400001492915050565b600080546001600160a01b03163314611e1757611005600160126133f4565b6001600160a01b03821660009081526008602052604090205460ff1615611e4457611005600a60116133f4565b816001600160a01b031663fe9c44ae6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea69190614b8b565b506001600160a01b03821660009081526008602052604081208054600160ff1991821681178355600383018054909216909155810191909155611ee8836134a5565b611ef18361358d565b6040516001600160a01b03841681527fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90602001611342565b6001600160a01b0381166000908152600760209081526040808320805482518185028101850190935280835260609493830182828015611f9357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f75575b5093979650505050505050565b6060600c805480602002602001604051908101604052809291908181526020018280548015611ff857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611fda575b5050505050905090565b600061100582613689565b600954600090600160b01b900460ff161561205f5760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c881a5cc81c185d5cd95960721b6044820152606401610c89565b600061206c868685613694565b9050801561207b5790506111b5565b60009695505050505050565b805160609060008167ffffffffffffffff8111156120a7576120a76147e8565b6040519080825280602002602001820160405280156120d0578160200160208202803683370190505b50905060005b828110156121475760008582815181106120f2576120f2614a28565b60200260200101519050612106813361374c565b601181111561211757612117614b75565b83838151811061212957612129614a28565b6020908102919091010152508061213f81614a67565b9150506120d6565b509392505050565b600080600061215d86612bec565b9050600061216a86612bec565b9050811580612177575080155b1561218b57600d6000935093505050612293565b6000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef9190614b5c565b905060006122096040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260055481528451928301909452888252919261224591613840565b925061226d604051806020016040528088815250604051806020016040528088815250613840565b91506122798383613888565b9050612285818b61348d565b600099509750505050505050505b935093915050565b600954600090600160b81b900460ff16156122ea5760405162461bcd60e51b815260206004820152600f60248201526e1cd95a5e99481a5cc81c185d5cd959608a1b6044820152606401610c89565b6001600160a01b03861660009081526008602052604090205460ff16158061232b57506001600160a01b03851660009081526008602052604090205460ff16155b156123375760096118eb565b846001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614b3f565b6001600160a01b0316866001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190614b3f565b6001600160a01b03161461207b5760026118eb565b6001600160a01b0383166000908152600b602052604081205460ff16156124755760405162461bcd60e51b815260206004820152601060248201526f189bdc9c9bddc81a5cc81c185d5cd95960821b6044820152606401610c89565b6001600160a01b03841660009081526008602052604090205460ff1661249c576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff1661259957336001600160a01b0385161461251d5760405162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329031aa37b5b2b760591b6044820152606401610c89565b6000612529338561374c565b9050600081601181111561253f5761253f614b75565b1461255e5780601181111561255657612556614b75565b91505061134d565b6001600160a01b038086166000908152600860209081526040808320938816835260029093019052205460ff1661259757612597614ba8565b505b6125a284612bec565b6000036125b057600d611707565b6001600160a01b0384166000908152601560205260409020548015612695576000856001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190614b5c565b905060006126418286613109565b90508281106126925760405162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f77206361702072656163686564000000000000006044820152606401610c89565b50505b6000806126a58688600088613121565b919350909150600090508260118111156126c1576126c1614b75565b146126e2578160118111156126d8576126d8614b75565b935050505061134d565b80156126ef5760046126d8565b6000979650505050505050565b6007602052816000526040600020818154811061271857600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080546001600160a01b0316331461275a57612753600160066133f4565b9050611005565b6001600160a01b0383166000908152600860205260409020805460ff1661278f57612787600960076133f4565b915050611005565b60408051602080820183528582528251908101909252670c7d713b49da00008252906127bd81835190511090565b156127d8576127ce600660086133f4565b9350505050611005565b84158015906127ed57506127eb86612bec565b155b156127fe576127ce600d60096133f4565b60018301805490869055604080516001600160a01b0389168152602081018390529081018790527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a160005b979650505050505050565b60008061286e858585613694565b9050801561287d57905061134d565b600095945050505050565b6040516361bfb47160e11b815233600482015260009082908290819081906001600160a01b0385169063c37f68e290602401608060405180830381865afa1580156128d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fb9190614bbe565b50925092509250826000146129605760405162461bcd60e51b815260206004820152602560248201527f657869744d61726b65743a206765744163636f756e74536e617073686f742066604482015264185a5b195960da1b6064820152608401610c89565b801561297c57612972600c60026133f4565b9695505050505050565b6000612989873385613694565b9050801561299e57612855600e6003836138c2565b6001600160a01b0385166000908152600860209081526040808320338452600281019092529091205460ff166129dd5760005b98975050505050505050565b3360009081526002820160209081526040808320805460ff191690556007825280832080548251818502810185019093528083529192909190830182828015612a4f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a31575b5050835193945083925060009150505b82811015612ab357896001600160a01b0316848281518110612a8357612a83614a28565b60200260200101516001600160a01b031603612aa157809150612ab3565b80612aab81614a67565b915050612a5f565b50818110612ac357612ac3614ba8565b33600090815260076020526040902080548190612ae290600190614a54565b81548110612af257612af2614a28565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110612b2257612b22614a28565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480612b6057612b60614bf4565b600082815260209020810160001990810180546001600160a01b03191690550190556040517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90612bc9908c9033906001600160a01b0392831681529116602082015260400190565b60405180910390a160009c9b505050505050505050505050565b6111868161393a565b6000806000604051602001612c0b90630c68aa8960e31b815260040190565b60405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612c5f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c879190810190614c0a565b604051602001612c979190614c9e565b6040516020818303038152906040528051906020012003612cc857612cc16208aa8960eb1b6139be565b9150613102565b604051640c6ae8aa8960db1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d589190810190614c0a565b604051602001612d689190614c9e565b6040516020818303038152906040528051906020012003612d9257612cc16208aa8960eb1b6139be565b60405164635553444360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612dfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e229190810190614c0a565b604051602001612e329190614c9e565b6040516020818303038152906040528051906020012003612e6c57612e5d635553444360e01b6139be565b612cc19064e8d4a51000614cba565b6040516418d554d11560da1b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612ed4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612efc9190810190614c0a565b604051602001612f0c9190614c9e565b6040516020818303038152906040528051906020012003612f3757612e5d631554d11560e21b6139be565b60405164635742544360d81b602082015260250160405160208183030381529060405280519060200120846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fc79190810190614c0a565b604051602001612fd79190614c9e565b6040516020818303038152906040528051906020012003613010576130016242544360e81b6139be565b612cc1906402540be400614cba565b6000846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130749190614b3f565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156130b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130d99190810190614c0a565b905060008082905080516000036130ef57600091505b60208301519150819350612855846139be565b5092915050565b600061134d8284614cd1565b600061134d8284614a54565b600080600061312e61435f565b6001600160a01b03881660009081526007602090815260408083208054825181850281018501909352808352849383018282801561319557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613177575b5050505050905060005b815181101561339e5760008282815181106131bc576131bc614a28565b60209081029190910101516040516361bfb47160e11b81526001600160a01b038e811660048301529192509082169063c37f68e290602401608060405180830381865afa158015613211573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132359190614bbe565b6080890152606088015260408701529350831561326157600f6000809750975097505050505050611680565b60408051602080820183526001600160a01b03841660009081526008825283902060010154825260c088019190915281519081019091526080860151815260e08601526132ad81612bec565b60a086018190526000036132d057600d6000809750975097505050505050611680565b604080516020810190915260a0860151815261010086015260c085015160e086015161330a916132ff91613840565b866101000151613840565b610120860181905260408601518651613324929190613a2e565b855261010085015160608601516020870151613341929190613a2e565b60208601526001600160a01b03808c169082160361338b5761336d8561012001518b8760200151613a2e565b60208601819052610100860151613385918b90613a2e565b60208601525b508061339681614a67565b91505061319f565b506020830151835111156133cf57602083015183516000916133bf91614a54565b6000955095509550505050611680565b600080846000015185602001516133e69190614a54565b955095509550505050611680565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561342957613429614b75565b83601381111561343b5761343b614b75565b60408051928352602083019190915260009082015260600160405180910390a182601181111561134d5761134d614b75565b6000806000613480846000806000613121565b9250925092509193909250565b60008061349a8484613a4f565b90506111b581613a77565b60005b600c5481101561353a57816001600160a01b0316600c82815481106134cf576134cf614a28565b6000918252602090912001546001600160a01b0316036135285760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08185b1c9958591e48185919195960621b6044820152606401610c89565b8061353281614a67565b9150506134a8565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b0392909216919091179055565b60006135ce436040518060400160405280601c81526020017f626c6f636b206e756d6265722065786365656473203332206269747300000000815250613a8f565b6001600160a01b0383166000908152600f60209081526040808320601090925282208154939450909290916001600160e01b03909116900361362a5781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b031660000361365c5780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b600061100582613abf565b6001600160a01b03831660009081526008602052604081205460ff166136bb576009611707565b6001600160a01b038085166000908152600860209081526040808320938716835260029093019052205460ff166136f3576000611707565b6000806137038587866000613121565b9193509091506000905082601181111561371f5761371f614b75565b1461373f5781601181111561373657613736614b75565b9250505061134d565b801561207b576004613736565b6001600160a01b0382166000908152600860205260408120805460ff16613777576009915050611005565b6001600160a01b038316600090815260028201602052604090205460ff1615156001036137a8576000915050611005565b6001600160a01b03838116600081815260028401602090815260408083208054600160ff199091168117909155600783528184208054918201815584529282902090920180546001600160a01b031916948916948517905581519384528301919091527f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5910160405180910390a15060009392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061387586600001518660000151613b7a565b61387f9190614cfa565b90529392505050565b604080516020810190915260008152604051806020016040528061387f6138bb8660000151670de0b6b3a7640000613b7a565b8551613b86565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460118111156138f7576138f7614b75565b84601381111561390957613909614b75565b604080519283526020830191909152810184905260600160405180910390a18360118111156111b5576111b5614b75565b60006139486103e883614cfa565b90508042101561398a57603c61395e4283614a54565b11156139865760405163b6b0916d60e01b815260048101829052426024820152604401610c89565b5050565b60b46139968242614a54565b111561398657604051630321d0b560e01b815260048101829052426024820152604401610c89565b6040805160018082528183019092526000918291906020808301908036833701905050905082816000815181106139f7576139f7614a28565b602002602001018181525050613a0c81613b92565b600081518110613a1e57613a1e614a28565b6020026020010151915050919050565b600080613a3b8585613a4f565b9050611a6b613a4982613a77565b84613109565b604080516020810190915260008152604051806020016040528061387f856000015185613b7a565b805160009061100590670de0b6b3a764000090614cfa565b6000816401000000008410613ab75760405162461bcd60e51b8152600401610c899190614902565b509192915050565b60008151600003613ae357604051639e198af960e01b815260040160405180910390fd5b613aec82613b9d565b600060028351613afc9190614cfa565b905060028351613b0c9190614d0e565b600003613b68576000613b5b84613b24600185614a54565b81518110613b3457613b34614a28565b6020026020010151858481518110613b4e57613b4e614a28565b6020026020010151613109565b90506111b5600282614cfa565b828181518110613a1e57613a1e614a28565b600061134d8284614cba565b600061134d8284614cfa565b606061100582613be5565b8051602082016020820281019150805b828110156105f557815b81811015613bdc578151815180821015613bd2578084528183525b5050602001613bb7565b50602001613bad565b60606000825167ffffffffffffffff811115613c0357613c036147e8565b604051908082528060200260200182016040528015613c2c578160200160208202803683370190505b5090506000835167ffffffffffffffff811115613c4b57613c4b6147e8565b604051908082528060200260200182016040528015613c74578160200160208202803683370190505b5090506000845167ffffffffffffffff811115613c9357613c936147e8565b604051908082528060200260200182016040528015613cc657816020015b6060815260200190600190039081613cb15790505b50905060005b8551811015613d245760408051600380825260808201909252906020820160608036833701905050828281518110613d0657613d06614a28565b60200260200101819052508080613d1c90614a67565b915050613ccc565b506000613d2f613d9e565b90506000613d3c82613e45565b61ffff169050613d4d600283614cd1565b60405190925060005b82811015613d93576000613d6d8a89898989613e7f565b9050613d798186614cd1565b945082604052508080613d8b90614a67565b915050613d56565b506129d1848761411f565b60006602ed57011e0000601f1936013581161480613dcf576040516373bb264f60e11b815260040160405180910390fd5b60003660291115613df357604051632bcb7bc560e11b815260040160405180910390fd5b5060281936013560006009613e0e600362ffffff8516614cd1565b613e189190614cd1565b905036613e26600283614cd1565b111561134d5760405163c30a7bd760e01b815260040160405180910390fd5b600080613e53602084614cd1565b905036811115613e7657604051632bcb7bc560e11b815260040160405180910390fd5b36033592915050565b600080600080613e8e85614238565b909250905060008080606081600d613eb1613eaa602089614cd1565b8990613b7a565b613ebb9190614cd1565b90506000613ed4613ecd60688d614cd1565b3690613115565b90506000613ef183613ee760418f614cd1565b613ecd9190614cd1565b9050613efd8382613f10565b9350826020850120945081359650613f34565b60408051838152602081850181019092526000910183838237601f19019392505050565b613f458765ffffffffffff16612be3565b613f5985613f5460418f614cd1565b614288565b9550613f6486611548565b60ff1699505050505050505060008060005b848110156140ec57613f89888583614300565b909350915060005b8c518110156140d9578c8181518110613fac57613fac614a28565b602002602001015184036140c75760008b8281518110613fce57613fce614a28565b60200260200101519050613fe781896001901b16151590565b1580156140105750600360ff168d838151811061400657614006614a28565b6020026020010151105b156140c1578c828151811061402757614027614a28565b60200260200101805180919061403c90614a67565b81525050838b838151811061405357614053614a28565b602002602001015160018f858151811061406f5761406f614a28565b60200260200101516140819190614a54565b8151811061409157614091614a28565b60209081029190910101526001881b81178c83815181106140b4576140b4614a28565b6020026020010181815250505b506140d9565b806140d181614a67565b915050613f91565b50806140e481614a67565b915050613f76565b505050816020826140fd9190614cd1565b6141079190614cba565b61411290604e614cd1565b9998505050505050505050565b60606000835167ffffffffffffffff81111561413d5761413d6147e8565b604051908082528060200260200182016040528015614166578160200160208202803683370190505b509050600360005b855181101561422e578185828151811061418a5761418a614a28565b602002602001015110156141d7578481815181106141aa576141aa614a28565b602002602001015182604051632b13aef560e01b8152600401610c89929190918252602082015260400190565b60006141fb8783815181106141ee576141ee614a28565b6020026020010151612002565b90508084838151811061421057614210614a28565b6020908102919091010152508061422681614a67565b91505061416e565b5090949350505050565b600080808080614249604187614cd1565b9050600061425b613ecd602084614cd1565b80359450905061426c816003613115565b62ffffff9490941697933563ffffffff16965092945050505050565b60408051600080825260208083018085528690523685900380850135831a948401859052803560608501819052910135608084018190529193909260019060a0016020604051602081039080840390855afa1580156142eb573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000808061430f604e87614cd1565b9050600061433c614335614324602089614cd1565b61432f886001614cd1565b90613b7a565b8390613109565b9050600061434a3683613115565b80359960209091013598509650505050505050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016143ab6040518060200160405280600081525090565b81526020016143c66040518060200160405280600081525090565b81526020016143e16040518060200160405280600081525090565b81526020016143fc6040518060200160405280600081525090565b905290565b60008083601f84011261441357600080fd5b50813567ffffffffffffffff81111561442b57600080fd5b6020830191508360208260051b850101111561444657600080fd5b9250929050565b6000806000806040858703121561446357600080fd5b843567ffffffffffffffff8082111561447b57600080fd5b61448788838901614401565b909650945060208701359150808211156144a057600080fd5b506144ad87828801614401565b95989497509550505050565b6001600160a01b038116811461118657600080fd5b801515811461118657600080fd5b600080604083850312156144ef57600080fd5b82356144fa816144b9565b9150602083013561450a816144ce565b809150509250929050565b60006020828403121561452757600080fd5b813561134d816144b9565b600080600080600060a0868803121561454a57600080fd5b8535614555816144b9565b94506020860135614565816144b9565b93506040860135614575816144b9565b94979396509394606081013594506080013592915050565b600080600080608085870312156145a357600080fd5b84356145ae816144b9565b935060208501356145be816144b9565b925060408501356145ce816144b9565b9396929550929360600135925050565b6000602082840312156145f057600080fd5b813561134d816144ce565b60006020828403121561460d57600080fd5b5035919050565b6000806000806080858703121561462a57600080fd5b8435614635816144b9565b93506020850135614645816144b9565b93969395505050506040820135916060013590565b60008060008060008060c0878903121561467357600080fd5b863561467e816144b9565b9550602087013561468e816144b9565b9450604087013561469e816144b9565b935060608701356146ae816144b9565b9598949750929560808101359460a0909101359350915050565b6000806000606084860312156146dd57600080fd5b83356146e8816144b9565b925060208401356146f8816144b9565b929592945050506040919091013590565b600080600080600060a0868803121561472157600080fd5b853561472c816144b9565b9450602086013561473c816144b9565b9350604086013561474c816144b9565b9250606086013561475c816144b9565b949793965091946080013592915050565b6000806040838503121561478057600080fd5b823561478b816144b9565b9150602083013561450a816144b9565b6020808252825182820181905260009190848201906040850190845b818110156147dc5783516001600160a01b0316835292840192918401916001016147b7565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614827576148276147e8565b604052919050565b600067ffffffffffffffff821115614849576148496147e8565b5060051b60200190565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b80356148a161489c8261482f565b6147fe565b81815260059190911b820183019083810190878311156148c057600080fd5b928401925b82841015612855578335825292840192908401906148c5565b60005b838110156148f95781810151838201526020016148e1565b50506000910152565b60208152600082518060208401526149218160408501602087016148de565b601f01601f19169190910160400192915050565b6000602080838503121561494857600080fd5b823567ffffffffffffffff81111561495f57600080fd5b8301601f8101851361497057600080fd5b803561497e61489c8261482f565b81815260059190911b8201830190838101908783111561499d57600080fd5b928401925b828410156128555783356149b5816144b9565b825292840192908401906149a2565b6020808252825182820181905260009190848201906040850190845b818110156147dc578351835292840192918401916001016149e0565b60008060408385031215614a0f57600080fd5b8235614a1a816144b9565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561100557611005614a3e565b600060018201614a7957614a79614a3e565b5060010190565b60208082526028908201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6040820152671d081b1a5cdd195960c21b606082015260800190565b60208082526027908201527f6f6e6c7920706175736520677561726469616e20616e642061646d696e2063616040820152666e20706175736560c81b606082015260800190565b6020808252601690820152756f6e6c792061646d696e2063616e20756e706175736560501b604082015260600190565b600060208284031215614b5157600080fd5b815161134d816144b9565b600060208284031215614b6e57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614b9d57600080fd5b815161134d816144ce565b634e487b7160e01b600052600160045260246000fd5b60008060008060808587031215614bd457600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614c1c57600080fd5b815167ffffffffffffffff80821115614c3457600080fd5b818401915084601f830112614c4857600080fd5b815181811115614c5a57614c5a6147e8565b614c6d601f8201601f19166020016147fe565b9150808252856020828501011115614c8457600080fd5b614c958160208401602086016148de565b50949350505050565b60008251614cb08184602087016148de565b9190910192915050565b808202811582820484141761100557611005614a3e565b8082018082111561100557611005614a3e565b634e487b7160e01b600052601260045260246000fd5b600082614d0957614d09614ce4565b500490565b600082614d1d57614d1d614ce4565b50069056fea2646970667358221220a58e7b3a602b383375b9890cf1561943f1fa328f230a4df9fda104da731ded4364736f6c63430008120033
Deployed Bytecode Sourcemap
89187:28162:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37657:41;;37694:4;37657:41;;;;;179:14:1;;172:22;154:41;;142:2;127:18;37657:41:0;;;;;;;;115273:1411;;;;;;:::i;:::-;;:::i;:::-;;113751:509;;;;;;:::i;:::-;;:::i;115031:234::-;;;;;;:::i;:::-;;:::i;80239:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2718:25:1;;;2706:2;2691:18;80239:42:0;2572:177:1;99769:369:0;;;;;;:::i;:::-;;;;;;;80694:32;;;;;-1:-1:-1;;;;;80694:32:0;;;;;;-1:-1:-1;;;;;3614:32:1;;;3596:51;;3584:2;3569:18;80694:32:0;3450:203:1;99383:378:0;;;;;;:::i;:::-;;:::i;79715:28::-;;;;;-1:-1:-1;;;;;79715:28:0;;;79042:27;;;;;-1:-1:-1;;;;;79042:27:0;;;114654:369;;;;;;:::i;:::-;;:::i;107987:391::-;;;;;;:::i;:::-;;:::i;112444:355::-;;;;;;:::i;:::-;;:::i;113240:503::-;;;;;;:::i;:::-;;:::i;79750:31::-;;;;;-1:-1:-1;;;79750:31:0;;;;;;36874:662;;;;;;:::i;:::-;;:::i;:::-;;;4888:4:1;4876:17;;;4858:36;;4846:2;4831:18;36874:662:0;4716:184:1;94481:273:0;;;;;;:::i;:::-;;;;;;117247:99;117326:12;117247:99;;101363:457;;;;;;:::i;:::-;;;;;;;;80735:42;;;;;;:::i;:::-;;;;;;;;;;;;;;79287:40;;;;;;104403:408;;;;;;:::i;:::-;;:::i;:::-;;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;6583:18;;;6576:34;6487:2;6472:18;104403:408:0;6297:319:1;94109:364:0;;;;;;:::i;:::-;;:::i;109685:552::-;;;;;;:::i;:::-;;:::i;95787:267::-;;;;;;:::i;:::-;;:::i;80175:26::-;;;;;;:::i;:::-;;:::i;99142:233::-;;;;;;:::i;:::-;;;;;103914:277;;;;;;:::i;:::-;;:::i;112807:425::-;;;;;;:::i;:::-;;:::i;100146:1209::-;;;;;;:::i;:::-;;:::i;111833:603::-;;;;;;:::i;:::-;;:::i;103295:256::-;;;;;;:::i;81090:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;80290:58;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80290:58:0;;;-1:-1:-1;;;80290:58:0;;;;;;;;;;-1:-1:-1;;;;;9081:32:1;;;9063:51;;9162:10;9150:23;;;9145:2;9130:18;;9123:51;9036:18;80290:58:0;8891:289:1;79964:52:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;102491:386;;;;;;:::i;79907:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;81251:46;;;;;;:::i;:::-;;;;;;;;;;;;;;79828:34;;;;;-1:-1:-1;;;79828:34:0;;;;;;80357:58;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80357:58:0;;;-1:-1:-1;;;80357:58:0;;;;;;79665: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;79665:41:0;9185:339:1;114268:378:0;;;;;;:::i;:::-;;:::i;91447:163::-;;;;;;:::i;:::-;-1:-1:-1;;;;;91551:24:0;;;91527:4;91551:24;;;:7;:24;;;;;;;;:51;;;;;:42;;;;:51;;;;;;91447:163;;;;;116955:284;;;;;;:::i;:::-;;:::i;79336:21::-;;;;;;80848:53;;;;;;:::i;:::-;;;;;;;;;;;;;;110245:745;;;;;;:::i;:::-;;:::i;90952:47::-;;90995:4;90952:47;;;;;-1:-1:-1;;;;;10392:32:1;;;10374:51;;10362:2;10347:18;90952:47:0;10228:203:1;80210:20:0;;;;;;91265:174;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;79869:31::-;;;;;-1:-1:-1;;;79869:31:0;;;;;;116848:99;;;:::i;80424:69::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;21037:151;;;;;;:::i;:::-;;:::i;79078:40::-;;;;;-1:-1:-1;;;;;79078:40:0;;;102885:402;;;;;;:::i;:::-;;:::i;80910:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;36635:124;36723:30;;;;;;;;;;;-1:-1:-1;;;36723:30:0;;;;36635:124;;;;36723:30;36635:124;:::i;91618:388::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;106904:1075::-;;;;;;:::i;:::-;;:::i;:::-;;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;;15438:18;106904:1075:0;15291:248:1;80502:69:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;80580:43;;;;;;:::i;:::-;;;;;;;;;;;;;;101828:655;;;;;;:::i;:::-;;:::i;97691:1443::-;;;;;;:::i;:::-;;:::i;79366:49::-;;;;;;:::i;:::-;;:::i;79127:47::-;;;;;-1:-1:-1;;;;;79127:47:0;;;108386:1291;;;;;;:::i;:::-;;:::i;79788:33::-;;;;;-1:-1:-1;;;79788:33:0;;;;;;79247:31;;;;;;94762:324;;;;;;:::i;:::-;;:::i;92587:1514::-;;;;;;:::i;:::-;;:::i;81209:33::-;;;;;;;;;81033:48;;;;;;:::i;:::-;;;;;;;;;;;;;;20243:167;;;;;;:::i;:::-;;:::i;79013:20::-;;;;;-1:-1:-1;;;;;79013:20:0;;;36765:103;36861:1;36765:103;;96062:1621;;;;;;:::i;:::-;;:::i;115273:1411::-;115398:5;;-1:-1:-1;;;;;115398:5:0;115384:10;:19;115376:65;;;;-1:-1:-1;;;115376:65:0;;16417:2:1;115376: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;;115376:65:0;;;;;;;;;115462:21;;;;115461:22;115453:73;;;;-1:-1:-1;;;115453:73:0;;16819:2:1;115453: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;;115453:73:0;16617:402:1;115453:73:0;115546:38;;;115538:64;;;;-1:-1:-1;;;115538:64:0;;17226:2:1;115538:64:0;;;17208:21:1;17265:2;17245:18;;;17238:30;-1:-1:-1;;;17284:18:1;;;17277:43;17337:18;;115538:64:0;17024:337:1;115538:64:0;115615:12;115638:19;115668:21;115700:15;115733:6;115728:907;115745:24;;;115728:907;;;115798:13;;115812:1;115798:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;115846:17:0;;;;;;:11;:17;;;;;;115791:23;;-1:-1:-1;115846:17:0;-1:-1:-1;115899:7:0;;115907:1;115899:10;;;;;;;:::i;:::-;;;;;;;115880:29;;115949:14;115930:16;:33;115926:469;;;115986:22;116011:33;116030:14;116011:16;:33;:::i;:::-;-1:-1:-1;;;;;116087:20:0;;116066:18;116087:20;;;:14;:20;;;;;;115986:58;;-1:-1:-1;116147:38:0;116087:20;115986:58;116147:4;:38::i;:::-;-1:-1:-1;;;;;116206:20:0;;;;;;:14;:20;;;;;;;;;:36;;;116268:57;;15465:25:1;;;15506:18;;;15499:34;;;116206:36:0;;-1:-1:-1;116206:20:0;;116268:57;;15438:18:1;116268:57:0;;;;;;;116365:14;116346:33;;115965:430;;;115926:469;116415:20;;116411:213;;116491:38;116496:14;116512:16;116491:4;:38::i;:::-;-1:-1:-1;;;;;116458:17:0;;;;;;:11;:17;;;;;;;;;:71;;;116555:53;;15465:25:1;;;15506:18;;;15499:34;;;116458:71:0;;-1:-1:-1;116458:17:0;;116555:53;;15438:18:1;116555:53:0;;;;;;;116411:213;115771:3;;;:::i;:::-;;;115728:907;;;-1:-1:-1;;116647:21:0;:28;;-1:-1:-1;;116647:28:0;116671:4;116647:28;;;-1:-1:-1;;;;;;;115273:1411:0:o;113751:509::-;-1:-1:-1;;;;;113845:24:0;;113820:4;113845:24;;;:7;:24;;;;;:33;;;113837:86;;;;-1:-1:-1;;;113837:86:0;;;;;;;:::i;:::-;113956:13;;-1:-1:-1;;;;;113956:13:0;113942:10;:27;;:50;;-1:-1:-1;113987:5:0;;-1:-1:-1;;;;;113987:5:0;113973:10;:19;113942:50;113934:102;;;;-1:-1:-1;;;113934:102:0;;;;;;;:::i;:::-;114069:5;;-1:-1:-1;;;;;114069:5:0;114055:10;:19;;:36;;-1:-1:-1;114087:4:0;114078:13;;;;114055:36;114047:71;;;;-1:-1:-1;;;114047:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;114131:37:0;;;;;;:20;:37;;;;;;;;;:45;;-1:-1:-1;;114131:45:0;;;;;;;;;;114192: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;114192:37:0;;19358:3:1;19511:19;114192:37:0;;;;;;;;-1:-1:-1;114247:5:0;113751:509;;;;;:::o;115031:234::-;115111:10;-1:-1:-1;;;;;115111:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;115097:32:0;:10;-1:-1:-1;;;;;115097:32:0;;115089:84;;;;-1:-1:-1;;;115089:84:0;;20066:2:1;115089: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;;115089:84:0;19864:403:1;115089:84:0;115192:10;-1:-1:-1;;;;;115192:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;115184:73;;;;-1:-1:-1;;;115184:73:0;;20663:2:1;115184:73:0;;;20645:21:1;20702:2;20682:18;;;20675:30;-1:-1:-1;;;20721:18:1;;;20714:51;20782:18;;115184:73:0;20461:345:1;115184:73:0;115031:234;:::o;99383:378::-;-1:-1:-1;;;;;99625:15:0;;99542:4;99625:15;;;:7;:15;;;;;:24;;;99620:94;;-1:-1:-1;99678:23:0;99666:36;;99620:94;-1:-1:-1;99738:14:0;99383:378;;;;;;;:::o;114654:369::-;114746:13;;114707:4;;-1:-1:-1;;;;;114746:13:0;114732:10;:27;;:50;;-1:-1:-1;114777:5:0;;-1:-1:-1;;;;;114777:5:0;114763:10;:19;114732:50;114724:102;;;;-1:-1:-1;;;114724:102:0;;;;;;;:::i;:::-;114859:5;;-1:-1:-1;;;;;114859:5:0;114845:10;:19;;:36;;-1:-1:-1;114877:4:0;114868:13;;;;114845:36;114837:71;;;;-1:-1:-1;;;114837:71:0;;;;;;;:::i;:::-;114921:19;:27;;;;;-1:-1:-1;;;114921:27:0;-1:-1:-1;;;;114921:27:0;;;;;;114964:28;;;;;;114943: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;114964:28:0;;;;;;;;-1:-1:-1;115010:5:0;114654:369::o;107987:391::-;108059:4;108097:5;;-1:-1:-1;;;;;108097:5:0;108083:10;:19;108075:63;;;;-1:-1:-1;;;108075:63:0;;21562:2:1;108075:63:0;;;21544:21:1;21601:2;21581:18;;;21574:30;21640:33;21620:18;;;21613:61;21691:18;;108075:63:0;21360:355:1;108075:63:0;108181:19;;;108211:44;;;;108271:59;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;108271:59:0;;15438:18:1;108271:59:0;;;;;;;;108355:14;108350:20;108343:27;107987:391;-1:-1:-1;;;107987:391:0:o;112444:355::-;112547:5;;-1:-1:-1;;;;;112547:5:0;112533:10;:19;112525:70;;;;-1:-1:-1;;;112525:70:0;;21922:2:1;112525: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;;112525:70:0;21720:402:1;112525:70:0;112639:17;;;-1:-1:-1;;;;;112669:40:0;;;-1:-1:-1;;;;;;112669:40:0;;;;;;;112727:64;;;112639:17;;;;22339:34:1;;;22404:2;22389:18;;22382:43;;;;112727:64:0;;22274:18:1;112727:64:0;;;;;;;112514:285;112444:355;:::o;113240:503::-;-1:-1:-1;;;;;113332:24:0;;113307:4;113332:24;;;:7;:24;;;;;:33;;;113324:86;;;;-1:-1:-1;;;113324:86:0;;;;;;;:::i;:::-;113443:13;;-1:-1:-1;;;;;113443:13:0;113429:10;:27;;:50;;-1:-1:-1;113474:5:0;;-1:-1:-1;;;;;113474:5:0;113460:10;:19;113429:50;113421:102;;;;-1:-1:-1;;;113421:102:0;;;;;;;:::i;:::-;113556:5;;-1:-1:-1;;;;;113556:5:0;113542:10;:19;;:36;;-1:-1:-1;113574:4:0;113565:13;;;;113542:36;113534:71;;;;-1:-1:-1;;;113534:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113618:35:0;;;;;;:18;:35;;;;;;;;;:43;;-1:-1:-1;;113618:43:0;;;;;;;;;;113677: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;113677:35:0;;22723:3:1;22874:19;113677:35:0;22436:522:1;36874:662:0;36979:5;-1:-1:-1;;;;;36997:59:0;;37014:42;36997:59;36993:538;;-1:-1:-1;37074:1:0;;36874:662;-1:-1:-1;36874:662:0:o;36993:538::-;-1:-1:-1;;;;;37093:59:0;;37110:42;37093:59;37089:442;;-1:-1:-1;37170:1:0;;36874:662;-1:-1:-1;36874:662:0:o;37089:442::-;-1:-1:-1;;;;;37189:59:0;;37206:42;37189:59;37185:346;;-1:-1:-1;37266:1:0;;36874:662;-1:-1:-1;36874:662:0:o;37185:346::-;-1:-1:-1;;;;;37285:59:0;;37302:42;37285:59;37281:250;;-1:-1:-1;37362:1:0;;36874:662;-1:-1:-1;36874:662:0:o;37281:250::-;-1:-1:-1;;;;;37381:59:0;;37398:42;37381:59;37377:154;;-1:-1:-1;37458:1:0;;36874:662;-1:-1:-1;36874:662:0:o;37377:154::-;37489:34;;-1:-1:-1;;;37489:34:0;;-1:-1:-1;;;;;3614:32:1;;37489:34:0;;;3596:51:1;3569:18;;37489:34:0;3450:203:1;104403:408:0;104579:4;104585;104591;104609:9;104620:14;104636;104654:98;104694:7;104710:12;104725;104739;104654:39;:98::i;:::-;104608:144;;;;;;104776:3;104771:9;;;;;;;;:::i;:::-;104763:40;-1:-1:-1;104782:9:0;;-1:-1:-1;104793:9:0;-1:-1:-1;;104403:408:0;;;;;;;;;:::o;94109:364::-;-1:-1:-1;;;;;94234:26:0;;94206:4;94234:26;;;:18;:26;;;;;;;;94233:27;94225:54;;;;-1:-1:-1;;;94225:54:0;;23165:2:1;94225:54:0;;;23147:21:1;23204:2;23184:18;;;23177:30;-1:-1:-1;;;23223:18:1;;;23216:44;23277:18;;94225:54:0;22963:338:1;94225:54:0;-1:-1:-1;;;;;94337:15:0;;;;;;:7;:15;;;;;:24;;;94332:94;;94390:23;94385:29;94378:36;;;;94332:94;94450:14;94438:27;94109:364;-1:-1:-1;;;;94109:364:0:o;109685:552::-;109775:4;109812:5;;-1:-1:-1;;;;;109812:5:0;109798:10;:19;109794:134;;109841:75;109846:18;109866:49;109841:4;:75::i;109794:134::-;109979:28;;;110020:62;;;;110100:89;;;15465:25:1;;;15521:2;15506:18;;15499:34;;;110100:89:0;;15438:18:1;110100:89:0;15291:248:1;95787:267:0;95954:17;;:37;;;;;95990:1;95975:12;:16;95954:37;95950:97;;;96008:27;;-1:-1:-1;;;96008:27:0;;23508:2:1;96008:27:0;;;23490:21:1;23547:2;23527:18;;;23520:30;-1:-1:-1;;;23566:18:1;;;23559:47;23623:18;;96008:27:0;23306:341:1;80175:26:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80175:26:0;;-1:-1:-1;80175:26:0;:::o;103914:277::-;103981:4;103987;103993;104011:9;104022:14;104038;104056:74;104096:7;104120:1;104125;104128;104056:39;:74::i;:::-;104010:120;;;;;;104156:3;104151:9;;;;;;;;:::i;:::-;104143:40;104162:9;;-1:-1:-1;104162:9:0;-1:-1:-1;103914:277:0;-1:-1:-1;;;103914:277:0:o;112807:425::-;112876:4;112911:5;;-1:-1:-1;;;;;112911:5:0;112897:10;:19;112893:127;;112940:68;112945:18;112965:42;112940:4;:68::i;112893:127::-;113059:13;;;-1:-1:-1;;;;;113085:32:0;;;-1:-1:-1;;;;;;113085:32:0;;;;;;;113135:49;;;113059:13;;;;22339:34:1;;;22404:2;22389:18;;22382:43;;;;113135:49:0;;22274:18:1;113135:49:0;22127:304:1;100146:1209:0;-1:-1:-1;;;;;100404:23:0;;100357:4;100404:23;;;:7;:23;;;;;:32;;;100403:33;;:72;;-1:-1:-1;;;;;;100441:25:0;;;;;;:7;:25;;;;;:34;;;100440:35;100403:72;100399:141;;;100504:23;100499:29;100492:36;;;;100399:141;100573:52;;-1:-1:-1;;;100573:52:0;;-1:-1:-1;;;;;3614:32:1;;;100573:52:0;;;3596:51:1;100552:18:0;;100573:42;;;;;;3569:18:1;;100573:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100552:73;;100642:36;100662:14;100642:12;:36::i;:::-;100638:672;;;100720:11;100703:13;:28;;100695:81;;;;-1:-1:-1;;;100695:81:0;;23854:2:1;100695: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;;100695:81:0;23652:404:1;100695:81:0;100638:672;;;100812:9;100825:14;100843:37;100871:8;100843:27;:37::i;:::-;100811:69;;-1:-1:-1;100811:69:0;;-1:-1:-1;100906:14:0;;-1:-1:-1;100899:3:0;:21;;;;;;;;:::i;:::-;;100895:78;;100953:3;100948:9;;;;;;;;:::i;:::-;100941:16;;;;;;;100895:78;100993:9;101006:1;100993:14;100989:96;;101040:28;101035:34;;100989:96;101101:13;101117:71;101136:36;;;;;;;;101151:19;;101136:36;;;101174:13;101117:18;:71::i;:::-;101101:87;;101221:8;101207:11;:22;101203:96;;;101262:20;101250:33;;;;;;;;101203:96;100794:516;;;100638:672;101332:14;101320:27;;;100146:1209;;;;;;;;:::o;111833:603::-;111960:5;;-1:-1:-1;;;;;111960:5:0;111946:10;:19;;:54;;-1:-1:-1;111983:17:0;;-1:-1:-1;;;;;111983:17:0;111969:10;:31;111946:54;111938:120;;;;-1:-1:-1;;;111938:120:0;;24263:2:1;111938: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;;111938:120:0;24061:417:1;111938:120:0;112089:7;112135:13;112176:15;;;;;:46;;;112209:13;112195:10;:27;112176:46;112168:72;;;;-1:-1:-1;;;112168:72:0;;24685:2:1;112168:72:0;;;24667:21:1;24724:2;24704:18;;;24697:30;-1:-1:-1;;;24743:18:1;;;24736:43;24796:18;;112168:72:0;24483:337:1;112168:72:0;112257:6;112253:176;112273:10;112269:1;:14;112253:176;;;112339:13;;112353:1;112339:16;;;;;;;:::i;:::-;;;;;;;112305:10;:31;112324:7;;112332:1;112324:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;112305:31:0;;;;;;;;;;;;-1:-1:-1;112305:31:0;:50;112388:7;;112396:1;112388:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;112375:42:0;;112400:13;;112414:1;112400:16;;;;;;;:::i;:::-;;;;;;;112375:42;;;;2718:25:1;;2706:2;2691:18;;2572:177;112375:42:0;;;;;;;;112285:3;;;;:::i;:::-;;;;112253:176;;;;111930:506;;111833:603;;;;:::o;114268:378::-;114363:13;;114324:4;;-1:-1:-1;;;;;114363:13:0;114349:10;:27;;:50;;-1:-1:-1;114394:5:0;;-1:-1:-1;;;;;114394:5:0;114380:10;:19;114349:50;114341:102;;;;-1:-1:-1;;;114341:102:0;;;;;;;:::i;:::-;114476:5;;-1:-1:-1;;;;;114476:5:0;114462:10;:19;;:36;;-1:-1:-1;114494:4:0;114485:13;;;;114462:36;114454:71;;;;-1:-1:-1;;;114454:71:0;;;;;;;:::i;:::-;114538:22;:30;;;;;-1:-1:-1;;;114538:30:0;-1:-1:-1;;;;114538:30:0;;;;;;114584:31;;;;;;114563: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;116955:284:0;-1:-1:-1;;;;;117050:24:0;;117013:4;117050:24;;;:7;:24;;;;;:49;;;:54;:116;;;;-1:-1:-1;;;;;;117121:37:0;;;;;;:20;:37;;;;;;;;:45;;:37;:45;117050:116;:171;;;;;117183:6;-1:-1:-1;;;;;117183:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117217:4;117183:38;117030:191;116955:284;-1:-1:-1;;116955:284:0:o;110245:745::-;110302:4;110337:5;;-1:-1:-1;;;;;110337:5:0;110323:10;:19;110319:123;;110366:64;110371:18;110391:38;110366:4;:64::i;110319:123::-;-1:-1:-1;;;;;110458:24:0;;;;;;:7;:24;;;;;:33;;;110454:141;;;110515:68;110520:27;110549:33;110515:4;:68::i;110454:141::-;110607:6;-1:-1:-1;;;;;110607:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;110665:24:0;;110638;110665;;;:7;:24;;;;;110700:25;;110721:4;-1:-1:-1;;110700:25:0;;;;;;;110736:18;;;:26;;;;;;;;110773:34;;:38;;;;110824:35;110665:24;110824:18;:35::i;:::-;110870:34;110896:6;110870:17;:34::i;:::-;110922:20;;-1:-1:-1;;;;;3614:32:1;;3596:51;;110922:20:0;;3584:2:1;3569:18;110922:20:0;3450:203:1;91265:174:0;-1:-1:-1;;;;;91381:22:0;;91354:24;91381:22;;;:13;:22;;;;;;;;91354:49;;;;;;;;;;;;;;;;;91326:15;;91354:24;:49;;91381:22;91354:49;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;91354:49:0;;;;;;;;;;;;;;;;-1:-1:-1;91354:49:0;;91265:174;-1:-1:-1;;;;;;;91265:174:0:o;116848:99::-;116894:15;116929:10;116922:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;116922:17:0;;;;;;;;;;;;;;;;;;;;;;;116848:99;:::o;21037:151::-;21116:7;21139:43;21175:6;21139:35;:43::i;102885:402::-;103028:22;;103000:4;;-1:-1:-1;;;103028:22:0;;;;103027:23;103019:54;;;;-1:-1:-1;;;103019:54:0;;25697:2:1;103019:54:0;;;25679:21:1;25736:2;25716:18;;;25709:30;-1:-1:-1;;;25755:18:1;;;25748:48;25813:18;;103019:54:0;25495:342:1;103019:54:0;103086:12;103101:50;103123:6;103131:3;103136:14;103101:21;:50::i;:::-;103086:65;-1:-1:-1;103166:31:0;;103162:78;;103221:7;-1:-1:-1;103214:14:0;;103162:78;103264:14;103252:27;102885:402;-1:-1:-1;;;;;;102885:402:0:o;91618:388::-;91728:14;;91691:13;;91717:8;91728:14;91779:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91779:15:0;;91755:39;;91810:6;91805:167;91826:3;91822:1;:7;91805:167;;;91851:13;91874:7;91882:1;91874:10;;;;;;;;:::i;:::-;;;;;;;91851:34;;91920:39;91940:6;91948:10;91920:19;:39::i;:::-;91915:45;;;;;;;;:::i;:::-;91902:7;91910:1;91902:10;;;;;;;;:::i;:::-;;;;;;;;;;:58;-1:-1:-1;91831:3:0;;;;:::i;:::-;;;;91805:167;;;-1:-1:-1;91991:7:0;91618:388;-1:-1:-1;;;91618:388:0:o;106904:1075::-;107049:4;107055;107074:26;107103:42;107129:14;107103:18;:42::i;:::-;107074:71;;107156:28;107187:44;107213:16;107187:18;:44::i;:::-;107156:75;-1:-1:-1;107246:26:0;;;:58;;-1:-1:-1;107276:28:0;;107246:58;107242:126;;;107334:17;107354:1;107321:35;;;;;;;;107242:126;107380:25;107415:16;-1:-1:-1;;;;;107408:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107380:73;;107465:16;107492:20;-1:-1:-1;;;;;;;;;;;;;;107492:20:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;107602:45:0;;;;;;;107617:28;;107602:45;;107649:38;;;;;;;;;;;-1:-1:-1;;107597:91:0;;:4;:91::i;:::-;107585:103;;107713:85;107718:40;;;;;;;;107733:23;107718:40;;;107760:37;;;;;;;;107775:20;107760:37;;;107713:4;:85::i;:::-;107699:99;;107817:28;107822:9;107833:11;107817:4;:28::i;:::-;107809:36;;107872:44;107891:5;107898:17;107872:18;:44::i;:::-;107942:14;;-1:-1:-1;107858:58:0;-1:-1:-1;;;;;;;;106904:1075:0;;;;;;;:::o;101828:655::-;102057:19;;102029:4;;-1:-1:-1;;;102057:19:0;;;;102056:20;102048:48;;;;-1:-1:-1;;;102048:48:0;;26044:2:1;102048:48:0;;;26026:21:1;26083:2;26063:18;;;26056:30;-1:-1:-1;;;26102:18:1;;;26095:45;26157:18;;102048:48:0;25842:339:1;102048:48:0;-1:-1:-1;;;;;102138:25:0;;;;;;:7;:25;;;;;:34;;;102137:35;;:72;;-1:-1:-1;;;;;;102177:23:0;;;;;;:7;:23;;;;;:32;;;102176:33;102137:72;102133:141;;;102238:23;102233:29;;102133:141;102339:14;-1:-1:-1;;;;;102332:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102290:78:0;102297:16;-1:-1:-1;;;;;102290:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102290:78:0;;102286:150;;102397:26;102392:32;;97691:1443;-1:-1:-1;;;;;97822:28:0;;97794:4;97822:28;;;:20;:28;;;;;;;;97821:29;97813:58;;;;-1:-1:-1;;;97813:58:0;;26681:2:1;97813:58:0;;;26663:21:1;26720:2;26700:18;;;26693:30;-1:-1:-1;;;26739:18:1;;;26732:46;26795:18;;97813:58:0;26479:340:1;97813:58:0;-1:-1:-1;;;;;97889:15:0;;;;;;:7;:15;;;;;:24;;;97884:94;;97942:23;97937:29;;97884:94;-1:-1:-1;;;;;97995:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;97990:371;;98065:10;-1:-1:-1;;;;;98065:20:0;;;98057:54;;;;-1:-1:-1;;;98057:54:0;;27026:2:1;98057:54:0;;;27008:21:1;27065:2;27045:18;;;27038:30;-1:-1:-1;;;27084:18:1;;;27077:51;27145:18;;98057:54:0;26824:345:1;98057:54:0;98128:9;98140:49;98167:10;98180:8;98140:19;:49::i;:::-;98128:61;-1:-1:-1;98215:14:0;98208:3;:21;;;;;;;;:::i;:::-;;98204:78;;98262:3;98257:9;;;;;;;;:::i;:::-;98250:16;;;;;98204:78;-1:-1:-1;;;;;98305:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;98298:51;;;;:::i;:::-;98040:321;97990:371;98377:34;98403:6;98377:18;:34::i;:::-;98415:1;98377:39;98373:102;;98445:17;98440:23;;98373:102;-1:-1:-1;;;;;98504:18:0;;98487:14;98504:18;;;:10;:18;;;;;;98539:14;;98535:248;;98570:17;98597:6;-1:-1:-1;;;;;98590:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98570:49;;98634:21;98658:32;98663:12;98677;98658:4;:32::i;:::-;98634:56;;98732:9;98713:16;:28;98705:66;;;;-1:-1:-1;;;98705:66:0;;27508:2:1;98705:66:0;;;27490:21:1;27547:2;27527:18;;;27520:30;27586:27;27566:18;;;27559:55;27631:18;;98705:66:0;27306:349:1;98705:66:0;98555:228;;98535:248;98796:9;98809:14;98827:82;98867:8;98884:6;98893:1;98896:12;98827:39;:82::i;:::-;98795:114;;-1:-1:-1;98795:114:0;;-1:-1:-1;98931:14:0;;-1:-1:-1;98924:3:0;:21;;;;;;;;:::i;:::-;;98920:70;;98974:3;98969:9;;;;;;;;:::i;:::-;98962:16;;;;;;;98920:70;99004:13;;99000:87;;99046:28;99041:34;;99000:87;99111:14;99099:27;97691:1443;-1:-1:-1;;;;;;;97691:1443:0:o;79366:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;79366:49:0;;-1:-1:-1;79366:49:0;;-1:-1:-1;79366:49:0:o;108386:1291::-;108483:4;108520:5;;-1:-1:-1;;;;;108520:5:0;108506:10;:19;108502:130;;108549:71;108554:18;108574:45;108549:4;:71::i;:::-;108542:78;;;;108502:130;-1:-1:-1;;;;;108668:24:0;;108644:21;108668:24;;;:7;:24;;;;;108708:15;;;;108703:130;;108747:74;108752:23;108777:43;108747:4;:74::i;:::-;108740:81;;;;;108703:130;108881:44;;;;;;;;;;;;108961;;;;;;;;91190:6;108961:44;;108881;109020:46;108961:44;108881;52795:14;52779:13;;:30;;52676:141;109020:46;109016:169;;;109090:83;109095:31;109128:44;109090:4;:83::i;:::-;109083:90;;;;;;;109016:169;109201:32;;;;;:67;;;109237:26;109256:6;109237:18;:26::i;:::-;:31;109201:67;109197:179;;;109292:72;109297:17;109316:47;109292:4;:72::i;109197:179::-;109423:31;;;;;109465:61;;;;109544:85;;;-1:-1:-1;;;;;27895:32:1;;27877:51;;27959:2;27944:18;;27937:34;;;27987:18;;;27980:34;;;109544:85:0;;27865:2:1;27850:18;109544:85:0;;;;;;;109654:14;109649:20;109642:27;108386:1291;-1:-1:-1;;;;;;;108386:1291:0:o;94762:324::-;94865:4;94882:12;94897:53;94919:6;94927:8;94937:12;94897:21;:53::i;:::-;94882:68;-1:-1:-1;94965:31:0;;94961:78;;95020:7;-1:-1:-1;95013:14:0;;94961:78;95063:14;95051:27;94762:324;-1:-1:-1;;;;;94762:324:0:o;92587:1514::-;92774:37;;-1:-1:-1;;;92774:37:0;;92800:10;92774:37;;;3596:51:1;92657:4:0;;92697:13;;92657:4;;;;;;-1:-1:-1;;;;;92774:25:0;;;;;3569:18:1;;92774:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92724:87;;;;;;;92830:4;92838:1;92830:9;92822:59;;;;-1:-1:-1;;;92822:59:0;;28600:2:1;92822: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;;92822:59:0;28398:401:1;92822:59:0;92899:15;;92895:127;;92938:72;92943:28;92973:36;92938:4;:72::i;:::-;92931:79;92587:1514;-1:-1:-1;;;;;;92587:1514:0:o;92895:127::-;93034:12;93049:60;93071:13;93086:10;93098;93049:21;:60::i;:::-;93034:75;-1:-1:-1;93124:12:0;;93120:123;;93160:71;93171:15;93188:33;93223:7;93160:10;:71::i;93120:123::-;-1:-1:-1;;;;;93285:24:0;;93255:27;93285:24;;;:7;:24;;;;;;;;93358:10;93327:42;;:30;;;:42;;;;;;;;;93322:103;;93398:14;93393:20;93386:27;92587:1514;-1:-1:-1;;;;;;;;92587:1514:0:o;93322:103::-;93475:10;93444:42;;;;:30;;;:42;;;;;;;;93437:49;;-1:-1:-1;;93437:49:0;;;93531:13;:25;;;;;93499:57;;;;;;;;;;;;;;;;;;;93531:25;;93499:57;;;93531:25;93499:57;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93499:57:0;;;;;;;;;;;;;;;;-1:-1:-1;;93578:20:0;;93499:57;;-1:-1:-1;93578:20:0;;-1:-1:-1;93567:8:0;;-1:-1:-1;;93641:162:0;93662:3;93658:1;:7;93641:162;;;93711:6;-1:-1:-1;;;;;93691:26:0;:13;93705:1;93691:16;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;93691:26:0;;93687:105;;93751:1;93738:14;;93771:5;;93687:105;93667:3;;;;:::i;:::-;;;;93641:162;;;;93835:3;93822:10;:16;93815:24;;;;:::i;:::-;93896:10;93852:27;93882:25;;;:13;:25;;;;;93954:17;;93882:25;;93954:21;;93974:1;;93954:21;:::i;:::-;93943:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93943:33:0;93918:10;93929;93918:22;;;;;;;;:::i;:::-;;;;;;;;;:58;;;;;-1:-1:-1;;;;;93918:58:0;;;;;-1:-1:-1;;;;;93918:58:0;;;;;;93987:10;:16;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;93987:16:0;;;;;-1:-1:-1;;;;;;93987:16:0;;;;;;94021:32;;;;;;94034:6;;94042:10;;-1:-1:-1;;;;;22357:15:1;;;22339:34;;22409:15;;22404:2;22389:18;;22382:43;22289:2;22274:18;;22127:304;94021:32:0;;;;;;;;94078:14;94066:27;92587:1514;-1:-1:-1;;;;;;;;;;;;92587:1514:0:o;20243:167::-;20336:68;20374:29;20336:37;:68::i;96062:1621::-;96126:4;96143:16;96172:13;96258:24;;;;;;-1:-1:-1;;;29462:19:1;;29506:1;29497:11;;29260:254;96258:24:0;;;;;;;;;;;;;96248:35;;;;;;96227:6;-1:-1:-1;;;;;96227:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96227:15:0;;;;;;;;;;;;:::i;:::-;96210:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96200:44;;;;;;:83;96196:1454;;96311:46;-1:-1:-1;;;96311:30:0;:46::i;:::-;96300:57;;96196:1454;;;96437:25;;-1:-1:-1;;;96437:25:0;;;30739:20:1;30775:11;;96437:25:0;;;;;;;;;;;;96427:36;;;;;;96406:6;-1:-1:-1;;;;;96406:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96406:15:0;;;;;;;;;;;;:::i;:::-;96389:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96379:44;;;;;;:84;96375:1275;;96491:46;-1:-1:-1;;;96491:30:0;:46::i;96375:1275::-;96617:25;;-1:-1:-1;;;96617:25:0;;;30999:20:1;31035:11;;96617:25:0;;;;;;;;;;;;96607:36;;;;;;96586:6;-1:-1:-1;;;;;96586:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96586:15:0;;;;;;;;;;;;:::i;:::-;96569:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96559:44;;;;;;:84;96555:1095;;96671:47;-1:-1:-1;;;96671:30:0;:47::i;:::-;:54;;96721:4;96671:54;:::i;96555:1095::-;96805:25;;-1:-1:-1;;;96805:25:0;;;31432:20:1;31468:11;;96805:25:0;;;;;;;;;;;;96795:36;;;;;;96774:6;-1:-1:-1;;;;;96774:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96774:15:0;;;;;;;;;;;;:::i;:::-;96757:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96747:44;;;;;;:84;96743:907;;96859:47;-1:-1:-1;;;96859:30:0;:47::i;96743:907::-;96993:25;;-1:-1:-1;;;96993:25:0;;;31692:20:1;31728:11;;96993:25:0;;;;;;;;;;;;96983:36;;;;;;96962:6;-1:-1:-1;;;;;96962:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96962:15:0;;;;;;;;;;;;:::i;:::-;96945:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;96935:44;;;;;;:84;96931:719;;97047:46;-1:-1:-1;;;97047:30:0;:46::i;:::-;:53;;97096:4;97047:53;:::i;96931:719::-;97133:30;97204:6;-1:-1:-1;;;;;97189:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;97166:68:0;;:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;97166:70:0;;;;;;;;;;;;:::i;:::-;97133:103;;97251:14;97280:32;97321:16;97280:58;;97357:19;:26;97387:1;97357:31;97353:84;;97418:3;;-1:-1:-1;97353:84:0;97517:2;97499:16;97495:25;97489:32;97479:42;;97566:6;97550:23;;97601:37;97632:5;97601:30;:37::i;96931:719::-;-1:-1:-1;97667:8:0;96062:1621;-1:-1:-1;;96062:1621:0:o;53919:90::-;53972:4;53996:5;54000:1;53996;:5;:::i;54341:90::-;54394:4;54418:5;54422:1;54418;:5;:::i;104819:2077::-;105004:5;105011:4;105017;105036:37;;:::i;:::-;-1:-1:-1;;;;;105132:22:0;;105085:9;105132:22;;;:13;:22;;;;;;;;105107:47;;;;;;;;;;;;;;;;;105085:9;;105107:47;;105132:22;105107:47;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105107:47:0;;;;;;;;;;;;;;;;;;;;;;;105170:6;105165:1452;105186:6;:13;105182:1;:17;105165:1452;;;105221:12;105236:6;105243:1;105236:9;;;;;;;;:::i;:::-;;;;;;;;;;;105338:33;;-1:-1:-1;;;105338:33:0;;-1:-1:-1;;;;;3614:32:1;;;105338:33:0;;;3596:51:1;105236:9:0;;-1:-1:-1;105338:24:0;;;;;;3569:18:1;;105338:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105309:25;;;105262:109;105289:18;;;105262:109;105269:18;;;105262:109;;-1:-1:-1;105390:9:0;;105386:86;;105429:20;105451:1;105454;105421:35;;;;;;;;;;;;;105386:86;105510:65;;;;;;;;;-1:-1:-1;;;;;105525:23:0;;-1:-1:-1;105525:23:0;;;:7;:23;;;;;:48;;;105510:65;;105486:21;;;:89;;;;105610:42;;;;;;;;-1:-1:-1;;;105625:25:0;105610:42;;105590:17;;;:62;105696:25;105541:5;105696:18;:25::i;:::-;105669:24;;;:52;;;105768:1;105740:29;105736:102;;105798:17;105817:1;105820;105790:32;;;;;;;;;;;;;105736:102;105871:41;;;;;;;;;105886:24;;;;105871:41;;105852:16;;;:60;105960:21;;;;105983:17;;;;105950:70;;105955:46;;:4;:46::i;:::-;106003:4;:16;;;105950:4;:70::i;:::-;105929:18;;;:91;;;106104:18;;;;106124;;106058:85;;105929:91;106104:18;106058:25;:85::i;:::-;106037:106;;106214:16;;;;106232:18;;;;106252:25;;;;106188:90;;106214:16;106232:18;106188:25;:90::i;:::-;106160:25;;;:118;-1:-1:-1;;;;;106299:21:0;;;;;;;106295:311;;106371:86;106397:4;:18;;;106417:12;106431:4;:25;;;106371;:86::i;:::-;106343:25;;;:114;;;106532:16;;;;106506:84;;106550:12;;106506:25;:84::i;:::-;106478:25;;;:112;106295:311;-1:-1:-1;105201:3:0;;;;:::i;:::-;;;;105165:1452;;;-1:-1:-1;106654:25:0;;;;106633:18;;:46;106629:260;;;106741:25;;;;106720:18;;106704:14;;106720:46;;;:::i;:::-;106768:1;106696:74;;;;;;;;;;;106629:260;106811:14;106827:1;106858:4;:18;;;106830:4;:25;;;:46;;;;:::i;:::-;106803:74;;;;;;;;;;;42730:153;42791:4;42813:33;42826:3;42821:9;;;;;;;;:::i;:::-;42837:4;42832:10;;;;;;;;:::i;:::-;42813:33;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;42844:1:0;6583:18:1;;;6576:34;6487:2;6472:18;42813:33:0;;;;;;;42871:3;42866:9;;;;;;;;:::i;104199:196::-;104276:5;104283:4;104289;104313:74;104353:7;104377:1;104382;104385;104313:39;:74::i;:::-;104306:81;;;;;;104199:196;;;;;:::o;52278:174::-;52356:4;52373:18;52394:15;52399:1;52402:6;52394:4;:15::i;:::-;52373:36;;52427:17;52436:7;52427:8;:17::i;110998:250::-;111067:6;111062:137;111083:10;:17;111079:21;;111062:137;;;111155:6;-1:-1:-1;;;;;111131:31:0;:10;111142:1;111131:13;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;111131:13:0;:31;111123:64;;;;-1:-1:-1;;;111123:64:0;;32414:2:1;111123:64:0;;;32396:21:1;32453:2;32433:18;;;32426:30;-1:-1:-1;;;32472:18:1;;;32465:50;32532:18;;111123:64:0;32212:344:1;111123:64:0;111102:4;;;;:::i;:::-;;;;111062:137;;;-1:-1:-1;111209:10:0;:31;;;;;;;-1:-1:-1;111209:31:0;;;;;;;;-1:-1:-1;;;;;;111209:31:0;-1:-1:-1;;;;;111209:31:0;;;;;;;;;;110998:250::o;111256:569::-;111319:18;111340:56;117326:12;111340:56;;;;;;;;;;;;;;;;;:6;:56::i;:::-;-1:-1:-1;;;;;111447:23:0;;111409:35;111447:23;;;:15;:23;;;;;;;;111519:15;:23;;;;;111559:17;;111319:77;;-1:-1:-1;111447:23:0;;111519;;-1:-1:-1;;;;;111559:17:0;;;:22;;111555:93;;111600:36;;-1:-1:-1;;;;;;111600:36:0;90995:4;111600:36;;;111555:93;111664:17;;-1:-1:-1;;;;;111664:17:0;;:22;111660:93;;111705:36;;-1:-1:-1;;;;;;111705:36:0;90995:4;111705:36;;;111660:93;111786:31;;;;;;-1:-1:-1;;;111786:31:0;-1:-1:-1;;;;;111786:31:0;;;;;;;;111766:51;;;;;;;;;;-1:-1:-1;111256:569:0:o;18736:136::-;18809:7;18832:34;18859:6;18832:26;:34::i;95094:685::-;-1:-1:-1;;;;;95223:15:0;;95201:4;95223:15;;;:7;:15;;;;;:24;;;95218:94;;95276:23;95271:29;;95218:94;-1:-1:-1;;;;;95329:15:0;;;;;;;:7;:15;;;;;;;;:43;;;;;:33;;;;:43;;;;;;95324:104;;95401:14;95396:20;;95324:104;95441:9;95454:14;95472:82;95512:8;95529:6;95538:12;95552:1;95472:39;:82::i;:::-;95440:114;;-1:-1:-1;95440:114:0;;-1:-1:-1;95576:14:0;;-1:-1:-1;95569:3:0;:21;;;;;;;;:::i;:::-;;95565:70;;95619:3;95614:9;;;;;;;;:::i;:::-;95607:16;;;;;;95565:70;95649:13;;95645:87;;95691:28;95686:34;;92014:565;-1:-1:-1;;;;;92142:24:0;;92094:5;92142:24;;;:7;:24;;;;;92184:21;;;;92179:87;;92231:23;92224:30;;;;;92179:87;-1:-1:-1;;;;;92282:40:0;;;;;;:30;;;:40;;;;;;;;:48;;:40;:48;92278:104;;92356:14;92349:21;;;;;92278:104;-1:-1:-1;;;;;92394:40:0;;;;;;;:30;;;:40;;;;;;;;:47;;92437:4;-1:-1:-1;;92394:47:0;;;;;;;;92452:13;:23;;;;;:36;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;92452:36:0;;;;;;;;;92506:31;;22339:34:1;;;22389:18;;22382:43;;;;92506:31:0;;22274:18:1;92506:31:0;;;;;;;-1:-1:-1;92557:14:0;;92014:565;-1:-1:-1;;;92014:565:0:o;54439:159::-;-1:-1:-1;;;;;;;;;;;;54534:56:0;;;;;;;;51910:4;54549:28;54554:1;:10;;;54566:1;:10;;;54549:4;:28::i;:::-;:39;;;;:::i;:::-;54534:56;;54527:63;54439:159;-1:-1:-1;;;54439:159:0:o;55441:164::-;-1:-1:-1;;;;;;;;;;;;55536:61:0;;;;;;;;55551:44;55556:26;55561:1;:10;;;51910:4;55556;:26::i;:::-;55584:10;;55551:4;:44::i;42891:187::-;42976:4;42998:43;43011:3;43006:9;;;;;;;;:::i;:::-;43022:4;43017:10;;;;;;;;:::i;:::-;42998:43;;;6499:25:1;;;6555:2;6540:18;;6533:34;;;;6583:18;;6576:34;;;6487:2;6472:18;42998:43:0;;;;;;;43066:3;43061:9;;;;;;;;:::i;17755:975::-;18208:32;18243:36;18275:4;18243:29;:36;:::i;:::-;18208:71;;18310:24;18292:15;:42;18288:437;;;17556:9;18350:42;18377:15;18350:24;:42;:::i;:::-;18349:87;18345:190;;;18456:69;;-1:-1:-1;;;18456:69:0;;;;;15465:25:1;;;18509:15:0;15506:18:1;;;15499:34;15438:18;;18456:69:0;15291:248:1;18345:190:0;17835:895;17755:975;:::o;18288:437::-;17482:9;18553:42;18571:24;18553:15;:42;:::i;:::-;18552:87;18548:177;;;18657:60;;-1:-1:-1;;;18657:60:0;;;;;15465:25:1;;;18701:15:0;15506:18:1;;;15499:34;15438:18;;18657:60:0;15291:248:1;32443:278:0;32604:16;;;32618:1;32604:16;;;;;;;;;32554:7;;;;32604:16;;;;;;;;;;;;-1:-1:-1;32604:16:0;32573:47;;32644:10;32627:11;32639:1;32627:14;;;;;;;;:::i;:::-;;;;;;:27;;;;;32668:44;32700:11;32668:31;:44::i;:::-;32713:1;32668:47;;;;;;;;:::i;:::-;;;;;;;32661:54;;;32443:278;;;:::o;52460:208::-;52558:4;52575:18;52596:15;52601:1;52604:6;52596:4;:15::i;:::-;52575:36;;52629:31;52634:17;52643:7;52634:8;:17::i;:::-;52653:6;52629:4;:31::i;54606:133::-;-1:-1:-1;;;;;;;;;;;;54695:36:0;;;;;;;;54710:19;54715:1;:10;;;54727:1;54710:4;:19::i;52156:114::-;52239:12;;52213:4;;52239:23;;51910:4;;52239:23;:::i;53426:161::-;53501:6;53539:12;53532:5;53528:9;;53520:32;;;;-1:-1:-1;;;53520:32:0;;;;;;;;:::i;:::-;-1:-1:-1;53577:1:0;;53426:161;-1:-1:-1;;53426:161:0:o;15956:403::-;16021:7;16041:3;:10;16055:1;16041:15;16037:75;;16074:30;;-1:-1:-1;;;16074:30:0;;;;;;;;;;;16037:75;16118:9;16123:3;16118:4;:9::i;:::-;16134:19;16169:1;16156:3;:10;:14;;;;:::i;:::-;16134:36;;16194:1;16181:3;:10;:14;;;;:::i;:::-;16199:1;16181:19;16177:177;;16211:11;16225:52;16238:3;16242:15;16256:1;16242:11;:15;:::i;:::-;16238:20;;;;;;;;:::i;:::-;;;;;;;16260:3;16264:11;16260:16;;;;;;;;:::i;:::-;;;;;;;16225:12;:52::i;:::-;16211:66;-1:-1:-1;16293:7:0;16299:1;16211:66;16293:7;:::i;16177:177::-;16330:3;16334:11;16330:16;;;;;;;;:::i;55343:90::-;55396:4;55420:5;55424:1;55420;:5;:::i;56365:90::-;56418:4;56442:5;56446:1;56442;:5;:::i;33582:213::-;33704:16;33739:50;33777:11;33739:37;:50::i;16365:774::-;16463:3;16457:10;16501:20;16496:3;16492:30;16574:16;16563:9;16559:32;16548:9;16544:48;16530:62;;16630:9;16600:527;16661:6;16652:7;16649:19;16600:527;;;16791:9;16759:359;16824:7;16815;16812:20;16759:359;;;16947:7;16941:14;16985:7;16979:14;17017:4;17011;17008:14;17005:102;;;17054:4;17045:7;17038:21;17089:4;17080:7;17073:21;17005:102;-1:-1:-1;;16870:16:0;16857:30;16759:359;;;-1:-1:-1;16704:16:0;16691:30;16600:527;;22105:2070;22220:16;22309:48;22374:11;:18;22360:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22360:33:0;;22309:84;;22400:44;22461:11;:18;22447:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22447:33:0;;22400:80;;22487:37;22543:11;:18;22527:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22487:75;;22574:9;22569:350;22593:11;:18;22589:1;:22;22569:350;;;22869:42;;;36861:1;22869:42;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22869:42:0;22845:18;22864:1;22845:21;;;;;;;;:::i;:::-;;;;;;:66;;;;22613:3;;;;;:::i;:::-;;;;22569:350;;;;22988:30;23021:36;:34;:36::i;:::-;22988:69;;23064:25;23092:61;23130:22;23092:37;:61::i;:::-;23064:89;;;-1:-1:-1;23160:48:0;2711:1;23160:48;;:::i;:::-;23323:15;23317:22;23160:48;;-1:-1:-1;23260:18:0;23397:585;23451:17;23432:16;:36;23397:585;;;23565:27;23595:192;23625:11;23647:31;23689:27;23727:18;23756:22;23595:19;:192::i;:::-;23565:222;-1:-1:-1;23796:45:0;23565:222;23796:45;;:::i;:::-;;;23955:10;23938:15;23931:35;23920:55;23470:18;;;;;:::i;:::-;;;;23397:585;;;;24096:73;24117:18;24137:31;24096:20;:73::i;11791:1200::-;11860:7;12172:20;-1:-1:-1;;12035:14:0;12031:37;12018:51;12147:46;;12103:99;;12215:83;;12260:30;;-1:-1:-1;;;12260:30:0;;;;;;;;;;;12215:83;12383:31;12468:8;3825:2;12425:58;12421:113;;;12501:25;;-1:-1:-1;;;12501:25:0;;;;;;;;;;;12421:113;-1:-1:-1;;;12613:14:0;12609:61;12586:93;12692:30;3067:1;12725:64;3014:1;12725:64;;;;:::i;:::-;:92;;;;:::i;:::-;12692:125;-1:-1:-1;12878:8:0;12828:47;2711:1;12692:125;12828:47;:::i;:::-;:65;12824:126;;;12911:31;;-1:-1:-1;;;12911:31:0;;;;;;;;;;;13076:540;13193:24;;13278:41;2096:2;13278:22;:41;:::i;:::-;13229:90;-1:-1:-1;13371:8:0;13330:56;;13326:111;;;13404:25;;-1:-1:-1;;;13404:25:0;;;;;;;;;;;13326:111;13509:14;13505:59;13482:91;;13076:540;-1:-1:-1;;13076:540:0:o;24990:4605::-;25268:7;25284:19;25321:23;25353:34;25397:63;25437:22;25397:39;:63::i;:::-;25312:148;;-1:-1:-1;25312:148:0;-1:-1:-1;25539:25:0;;;25630:26;25539:25;3678:2;25733:70;25753:49;2885:2;25312:148;25753:49;:::i;:::-;25733:15;;:19;:70::i;:::-;:125;;;;:::i;:::-;25707:151;-1:-1:-1;25939:31:0;25973:119;26003:88;3363:3;26003:22;:88;:::i;:::-;25973:8;;:19;:119::i;:::-;25939:153;-1:-1:-1;26103:35:0;26141:88;26205:23;26171:31;2606:2;26171:22;:31;:::i;:::-;:57;;;;:::i;26141:88::-;26103:126;;26319:111;26396:23;26356:27;26319:111;:::i;:::-;26302:128;;26547:23;26524:20;26509:13;26505:40;26495:76;26481:90;;26651:23;26638:37;26616:59;;26687:236;;26935:350;26755:15;26749:22;;26783:23;;;26834:20;26891;;;;;26867:45;;;26992:14;;26825:30;27172:10;27151:6;27114:22;27087:108;-1:-1:-1;;27225:49:0;;26935:350;-1:-1:-1;;;26935:350:0:o;:::-;27335:37;27353:18;27335:37;;:17;:37::i;:::-;27472:105;27516:10;27537:31;2606:2;27537:22;:31;:::i;:::-;27472:33;:105::i;:::-;27456:121;;27600:39;27625:13;27600:24;:39::i;:::-;27586:53;;;;25530:2117;;;;;;;27696:27;27732:22;27768;27763:1632;27813:15;27796:14;:32;27763:1632;;;27972:147;28020:22;28055:26;28094:14;27972:35;:147::i;:::-;27932:187;;-1:-1:-1;27932:187:0;-1:-1:-1;28149:23:0;28132:1254;28207:11;:18;28189:15;:36;28132:1254;;;28307:11;28319:15;28307:28;;;;;;;;:::i;:::-;;;;;;;28284:19;:51;28280:1095;;28352:34;28389:27;28417:15;28389:44;;;;;;;;:::i;:::-;;;;;;;28352:81;;28471:67;28498:26;28526:11;1455:1;:13;;1445:24;1483:14;;;1328:175;28471:67;28470:68;:225;;;;-1:-1:-1;36861:1:0;28617:78;;:31;28649:15;28617:48;;;;;;;;:::i;:::-;;;;;;;:78;28470:225;28450:806;;;28777:31;28809:15;28777:48;;;;;;;;:::i;:::-;;;;;;:50;;;;;;;;:::i;:::-;;;;;29004:14;28878:18;28897:15;28878:35;;;;;;;;:::i;:::-;;;;;;;28983:1;28932:31;28964:15;28932:48;;;;;;;;:::i;:::-;;;;;;;:52;;;;:::i;:::-;28878:123;;;;;;;;:::i;:::-;;;;;;;;;;:140;1302:1;:13;;1292:24;;29077:27;29105:15;29077:44;;;;;;;;:::i;:::-;;;;;;:163;;;;;28450:806;29356:5;;;28280:1095;28238:17;;;;:::i;:::-;;;;28132:1254;;;-1:-1:-1;27830:16:0;;;;:::i;:::-;;;;27763:1632;;;;27687:1715;;29574:15;2885:2;29514:26;:49;;;;:::i;:::-;29513:76;;;;:::i;:::-;29468:121;;3519:2;29468:121;:::i;:::-;29454:135;24990:4605;-1:-1:-1;;;;;;;;;24990:4605:0:o;30077:880::-;30233:16;30258:33;30308:18;:25;30294:40;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30294:40:0;-1:-1:-1;30258:76:0;-1:-1:-1;36861:1:0;30341:30;30410:510;30458:18;:25;30442:13;:41;30410:510;;;30564:22;30515:31;30547:13;30515:46;;;;;;;;:::i;:::-;;;;;;;:71;30511:233;;;30652:31;30684:13;30652:46;;;;;;;;:::i;:::-;;;;;;;30711:22;30606:128;;-1:-1:-1;;;30606:128:0;;;;;;;;15465:25:1;;;15521:2;15506:18;;15499:34;15453:2;15438:18;;15291:248;30511:233:0;30752:36;30791:50;30807:18;30826:13;30807:33;;;;;;;;:::i;:::-;;;;;;;30791:15;:50::i;:::-;30752:89;;30884:28;30850:16;30867:13;30850:31;;;;;;;;:::i;:::-;;;;;;;;;;:62;-1:-1:-1;30485:15:0;;;;:::i;:::-;;;;30410:510;;;-1:-1:-1;30935:16:0;;30077:880;-1:-1:-1;;;;30077:880:0:o;14443:1053::-;14576:23;;;;;14935:45;2606:2;14935:36;:45;:::i;:::-;14902:78;-1:-1:-1;14987:22:0;15012:62;15032:41;2096:2;14902:78;15032:41;:::i;15012:62::-;15119:28;;;-1:-1:-1;14987:87:0;-1:-1:-1;15222:40:0;14987:87;2766:1;15222:18;:40::i;:::-;15393:34;;;;;;15318:28;;15434:56;;;-1:-1:-1;15393:34:0;;-1:-1:-1;;;;;14443:1053:0:o;327:727::-;848:46;1018:30;;456:7;1018:30;;;744:14;1018:30;;;;;;33162:25:1;;;576:14:0;572:52;;;848:46;;;915:39;907:48;;33203:18:1;;;33196:45;;;637:39:0;;33257:18:1;;;33250:34;;;713:46:0;;772:39;33300:18:1;;;33293:34;;;456:7:0;;637:39;;1018:30;;33134:19:1;;1018:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1018:30:0;;-1:-1:-1;;1018:30:0;;;327:727;-1:-1:-1;;;;;;;327:727:0:o;13622:815::-;13827:27;;;13924:74;3519:2;13924:36;:74;:::i;:::-;13887:111;-1:-1:-1;14005:31:0;14039:126;14078:80;14104:52;2885:2;14104:29;:52;:::i;:::-;14079:18;14083:14;14079:1;:18;:::i;:::-;14078:24;;:80::i;:::-;14039:26;;:30;:126::i;:::-;14005:160;-1:-1:-1;14172:31:0;14206:44;:8;14005:160;14206:19;:44::i;:::-;14298:37;;;14403:20;14374:50;;;14361:64;;-1:-1:-1;13622:815:0;-1:-1:-1;;;;;;;13622: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://a58e7b3a602b383375b9890cf1561943f1fa328f230a4df9fda104da731ded43
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.