Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 4 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
7408273 | 11 days ago | Contract Creation | 0 S | |||
7408273 | 11 days ago | Contract Creation | 0 S | |||
7408273 | 11 days ago | Contract Creation | 0 S | |||
7408273 | 11 days ago | Contract Creation | 0 S |
Loading...
Loading
Contract Name:
AaveV3GettersBatchOne
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {AaveV3GettersProcedureOne} from '../../../contracts/procedures/AaveV3GettersProcedureOne.sol'; contract AaveV3GettersBatchOne is AaveV3GettersProcedureOne { GettersReportBatchOne internal _gettersReport; constructor( address poolAddressesProvider, address networkBaseTokenPriceInUsdProxyAggregator, address marketReferenceCurrencyPriceInUsdProxyAggregator ) { _gettersReport = _deployAaveV3GettersBatchOne( poolAddressesProvider, networkBaseTokenPriceInUsdProxyAggregator, marketReferenceCurrencyPriceInUsdProxyAggregator ); } function getGettersReportOne() external view returns (GettersReportBatchOne memory) { return _gettersReport; } }
// SPDX-License-Identifier: MIT // Chainlink Contracts v0.8 pragma solidity ^0.8.0; interface AggregatorInterface { function decimals() external view returns (uint8); function description() external view returns (string memory); function getRoundData( uint80 _roundId ) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); function latestRound() external view returns (uint256); function getAnswer(uint256 roundId) external view returns (int256); function getTimestamp(uint256 roundId) external view returns (uint256); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8.10; import {IERC20} from '../../openzeppelin/contracts/IERC20.sol'; /// @title Gnosis Protocol v2 Safe ERC20 Transfer Library /// @author Gnosis Developers /// @dev Gas-efficient version of Openzeppelin's SafeERC20 contract. library GPv2SafeERC20 { /// @dev Wrapper around a call to the ERC20 function `transfer` that reverts /// also when the token returns `false`. function safeTransfer(IERC20 token, address to, uint256 value) internal { bytes4 selector_ = token.transfer.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transfer'); } /// @dev Wrapper around a call to the ERC20 function `transferFrom` that /// reverts also when the token returns `false`. function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { bytes4 selector_ = token.transferFrom.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 68), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transferFrom'); } /// @dev Verifies that the last return was a successful `transfer*` call. /// This is done by checking that the return data is either empty, or /// is a valid ABI encoded boolean. function getLastTransferResult(IERC20 token) private view returns (bool success) { // NOTE: Inspecting previous return data requires assembly. Note that // we write the return data to memory 0 in the case where the return // data size is 32, this is OK since the first 64 bytes of memory are // reserved by Solidy as a scratch space that can be used within // assembly blocks. // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html> // solhint-disable-next-line no-inline-assembly assembly { /// @dev Revert with an ABI encoded Solidity error with a message /// that fits into 32-bytes. /// /// An ABI encoded Solidity error has the following memory layout: /// /// ------------+---------------------------------- /// byte range | value /// ------------+---------------------------------- /// 0x00..0x04 | selector("Error(string)") /// 0x04..0x24 | string offset (always 0x20) /// 0x24..0x44 | string length /// 0x44..0x64 | string value, padded to 32-bytes function revertWithMessage(length, message) { mstore(0x00, '\x08\xc3\x79\xa0') mstore(0x04, 0x20) mstore(0x24, length) mstore(0x44, message) revert(0x00, 0x64) } switch returndatasize() // Non-standard ERC20 transfer without return. case 0 { // NOTE: When the return data size is 0, verify that there // is code at the address. This is done in order to maintain // compatibility with Solidity calling conventions. // <https://docs.soliditylang.org/en/v0.7.6/control-structures.html#external-function-calls> if iszero(extcodesize(token)) { revertWithMessage(20, 'GPv2: not a contract') } success := 1 } // Standard ERC20 transfer returning boolean success value. case 32 { returndatacopy(0, 0, returndatasize()) // NOTE: For ABI encoding v1, any non-zero value is accepted // as `true` for a boolean. In order to stay compatible with // OpenZeppelin's `SafeERC20` library which is known to work // with the existing ERC20 implementation we care about, // make sure we return success for any non-zero return value // from the `transfer*` call. success := iszero(iszero(mload(0))) } default { revertWithMessage(31, 'GPv2: malformed transfer result') } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, 'Address: low-level delegate call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return payable(msg.sender); } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20} from './IERC20.sol'; interface IERC20Detailed is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) pragma solidity ^0.8.10; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, 'SafeCast: value must be positive'); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require( value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits" ); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require( value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits" ); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require( value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits" ); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require( value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits" ); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require( value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits" ); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IPoolDataProvider} from '../interfaces/IPoolDataProvider.sol'; /** * @title AaveProtocolDataProvider * @author Aave * @notice Peripheral contract to collect and pre-process information from the Pool. */ contract AaveProtocolDataProvider is IPoolDataProvider { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using UserConfiguration for DataTypes.UserConfigurationMap; using WadRayMath for uint256; address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /// @inheritdoc IPoolDataProvider IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; /** * @notice Constructor * @param addressesProvider The address of the PoolAddressesProvider contract */ constructor(IPoolAddressesProvider addressesProvider) { ADDRESSES_PROVIDER = addressesProvider; } /// @inheritdoc IPoolDataProvider function getAllReservesTokens() external view override returns (TokenData[] memory) { IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); address[] memory reserves = pool.getReservesList(); TokenData[] memory reservesTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { if (reserves[i] == MKR) { reservesTokens[i] = TokenData({symbol: 'MKR', tokenAddress: reserves[i]}); continue; } if (reserves[i] == ETH) { reservesTokens[i] = TokenData({symbol: 'ETH', tokenAddress: reserves[i]}); continue; } reservesTokens[i] = TokenData({ symbol: IERC20Detailed(reserves[i]).symbol(), tokenAddress: reserves[i] }); } return reservesTokens; } /// @inheritdoc IPoolDataProvider function getAllATokens() external view override returns (TokenData[] memory) { IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { address aTokenAddress = pool.getReserveAToken(reserves[i]); aTokens[i] = TokenData({ symbol: IERC20Detailed(aTokenAddress).symbol(), tokenAddress: aTokenAddress }); } return aTokens; } /// @inheritdoc IPoolDataProvider function getReserveConfigurationData( address asset ) external view override returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration .getParams(); (isActive, isFrozen, borrowingEnabled, ) = configuration.getFlags(); // @notice all stable debt related parameters deprecated in v3.2.0 stableBorrowRateEnabled = false; usageAsCollateralEnabled = liquidationThreshold != 0; } /// @inheritdoc IPoolDataProvider function getReserveCaps( address asset ) external view override returns (uint256 borrowCap, uint256 supplyCap) { (borrowCap, supplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps(); } /// @inheritdoc IPoolDataProvider function getPaused(address asset) external view override returns (bool isPaused) { (, , , isPaused) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getFlags(); } /// @inheritdoc IPoolDataProvider function getSiloedBorrowing(address asset) external view override returns (bool) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getSiloedBorrowing(); } /// @inheritdoc IPoolDataProvider function getLiquidationProtocolFee(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getLiquidationProtocolFee(); } /// @inheritdoc IPoolDataProvider function getUnbackedMintCap(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getUnbackedMintCap(); } /// @inheritdoc IPoolDataProvider function getDebtCeiling(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getDebtCeiling(); } /// @inheritdoc IPoolDataProvider function getDebtCeilingDecimals() external pure override returns (uint256) { return ReserveConfiguration.DEBT_CEILING_DECIMALS; } /// @inheritdoc IPoolDataProvider function getReserveData( address asset ) external view override returns ( uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256, uint256, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); // @notice all stable debt related parameters deprecated in v3.2.0 return ( reserve.unbacked, reserve.accruedToTreasury, IERC20Detailed(reserve.aTokenAddress).totalSupply(), 0, IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(), reserve.currentLiquidityRate, reserve.currentVariableBorrowRate, 0, 0, reserve.liquidityIndex, reserve.variableBorrowIndex, reserve.lastUpdateTimestamp ); } /// @inheritdoc IPoolDataProvider function getATokenTotalSupply(address asset) external view override returns (uint256) { address aTokenAddress = IPool(ADDRESSES_PROVIDER.getPool()).getReserveAToken(asset); return IERC20Detailed(aTokenAddress).totalSupply(); } /// @inheritdoc IPoolDataProvider function getTotalDebt(address asset) external view override returns (uint256) { address variableDebtTokenAddress = IPool(ADDRESSES_PROVIDER.getPool()) .getReserveVariableDebtToken(asset); return IERC20Detailed(variableDebtTokenAddress).totalSupply(); } /// @inheritdoc IPoolDataProvider function getUserReserveData( address asset, address user ) external view override returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); DataTypes.UserConfigurationMap memory userConfig = IPool(ADDRESSES_PROVIDER.getPool()) .getUserConfiguration(user); currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user); // @notice all stable debt related parameters deprecated in v3.2.0 currentStableDebt = principalStableDebt = stableBorrowRate = stableRateLastUpdated = 0; scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); liquidityRate = reserve.currentLiquidityRate; usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id); } /// @inheritdoc IPoolDataProvider function getReserveTokensAddresses( address asset ) external view override returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ) { IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); // @notice all stable debt related parameters deprecated in v3.2.0 return (pool.getReserveAToken(asset), address(0), pool.getReserveVariableDebtToken(asset)); } /// @inheritdoc IPoolDataProvider function getInterestRateStrategyAddress( address asset ) external view override returns (address irStrategyAddress) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); return (reserve.interestRateStrategyAddress); } /// @inheritdoc IPoolDataProvider function getFlashLoanEnabled(address asset) external view override returns (bool) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); return configuration.getFlashLoanEnabled(); } /// @inheritdoc IPoolDataProvider function getIsVirtualAccActive(address asset) external view override returns (bool) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); return configuration.getIsVirtualAccActive(); } /// @inheritdoc IPoolDataProvider function getVirtualUnderlyingBalance(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getVirtualUnderlyingBalance(asset); } /// @inheritdoc IPoolDataProvider function getReserveDeficit(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getReserveDeficit(asset); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IncentivizedERC20} from '../protocol/tokenization/base/IncentivizedERC20.sol'; import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IRewardsController} from '../rewards/interfaces/IRewardsController.sol'; import {AggregatorInterface} from '../dependencies/chainlink/AggregatorInterface.sol'; import {IUiIncentiveDataProviderV3} from './interfaces/IUiIncentiveDataProviderV3.sol'; contract UiIncentiveDataProviderV3 is IUiIncentiveDataProviderV3 { using UserConfiguration for DataTypes.UserConfigurationMap; function getFullReservesIncentiveData( IPoolAddressesProvider provider, address user ) external view override returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory) { return (_getReservesIncentivesData(provider), _getUserReservesIncentivesData(provider, user)); } function getReservesIncentivesData( IPoolAddressesProvider provider ) external view override returns (AggregatedReserveIncentiveData[] memory) { return _getReservesIncentivesData(provider); } function _getReservesIncentivesData( IPoolAddressesProvider provider ) private view returns (AggregatedReserveIncentiveData[] memory) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); AggregatedReserveIncentiveData[] memory reservesIncentiveData = new AggregatedReserveIncentiveData[](reserves.length); // Iterate through the reserves to get all the information from the (a/s/v) Tokens for (uint256 i = 0; i < reserves.length; i++) { AggregatedReserveIncentiveData memory reserveIncentiveData = reservesIncentiveData[i]; reserveIncentiveData.underlyingAsset = reserves[i]; DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // Get aTokens rewards information IRewardsController aTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.aTokenAddress).getIncentivesController()) ); RewardInfo[] memory aRewardsInformation; if (address(aTokenIncentiveController) != address(0)) { address[] memory aTokenRewardAddresses = aTokenIncentiveController.getRewardsByAsset( baseData.aTokenAddress ); aRewardsInformation = new RewardInfo[](aTokenRewardAddresses.length); for (uint256 j = 0; j < aTokenRewardAddresses.length; ++j) { RewardInfo memory rewardInformation; rewardInformation.rewardTokenAddress = aTokenRewardAddresses[j]; ( rewardInformation.tokenIncentivesIndex, rewardInformation.emissionPerSecond, rewardInformation.incentivesLastUpdateTimestamp, rewardInformation.emissionEndTimestamp ) = aTokenIncentiveController.getRewardsData( baseData.aTokenAddress, rewardInformation.rewardTokenAddress ); rewardInformation.precision = aTokenIncentiveController.getAssetDecimals( baseData.aTokenAddress ); rewardInformation.rewardTokenDecimals = IERC20Detailed( rewardInformation.rewardTokenAddress ).decimals(); rewardInformation.rewardTokenSymbol = IERC20Detailed(rewardInformation.rewardTokenAddress) .symbol(); // Get price of reward token from Chainlink Proxy Oracle rewardInformation.rewardOracleAddress = aTokenIncentiveController.getRewardOracle( rewardInformation.rewardTokenAddress ); rewardInformation.priceFeedDecimals = AggregatorInterface( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = AggregatorInterface( rewardInformation.rewardOracleAddress ).latestAnswer(); aRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.aIncentiveData = IncentiveData( baseData.aTokenAddress, address(aTokenIncentiveController), aRewardsInformation ); // Get vTokens rewards information IRewardsController vTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.variableDebtTokenAddress).getIncentivesController()) ); RewardInfo[] memory vRewardsInformation; if (address(vTokenIncentiveController) != address(0)) { address[] memory vTokenRewardAddresses = vTokenIncentiveController.getRewardsByAsset( baseData.variableDebtTokenAddress ); vRewardsInformation = new RewardInfo[](vTokenRewardAddresses.length); for (uint256 j = 0; j < vTokenRewardAddresses.length; ++j) { RewardInfo memory rewardInformation; rewardInformation.rewardTokenAddress = vTokenRewardAddresses[j]; ( rewardInformation.tokenIncentivesIndex, rewardInformation.emissionPerSecond, rewardInformation.incentivesLastUpdateTimestamp, rewardInformation.emissionEndTimestamp ) = vTokenIncentiveController.getRewardsData( baseData.variableDebtTokenAddress, rewardInformation.rewardTokenAddress ); rewardInformation.precision = vTokenIncentiveController.getAssetDecimals( baseData.variableDebtTokenAddress ); rewardInformation.rewardTokenDecimals = IERC20Detailed( rewardInformation.rewardTokenAddress ).decimals(); rewardInformation.rewardTokenSymbol = IERC20Detailed(rewardInformation.rewardTokenAddress) .symbol(); // Get price of reward token from Chainlink Proxy Oracle rewardInformation.rewardOracleAddress = vTokenIncentiveController.getRewardOracle( rewardInformation.rewardTokenAddress ); rewardInformation.priceFeedDecimals = AggregatorInterface( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = AggregatorInterface( rewardInformation.rewardOracleAddress ).latestAnswer(); vRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.vIncentiveData = IncentiveData( baseData.variableDebtTokenAddress, address(vTokenIncentiveController), vRewardsInformation ); } return (reservesIncentiveData); } function getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) external view override returns (UserReserveIncentiveData[] memory) { return _getUserReservesIncentivesData(provider, user); } function _getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) private view returns (UserReserveIncentiveData[] memory) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); UserReserveIncentiveData[] memory userReservesIncentivesData = new UserReserveIncentiveData[]( user != address(0) ? reserves.length : 0 ); for (uint256 i = 0; i < reserves.length; i++) { DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // user reserve data userReservesIncentivesData[i].underlyingAsset = reserves[i]; IRewardsController aTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.aTokenAddress).getIncentivesController()) ); if (address(aTokenIncentiveController) != address(0)) { // get all rewards information from the asset address[] memory aTokenRewardAddresses = aTokenIncentiveController.getRewardsByAsset( baseData.aTokenAddress ); UserRewardInfo[] memory aUserRewardsInformation = new UserRewardInfo[]( aTokenRewardAddresses.length ); for (uint256 j = 0; j < aTokenRewardAddresses.length; ++j) { UserRewardInfo memory userRewardInformation; userRewardInformation.rewardTokenAddress = aTokenRewardAddresses[j]; userRewardInformation.tokenIncentivesUserIndex = aTokenIncentiveController .getUserAssetIndex( user, baseData.aTokenAddress, userRewardInformation.rewardTokenAddress ); userRewardInformation.userUnclaimedRewards = aTokenIncentiveController .getUserAccruedRewards(user, userRewardInformation.rewardTokenAddress); userRewardInformation.rewardTokenDecimals = IERC20Detailed( userRewardInformation.rewardTokenAddress ).decimals(); userRewardInformation.rewardTokenSymbol = IERC20Detailed( userRewardInformation.rewardTokenAddress ).symbol(); // Get price of reward token from Chainlink Proxy Oracle userRewardInformation.rewardOracleAddress = aTokenIncentiveController.getRewardOracle( userRewardInformation.rewardTokenAddress ); userRewardInformation.priceFeedDecimals = AggregatorInterface( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = AggregatorInterface( userRewardInformation.rewardOracleAddress ).latestAnswer(); aUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].aTokenIncentivesUserData = UserIncentiveData( baseData.aTokenAddress, address(aTokenIncentiveController), aUserRewardsInformation ); } // variable debt token IRewardsController vTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.variableDebtTokenAddress).getIncentivesController()) ); if (address(vTokenIncentiveController) != address(0)) { // get all rewards information from the asset address[] memory vTokenRewardAddresses = vTokenIncentiveController.getRewardsByAsset( baseData.variableDebtTokenAddress ); UserRewardInfo[] memory vUserRewardsInformation = new UserRewardInfo[]( vTokenRewardAddresses.length ); for (uint256 j = 0; j < vTokenRewardAddresses.length; ++j) { UserRewardInfo memory userRewardInformation; userRewardInformation.rewardTokenAddress = vTokenRewardAddresses[j]; userRewardInformation.tokenIncentivesUserIndex = vTokenIncentiveController .getUserAssetIndex( user, baseData.variableDebtTokenAddress, userRewardInformation.rewardTokenAddress ); userRewardInformation.userUnclaimedRewards = vTokenIncentiveController .getUserAccruedRewards(user, userRewardInformation.rewardTokenAddress); userRewardInformation.rewardTokenDecimals = IERC20Detailed( userRewardInformation.rewardTokenAddress ).decimals(); userRewardInformation.rewardTokenSymbol = IERC20Detailed( userRewardInformation.rewardTokenAddress ).symbol(); // Get price of reward token from Chainlink Proxy Oracle userRewardInformation.rewardOracleAddress = vTokenIncentiveController.getRewardOracle( userRewardInformation.rewardTokenAddress ); userRewardInformation.priceFeedDecimals = AggregatorInterface( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = AggregatorInterface( userRewardInformation.rewardOracleAddress ).latestAnswer(); vUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].vTokenIncentivesUserData = UserIncentiveData( baseData.variableDebtTokenAddress, address(aTokenIncentiveController), vUserRewardsInformation ); } } return (userReservesIncentivesData); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IAaveOracle} from '../interfaces/IAaveOracle.sol'; import {IAToken} from '../interfaces/IAToken.sol'; import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol'; import {AaveProtocolDataProvider} from './AaveProtocolDataProvider.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {AggregatorInterface} from '../dependencies/chainlink/AggregatorInterface.sol'; import {IERC20DetailedBytes} from './interfaces/IERC20DetailedBytes.sol'; import {IUiPoolDataProviderV3} from './interfaces/IUiPoolDataProviderV3.sol'; contract UiPoolDataProviderV3 is IUiPoolDataProviderV3 { using WadRayMath for uint256; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using UserConfiguration for DataTypes.UserConfigurationMap; AggregatorInterface public immutable networkBaseTokenPriceInUsdProxyAggregator; AggregatorInterface public immutable marketReferenceCurrencyPriceInUsdProxyAggregator; uint256 public constant ETH_CURRENCY_UNIT = 1 ether; address public constant MKR_ADDRESS = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; constructor( AggregatorInterface _networkBaseTokenPriceInUsdProxyAggregator, AggregatorInterface _marketReferenceCurrencyPriceInUsdProxyAggregator ) { networkBaseTokenPriceInUsdProxyAggregator = _networkBaseTokenPriceInUsdProxyAggregator; marketReferenceCurrencyPriceInUsdProxyAggregator = _marketReferenceCurrencyPriceInUsdProxyAggregator; } function getReservesList( IPoolAddressesProvider provider ) external view override returns (address[] memory) { IPool pool = IPool(provider.getPool()); return pool.getReservesList(); } function getReservesData( IPoolAddressesProvider provider ) external view override returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory) { IAaveOracle oracle = IAaveOracle(provider.getPriceOracle()); IPool pool = IPool(provider.getPool()); AaveProtocolDataProvider poolDataProvider = AaveProtocolDataProvider( provider.getPoolDataProvider() ); address[] memory reserves = pool.getReservesList(); AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { AggregatedReserveData memory reserveData = reservesData[i]; reserveData.underlyingAsset = reserves[i]; // reserve current state DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData( reserveData.underlyingAsset ); //the liquidity index. Expressed in ray reserveData.liquidityIndex = baseData.liquidityIndex; //variable borrow index. Expressed in ray reserveData.variableBorrowIndex = baseData.variableBorrowIndex; //the current supply rate. Expressed in ray reserveData.liquidityRate = baseData.currentLiquidityRate; //the current variable borrow rate. Expressed in ray reserveData.variableBorrowRate = baseData.currentVariableBorrowRate; reserveData.lastUpdateTimestamp = baseData.lastUpdateTimestamp; reserveData.aTokenAddress = baseData.aTokenAddress; reserveData.variableDebtTokenAddress = baseData.variableDebtTokenAddress; //address of the interest rate strategy reserveData.interestRateStrategyAddress = baseData.interestRateStrategyAddress; reserveData.priceInMarketReferenceCurrency = oracle.getAssetPrice( reserveData.underlyingAsset ); reserveData.priceOracle = oracle.getSourceOfAsset(reserveData.underlyingAsset); reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf( reserveData.aTokenAddress ); reserveData.totalScaledVariableDebt = IVariableDebtToken(reserveData.variableDebtTokenAddress) .scaledTotalSupply(); // Due we take the symbol from underlying token we need a special case for $MKR as symbol() returns bytes32 if (address(reserveData.underlyingAsset) == address(MKR_ADDRESS)) { bytes32 symbol = IERC20DetailedBytes(reserveData.underlyingAsset).symbol(); bytes32 name = IERC20DetailedBytes(reserveData.underlyingAsset).name(); reserveData.symbol = bytes32ToString(symbol); reserveData.name = bytes32ToString(name); } else { reserveData.symbol = IERC20Detailed(reserveData.underlyingAsset).symbol(); reserveData.name = IERC20Detailed(reserveData.underlyingAsset).name(); } //stores the reserve configuration DataTypes.ReserveConfigurationMap memory reserveConfigurationMap = baseData.configuration; ( reserveData.baseLTVasCollateral, reserveData.reserveLiquidationThreshold, reserveData.reserveLiquidationBonus, reserveData.decimals, reserveData.reserveFactor ) = reserveConfigurationMap.getParams(); reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0; ( reserveData.isActive, reserveData.isFrozen, reserveData.borrowingEnabled, reserveData.isPaused ) = reserveConfigurationMap.getFlags(); // interest rates try IDefaultInterestRateStrategyV2(reserveData.interestRateStrategyAddress).getInterestRateData( reserveData.underlyingAsset ) returns (IDefaultInterestRateStrategyV2.InterestRateDataRay memory res) { reserveData.baseVariableBorrowRate = res.baseVariableBorrowRate; reserveData.variableRateSlope1 = res.variableRateSlope1; reserveData.variableRateSlope2 = res.variableRateSlope2; reserveData.optimalUsageRatio = res.optimalUsageRatio; } catch {} // v3 only reserveData.deficit = uint128(pool.getReserveDeficit(reserveData.underlyingAsset)); reserveData.debtCeiling = reserveConfigurationMap.getDebtCeiling(); reserveData.debtCeilingDecimals = poolDataProvider.getDebtCeilingDecimals(); (reserveData.borrowCap, reserveData.supplyCap) = reserveConfigurationMap.getCaps(); try poolDataProvider.getFlashLoanEnabled(reserveData.underlyingAsset) returns ( bool flashLoanEnabled ) { reserveData.flashLoanEnabled = flashLoanEnabled; } catch (bytes memory) { reserveData.flashLoanEnabled = true; } reserveData.isSiloedBorrowing = reserveConfigurationMap.getSiloedBorrowing(); reserveData.unbacked = baseData.unbacked; reserveData.isolationModeTotalDebt = baseData.isolationModeTotalDebt; reserveData.accruedToTreasury = baseData.accruedToTreasury; reserveData.borrowableInIsolation = reserveConfigurationMap.getBorrowableInIsolation(); try poolDataProvider.getIsVirtualAccActive(reserveData.underlyingAsset) returns ( bool virtualAccActive ) { reserveData.virtualAccActive = virtualAccActive; } catch (bytes memory) { reserveData.virtualAccActive = false; } try pool.getVirtualUnderlyingBalance(reserveData.underlyingAsset) returns ( uint128 virtualUnderlyingBalance ) { reserveData.virtualUnderlyingBalance = virtualUnderlyingBalance; } catch (bytes memory) { reserveData.virtualUnderlyingBalance = 0; } } BaseCurrencyInfo memory baseCurrencyInfo; baseCurrencyInfo.networkBaseTokenPriceInUsd = networkBaseTokenPriceInUsdProxyAggregator .latestAnswer(); baseCurrencyInfo.networkBaseTokenPriceDecimals = networkBaseTokenPriceInUsdProxyAggregator .decimals(); try oracle.BASE_CURRENCY_UNIT() returns (uint256 baseCurrencyUnit) { baseCurrencyInfo.marketReferenceCurrencyUnit = baseCurrencyUnit; baseCurrencyInfo.marketReferenceCurrencyPriceInUsd = int256(baseCurrencyUnit); } catch (bytes memory /*lowLevelData*/) { baseCurrencyInfo.marketReferenceCurrencyUnit = ETH_CURRENCY_UNIT; baseCurrencyInfo .marketReferenceCurrencyPriceInUsd = marketReferenceCurrencyPriceInUsdProxyAggregator .latestAnswer(); } return (reservesData, baseCurrencyInfo); } /// @inheritdoc IUiPoolDataProviderV3 function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory) { IPool pool = IPool(provider.getPool()); Emode[] memory tempCategories = new Emode[](256); uint8 eModesFound = 0; uint8 missCounter = 0; for (uint8 i = 1; i < 256; i++) { DataTypes.CollateralConfig memory cfg = pool.getEModeCategoryCollateralConfig(i); if (cfg.liquidationThreshold != 0) { tempCategories[eModesFound] = Emode({ eMode: DataTypes.EModeCategory({ ltv: cfg.ltv, liquidationThreshold: cfg.liquidationThreshold, liquidationBonus: cfg.liquidationBonus, label: pool.getEModeCategoryLabel(i), collateralBitmap: pool.getEModeCategoryCollateralBitmap(i), borrowableBitmap: pool.getEModeCategoryBorrowableBitmap(i) }), id: i }); ++eModesFound; missCounter = 0; } else { ++missCounter; } // assumes there will never be a gap > 2 when setting eModes if (missCounter > 2) break; } Emode[] memory categories = new Emode[](eModesFound); for (uint8 i = 0; i < eModesFound; i++) { categories[i] = tempCategories[i]; } return categories; } function getUserReservesData( IPoolAddressesProvider provider, address user ) external view override returns (UserReserveData[] memory, uint8) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); DataTypes.UserConfigurationMap memory userConfig = pool.getUserConfiguration(user); uint8 userEmodeCategoryId = uint8(pool.getUserEMode(user)); UserReserveData[] memory userReservesData = new UserReserveData[]( user != address(0) ? reserves.length : 0 ); for (uint256 i = 0; i < reserves.length; i++) { DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // user reserve data userReservesData[i].underlyingAsset = reserves[i]; userReservesData[i].scaledATokenBalance = IAToken(baseData.aTokenAddress).scaledBalanceOf( user ); userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i); if (userConfig.isBorrowing(i)) { userReservesData[i].scaledVariableDebt = IVariableDebtToken( baseData.variableDebtTokenAddress ).scaledBalanceOf(user); } } return (userReservesData, userEmodeCategoryId); } function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) { uint8 i = 0; while (i < 32 && _bytes32[i] != 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 32 && _bytes32[i] != 0; i++) { bytesArray[i] = _bytes32[i]; } return string(bytesArray); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {Address} from '../dependencies/openzeppelin/contracts/Address.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title WalletBalanceProvider contract * @author Aave, influenced by https://github.com/wbobeirne/eth-balance-checker/blob/master/contracts/BalanceChecker.sol * @notice Implements a logic of getting multiple tokens balance for one user address * @dev NOTE: THIS CONTRACT IS NOT USED WITHIN THE AAVE PROTOCOL. It's an accessory contract used to reduce the number of calls * towards the blockchain from the Aave backend. **/ contract WalletBalanceProvider { using Address for address payable; using Address for address; using GPv2SafeERC20 for IERC20; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /** @dev Fallback function, don't accept any ETH **/ receive() external payable { //only contracts can send ETH to the core require(msg.sender.isContract(), '22'); } /** @dev Check the token balance of a wallet in a token contract Returns the balance of the token for user. Avoids possible errors: - return 0 on non-contract address **/ function balanceOf(address user, address token) public view returns (uint256) { if (token == MOCK_ETH_ADDRESS) { return user.balance; // ETH balance // check if token is actually a contract } else if (token.isContract()) { return IERC20(token).balanceOf(user); } revert('INVALID_TOKEN'); } /** * @notice Fetches, for a list of _users and _tokens (ETH included with mock address), the balances * @param users The list of users * @param tokens The list of tokens * @return And array with the concatenation of, for each user, his/her balances **/ function batchBalanceOf( address[] calldata users, address[] calldata tokens ) external view returns (uint256[] memory) { uint256[] memory balances = new uint256[](users.length * tokens.length); for (uint256 i = 0; i < users.length; i++) { for (uint256 j = 0; j < tokens.length; j++) { balances[i * tokens.length + j] = balanceOf(users[i], tokens[j]); } } return balances; } /** @dev provides balances of user wallet for all reserves available on the pool */ function getUserWalletBalances( address provider, address user ) external view returns (address[] memory, uint256[] memory) { IPool pool = IPool(IPoolAddressesProvider(provider).getPool()); address[] memory reserves = pool.getReservesList(); address[] memory reservesWithEth = new address[](reserves.length + 1); for (uint256 i = 0; i < reserves.length; i++) { reservesWithEth[i] = reserves[i]; } reservesWithEth[reserves.length] = MOCK_ETH_ADDRESS; uint256[] memory balances = new uint256[](reservesWithEth.length); for (uint256 j = 0; j < reserves.length; j++) { DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration( reservesWithEth[j] ); (bool isActive, , , ) = configuration.getFlags(); if (!isActive) { balances[j] = 0; continue; } balances[j] = balanceOf(user, reservesWithEth[j]); } balances[reserves.length] = balanceOf(user, MOCK_ETH_ADDRESS); return (reservesWithEth, balances); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; interface IERC20DetailedBytes is IERC20 { function name() external view returns (bytes32); function symbol() external view returns (bytes32); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; interface IUiIncentiveDataProviderV3 { struct AggregatedReserveIncentiveData { address underlyingAsset; IncentiveData aIncentiveData; IncentiveData vIncentiveData; } struct IncentiveData { address tokenAddress; address incentiveControllerAddress; RewardInfo[] rewardsTokenInformation; } struct RewardInfo { string rewardTokenSymbol; address rewardTokenAddress; address rewardOracleAddress; uint256 emissionPerSecond; uint256 incentivesLastUpdateTimestamp; uint256 tokenIncentivesIndex; uint256 emissionEndTimestamp; int256 rewardPriceFeed; uint8 rewardTokenDecimals; uint8 precision; uint8 priceFeedDecimals; } struct UserReserveIncentiveData { address underlyingAsset; UserIncentiveData aTokenIncentivesUserData; UserIncentiveData vTokenIncentivesUserData; } struct UserIncentiveData { address tokenAddress; address incentiveControllerAddress; UserRewardInfo[] userRewardsInformation; } struct UserRewardInfo { string rewardTokenSymbol; address rewardOracleAddress; address rewardTokenAddress; uint256 userUnclaimedRewards; uint256 tokenIncentivesUserIndex; int256 rewardPriceFeed; uint8 priceFeedDecimals; uint8 rewardTokenDecimals; } function getReservesIncentivesData( IPoolAddressesProvider provider ) external view returns (AggregatedReserveIncentiveData[] memory); function getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data function getFullReservesIncentiveData( IPoolAddressesProvider provider, address user ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; interface IUiPoolDataProviderV3 { struct AggregatedReserveData { address underlyingAsset; string name; string symbol; uint256 decimals; uint256 baseLTVasCollateral; uint256 reserveLiquidationThreshold; uint256 reserveLiquidationBonus; uint256 reserveFactor; bool usageAsCollateralEnabled; bool borrowingEnabled; bool isActive; bool isFrozen; // base data uint128 liquidityIndex; uint128 variableBorrowIndex; uint128 liquidityRate; uint128 variableBorrowRate; uint40 lastUpdateTimestamp; address aTokenAddress; address variableDebtTokenAddress; address interestRateStrategyAddress; // uint256 availableLiquidity; uint256 totalScaledVariableDebt; uint256 priceInMarketReferenceCurrency; address priceOracle; uint256 variableRateSlope1; uint256 variableRateSlope2; uint256 baseVariableBorrowRate; uint256 optimalUsageRatio; // v3 only bool isPaused; bool isSiloedBorrowing; uint128 accruedToTreasury; uint128 unbacked; uint128 isolationModeTotalDebt; bool flashLoanEnabled; // uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 borrowCap; uint256 supplyCap; bool borrowableInIsolation; // v3.1 bool virtualAccActive; uint128 virtualUnderlyingBalance; // v3.3 uint128 deficit; } struct UserReserveData { address underlyingAsset; uint256 scaledATokenBalance; bool usageAsCollateralEnabledOnUser; uint256 scaledVariableDebt; } struct BaseCurrencyInfo { uint256 marketReferenceCurrencyUnit; int256 marketReferenceCurrencyPriceInUsd; int256 networkBaseTokenPriceInUsd; uint8 networkBaseTokenPriceDecimals; } struct Emode { uint8 id; DataTypes.EModeCategory eMode; } function getReservesList( IPoolAddressesProvider provider ) external view returns (address[] memory); function getReservesData( IPoolAddressesProvider provider ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); function getUserReservesData( IPoolAddressesProvider provider, address user ) external view returns (UserReserveData[] memory, uint8); /** * @dev Iterates the eModes mapping and returns all eModes found * @notice The method assumes for id gaps <= 2 within the eMode definitions * @return an array of eModes that were found in the eMode mapping */ function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IACLManager * @author Aave * @notice Defines the basic interface for the ACL Manager */ interface IACLManager { /** * @notice Returns the contract address of the PoolAddressesProvider * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the identifier of the PoolAdmin role * @return The id of the PoolAdmin role */ function POOL_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the EmergencyAdmin role * @return The id of the EmergencyAdmin role */ function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the RiskAdmin role * @return The id of the RiskAdmin role */ function RISK_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the FlashBorrower role * @return The id of the FlashBorrower role */ function FLASH_BORROWER_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the Bridge role * @return The id of the Bridge role */ function BRIDGE_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the AssetListingAdmin role * @return The id of the AssetListingAdmin role */ function ASSET_LISTING_ADMIN_ROLE() external view returns (bytes32); /** * @notice Set the role as admin of a specific role. * @dev By default the admin role for all roles is `DEFAULT_ADMIN_ROLE`. * @param role The role to be managed by the admin role * @param adminRole The admin role */ function setRoleAdmin(bytes32 role, bytes32 adminRole) external; /** * @notice Adds a new admin as PoolAdmin * @param admin The address of the new admin */ function addPoolAdmin(address admin) external; /** * @notice Removes an admin as PoolAdmin * @param admin The address of the admin to remove */ function removePoolAdmin(address admin) external; /** * @notice Returns true if the address is PoolAdmin, false otherwise * @param admin The address to check * @return True if the given address is PoolAdmin, false otherwise */ function isPoolAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as EmergencyAdmin * @param admin The address of the new admin */ function addEmergencyAdmin(address admin) external; /** * @notice Removes an admin as EmergencyAdmin * @param admin The address of the admin to remove */ function removeEmergencyAdmin(address admin) external; /** * @notice Returns true if the address is EmergencyAdmin, false otherwise * @param admin The address to check * @return True if the given address is EmergencyAdmin, false otherwise */ function isEmergencyAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as RiskAdmin * @param admin The address of the new admin */ function addRiskAdmin(address admin) external; /** * @notice Removes an admin as RiskAdmin * @param admin The address of the admin to remove */ function removeRiskAdmin(address admin) external; /** * @notice Returns true if the address is RiskAdmin, false otherwise * @param admin The address to check * @return True if the given address is RiskAdmin, false otherwise */ function isRiskAdmin(address admin) external view returns (bool); /** * @notice Adds a new address as FlashBorrower * @param borrower The address of the new FlashBorrower */ function addFlashBorrower(address borrower) external; /** * @notice Removes an address as FlashBorrower * @param borrower The address of the FlashBorrower to remove */ function removeFlashBorrower(address borrower) external; /** * @notice Returns true if the address is FlashBorrower, false otherwise * @param borrower The address to check * @return True if the given address is FlashBorrower, false otherwise */ function isFlashBorrower(address borrower) external view returns (bool); /** * @notice Adds a new address as Bridge * @param bridge The address of the new Bridge */ function addBridge(address bridge) external; /** * @notice Removes an address as Bridge * @param bridge The address of the bridge to remove */ function removeBridge(address bridge) external; /** * @notice Returns true if the address is Bridge, false otherwise * @param bridge The address to check * @return True if the given address is Bridge, false otherwise */ function isBridge(address bridge) external view returns (bool); /** * @notice Adds a new admin as AssetListingAdmin * @param admin The address of the new admin */ function addAssetListingAdmin(address admin) external; /** * @notice Removes an admin as AssetListingAdmin * @param admin The address of the admin to remove */ function removeAssetListingAdmin(address admin) external; /** * @notice Returns true if the address is AssetListingAdmin, false otherwise * @param admin The address to check * @return True if the given address is AssetListingAdmin, false otherwise */ function isAssetListingAdmin(address admin) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableAToken} from './IInitializableAToken.sol'; /** * @title IAToken * @author Aave * @notice Defines the basic interface for an AToken. */ interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken { /** * @dev Emitted during the transfer action * @param from The user whose tokens are being transferred * @param to The recipient * @param value The scaled amount being transferred * @param index The next liquidity index of the reserve */ event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); /** * @notice Mints `amount` aTokens to `user` * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted aTokens * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve * @return `true` if the the previous balance of the user was 0 */ function mint( address caller, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool); /** * @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` * @dev In some instances, the mint event could be emitted from a burn transaction * if the amount to burn is less than the interest that the user accrued * @param from The address from which the aTokens will be burned * @param receiverOfUnderlying The address that will receive the underlying * @param amount The amount being burned * @param index The next liquidity index of the reserve */ function burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external; /** * @notice Mints aTokens to the reserve treasury * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve */ function mintToTreasury(uint256 amount, uint256 index) external; /** * @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * @param from The address getting liquidated, current owner of the aTokens * @param to The recipient * @param value The amount of tokens getting transferred */ function transferOnLiquidation(address from, address to, uint256 value) external; /** * @notice Transfers the underlying asset to `target`. * @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan() * @param target The recipient of the underlying * @param amount The amount getting transferred */ function transferUnderlyingTo(address target, uint256 amount) external; /** * @notice Handles the underlying received by the aToken after the transfer has been completed. * @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the * transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying * to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset. * @param user The user executing the repayment * @param onBehalfOf The address of the user who will get his debt reduced/removed * @param amount The amount getting repaid */ function handleRepayment(address user, address onBehalfOf, uint256 amount) external; /** * @notice Allow passing a signed message to approve spending * @dev implements the permit function as for * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md * @param owner The owner of the funds * @param spender The spender * @param value The amount * @param deadline The deadline timestamp, type(uint256).max for max deadline * @param v Signature param * @param s Signature param * @param r Signature param */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) * @return The address of the underlying asset */ function UNDERLYING_ASSET_ADDRESS() external view returns (address); /** * @notice Returns the address of the Aave treasury, receiving the fees on this aToken. * @return Address of the Aave treasury */ function RESERVE_TREASURY_ADDRESS() external view returns (address); /** * @notice Get the domain separator for the token * @dev Return cached value if chainId matches cache, otherwise recomputes separator * @return The domain separator of the token at current chain */ function DOMAIN_SEPARATOR() external view returns (bytes32); /** * @notice Returns the nonce for owner. * @param owner The address of the owner * @return The nonce of the owner */ function nonces(address owner) external view returns (uint256); /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IAaveIncentivesController * @author Aave * @notice Defines the basic interface for an Aave Incentives Controller. * @dev It only contains one single function, needed as a hook on aToken and debtToken transfers. */ interface IAaveIncentivesController { /** * @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution. * @dev The units of `totalSupply` and `userBalance` should be the same. * @param user The address of the user whose asset balance has changed * @param totalSupply The total supply of the asset prior to user balance change * @param userBalance The previous user balance prior to balance change */ function handleAction(address user, uint256 totalSupply, uint256 userBalance) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPriceOracleGetter} from './IPriceOracleGetter.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IAaveOracle * @author Aave * @notice Defines the basic interface for the Aave Oracle */ interface IAaveOracle is IPriceOracleGetter { /** * @dev Emitted after the base currency is set * @param baseCurrency The base currency of used for price quotes * @param baseCurrencyUnit The unit of the base currency */ event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit); /** * @dev Emitted after the price source of an asset is updated * @param asset The address of the asset * @param source The price source of the asset */ event AssetSourceUpdated(address indexed asset, address indexed source); /** * @dev Emitted after the address of fallback oracle is updated * @param fallbackOracle The address of the fallback oracle */ event FallbackOracleUpdated(address indexed fallbackOracle); /** * @notice Returns the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Sets or replaces price sources of assets * @param assets The addresses of the assets * @param sources The addresses of the price sources */ function setAssetSources(address[] calldata assets, address[] calldata sources) external; /** * @notice Sets the fallback oracle * @param fallbackOracle The address of the fallback oracle */ function setFallbackOracle(address fallbackOracle) external; /** * @notice Returns a list of prices from a list of assets addresses * @param assets The list of assets addresses * @return The prices of the given assets */ function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory); /** * @notice Returns the address of the source for an asset address * @param asset The address of the asset * @return The address of the source */ function getSourceOfAsset(address asset) external view returns (address); /** * @notice Returns the address of the fallback oracle * @return The address of the fallback oracle */ function getFallbackOracle() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IReserveInterestRateStrategy} from './IReserveInterestRateStrategy.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IDefaultInterestRateStrategyV2 * @author BGD Labs * @notice Interface of the default interest rate strategy used by the Aave protocol */ interface IDefaultInterestRateStrategyV2 is IReserveInterestRateStrategy { /** * @notice Holds the interest rate data for a given reserve * * @dev Since values are in bps, they are multiplied by 1e23 in order to become rays with 27 decimals. This * in turn means that the maximum supported interest rate is 4294967295 (2**32-1) bps or 42949672.95%. * * @param optimalUsageRatio The optimal usage ratio, in bps * @param baseVariableBorrowRate The base variable borrow rate, in bps * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps */ struct InterestRateData { uint16 optimalUsageRatio; uint32 baseVariableBorrowRate; uint32 variableRateSlope1; uint32 variableRateSlope2; } /** * @notice The interest rate data, where all values are in ray (fixed-point 27 decimal numbers) for a given reserve, * used in in-memory calculations. * * @param optimalUsageRatio The optimal usage ratio * @param baseVariableBorrowRate The base variable borrow rate * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio */ struct InterestRateDataRay { uint256 optimalUsageRatio; uint256 baseVariableBorrowRate; uint256 variableRateSlope1; uint256 variableRateSlope2; } /** * @notice emitted when new interest rate data is set in a reserve * * @param reserve address of the reserve that has new interest rate data set * @param optimalUsageRatio The optimal usage ratio, in bps * @param baseVariableBorrowRate The base variable borrow rate, in bps * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps */ event RateDataUpdate( address indexed reserve, uint256 optimalUsageRatio, uint256 baseVariableBorrowRate, uint256 variableRateSlope1, uint256 variableRateSlope2 ); /** * @notice Returns the address of the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the maximum value achievable for variable borrow rate, in bps * @return The maximum rate */ function MAX_BORROW_RATE() external view returns (uint256); /** * @notice Returns the minimum optimal point, in bps * @return The optimal point */ function MIN_OPTIMAL_POINT() external view returns (uint256); /** * @notice Returns the maximum optimal point, in bps * @return The optimal point */ function MAX_OPTIMAL_POINT() external view returns (uint256); /** * notice Returns the full InterestRateData object for the given reserve, in ray * * @param reserve The reserve to get the data of * * @return The InterestRateDataRay object for the given reserve */ function getInterestRateData(address reserve) external view returns (InterestRateDataRay memory); /** * notice Returns the full InterestRateDataRay object for the given reserve, in bps * * @param reserve The reserve to get the data of * * @return The InterestRateData object for the given reserve */ function getInterestRateDataBps(address reserve) external view returns (InterestRateData memory); /** * @notice Returns the optimal usage rate for the given reserve in ray * * @param reserve The reserve to get the optimal usage rate of * * @return The optimal usage rate is the level of borrow / collateral at which the borrow rate */ function getOptimalUsageRatio(address reserve) external view returns (uint256); /** * @notice Returns the variable rate slope below optimal usage ratio in ray * @dev It's the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO * * @param reserve The reserve to get the variable rate slope 1 of * * @return The variable rate slope */ function getVariableRateSlope1(address reserve) external view returns (uint256); /** * @notice Returns the variable rate slope above optimal usage ratio in ray * @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO * * @param reserve The reserve to get the variable rate slope 2 of * * @return The variable rate slope */ function getVariableRateSlope2(address reserve) external view returns (uint256); /** * @notice Returns the base variable borrow rate, in ray * * @param reserve The reserve to get the base variable borrow rate of * * @return The base variable borrow rate */ function getBaseVariableBorrowRate(address reserve) external view returns (uint256); /** * @notice Returns the maximum variable borrow rate, in ray * * @param reserve The reserve to get the maximum variable borrow rate of * * @return The maximum variable borrow rate */ function getMaxVariableBorrowRate(address reserve) external view returns (uint256); /** * @notice Sets interest rate data for an Aave rate strategy * @param reserve The reserve to update * @param rateData The reserve interest rate data to apply to the given reserve * Being specific to this custom implementation, with custom struct type, * overloading the function on the generic interface */ function setInterestRateParams(address reserve, InterestRateData calldata rateData) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; import {IPool} from './IPool.sol'; /** * @title IInitializableAToken * @author Aave * @notice Interface for the initialize function on AToken */ interface IInitializableAToken { /** * @dev Emitted when an aToken is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated pool * @param treasury The address of the treasury * @param incentivesController The address of the incentives controller for this aToken * @param aTokenDecimals The decimals of the underlying * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ event Initialized( address indexed underlyingAsset, address indexed pool, address treasury, address incentivesController, uint8 aTokenDecimals, string aTokenName, string aTokenSymbol, bytes params ); /** * @notice Initializes the aToken * @param pool The pool contract that is initializing this contract * @param treasury The address of the Aave treasury, receiving the fees on this aToken * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ function initialize( IPool pool, address treasury, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 aTokenDecimals, string calldata aTokenName, string calldata aTokenSymbol, bytes calldata params ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; import {IPool} from './IPool.sol'; /** * @title IInitializableDebtToken * @author Aave * @notice Interface for the initialize function common between debt tokens */ interface IInitializableDebtToken { /** * @dev Emitted when a debt token is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated pool * @param incentivesController The address of the incentives controller for this aToken * @param debtTokenDecimals The decimals of the debt token * @param debtTokenName The name of the debt token * @param debtTokenSymbol The symbol of the debt token * @param params A set of encoded parameters for additional initialization */ event Initialized( address indexed underlyingAsset, address indexed pool, address incentivesController, uint8 debtTokenDecimals, string debtTokenName, string debtTokenSymbol, bytes params ); /** * @notice Initializes the debt token. * @param pool The pool contract that is initializing this contract * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's * @param debtTokenName The name of the token * @param debtTokenSymbol The symbol of the token * @param params A set of encoded parameters for additional initialization */ function initialize( IPool pool, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 debtTokenDecimals, string memory debtTokenName, string memory debtTokenSymbol, bytes calldata params ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, * 1 for Stable (Deprecated on v3.2.0), 2 for Variable * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate @note deprecated on v3.2.0 * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the deficit of a reserve is covered. * @param reserve The address of the underlying asset of the reserve * @param caller The caller that triggered the DeficitCovered event * @param amountCovered The amount of deficit covered */ event DeficitCovered(address indexed reserve, address caller, uint256 amountCovered); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @dev Emitted when deficit is realized on a liquidation. * @param user The user address where the bad debt will be burned * @param debtAsset The address of the underlying borrowed asset to be burned * @param amountCreated The amount of deficit created */ event DeficitCreated(address indexed user, address indexed debtAsset, uint256 amountCreated); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the VariableDebtToken * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 variable debt tokens * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode DEPRECATED in v3.2.0 * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Deprecated on v3.2.0 * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using 2 on `modes` * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve. * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Accumulates interest to all indexes of the reserve * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncIndexesState(address asset) external; /** * @notice Updates interest rates on the reserve data * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncRatesState(address asset) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve */ function getConfiguration( address asset ) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @notice Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user */ function getUserConfiguration( address user ) external view returns (DataTypes.UserConfigurationMap memory); /** * @notice Returns the normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory); /** * @notice Returns the virtual underlying balance of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve virtual underlying balance */ function getVirtualUnderlyingBalance(address asset) external view returns (uint128); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the number of initialized reserves * @dev It includes dropped reserves * @return The count */ function getReservesCount() external view returns (uint256); /** * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct * @param id The id of the reserve as stored in the DataTypes.ReserveData struct * @return The address of the reserve associated with id */ function getReserveAddressById(uint16 id) external view returns (address); /** * @notice Returns the PoolAddressesProvider connected to this contract * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Updates the protocol fee on the bridging * @param bridgeProtocolFee The part of the premium sent to the protocol treasury */ function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; /** * @notice Updates flash loan premiums. Flash loan premium consists of two parts: * - A part is sent to aToken holders as extra, one time accumulated interest * - A part is collected by the protocol treasury * @dev The total premium is calculated on the total borrowed amount * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` * @dev Only callable by the PoolConfigurator contract * @param flashLoanPremiumTotal The total premium, expressed in bps * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps */ function updateFlashloanPremiums( uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol ) external; /** * @notice Configures a new or alters an existing collateral configuration of an eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory( uint8 id, DataTypes.EModeCategoryBaseConfiguration memory config ) external; /** * @notice Replaces the current eMode collateralBitmap. * @param id The id of the category * @param collateralBitmap The collateralBitmap of the category */ function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external; /** * @notice Replaces the current eMode borrowableBitmap. * @param id The id of the category * @param borrowableBitmap The borrowableBitmap of the category */ function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external; /** * @notice Returns the data of an eMode category * @dev DEPRECATED use independent getters instead * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData( uint8 id ) external view returns (DataTypes.EModeCategoryLegacy memory); /** * @notice Returns the label of an eMode category * @param id The id of the category * @return The label of the category */ function getEModeCategoryLabel(uint8 id) external view returns (string memory); /** * @notice Returns the collateral config of an eMode category * @param id The id of the category * @return The ltv,lt,lb of the category */ function getEModeCategoryCollateralConfig( uint8 id ) external view returns (DataTypes.CollateralConfig memory); /** * @notice Returns the collateralBitmap of an eMode category * @param id The id of the category * @return The collateralBitmap of the category */ function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); /** * @notice Returns the borrowableBitmap of an eMode category * @param id The id of the category * @return The borrowableBitmap of the category */ function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Sets the liquidation grace period of the given asset * @dev To enable a liquidation grace period, a timestamp in the future should be set, * To disable a liquidation grace period, any timestamp in the past works, like 0 * @param asset The address of the underlying asset to set the liquidationGracePeriod * @param until Timestamp when the liquidation grace period will end **/ function setLiquidationGracePeriod(address asset, uint40 until) external; /** * @notice Returns the liquidation grace period of the given asset * @param asset The address of the underlying asset * @return Timestamp when the liquidation grace period will end **/ function getLiquidationGracePeriod(address asset) external view returns (uint40); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice It covers the deficit of a specified reserve by burning: * - the equivalent aToken `amount` for assets with virtual accounting enabled * - the equivalent `amount` of underlying for assets with virtual accounting disabled (e.g. GHO) * @dev The deficit of a reserve can occur due to situations where borrowed assets are not repaid, leading to bad debt. * @param asset The address of the underlying asset to cover the deficit. * @param amount The amount to be covered, in aToken or underlying on non-virtual accounted assets */ function eliminateReserveDeficit(address asset, uint256 amount) external; /** * @notice Returns the current deficit of a reserve. * @param asset The address of the underlying asset of the reserve * @return The current deficit of the reserve */ function getReserveDeficit(address asset) external view returns (uint256); /** * @notice Returns the aToken address of a reserve. * @param asset The address of the underlying asset of the reserve * @return The address of the aToken */ function getReserveAToken(address asset) external view returns (address); /** * @notice Returns the variableDebtToken address of a reserve. * @param asset The address of the underlying asset of the reserve * @return The address of the variableDebtToken */ function getReserveVariableDebtToken(address asset) external view returns (address); /** * @notice Gets the address of the external FlashLoanLogic */ function getFlashLoanLogic() external view returns (address); /** * @notice Gets the address of the external BorrowLogic */ function getBorrowLogic() external view returns (address); /** * @notice Gets the address of the external BridgeLogic */ function getBridgeLogic() external view returns (address); /** * @notice Gets the address of the external EModeLogic */ function getEModeLogic() external view returns (address); /** * @notice Gets the address of the external LiquidationLogic */ function getLiquidationLogic() external view returns (address); /** * @notice Gets the address of the external PoolLogic */ function getPoolLogic() external view returns (address); /** * @notice Gets the address of the external SupplyLogic */ function getSupplyLogic() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IPoolDataProvider * @author Aave * @notice Defines the basic interface of a PoolDataProvider */ interface IPoolDataProvider { struct TokenData { string symbol; address tokenAddress; } /** * @notice Returns the address for the PoolAddressesProvider contract. * @return The address for the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the list of the existing reserves in the pool. * @dev Handling MKR and ETH in a different way since they do not have standard `symbol` functions. * @return The list of reserves, pairs of symbols and addresses */ function getAllReservesTokens() external view returns (TokenData[] memory); /** * @notice Returns the list of the existing ATokens in the pool. * @return The list of ATokens, pairs of symbols and addresses */ function getAllATokens() external view returns (TokenData[] memory); /** * @notice Returns the configuration data of the reserve * @dev Not returning borrow and supply caps for compatibility, nor pause flag * @param asset The address of the underlying asset of the reserve * @return decimals The number of decimals of the reserve * @return ltv The ltv of the reserve * @return liquidationThreshold The liquidationThreshold of the reserve * @return liquidationBonus The liquidationBonus of the reserve * @return reserveFactor The reserveFactor of the reserve * @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise * @return borrowingEnabled True if borrowing is enabled, false otherwise * @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise * @return isActive True if it is active, false otherwise * @return isFrozen True if it is frozen, false otherwise */ function getReserveConfigurationData( address asset ) external view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); /** * @notice Returns the caps parameters of the reserve * @param asset The address of the underlying asset of the reserve * @return borrowCap The borrow cap of the reserve * @return supplyCap The supply cap of the reserve */ function getReserveCaps( address asset ) external view returns (uint256 borrowCap, uint256 supplyCap); /** * @notice Returns if the pool is paused * @param asset The address of the underlying asset of the reserve * @return isPaused True if the pool is paused, false otherwise */ function getPaused(address asset) external view returns (bool isPaused); /** * @notice Returns the siloed borrowing flag * @param asset The address of the underlying asset of the reserve * @return True if the asset is siloed for borrowing */ function getSiloedBorrowing(address asset) external view returns (bool); /** * @notice Returns the protocol fee on the liquidation bonus * @param asset The address of the underlying asset of the reserve * @return The protocol fee on liquidation */ function getLiquidationProtocolFee(address asset) external view returns (uint256); /** * @notice Returns the unbacked mint cap of the reserve * @param asset The address of the underlying asset of the reserve * @return The unbacked mint cap of the reserve */ function getUnbackedMintCap(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling of the reserve * @param asset The address of the underlying asset of the reserve * @return The debt ceiling of the reserve */ function getDebtCeiling(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling decimals * @return The debt ceiling decimals */ function getDebtCeilingDecimals() external pure returns (uint256); /** * @notice Returns the reserve data * @param asset The address of the underlying asset of the reserve * @return unbacked The amount of unbacked tokens * @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted * @return totalAToken The total supply of the aToken * @return totalStableDebt The total stable debt of the reserve * @return totalVariableDebt The total variable debt of the reserve * @return liquidityRate The liquidity rate of the reserve * @return variableBorrowRate The variable borrow rate of the reserve * @return stableBorrowRate The stable borrow rate of the reserve * @return averageStableBorrowRate The average stable borrow rate of the reserve * @return liquidityIndex The liquidity index of the reserve * @return variableBorrowIndex The variable borrow index of the reserve * @return lastUpdateTimestamp The timestamp of the last update of the reserve */ function getReserveData( address asset ) external view returns ( uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); /** * @notice Returns the total supply of aTokens for a given asset * @param asset The address of the underlying asset of the reserve * @return The total supply of the aToken */ function getATokenTotalSupply(address asset) external view returns (uint256); /** * @notice Returns the total debt for a given asset * @param asset The address of the underlying asset of the reserve * @return The total debt for asset */ function getTotalDebt(address asset) external view returns (uint256); /** * @notice Returns the user data in a reserve * @param asset The address of the underlying asset of the reserve * @param user The address of the user * @return currentATokenBalance The current AToken balance of the user * @return currentStableDebt The current stable debt of the user * @return currentVariableDebt The current variable debt of the user * @return principalStableDebt The principal stable debt of the user * @return scaledVariableDebt The scaled variable debt of the user * @return stableBorrowRate The stable borrow rate of the user * @return liquidityRate The liquidity rate of the reserve * @return stableRateLastUpdated The timestamp of the last update of the user stable rate * @return usageAsCollateralEnabled True if the user is using the asset as collateral, false * otherwise */ function getUserReserveData( address asset, address user ) external view returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); /** * @notice Returns the token addresses of the reserve * @param asset The address of the underlying asset of the reserve * @return aTokenAddress The AToken address of the reserve * @return stableDebtTokenAddress DEPRECATED in v3.2.0 * @return variableDebtTokenAddress The VariableDebtToken address of the reserve */ function getReserveTokensAddresses( address asset ) external view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); /** * @notice Returns the address of the Interest Rate strategy * @param asset The address of the underlying asset of the reserve * @return irStrategyAddress The address of the Interest Rate strategy */ function getInterestRateStrategyAddress( address asset ) external view returns (address irStrategyAddress); /** * @notice Returns whether the reserve has FlashLoans enabled or disabled * @param asset The address of the underlying asset of the reserve * @return True if FlashLoans are enabled, false otherwise */ function getFlashLoanEnabled(address asset) external view returns (bool); /** * @notice Returns whether virtual accounting is enabled/not for a reserve * @param asset The address of the underlying asset of the reserve * @return True if active, false otherwise */ function getIsVirtualAccActive(address asset) external view returns (bool); /** * @notice Returns the virtual underlying balance of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve virtual underlying balance */ function getVirtualUnderlyingBalance(address asset) external view returns (uint256); /** * @notice Returns the deficit of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve deficit */ function getReserveDeficit(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPriceOracleGetter * @author Aave * @notice Interface for the Aave price oracle. */ interface IPriceOracleGetter { /** * @notice Returns the base currency address * @dev Address 0x0 is reserved for USD as base currency. * @return Returns the base currency address. */ function BASE_CURRENCY() external view returns (address); /** * @notice Returns the base currency unit * @dev 1 ether for ETH, 1e8 for USD. * @return Returns the base currency unit. */ function BASE_CURRENCY_UNIT() external view returns (uint256); /** * @notice Returns the asset price in the base currency * @param asset The address of the asset * @return The price of the asset */ function getAssetPrice(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IReserveInterestRateStrategy * @author BGD Labs * @notice Basic interface for any rate strategy used by the Aave protocol */ interface IReserveInterestRateStrategy { /** * @notice Sets interest rate data for an Aave rate strategy * @param reserve The reserve to update * @param rateData The abi encoded reserve interest rate data to apply to the given reserve * Abstracted this way as rate strategies can be custom */ function setInterestRateParams(address reserve, bytes calldata rateData) external; /** * @notice Calculates the interest rates depending on the reserve's state and configurations * @param params The parameters needed to calculate interest rates * @return liquidityRate The liquidity rate expressed in ray * @return variableBorrowRate The variable borrow rate expressed in ray */ function calculateInterestRates( DataTypes.CalculateInterestRatesParams memory params ) external view returns (uint256, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IScaledBalanceToken * @author Aave * @notice Defines the basic interface for a scaled-balance token. */ interface IScaledBalanceToken { /** * @dev Emitted after the mint action * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted tokens * @param value The scaled-up amount being minted (based on user entered amount and balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'onBehalfOf' * @param index The next liquidity index of the reserve */ event Mint( address indexed caller, address indexed onBehalfOf, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @dev Emitted after the burn action * @dev If the burn function does not involve a transfer of the underlying asset, the target defaults to zero address * @param from The address from which the tokens will be burned * @param target The address that will receive the underlying, if any * @param value The scaled-up amount being burned (user entered amount - balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'from' * @param index The next liquidity index of the reserve */ event Burn( address indexed from, address indexed target, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @notice Returns the scaled balance of the user. * @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index * at the moment of the update * @param user The user whose balance is calculated * @return The scaled balance of the user */ function scaledBalanceOf(address user) external view returns (uint256); /** * @notice Returns the scaled balance of the user and the scaled total supply. * @param user The address of the user * @return The scaled balance of the user * @return The scaled total supply */ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); /** * @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index) * @return The scaled total supply */ function scaledTotalSupply() external view returns (uint256); /** * @notice Returns last index interest was accrued to the user's balance * @param user The address of the user * @return The last index interest was accrued to the user's balance, expressed in ray */ function getPreviousIndex(address user) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; /** * @title IVariableDebtToken * @author Aave * @notice Defines the basic interface for a variable debt token. */ interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken { /** * @notice Mints debt token to the `onBehalfOf` address * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt being minted * @param index The variable debt index of the reserve * @return True if the previous balance of the user is 0, false otherwise * @return The scaled total debt of the reserve */ function mint( address user, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool, uint256); /** * @notice Burns user variable debt * @dev In some instances, a burn transaction will emit a mint event * if the amount to burn is less than the interest that the user accrued * @param from The address from which the debt will be burned * @param amount The amount getting burned * @param index The variable debt index of the reserve * @return The scaled total debt of the reserve */ function burn(address from, uint256 amount, uint256 index) external returns (uint256); /** * @notice Returns the address of the underlying asset of this debtToken (E.g. WETH for variableDebtWETH) * @return The address of the underlying asset */ function UNDERLYING_ASSET_ADDRESS() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Errors} from '../helpers/Errors.sol'; import {DataTypes} from '../types/DataTypes.sol'; /** * @title ReserveConfiguration library * @author Aave * @notice Implements the bitmap logic to handle the reserve configuration */ library ReserveConfiguration { uint256 internal constant LTV_MASK = 0x000000000000000000000000000000000000000000000000000000000000FFFF; // prettier-ignore uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0x00000000000000000000000000000000000000000000000000000000FFFF0000; // prettier-ignore uint256 internal constant LIQUIDATION_BONUS_MASK = 0x0000000000000000000000000000000000000000000000000000FFFF00000000; // prettier-ignore uint256 internal constant DECIMALS_MASK = 0x00000000000000000000000000000000000000000000000000FF000000000000; // prettier-ignore uint256 internal constant ACTIVE_MASK = 0x0000000000000000000000000000000000000000000000000100000000000000; // prettier-ignore uint256 internal constant FROZEN_MASK = 0x0000000000000000000000000000000000000000000000000200000000000000; // prettier-ignore uint256 internal constant BORROWING_MASK = 0x0000000000000000000000000000000000000000000000000400000000000000; // prettier-ignore // @notice there is an unoccupied hole of 1 bit at position 59 from pre 3.2 stableBorrowRateEnabled uint256 internal constant PAUSED_MASK = 0x0000000000000000000000000000000000000000000000001000000000000000; // prettier-ignore uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0x0000000000000000000000000000000000000000000000002000000000000000; // prettier-ignore uint256 internal constant SILOED_BORROWING_MASK = 0x0000000000000000000000000000000000000000000000004000000000000000; // prettier-ignore uint256 internal constant FLASHLOAN_ENABLED_MASK = 0x0000000000000000000000000000000000000000000000008000000000000000; // prettier-ignore uint256 internal constant RESERVE_FACTOR_MASK = 0x00000000000000000000000000000000000000000000FFFF0000000000000000; // prettier-ignore uint256 internal constant BORROW_CAP_MASK = 0x00000000000000000000000000000000000FFFFFFFFF00000000000000000000; // prettier-ignore uint256 internal constant SUPPLY_CAP_MASK = 0x00000000000000000000000000FFFFFFFFF00000000000000000000000000000; // prettier-ignore uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0x0000000000000000000000FFFF00000000000000000000000000000000000000; // prettier-ignore //@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory uint256 internal constant UNBACKED_MINT_CAP_MASK = 0x00000000000FFFFFFFFF00000000000000000000000000000000000000000000; // prettier-ignore uint256 internal constant DEBT_CEILING_MASK = 0x0FFFFFFFFFF00000000000000000000000000000000000000000000000000000; // prettier-ignore uint256 internal constant VIRTUAL_ACC_ACTIVE_MASK = 0x1000000000000000000000000000000000000000000000000000000000000000; // prettier-ignore /// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16; uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32; uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48; uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56; uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57; uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58; uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60; uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61; uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62; uint256 internal constant FLASHLOAN_ENABLED_START_BIT_POSITION = 63; uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64; uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80; uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116; uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152; //@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176; uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212; uint256 internal constant VIRTUAL_ACC_START_BIT_POSITION = 252; uint256 internal constant MAX_VALID_LTV = 65535; uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535; uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535; uint256 internal constant MAX_VALID_DECIMALS = 255; uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535; uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735; uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735; uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535; uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735; uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775; uint256 public constant DEBT_CEILING_DECIMALS = 2; uint16 public constant MAX_RESERVES_COUNT = 128; /** * @notice Sets the Loan to Value of the reserve * @param self The reserve configuration * @param ltv The new ltv */ function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure { require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV); self.data = (self.data & ~LTV_MASK) | ltv; } /** * @notice Gets the Loan to Value of the reserve * @param self The reserve configuration * @return The loan to value */ function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) { return self.data & LTV_MASK; } /** * @notice Sets the liquidation threshold of the reserve * @param self The reserve configuration * @param threshold The new liquidation threshold */ function setLiquidationThreshold( DataTypes.ReserveConfigurationMap memory self, uint256 threshold ) internal pure { require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD); self.data = (self.data & ~LIQUIDATION_THRESHOLD_MASK) | (threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION); } /** * @notice Gets the liquidation threshold of the reserve * @param self The reserve configuration * @return The liquidation threshold */ function getLiquidationThreshold( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION; } /** * @notice Sets the liquidation bonus of the reserve * @param self The reserve configuration * @param bonus The new liquidation bonus */ function setLiquidationBonus( DataTypes.ReserveConfigurationMap memory self, uint256 bonus ) internal pure { require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS); self.data = (self.data & ~LIQUIDATION_BONUS_MASK) | (bonus << LIQUIDATION_BONUS_START_BIT_POSITION); } /** * @notice Gets the liquidation bonus of the reserve * @param self The reserve configuration * @return The liquidation bonus */ function getLiquidationBonus( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION; } /** * @notice Sets the decimals of the underlying asset of the reserve * @param self The reserve configuration * @param decimals The decimals */ function setDecimals( DataTypes.ReserveConfigurationMap memory self, uint256 decimals ) internal pure { require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS); self.data = (self.data & ~DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); } /** * @notice Gets the decimals of the underlying asset of the reserve * @param self The reserve configuration * @return The decimals of the asset */ function getDecimals( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; } /** * @notice Sets the active state of the reserve * @param self The reserve configuration * @param active The active state */ function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure { self.data = (self.data & ~ACTIVE_MASK) | (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); } /** * @notice Gets the active state of the reserve * @param self The reserve configuration * @return The active state */ function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & ACTIVE_MASK) != 0; } /** * @notice Sets the frozen state of the reserve * @param self The reserve configuration * @param frozen The frozen state */ function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure { self.data = (self.data & ~FROZEN_MASK) | (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); } /** * @notice Gets the frozen state of the reserve * @param self The reserve configuration * @return The frozen state */ function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & FROZEN_MASK) != 0; } /** * @notice Sets the paused state of the reserve * @param self The reserve configuration * @param paused The paused state */ function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure { self.data = (self.data & ~PAUSED_MASK) | (uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION); } /** * @notice Gets the paused state of the reserve * @param self The reserve configuration * @return The paused state */ function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & PAUSED_MASK) != 0; } /** * @notice Sets the borrowable in isolation flag for the reserve. * @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed * amount will be accumulated in the isolated collateral's total debt exposure. * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep * consistency in the debt ceiling calculations. * @param self The reserve configuration * @param borrowable True if the asset is borrowable */ function setBorrowableInIsolation( DataTypes.ReserveConfigurationMap memory self, bool borrowable ) internal pure { self.data = (self.data & ~BORROWABLE_IN_ISOLATION_MASK) | (uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION); } /** * @notice Gets the borrowable in isolation flag for the reserve. * @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with * isolated collateral is accounted for in the isolated collateral's total debt exposure. * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep * consistency in the debt ceiling calculations. * @param self The reserve configuration * @return The borrowable in isolation flag */ function getBorrowableInIsolation( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & BORROWABLE_IN_ISOLATION_MASK) != 0; } /** * @notice Sets the siloed borrowing flag for the reserve. * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. * @param self The reserve configuration * @param siloed True if the asset is siloed */ function setSiloedBorrowing( DataTypes.ReserveConfigurationMap memory self, bool siloed ) internal pure { self.data = (self.data & ~SILOED_BORROWING_MASK) | (uint256(siloed ? 1 : 0) << SILOED_BORROWING_START_BIT_POSITION); } /** * @notice Gets the siloed borrowing flag for the reserve. * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. * @param self The reserve configuration * @return The siloed borrowing flag */ function getSiloedBorrowing( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & SILOED_BORROWING_MASK) != 0; } /** * @notice Enables or disables borrowing on the reserve * @param self The reserve configuration * @param enabled True if the borrowing needs to be enabled, false otherwise */ function setBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self, bool enabled ) internal pure { self.data = (self.data & ~BORROWING_MASK) | (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); } /** * @notice Gets the borrowing state of the reserve * @param self The reserve configuration * @return The borrowing state */ function getBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & BORROWING_MASK) != 0; } /** * @notice Sets the reserve factor of the reserve * @param self The reserve configuration * @param reserveFactor The reserve factor */ function setReserveFactor( DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor ) internal pure { require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR); self.data = (self.data & ~RESERVE_FACTOR_MASK) | (reserveFactor << RESERVE_FACTOR_START_BIT_POSITION); } /** * @notice Gets the reserve factor of the reserve * @param self The reserve configuration * @return The reserve factor */ function getReserveFactor( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; } /** * @notice Sets the borrow cap of the reserve * @param self The reserve configuration * @param borrowCap The borrow cap */ function setBorrowCap( DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap ) internal pure { require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.INVALID_BORROW_CAP); self.data = (self.data & ~BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION); } /** * @notice Gets the borrow cap of the reserve * @param self The reserve configuration * @return The borrow cap */ function getBorrowCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION; } /** * @notice Sets the supply cap of the reserve * @param self The reserve configuration * @param supplyCap The supply cap */ function setSupplyCap( DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap ) internal pure { require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.INVALID_SUPPLY_CAP); self.data = (self.data & ~SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION); } /** * @notice Gets the supply cap of the reserve * @param self The reserve configuration * @return The supply cap */ function getSupplyCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION; } /** * @notice Sets the debt ceiling in isolation mode for the asset * @param self The reserve configuration * @param ceiling The maximum debt ceiling for the asset */ function setDebtCeiling( DataTypes.ReserveConfigurationMap memory self, uint256 ceiling ) internal pure { require(ceiling <= MAX_VALID_DEBT_CEILING, Errors.INVALID_DEBT_CEILING); self.data = (self.data & ~DEBT_CEILING_MASK) | (ceiling << DEBT_CEILING_START_BIT_POSITION); } /** * @notice Gets the debt ceiling for the asset if the asset is in isolation mode * @param self The reserve configuration * @return The debt ceiling (0 = isolation mode disabled) */ function getDebtCeiling( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & DEBT_CEILING_MASK) >> DEBT_CEILING_START_BIT_POSITION; } /** * @notice Sets the liquidation protocol fee of the reserve * @param self The reserve configuration * @param liquidationProtocolFee The liquidation protocol fee */ function setLiquidationProtocolFee( DataTypes.ReserveConfigurationMap memory self, uint256 liquidationProtocolFee ) internal pure { require( liquidationProtocolFee <= MAX_VALID_LIQUIDATION_PROTOCOL_FEE, Errors.INVALID_LIQUIDATION_PROTOCOL_FEE ); self.data = (self.data & ~LIQUIDATION_PROTOCOL_FEE_MASK) | (liquidationProtocolFee << LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION); } /** * @dev Gets the liquidation protocol fee * @param self The reserve configuration * @return The liquidation protocol fee */ function getLiquidationProtocolFee( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & LIQUIDATION_PROTOCOL_FEE_MASK) >> LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION; } /** * @notice Sets the unbacked mint cap of the reserve * @param self The reserve configuration * @param unbackedMintCap The unbacked mint cap */ function setUnbackedMintCap( DataTypes.ReserveConfigurationMap memory self, uint256 unbackedMintCap ) internal pure { require(unbackedMintCap <= MAX_VALID_UNBACKED_MINT_CAP, Errors.INVALID_UNBACKED_MINT_CAP); self.data = (self.data & ~UNBACKED_MINT_CAP_MASK) | (unbackedMintCap << UNBACKED_MINT_CAP_START_BIT_POSITION); } /** * @dev Gets the unbacked mint cap of the reserve * @param self The reserve configuration * @return The unbacked mint cap */ function getUnbackedMintCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & UNBACKED_MINT_CAP_MASK) >> UNBACKED_MINT_CAP_START_BIT_POSITION; } /** * @notice Sets the flashloanable flag for the reserve * @param self The reserve configuration * @param flashLoanEnabled True if the asset is flashloanable, false otherwise */ function setFlashLoanEnabled( DataTypes.ReserveConfigurationMap memory self, bool flashLoanEnabled ) internal pure { self.data = (self.data & ~FLASHLOAN_ENABLED_MASK) | (uint256(flashLoanEnabled ? 1 : 0) << FLASHLOAN_ENABLED_START_BIT_POSITION); } /** * @notice Gets the flashloanable flag for the reserve * @param self The reserve configuration * @return The flashloanable flag */ function getFlashLoanEnabled( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & FLASHLOAN_ENABLED_MASK) != 0; } /** * @notice Sets the virtual account active/not state of the reserve * @param self The reserve configuration * @param active The active state */ function setVirtualAccActive( DataTypes.ReserveConfigurationMap memory self, bool active ) internal pure { self.data = (self.data & ~VIRTUAL_ACC_ACTIVE_MASK) | (uint256(active ? 1 : 0) << VIRTUAL_ACC_START_BIT_POSITION); } /** * @notice Gets the virtual account active/not state of the reserve * @dev The state should be true for all normal assets and should be false * Virtual accounting being disabled means that the asset: * - is GHO * - can never be supplied * - the interest rate strategy is not influenced by the virtual balance * @param self The reserve configuration * @return The active state */ function getIsVirtualAccActive( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & VIRTUAL_ACC_ACTIVE_MASK) != 0; } /** * @notice Gets the configuration flags of the reserve * @param self The reserve configuration * @return The state flag representing active * @return The state flag representing frozen * @return The state flag representing borrowing enabled * @return The state flag representing paused */ function getFlags( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool, bool, bool, bool) { uint256 dataLocal = self.data; return ( (dataLocal & ACTIVE_MASK) != 0, (dataLocal & FROZEN_MASK) != 0, (dataLocal & BORROWING_MASK) != 0, (dataLocal & PAUSED_MASK) != 0 ); } /** * @notice Gets the configuration parameters of the reserve from storage * @param self The reserve configuration * @return The state param representing ltv * @return The state param representing liquidation threshold * @return The state param representing liquidation bonus * @return The state param representing reserve decimals * @return The state param representing reserve factor */ function getParams( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256, uint256, uint256, uint256, uint256) { uint256 dataLocal = self.data; return ( dataLocal & LTV_MASK, (dataLocal & LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, (dataLocal & LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, (dataLocal & DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, (dataLocal & RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION ); } /** * @notice Gets the caps parameters of the reserve from storage * @param self The reserve configuration * @return The state param representing borrow cap * @return The state param representing supply cap. */ function getCaps( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256, uint256) { uint256 dataLocal = self.data; return ( (dataLocal & BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION, (dataLocal & SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Errors} from '../helpers/Errors.sol'; import {DataTypes} from '../types/DataTypes.sol'; import {ReserveConfiguration} from './ReserveConfiguration.sol'; /** * @title UserConfiguration library * @author Aave * @notice Implements the bitmap logic to handle the user configuration */ library UserConfiguration { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; uint256 internal constant BORROWING_MASK = 0x5555555555555555555555555555555555555555555555555555555555555555; uint256 internal constant COLLATERAL_MASK = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; /** * @notice Sets if the user is borrowing the reserve identified by reserveIndex * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @param borrowing True if the user is borrowing the reserve, false otherwise */ function setBorrowing( DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool borrowing ) internal { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); uint256 bit = 1 << (reserveIndex << 1); if (borrowing) { self.data |= bit; } else { self.data &= ~bit; } } } /** * @notice Sets if the user is using as collateral the reserve identified by reserveIndex * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @param usingAsCollateral True if the user is using the reserve as collateral, false otherwise */ function setUsingAsCollateral( DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool usingAsCollateral ) internal { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); uint256 bit = 1 << ((reserveIndex << 1) + 1); if (usingAsCollateral) { self.data |= bit; } else { self.data &= ~bit; } } } /** * @notice Returns if a user has been using the reserve for borrowing or as collateral * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve for borrowing or as collateral, false otherwise */ function isUsingAsCollateralOrBorrowing( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> (reserveIndex << 1)) & 3 != 0; } } /** * @notice Validate a user has been using the reserve for borrowing * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve for borrowing, false otherwise */ function isBorrowing( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> (reserveIndex << 1)) & 1 != 0; } } /** * @notice Validate a user has been using the reserve as collateral * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve as collateral, false otherwise */ function isUsingAsCollateral( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> ((reserveIndex << 1) + 1)) & 1 != 0; } } /** * @notice Checks if a user has been supplying only one reserve as collateral * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 * @param self The configuration object * @return True if the user has been supplying as collateral one reserve, false otherwise */ function isUsingAsCollateralOne( DataTypes.UserConfigurationMap memory self ) internal pure returns (bool) { uint256 collateralData = self.data & COLLATERAL_MASK; return collateralData != 0 && (collateralData & (collateralData - 1) == 0); } /** * @notice Checks if a user has been supplying any reserve as collateral * @param self The configuration object * @return True if the user has been supplying as collateral any reserve, false otherwise */ function isUsingAsCollateralAny( DataTypes.UserConfigurationMap memory self ) internal pure returns (bool) { return self.data & COLLATERAL_MASK != 0; } /** * @notice Checks if a user has been borrowing only one asset * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 * @param self The configuration object * @return True if the user has been supplying as collateral one reserve, false otherwise */ function isBorrowingOne(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { uint256 borrowingData = self.data & BORROWING_MASK; return borrowingData != 0 && (borrowingData & (borrowingData - 1) == 0); } /** * @notice Checks if a user has been borrowing from any reserve * @param self The configuration object * @return True if the user has been borrowing any reserve, false otherwise */ function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data & BORROWING_MASK != 0; } /** * @notice Checks if a user has not been using any reserve for borrowing or supply * @param self The configuration object * @return True if the user has not been borrowing or supplying any reserve, false otherwise */ function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data == 0; } /** * @notice Returns the Isolation Mode state of the user * @param self The configuration object * @param reservesData The state of all the reserves * @param reservesList The addresses of all the active reserves * @return True if the user is in isolation mode, false otherwise * @return The address of the only asset used as collateral * @return The debt ceiling of the reserve */ function getIsolationModeState( DataTypes.UserConfigurationMap memory self, mapping(address => DataTypes.ReserveData) storage reservesData, mapping(uint256 => address) storage reservesList ) internal view returns (bool, address, uint256) { if (isUsingAsCollateralOne(self)) { uint256 assetId = _getFirstAssetIdByMask(self, COLLATERAL_MASK); address assetAddress = reservesList[assetId]; uint256 ceiling = reservesData[assetAddress].configuration.getDebtCeiling(); if (ceiling != 0) { return (true, assetAddress, ceiling); } } return (false, address(0), 0); } /** * @notice Returns the siloed borrowing state for the user * @param self The configuration object * @param reservesData The data of all the reserves * @param reservesList The reserve list * @return True if the user has borrowed a siloed asset, false otherwise * @return The address of the only borrowed asset */ function getSiloedBorrowingState( DataTypes.UserConfigurationMap memory self, mapping(address => DataTypes.ReserveData) storage reservesData, mapping(uint256 => address) storage reservesList ) internal view returns (bool, address) { if (isBorrowingOne(self)) { uint256 assetId = _getFirstAssetIdByMask(self, BORROWING_MASK); address assetAddress = reservesList[assetId]; if (reservesData[assetAddress].configuration.getSiloedBorrowing()) { return (true, assetAddress); } } return (false, address(0)); } /** * @notice Returns the address of the first asset flagged in the bitmap given the corresponding bitmask * @param self The configuration object * @return The index of the first asset flagged in the bitmap once the corresponding mask is applied */ function _getFirstAssetIdByMask( DataTypes.UserConfigurationMap memory self, uint256 mask ) internal pure returns (uint256) { unchecked { uint256 bitmapData = self.data & mask; uint256 firstAssetPosition = bitmapData & ~(bitmapData - 1); uint256 id; while ((firstAssetPosition >>= 2) != 0) { id += 1; } return id; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Errors library * @author Aave * @notice Defines the error messages emitted by the different contracts of the Aave protocol */ library Errors { string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin' string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin' string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin' string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin' string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin' string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge' string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered' string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider' string public constant NOT_CONTRACT = '9'; // 'Address is not a contract' string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator' string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken' string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid' string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function' string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list' string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached' string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets' string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset' string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0' string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium' string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve' string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category' string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee' string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool' string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint' string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn' string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0' string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve' string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen' string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused' string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled' string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance' string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected' string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0' string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold' string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow' string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed' string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type' string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed' string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve' string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0' string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met' string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold' string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated' string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency' string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters' string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded' string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded' string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded' string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded' string public constant UNDERLYING_CLAIMABLE_RIGHTS_NOT_ZERO = '54'; // 'Claimable rights over underlying not zero (aToken supply or accruedToTreasury)' string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero' string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed' string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category' string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed' string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode' string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized' string public constant USER_IN_ISOLATION_MODE_OR_LTV_ZERO = '62'; // 'User is in isolation mode or ltv is zero' string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve' string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve' string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve' string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve' string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve' string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve' string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve' string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve' string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve' string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve' string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index' string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address' string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not' string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid' string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration' string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature' string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported' string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero' string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed' string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio' string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued' string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list' string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match' string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one' string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0 string public constant FLASHLOAN_DISABLED = '91'; // FlashLoaning for this asset is disabled string public constant INVALID_MAX_RATE = '92'; // The expect maximum borrow rate is invalid string public constant WITHDRAW_TO_ATOKEN = '93'; // Withdrawing to the aToken is not allowed string public constant SUPPLY_TO_ATOKEN = '94'; // Supplying to the aToken is not allowed string public constant SLOPE_2_MUST_BE_GTE_SLOPE_1 = '95'; // Variable interest rate slope 2 can not be lower than slope 1 string public constant CALLER_NOT_RISK_OR_POOL_OR_EMERGENCY_ADMIN = '96'; // 'The caller of the function is not a risk, pool or emergency admin' string public constant LIQUIDATION_GRACE_SENTINEL_CHECK_FAILED = '97'; // 'Liquidation grace sentinel validation failed' string public constant INVALID_GRACE_PERIOD = '98'; // Grace period above a valid range string public constant INVALID_FREEZE_STATE = '99'; // Reserve is already in the passed freeze state string public constant NOT_BORROWABLE_IN_EMODE = '100'; // Asset not borrowable in eMode string public constant CALLER_NOT_UMBRELLA = '101'; // The caller of the function is not the umbrella contract string public constant RESERVE_NOT_IN_DEFICIT = '102'; // The reserve is not in deficit string public constant MUST_NOT_LEAVE_DUST = '103'; // Below a certain threshold liquidators need to take the full position string public constant USER_CANNOT_HAVE_DEBT = '104'; // Thrown when a user tries to interact with a method that requires a position without debt }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /** * @title WadRayMath library * @author Aave * @notice Provides functions to perform calculations with Wad and Ray units * @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers * with 27 digits of precision) * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down. */ library WadRayMath { // HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly uint256 internal constant WAD = 1e18; uint256 internal constant HALF_WAD = 0.5e18; uint256 internal constant RAY = 1e27; uint256 internal constant HALF_RAY = 0.5e27; uint256 internal constant WAD_RAY_RATIO = 1e9; /** * @dev Multiplies two wad, rounding half up to the nearest wad * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Wad * @param b Wad * @return c = a*b, in wad */ function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) { // to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b assembly { if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) { revert(0, 0) } c := div(add(mul(a, b), HALF_WAD), WAD) } } /** * @dev Divides two wad, rounding half up to the nearest wad * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Wad * @param b Wad * @return c = a/b, in wad */ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) { // to avoid overflow, a <= (type(uint256).max - halfB) / WAD assembly { if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) { revert(0, 0) } c := div(add(mul(a, WAD), div(b, 2)), b) } } /** * @notice Multiplies two ray, rounding half up to the nearest ray * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Ray * @param b Ray * @return c = a raymul b */ function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) { // to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b assembly { if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) { revert(0, 0) } c := div(add(mul(a, b), HALF_RAY), RAY) } } /** * @notice Divides two ray, rounding half up to the nearest ray * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Ray * @param b Ray * @return c = a raydiv b */ function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) { // to avoid overflow, a <= (type(uint256).max - halfB) / RAY assembly { if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) { revert(0, 0) } c := div(add(mul(a, RAY), div(b, 2)), b) } } /** * @dev Casts ray down to wad * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Ray * @return b = a converted to wad, rounded half up to the nearest wad */ function rayToWad(uint256 a) internal pure returns (uint256 b) { assembly { b := div(a, WAD_RAY_RATIO) let remainder := mod(a, WAD_RAY_RATIO) if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) { b := add(b, 1) } } } /** * @dev Converts wad up to ray * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 * @param a Wad * @return b = a converted in ray */ function wadToRay(uint256 a) internal pure returns (uint256 b) { // to avoid overflow, b/WAD_RAY_RATIO == a assembly { b := mul(a, WAD_RAY_RATIO) if iszero(eq(div(b, WAD_RAY_RATIO), a)) { revert(0, 0) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library DataTypes { /** * This exists specifically to maintain the `getReserveData()` interface, since the new, internal * `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`. */ struct ReserveDataLegacy { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; // DEPRECATED on v3.2.0 uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; /// @notice reused `__deprecatedStableBorrowRate` storage from pre 3.2 // the current accumulate deficit in underlying tokens uint128 deficit; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed uint40 liquidationGracePeriodUntil; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address __deprecatedStableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; //the amount of underlying accounted for by the protocol uint128 virtualUnderlyingBalance; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: DEPRECATED: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167: liquidation protocol fee //bit 168-175: DEPRECATED: eMode category //bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252: virtual accounting is enabled for the reserve //bit 253-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } // DEPRECATED: kept for backwards compatibility, might be removed in a future version struct EModeCategoryLegacy { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // DEPRECATED address priceSource; string label; } struct CollateralConfig { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; } struct EModeCategoryBaseConfiguration { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; string label; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; uint128 collateralBitmap; string label; uint128 borrowableBitmap; } enum InterestRateMode { NONE, __DEPRECATED, VARIABLE } struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteEliminateDeficitParams { address asset; uint256 amount; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 reservesCount; address addressesProvider; address pool; uint8 userEModeCategory; bool isAuthorizedFlashBorrower; } struct FlashloanSimpleParams { address receiverAddress; address asset; uint256 amount; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; } struct FlashLoanRepaymentParams { uint256 amount; uint256 totalPremium; uint256 flashLoanPremiumToProtocol; address asset; address receiverAddress; uint16 referralCode; } struct CalculateUserAccountDataParams { UserConfigurationMap userConfig; uint256 reservesCount; address user; address oracle; uint8 userEModeCategory; } struct ValidateBorrowParams { ReserveCache reserveCache; UserConfigurationMap userConfig; address asset; address userAddress; uint256 amount; InterestRateMode interestRateMode; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalDebt; uint256 reserveFactor; address reserve; bool usingVirtualBalance; uint256 virtualUnderlyingBalance; } struct InitReserveParams { address asset; address aTokenAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol'; import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20Detailed} from '../../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; import {WadRayMath} from '../../libraries/math/WadRayMath.sol'; import {Errors} from '../../libraries/helpers/Errors.sol'; import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../../../interfaces/IPool.sol'; import {IACLManager} from '../../../interfaces/IACLManager.sol'; /** * @title IncentivizedERC20 * @author Aave, inspired by the Openzeppelin ERC20 implementation * @notice Basic ERC20 implementation */ abstract contract IncentivizedERC20 is Context, IERC20Detailed { using WadRayMath for uint256; using SafeCast for uint256; /** * @dev Only pool admin can call functions marked by this modifier. */ modifier onlyPoolAdmin() { IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); _; } /** * @dev Only pool can call functions marked by this modifier. */ modifier onlyPool() { require(_msgSender() == address(POOL), Errors.CALLER_MUST_BE_POOL); _; } /** * @dev UserState - additionalData is a flexible field. * ATokens and VariableDebtTokens use this field store the index of the * user's last supply/withdrawal/borrow/repayment. */ struct UserState { uint128 balance; uint128 additionalData; } // Map of users address and their state data (userAddress => userStateData) mapping(address => UserState) internal _userState; // Map of allowances (delegator => delegatee => allowanceAmount) mapping(address => mapping(address => uint256)) private _allowances; uint256 internal _totalSupply; string private _name; string private _symbol; uint8 private _decimals; IAaveIncentivesController internal _incentivesController; IPoolAddressesProvider internal immutable _addressesProvider; IPool public immutable POOL; /** * @dev Constructor. * @param pool The reference to the main Pool contract * @param name_ The name of the token * @param symbol_ The symbol of the token * @param decimals_ The number of decimals of the token */ constructor(IPool pool, string memory name_, string memory symbol_, uint8 decimals_) { _addressesProvider = pool.ADDRESSES_PROVIDER(); _name = name_; _symbol = symbol_; _decimals = decimals_; POOL = pool; } /// @inheritdoc IERC20Detailed function name() public view override returns (string memory) { return _name; } /// @inheritdoc IERC20Detailed function symbol() external view override returns (string memory) { return _symbol; } /// @inheritdoc IERC20Detailed function decimals() external view override returns (uint8) { return _decimals; } /// @inheritdoc IERC20 function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /// @inheritdoc IERC20 function balanceOf(address account) public view virtual override returns (uint256) { return _userState[account].balance; } /** * @notice Returns the address of the Incentives Controller contract * @return The address of the Incentives Controller */ function getIncentivesController() external view virtual returns (IAaveIncentivesController) { return _incentivesController; } /** * @notice Sets a new Incentives Controller * @param controller the new Incentives controller */ function setIncentivesController(IAaveIncentivesController controller) external onlyPoolAdmin { _incentivesController = controller; } /// @inheritdoc IERC20 function transfer(address recipient, uint256 amount) external virtual override returns (bool) { uint128 castAmount = amount.toUint128(); _transfer(_msgSender(), recipient, castAmount); return true; } /// @inheritdoc IERC20 function allowance( address owner, address spender ) external view virtual override returns (uint256) { return _allowances[owner][spender]; } /// @inheritdoc IERC20 function approve(address spender, uint256 amount) external virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /// @inheritdoc IERC20 function transferFrom( address sender, address recipient, uint256 amount ) external virtual override returns (bool) { uint128 castAmount = amount.toUint128(); _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - castAmount); _transfer(sender, recipient, castAmount); return true; } /** * @notice Increases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param addedValue The amount being added to the allowance * @return `true` */ function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @notice Decreases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param subtractedValue The amount being subtracted to the allowance * @return `true` */ function decreaseAllowance( address spender, uint256 subtractedValue ) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue); return true; } /** * @notice Transfers tokens between two users and apply incentives if defined. * @param sender The source address * @param recipient The destination address * @param amount The amount getting transferred */ function _transfer(address sender, address recipient, uint128 amount) internal virtual { uint128 oldSenderBalance = _userState[sender].balance; _userState[sender].balance = oldSenderBalance - amount; uint128 oldRecipientBalance = _userState[recipient].balance; _userState[recipient].balance = oldRecipientBalance + amount; IAaveIncentivesController incentivesControllerLocal = _incentivesController; if (address(incentivesControllerLocal) != address(0)) { uint256 currentTotalSupply = _totalSupply; incentivesControllerLocal.handleAction(sender, currentTotalSupply, oldSenderBalance); if (sender != recipient) { incentivesControllerLocal.handleAction(recipient, currentTotalSupply, oldRecipientBalance); } } } /** * @notice Approve `spender` to use `amount` of `owner`s balance * @param owner The address owning the tokens * @param spender The address approved for spending * @param amount The amount of tokens to approve spending of */ function _approve(address owner, address spender, uint256 amount) internal virtual { _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @notice Update the name of the token * @param newName The new name for the token */ function _setName(string memory newName) internal { _name = newName; } /** * @notice Update the symbol for the token * @param newSymbol The new symbol for the token */ function _setSymbol(string memory newSymbol) internal { _symbol = newSymbol; } /** * @notice Update the number of decimals for the token * @param newDecimals The new number of decimals for the token */ function _setDecimals(uint8 newDecimals) internal { _decimals = newDecimals; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IRewardsDistributor} from './IRewardsDistributor.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; import {AggregatorInterface} from '../../dependencies/chainlink/AggregatorInterface.sol'; import {RewardsDataTypes} from '../libraries/RewardsDataTypes.sol'; /** * @title IRewardsController * @author Aave * @notice Defines the basic interface for a Rewards Controller. */ interface IRewardsController is IRewardsDistributor { /** * @dev Emitted when a new address is whitelisted as claimer of rewards on behalf of a user * @param user The address of the user * @param claimer The address of the claimer */ event ClaimerSet(address indexed user, address indexed claimer); /** * @dev Emitted when rewards are claimed * @param user The address of the user rewards has been claimed on behalf of * @param reward The address of the token reward is claimed * @param to The address of the receiver of the rewards * @param claimer The address of the claimer * @param amount The amount of rewards claimed */ event RewardsClaimed( address indexed user, address indexed reward, address indexed to, address claimer, uint256 amount ); /** * @dev Emitted when a transfer strategy is installed for the reward distribution * @param reward The address of the token reward * @param transferStrategy The address of TransferStrategy contract */ event TransferStrategyInstalled(address indexed reward, address indexed transferStrategy); /** * @dev Emitted when the reward oracle is updated * @param reward The address of the token reward * @param rewardOracle The address of oracle */ event RewardOracleUpdated(address indexed reward, address indexed rewardOracle); /** * @dev Whitelists an address to claim the rewards on behalf of another address * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Sets a TransferStrategy logic contract that determines the logic of the rewards transfer * @param reward The address of the reward token * @param transferStrategy The address of the TransferStrategy logic contract */ function setTransferStrategy(address reward, ITransferStrategyBase transferStrategy) external; /** * @dev Sets an Aave Oracle contract to enforce rewards with a source of value. * @notice At the moment of reward configuration, the Incentives Controller performs * a check to see if the reward asset oracle is compatible with IEACAggregator proxy. * This check is enforced for integrators to be able to show incentives at * the current Aave UI without the need to setup an external price registry * @param reward The address of the reward to set the price aggregator * @param rewardOracle The address of price aggregator that follows AggregatorInterface interface */ function setRewardOracle(address reward, AggregatorInterface rewardOracle) external; /** * @dev Get the price aggregator oracle address * @param reward The address of the reward * @return The price oracle of the reward */ function getRewardOracle(address reward) external view returns (address); /** * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) * @param user The address of the user * @return The claimer address */ function getClaimer(address user) external view returns (address); /** * @dev Returns the Transfer Strategy implementation contract address being used for a reward address * @param reward The address of the reward * @return The address of the TransferStrategy contract */ function getTransferStrategy(address reward) external view returns (address); /** * @dev Configure assets to incentivize with an emission of rewards per second until the end of distribution. * @param config The assets configuration input, the list of structs contains the following fields: * uint104 emissionPerSecond: The emission per second following rewards unit decimals. * uint256 totalSupply: The total supply of the asset to incentivize * uint40 distributionEnd: The end of the distribution of the incentives for an asset * address asset: The asset address to incentivize * address reward: The reward token address * ITransferStrategy transferStrategy: The TransferStrategy address with the install hook and claim logic. * AggregatorInterface rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend. * Must follow Chainlink Aggregator AggregatorInterface interface to be compatible. */ function configureAssets(RewardsDataTypes.RewardsConfigInput[] memory config) external; /** * @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution. * @dev The units of `totalSupply` and `userBalance` should be the same. * @param user The address of the user whose asset balance has changed * @param totalSupply The total supply of the asset prior to user balance change * @param userBalance The previous user balance prior to balance change **/ function handleAction(address user, uint256 totalSupply, uint256 userBalance) external; /** * @dev Claims reward for a user to the desired address, on all the assets of the pool, accumulating the pending rewards * @param assets List of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param to The address that will be receiving the rewards * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to, address reward ) external returns (uint256); /** * @dev Claims reward for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The * caller must be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param assets The list of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param user The address to check and claim rewards * @param to The address that will be receiving the rewards * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to, address reward ) external returns (uint256); /** * @dev Claims reward for msg.sender, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewardsToSelf( address[] calldata assets, uint256 amount, address reward ) external returns (uint256); /** * @dev Claims all rewards for a user to the desired address, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @param to The address that will be receiving the rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardList" **/ function claimAllRewards( address[] calldata assets, address to ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); /** * @dev Claims all rewards for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param assets The list of assets to check eligible distributions before claiming rewards * @param user The address to check and claim rewards * @param to The address that will be receiving the rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList" **/ function claimAllRewardsOnBehalf( address[] calldata assets, address user, address to ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); /** * @dev Claims all reward for msg.sender, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList" **/ function claimAllRewardsToSelf( address[] calldata assets ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /** * @title IRewardsDistributor * @author Aave * @notice Defines the basic interface for a Rewards Distributor. */ interface IRewardsDistributor { /** * @dev Emitted when the configuration of the rewards of an asset is updated. * @param asset The address of the incentivized asset * @param reward The address of the reward token * @param oldEmission The old emissions per second value of the reward distribution * @param newEmission The new emissions per second value of the reward distribution * @param oldDistributionEnd The old end timestamp of the reward distribution * @param newDistributionEnd The new end timestamp of the reward distribution * @param assetIndex The index of the asset distribution */ event AssetConfigUpdated( address indexed asset, address indexed reward, uint256 oldEmission, uint256 newEmission, uint256 oldDistributionEnd, uint256 newDistributionEnd, uint256 assetIndex ); /** * @dev Emitted when rewards of an asset are accrued on behalf of a user. * @param asset The address of the incentivized asset * @param reward The address of the reward token * @param user The address of the user that rewards are accrued on behalf of * @param assetIndex The index of the asset distribution * @param userIndex The index of the asset distribution on behalf of the user * @param rewardsAccrued The amount of rewards accrued */ event Accrued( address indexed asset, address indexed reward, address indexed user, uint256 assetIndex, uint256 userIndex, uint256 rewardsAccrued ); /** * @dev Sets the end date for the distribution * @param asset The asset to incentivize * @param reward The reward token that incentives the asset * @param newDistributionEnd The end date of the incentivization, in unix time format **/ function setDistributionEnd(address asset, address reward, uint32 newDistributionEnd) external; /** * @dev Sets the emission per second of a set of reward distributions * @param asset The asset is being incentivized * @param rewards List of reward addresses are being distributed * @param newEmissionsPerSecond List of new reward emissions per second */ function setEmissionPerSecond( address asset, address[] calldata rewards, uint88[] calldata newEmissionsPerSecond ) external; /** * @dev Gets the end date for the distribution * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The timestamp with the end of the distribution, in unix time format **/ function getDistributionEnd(address asset, address reward) external view returns (uint256); /** * @dev Returns the index of a user on a reward distribution * @param user Address of the user * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The current user asset index, not including new distributions **/ function getUserAssetIndex( address user, address asset, address reward ) external view returns (uint256); /** * @dev Returns the configuration of the distribution reward for a certain asset * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The index of the asset distribution * @return The emission per second of the reward distribution * @return The timestamp of the last update of the index * @return The timestamp of the distribution end **/ function getRewardsData( address asset, address reward ) external view returns (uint256, uint256, uint256, uint256); /** * @dev Calculates the next value of an specific distribution index, with validations. * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The old index of the asset distribution * @return The new index of the asset distribution **/ function getAssetIndex(address asset, address reward) external view returns (uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset * @param asset The incentivized asset * @return List of rewards addresses of the input asset **/ function getRewardsByAsset(address asset) external view returns (address[] memory); /** * @dev Returns the list of available reward addresses * @return List of rewards supported in this contract **/ function getRewardsList() external view returns (address[] memory); /** * @dev Returns the accrued rewards balance of a user, not including virtually accrued rewards since last distribution. * @param user The address of the user * @param reward The address of the reward token * @return Unclaimed rewards, not including new distributions **/ function getUserAccruedRewards(address user, address reward) external view returns (uint256); /** * @dev Returns a single rewards balance of a user, including virtually accrued and unrealized claimable rewards. * @param assets List of incentivized assets to check eligible distributions * @param user The address of the user * @param reward The address of the reward token * @return The rewards amount **/ function getUserRewards( address[] calldata assets, address user, address reward ) external view returns (uint256); /** * @dev Returns a list all rewards of a user, including already accrued and unrealized claimable rewards * @param assets List of incentivized assets to check eligible distributions * @param user The address of the user * @return The list of reward addresses * @return The list of unclaimed amount of rewards **/ function getAllUserRewards( address[] calldata assets, address user ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta * @param asset The address to retrieve decimals * @return The decimals of an underlying asset */ function getAssetDecimals(address asset) external view returns (uint8); /** * @dev Returns the address of the emission manager * @return The address of the EmissionManager */ function EMISSION_MANAGER() external view returns (address); /** * @dev Returns the address of the emission manager. * Deprecated: This getter is maintained for compatibility purposes. Use the `EMISSION_MANAGER()` function instead. * @return The address of the EmissionManager */ function getEmissionManager() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface ITransferStrategyBase { event EmergencyWithdrawal( address indexed caller, address indexed token, address indexed to, uint256 amount ); /** * @dev Perform custom transfer logic via delegate call from source contract to a TransferStrategy implementation * @param to Account to transfer rewards * @param reward Address of the reward token * @param amount Amount to transfer to the "to" address parameter * @return Returns true bool if transfer logic succeeds */ function performTransfer(address to, address reward, uint256 amount) external returns (bool); /** * @return Returns the address of the Incentives Controller */ function getIncentivesController() external view returns (address); /** * @return Returns the address of the Rewards admin */ function getRewardsAdmin() external view returns (address); /** * @dev Perform an emergency token withdrawal only callable by the Rewards admin * @param token Address of the token to withdraw funds from this contract * @param to Address of the recipient of the withdrawal * @param amount Amount of the withdrawal */ function emergencyWithdrawal(address token, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {AggregatorInterface} from '../../dependencies/chainlink/AggregatorInterface.sol'; library RewardsDataTypes { struct RewardsConfigInput { uint88 emissionPerSecond; uint256 totalSupply; uint32 distributionEnd; address asset; address reward; ITransferStrategyBase transferStrategy; AggregatorInterface rewardOracle; } struct UserAssetBalance { address asset; uint256 userBalance; uint256 totalSupply; } struct UserData { // Liquidity index of the reward distribution for the user uint104 index; // Amount of accrued rewards for the user since last user index update uint128 accrued; } struct RewardData { // Liquidity index of the reward distribution uint104 index; // Amount of reward tokens distributed per second uint88 emissionPerSecond; // Timestamp of the last reward index update uint32 lastUpdateTimestamp; // The end of the distribution of rewards (in seconds) uint32 distributionEnd; // Map of user addresses and their rewards data (userAddress => userData) mapping(address => UserData) usersData; } struct AssetData { // Map of reward token addresses and their data (rewardTokenAddress => rewardData) mapping(address => RewardData) rewards; // List of reward token addresses for the asset mapping(uint128 => address) availableRewards; // Count of reward tokens for the asset uint128 availableRewardsCount; // Number of decimals of the asset uint8 decimals; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {WalletBalanceProvider} from '../../../contracts/helpers/WalletBalanceProvider.sol'; import {UiPoolDataProviderV3} from '../../../contracts/helpers/UiPoolDataProviderV3.sol'; import {UiIncentiveDataProviderV3} from '../../../contracts/helpers/UiIncentiveDataProviderV3.sol'; import {AggregatorInterface} from '../../../contracts/dependencies/chainlink/AggregatorInterface.sol'; import {AaveProtocolDataProvider} from '../../../contracts/helpers/AaveProtocolDataProvider.sol'; import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; contract AaveV3GettersProcedureOne { struct GettersReportBatchOne { address walletBalanceProvider; address uiIncentiveDataProvider; address protocolDataProvider; address uiPoolDataProvider; } function _deployAaveV3GettersBatchOne( address poolAddressesProvider, address networkBaseTokenPriceInUsdProxyAggregator, address marketReferenceCurrencyPriceInUsdProxyAggregator ) internal returns (GettersReportBatchOne memory) { GettersReportBatchOne memory report; report.walletBalanceProvider = address(new WalletBalanceProvider()); report.uiIncentiveDataProvider = address(new UiIncentiveDataProviderV3()); report.protocolDataProvider = address( new AaveProtocolDataProvider(IPoolAddressesProvider(poolAddressesProvider)) ); if ( networkBaseTokenPriceInUsdProxyAggregator != address(0) && marketReferenceCurrencyPriceInUsdProxyAggregator != address(0) ) { report.uiPoolDataProvider = address( new UiPoolDataProviderV3( AggregatorInterface(networkBaseTokenPriceInUsdProxyAggregator), AggregatorInterface(marketReferenceCurrencyPriceInUsdProxyAggregator) ) ); } return report; } }
{ "remappings": [ "solidity-utils/=lib/solidity-utils/src/", "forge-std/=lib/forge-std/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "openzeppelin-contracts-upgradeable/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/", "@openzeppelin/contracts-upgradeable/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "erc4626-tests/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "halmos-cheatcodes/=lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": false, "libraries": { "src/contracts/protocol/libraries/logic/BorrowLogic.sol": { "BorrowLogic": "0x62325c94E1c49dcDb5937726aB5D8A4c37bCAd36" }, "src/contracts/protocol/libraries/logic/BridgeLogic.sol": { "BridgeLogic": "0x621Ef86D8A5C693a06295BC288B95C12D4CE4994" }, "src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol": { "ConfiguratorLogic": "0x09e88e877B39D883BAFd46b65E7B06CC56963041" }, "src/contracts/protocol/libraries/logic/EModeLogic.sol": { "EModeLogic": "0xC31d2362fAeD85dF79d0bec99693D0EB0Abd3f74" }, "src/contracts/protocol/libraries/logic/FlashLoanLogic.sol": { "FlashLoanLogic": "0x34039100cc9584Ae5D741d322e16d0d18CEE8770" }, "src/contracts/protocol/libraries/logic/LiquidationLogic.sol": { "LiquidationLogic": "0x4731bF01583F991278692E8727d0700a00A1fBBf" }, "src/contracts/protocol/libraries/logic/PoolLogic.sol": { "PoolLogic": "0xf8C97539934ee66a67C26010e8e027D77E821B0C" }, "src/contracts/protocol/libraries/logic/SupplyLogic.sol": { "SupplyLogic": "0x185477906B46D9b8DE0DEB73A1bBfb87b5b51BC3" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"poolAddressesProvider","type":"address"},{"internalType":"address","name":"networkBaseTokenPriceInUsdProxyAggregator","type":"address"},{"internalType":"address","name":"marketReferenceCurrencyPriceInUsdProxyAggregator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"getGettersReportOne","outputs":[{"components":[{"internalType":"address","name":"walletBalanceProvider","type":"address"},{"internalType":"address","name":"uiIncentiveDataProvider","type":"address"},{"internalType":"address","name":"protocolDataProvider","type":"address"},{"internalType":"address","name":"uiPoolDataProvider","type":"address"}],"internalType":"struct AaveV3GettersProcedureOne.GettersReportBatchOne","name":"","type":"tuple"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561000f575f80fd5b50604051617fa3380380617fa383398101604081905261002e9161024b565b61003983838361009c565b80515f80546001600160a01b03199081166001600160a01b0393841617909155602083015160018054831691841691909117905560408301516002805483169184169190911790556060909201516003805490931691161790555061028b915050565b60408051608080820183525f808352602080840182905283850182905260608085018390528551938401865282845290830182905282850182905282015291519091906100e8906101fc565b604051809103905ff080158015610101573d5f803e3d5ffd5b506001600160a01b0316815260405161011990610209565b604051809103905ff080158015610132573d5f803e3d5ffd5b506001600160a01b03166020820152604051859061014f90610216565b6001600160a01b039091168152602001604051809103905ff080158015610178573d5f803e3d5ffd5b506001600160a01b0390811660408301528416158015906101a157506001600160a01b03831615155b156101f45783836040516101b490610223565b6001600160a01b03928316815291166020820152604001604051809103905ff0801580156101e4573d5f803e3d5ffd5b506001600160a01b031660608201525b949350505050565b610a1a8061037c83390190565b61237380610d9683390190565b6126b58061310983390190565b6127e5806157be83390190565b80516001600160a01b0381168114610246575f80fd5b919050565b5f805f6060848603121561025d575f80fd5b61026684610230565b925061027460208501610230565b915061028260408501610230565b90509250925092565b60e5806102975f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80630cf19f2c14602a575b5f80fd5b608d604080516080810182525f80825260208201819052918101829052606081019190915250604080516080810182525f546001600160a01b03908116825260015481166020830152600254811692820192909252600354909116606082015290565b60405160cf919081516001600160a01b039081168252602080840151821690830152604080840151821690830152606092830151169181019190915260800190565b60405180910390f3fea164736f6c6343000816000a608060405234801561000f575f80fd5b506109fd8061001d5f395ff3fe608060405260043610610036575f3560e01c80630240534314610079578063b59b28ef146100af578063f7888aec146100db575f80fd5b3661007557333b6100735760405162461bcd60e51b8152602060048201526002602482015261191960f11b60448201526064015b60405180910390fd5b005b5f80fd5b348015610084575f80fd5b5061009861009336600461068d565b610108565b6040516100a69291906106fe565b60405180910390f35b3480156100ba575f80fd5b506100ce6100c936600461079f565b610480565b6040516100a69190610806565b3480156100e6575f80fd5b506100fa6100f536600461068d565b610582565b6040519081526020016100a6565b6060805f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610148573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061016c919061081f565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156101aa573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101d1919081019061087f565b90505f815160016101e29190610940565b67ffffffffffffffff8111156101fa576101fa61083a565b604051908082528060200260200182016040528015610223578160200160208202803683370190505b5090505f5b825181101561027d5782818151811061024357610243610953565b602002602001015182828151811061025d5761025d610953565b6001600160a01b0390921660209283029190910190910152600101610228565b5073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee818351815181106102a6576102a6610953565b60200260200101906001600160a01b031690816001600160a01b0316815250505f815167ffffffffffffffff8111156102e1576102e161083a565b60405190808252806020026020018201604052801561030a578160200160208202803683370190505b5090505f5b8351811015610434575f856001600160a01b031663c44b11f785848151811061033a5761033a610953565b60200260200101516040518263ffffffff1660e01b815260040161036d91906001600160a01b0391909116815260200190565b602060405180830381865afa158015610388573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ac9190610967565b8051909150670100000000000000161515806103e8575f8484815181106103d5576103d5610953565b602002602001018181525050505061042c565b61040b8a8685815181106103fe576103fe610953565b6020026020010151610582565b84848151811061041d5761041d610953565b60200260200101818152505050505b60010161030f565b506104538773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee610582565b8184518151811061046657610466610953565b6020908102919091010152909450925050505b9250929050565b60605f61048d83866109a7565b67ffffffffffffffff8111156104a5576104a561083a565b6040519080825280602002602001820160405280156104ce578160200160208202803683370190505b5090505f5b85811015610578575f5b8481101561056f576105368888848181106104fa576104fa610953565b905060200201602081019061050f91906109be565b87878481811061052157610521610953565b90506020020160208101906100f591906109be565b838261054288866109a7565b61054c9190610940565b8151811061055c5761055c610953565b60209081029190910101526001016104dd565b506001016104d3565b5095945050505050565b5f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038316016105b957506001600160a01b03821631610670565b6001600160a01b0382163b15610638576040516370a0823160e01b81526001600160a01b0384811660048301528316906370a0823190602401602060405180830381865afa15801561060d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061063191906109d9565b9050610670565b60405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015260640161006a565b92915050565b6001600160a01b038116811461068a575f80fd5b50565b5f806040838503121561069e575f80fd5b82356106a981610676565b915060208301356106b981610676565b809150509250929050565b5f815180845260208085019450602084015f5b838110156106f3578151875295820195908201906001016106d7565b509495945050505050565b604080825283519082018190525f906020906060840190828701845b8281101561073f5781516001600160a01b03168452928401929084019060010161071a565b505050838103602085015261075481866106c4565b9695505050505050565b5f8083601f84011261076e575f80fd5b50813567ffffffffffffffff811115610785575f80fd5b6020830191508360208260051b8501011115610479575f80fd5b5f805f80604085870312156107b2575f80fd5b843567ffffffffffffffff808211156107c9575f80fd5b6107d58883890161075e565b909650945060208701359150808211156107ed575f80fd5b506107fa8782880161075e565b95989497509550505050565b602081525f61081860208301846106c4565b9392505050565b5f6020828403121561082f575f80fd5b815161081881610676565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156108775761087761083a565b604052919050565b5f6020808385031215610890575f80fd5b825167ffffffffffffffff808211156108a7575f80fd5b818501915085601f8301126108ba575f80fd5b8151818111156108cc576108cc61083a565b8060051b91506108dd84830161084e565b81815291830184019184810190888411156108f6575f80fd5b938501935b83851015610920578451925061091083610676565b82825293850193908501906108fb565b98975050505050505050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156106705761067061092c565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610977575f80fd5b6040516020810181811067ffffffffffffffff8211171561099a5761099a61083a565b6040529151825250919050565b80820281158282048414176106705761067061092c565b5f602082840312156109ce575f80fd5b813561081881610676565b5f602082840312156109e9575f80fd5b505191905056fea164736f6c6343000816000a608060405234801561000f575f80fd5b506123568061001d5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c80634763753614610043578063799bdcf51461006d578063976fafc51461008d575b5f80fd5b610056610051366004611b49565b6100ad565b604051610064929190611eed565b60405180910390f35b61008061007b366004611b49565b6100ce565b6040516100649190611f1a565b6100a061009b366004611f2c565b6100e1565b6040516100649190611f47565b6060806100b9846100f2565b6100c38585610d50565b915091509250929050565b60606100da8383610d50565b9392505050565b60606100ec826100f2565b92915050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610131573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101559190611f69565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610193573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101ba9190810190611ff3565b90505f815167ffffffffffffffff8111156101d7576101d7611f84565b60405190808252806020026020018201604052801561021057816020015b6101fd611a0b565b8152602001906001900390816101f55790505b5090505f5b8251811015610d47575f828281518110610231576102316120a0565b6020026020010151905083828151811061024d5761024d6120a0565b6020026020010151815f01906001600160a01b031690816001600160a01b0316815250505f856001600160a01b03166335ea6a75868581518110610293576102936120a0565b60200260200101516040518263ffffffff1660e01b81526004016102c691906001600160a01b0391909116815260200190565b6101e060405180830381865afa1580156102e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103069190612138565b90505f8161010001516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561034a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061036e9190611f69565b905060606001600160a01b038216156107ec57610100830151604051636657732f60e01b81526001600160a01b0391821660048201525f91841690636657732f906024015f60405180830381865afa1580156103cc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526103f39190810190611ff3565b9050805167ffffffffffffffff81111561040f5761040f611f84565b60405190808252806020026020018201604052801561044857816020015b610435611a71565b81526020019060019003908161042d5790505b5091505f5b81518110156107e95761045e611a71565b828281518110610470576104706120a0565b6020908102919091018101516001600160a01b03908116918301829052610100880151604051630fdfe97560e31b815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190612259565b60c08501526080840152606083015260a0820152610100860151604051634f7eb7b960e11b81526001600160a01b03918216600482015290861690639efd6f7290602401602060405180830381865afa15801561055a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061057e919061228c565b60ff166101208201526020808201516040805163313ce56760e01b815290516001600160a01b039092169263313ce567926004808401938290030181865afa1580156105cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f0919061228c565b81610100019060ff16908160ff168152505080602001516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610641573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261066891908101906122ac565b81526020810151604051630150bdfb60e51b81526001600160a01b03918216600482015290861690632a17bf6090602401602060405180830381865afa1580156106b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106d89190611f69565b6001600160a01b03166040808301829052805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa158015610720573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610744919061228c565b81610140019060ff16908160ff168152505080604001516001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610796573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ba9190612332565b60e0820152835181908590849081106107d5576107d56120a0565b60209081029190910101525060010161044d565b50505b60405180606001604052808461010001516001600160a01b03168152602001836001600160a01b031681526020018281525084602001819052505f8361014001516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015610868573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061088c9190611f69565b905060606001600160a01b03821615610d0a57610140850151604051636657732f60e01b81526001600160a01b0391821660048201525f91841690636657732f906024015f60405180830381865afa1580156108ea573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109119190810190611ff3565b9050805167ffffffffffffffff81111561092d5761092d611f84565b60405190808252806020026020018201604052801561096657816020015b610953611a71565b81526020019060019003908161094b5790505b5091505f5b8151811015610d075761097c611a71565b82828151811061098e5761098e6120a0565b6020908102919091018101516001600160a01b039081169183018290526101408a0151604051630fdfe97560e31b815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa1580156109f5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a199190612259565b60c08501526080840152606083015260a0820152610140880151604051634f7eb7b960e11b81526001600160a01b03918216600482015290861690639efd6f7290602401602060405180830381865afa158015610a78573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9c919061228c565b60ff166101208201526020808201516040805163313ce56760e01b815290516001600160a01b039092169263313ce567926004808401938290030181865afa158015610aea573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0e919061228c565b81610100019060ff16908160ff168152505080602001516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b5f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b8691908101906122ac565b81526020810151604051630150bdfb60e51b81526001600160a01b03918216600482015290861690632a17bf6090602401602060405180830381865afa158015610bd2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf69190611f69565b6001600160a01b03166040808301829052805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa158015610c3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c62919061228c565b81610140019060ff16908160ff168152505080604001516001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cb4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cd89190612332565b60e082015283518190859084908110610cf357610cf36120a0565b60209081029190910101525060010161096b565b50505b60408051606081018252610140909601516001600160a01b0390811687529290921660208601528482015293909301919091525050600101610215565b50949350505050565b60605f836001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db39190611f69565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610df1573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e189190810190611ff3565b90505f6001600160a01b038516610e2f575f610e32565b81515b67ffffffffffffffff811115610e4a57610e4a611f84565b604051908082528060200260200182016040528015610e8357816020015b610e70611a0b565b815260200190600190039081610e685790505b5090505f5b8251811015611a01575f846001600160a01b03166335ea6a75858481518110610eb357610eb36120a0565b60200260200101516040518263ffffffff1660e01b8152600401610ee691906001600160a01b0391909116815260200190565b6101e060405180830381865afa158015610f02573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f269190612138565b9050838281518110610f3a57610f3a6120a0565b6020026020010151838381518110610f5457610f546120a0565b60200260200101515f01906001600160a01b031690816001600160a01b0316815250505f8161010001516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fdd9190611f69565b90506001600160a01b038116156114a357610100820151604051636657732f60e01b81526001600160a01b0391821660048201525f91831690636657732f906024015f60405180830381865afa158015611039573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526110609190810190611ff3565b90505f815167ffffffffffffffff81111561107d5761107d611f84565b6040519080825280602002602001820160405280156110b657816020015b6110a3611adc565b81526020019060019003908161109b5790505b5090505f5b825181101561144c576110cc611adc565b8382815181106110de576110de6120a0565b60209081029190910101516001600160a01b039081166040808401829052610100890151905163299faa1560e11b81528f84166004820152908316602482015260448101919091529086169063533f542a90606401602060405180830381865afa15801561114e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111729190612332565b60808201526040808201519051632c08906360e21b81526001600160a01b038e8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa1580156111c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ed9190612332565b81606001818152505080604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611236573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125a919061228c565b8160e0019060ff16908160ff168152505080604001516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156112aa573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526112d191908101906122ac565b81526040808201519051630150bdfb60e51b81526001600160a01b03918216600482015290861690632a17bf6090602401602060405180830381865afa15801561131d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113419190611f69565b6001600160a01b031660208083018290526040805163313ce56760e01b8152905163313ce567926004808401939192918290030181865afa158015611388573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113ac919061228c565b60ff1660c0820152602080820151604080516350d25bcd60e01b815290516001600160a01b03909216926350d25bcd926004808401938290030181865afa1580156113f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061141d9190612332565b60a082015282518190849084908110611438576114386120a0565b6020908102919091010152506001016110bb565b5060405180606001604052808561010001516001600160a01b03168152602001846001600160a01b0316815260200182815250868681518110611491576114916120a0565b60200260200101516020018190525050505b5f8261014001516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115099190611f69565b90506001600160a01b038116156119f657610140830151604051636657732f60e01b81526001600160a01b0391821660048201525f91831690636657732f906024015f60405180830381865afa158015611565573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261158c9190810190611ff3565b90505f815167ffffffffffffffff8111156115a9576115a9611f84565b6040519080825280602002602001820160405280156115e257816020015b6115cf611adc565b8152602001906001900390816115c75790505b5090505f5b825181101561199f576115f8611adc565b83828151811061160a5761160a6120a0565b602002602001015181604001906001600160a01b031690816001600160a01b031681525050846001600160a01b031663533f542a8e89610140015184604001516040518463ffffffff1660e01b8152600401611686939291906001600160a01b0393841681529183166020830152909116604082015260600190565b602060405180830381865afa1580156116a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c59190612332565b60808201526040808201519051632c08906360e21b81526001600160a01b038f8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa15801561171c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117409190612332565b81606001818152505080604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611789573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117ad919061228c565b8160e0019060ff16908160ff168152505080604001516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156117fd573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261182491908101906122ac565b81526040808201519051630150bdfb60e51b81526001600160a01b03918216600482015290861690632a17bf6090602401602060405180830381865afa158015611870573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118949190611f69565b6001600160a01b031660208083018290526040805163313ce56760e01b8152905163313ce567926004808401939192918290030181865afa1580156118db573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ff919061228c565b60ff1660c0820152602080820151604080516350d25bcd60e01b815290516001600160a01b03909216926350d25bcd926004808401938290030181865afa15801561194c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119709190612332565b60a08201528251819084908490811061198b5761198b6120a0565b6020908102919091010152506001016115e7565b5060405180606001604052808661014001516001600160a01b03168152602001856001600160a01b03168152602001828152508787815181106119e4576119e46120a0565b60200260200101516040018190525050505b505050600101610e88565b5095945050505050565b60405180606001604052805f6001600160a01b03168152602001611a4660408051606080820183525f80835260208301529181019190915290565b8152602001611a6c60408051606080820183525f80835260208301529181019190915290565b905290565b604051806101600160405280606081526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f60ff1681526020015f60ff1681526020015f60ff1681525090565b604051806101000160405280606081526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f60ff1681526020015f60ff1681525090565b6001600160a01b0381168114611b46575f80fd5b50565b5f8060408385031215611b5a575f80fd5b8235611b6581611b32565b91506020830135611b7581611b32565b809150509250929050565b5f5b83811015611b9a578181015183820152602001611b82565b50505f910152565b5f8151808452611bb9816020860160208601611b80565b601f01601f19169290920160200192915050565b5f606080840160018060a01b03808551168652602081818701511681880152604091506040860151606060408901528381518086526080955060808a01915060808160051b8b010184840193505f5b82811015611cdb57607f198c830301845284516101608151818552611c4382860182611ba2565b91505087820151611c5e898601826001600160a01b03169052565b50888201516001600160a01b0316848a01528a8201518b850152898201518a85015260a0808301519085015260c0808301519085015260e080830151908501526101008083015160ff9081169186019190915261012080840151821690860152610140928301511691909301529385019392850192600101611c1c565b509a9950505050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611d6f57858303601f19018952815180516001600160a01b0316845284810151606086860181905290611d3e82870182611bcd565b91505060408083015192508582038187015250611d5b8183611bcd565b9a86019a9450505090830190600101611d05565b5090979650505050505050565b5f606080840160018060a01b03808551168652602081818701511681880152604080870151606060408a01528481518087526080965060808b01915060808160051b8c010185840193505f5b82811015611e5857607f198d830301845284516101008151818552611def82860182611ba2565b91505089898301511689850152898883015116888501528b8201518c8501528a8201518b85015260a080830151818601525060c080830151611e358287018260ff169052565b505060e09182015160ff1693909101929092529386019392860192600101611dc8565b509b9a5050505050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611d6f57858303601f19018952815180516001600160a01b0316845284810151606086860181905290611ebc82870182611d7c565b91505060408083015192508582038187015250611ed98183611d7c565b9a86019a9450505090830190600101611e83565b604081525f611eff6040830185611cea565b8281036020840152611f118185611e68565b95945050505050565b602081525f6100da6020830184611e68565b5f60208284031215611f3c575f80fd5b81356100da81611b32565b602081525f6100da6020830184611cea565b8051611f6481611b32565b919050565b5f60208284031215611f79575f80fd5b81516100da81611b32565b634e487b7160e01b5f52604160045260245ffd5b6040516101e0810167ffffffffffffffff81118282101715611fbc57611fbc611f84565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611feb57611feb611f84565b604052919050565b5f6020808385031215612004575f80fd5b825167ffffffffffffffff8082111561201b575f80fd5b818501915085601f83011261202e575f80fd5b81518181111561204057612040611f84565b8060051b9150612051848301611fc2565b818152918301840191848101908884111561206a575f80fd5b938501935b83851015612094578451925061208483611b32565b828252938501939085019061206f565b98975050505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156120c4575f80fd5b6040516020810181811067ffffffffffffffff821117156120e7576120e7611f84565b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff81168114611f64575f80fd5b805164ffffffffff81168114611f64575f80fd5b805161ffff81168114611f64575f80fd5b5f6101e08284031215612149575f80fd5b612151611f98565b61215b84846120b4565b8152612169602084016120f4565b602082015261217a604084016120f4565b604082015261218b606084016120f4565b606082015261219c608084016120f4565b60808201526121ad60a084016120f4565b60a08201526121be60c08401612113565b60c08201526121cf60e08401612127565b60e08201526101006121e2818501611f59565b908201526101206121f4848201611f59565b90820152610140612206848201611f59565b90820152610160612218848201611f59565b9082015261018061222a8482016120f4565b908201526101a061223c8482016120f4565b908201526101c061224e8482016120f4565b908201529392505050565b5f805f806080858703121561226c575f80fd5b505082516020840151604085015160609095015191969095509092509050565b5f6020828403121561229c575f80fd5b815160ff811681146100da575f80fd5b5f602082840312156122bc575f80fd5b815167ffffffffffffffff808211156122d3575f80fd5b818401915084601f8301126122e6575f80fd5b8151818111156122f8576122f8611f84565b61230b601f8201601f1916602001611fc2565b9150808252856020828501011115612321575f80fd5b610d47816020840160208601611b80565b5f60208284031215612342575f80fd5b505191905056fea164736f6c6343000816000a60a060405234801562000010575f80fd5b50604051620026b5380380620026b5833981016040819052620000339162000045565b6001600160a01b031660805262000074565b5f6020828403121562000056575f80fd5b81516001600160a01b03811681146200006d575f80fd5b9392505050565b60805161259c620001195f395f818161013b0152818161044b01528181610539015281816107cd01528181610a2f01528181610b3101528181610c3101528181610d9e01528181610ead01528181611003015281816110b5015281816111ad015281816112aa015281816113a50152818161171b0152818161183f0152818161192d01528181611a9401528181611b9701528181611e290152611f29015261259c5ff3fe608060405234801561000f575f80fd5b5060043610610132575f3560e01c806369b169e1116100b4578063c952485d11610079578063c952485d146103ae578063d2493b6c146103c1578063d7ed3ef4146103fe578063f561ae4114610411578063f7e1430714610419578063fcf40a621461042c575f80fd5b806369b169e1146103495780636fb07f96146103505780637ba1ae3614610363578063b316ff8914610376578063b55d99041461038b575f80fd5b80633e150141116100fa5780633e1501411461028157806346fbe558146102e85780634d44ac4f1461031057806351460e25146103235780636744362a14610336575f80fd5b80630542975c1461013657806328dd2d011461017a57806335ea6a75146101da5780633c7981091461024d5780633cb8a6221461026e575b5f80fd5b61015d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61018d61018836600461208f565b61043f565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015264ffffffffff1660e0830152151561010082015261012001610171565b6101ed6101e83660046120c6565b6107be565b604080519c8d5260208d019b909b52998b019890985260608a0196909652608089019490945260a088019290925260c087015260e086015261010085015261012084015261014083015264ffffffffff1661016082015261018001610171565b61026061025b3660046120c6565b610a29565b604051908152602001610171565b61026061027c3660046120c6565b610b2b565b61029461028f3660046120c6565b610c24565b604080519a8b5260208b01999099529789019690965260608801949094526080870192909252151560a0860152151560c0850152151560e08401521515610100830152151561012082015261014001610171565b6102fb6102f63660046120c6565b610d97565b60408051928352602083019190915201610171565b61026061031e3660046120c6565b610ea9565b6102606103313660046120c6565b610fff565b61015d6103443660046120c6565b6110b1565b6002610260565b61026061035e3660046120c6565b6111aa565b6102606103713660046120c6565b6112a4565b61037e6113a0565b604051610171919061212e565b61039e6103993660046120c6565b611715565b6040519015158152602001610171565b6102606103bc3660046120c6565b61183c565b6103d46103cf3660046120c6565b611927565b604080516001600160a01b0394851681529284166020840152921691810191909152606001610171565b61039e61040c3660046120c6565b611a90565b61037e611b92565b61039e6104273660046120c6565b611e25565b61039e61043a3660046120c6565b611f23565b5f805f805f805f805f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104c991906121bd565b6040516335ea6a7560e01b81526001600160a01b038e8116600483015291909116906335ea6a75906024016101e060405180830381865afa158015610510573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053491906122c2565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610593573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105b791906121bd565b604051634417a58360e01b81526001600160a01b038e811660048301529190911690634417a58390602401602060405180830381865afa1580156105fd573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062191906123e3565b6101008301516040516370a0823160e01b81526001600160a01b038f811660048301529293509116906370a0823190602401602060405180830381865afa15801561066e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069291906123fd565b6101408301516040516370a0823160e01b81526001600160a01b038f81166004830152929d509116906370a0823190602401602060405180830381865afa1580156106df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061070391906123fd565b610140830151604051630ed1279f60e11b81526001600160a01b038f811660048301525f9d50929b508c9a508a9850889650911690631da24f3e90602401602060405180830381865afa15801561075c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061078091906123fd565b965081604001516001600160801b031694506107ad8260e0015161ffff168261202190919063ffffffff16565b925050509295985092959850929598565b5f805f805f805f805f805f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610827573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084b91906121bd565b6001600160a01b03166335ea6a758f6040518263ffffffff1660e01b815260040161088591906001600160a01b0391909116815260200190565b6101e060405180830381865afa1580156108a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108c591906122c2565b9050806101a001518161018001518261010001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610914573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061093891906123fd565b5f8461014001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561097a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061099e91906123fd565b856040015186608001515f8089602001518a606001518b60c001518b6001600160801b03169b508a6001600160801b03169a50866001600160801b03169650856001600160801b03169550826001600160801b03169250816001600160801b031691509c509c509c509c509c509c509c509c509c509c509c509c505091939597999b5091939597999b565b5f610b257f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a89573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aad91906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa158015610af3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b1791906123e3565b5160d41c64ffffffffff1690565b92915050565b5f610b257f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610baf91906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa158015610bf5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c1991906123e3565b5160981c61ffff1690565b5f805f805f805f805f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c8b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610caf91906121bd565b60405163c44b11f760e01b81526001600160a01b038e81166004830152919091169063c44b11f790602401602060405180830381865afa158015610cf5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1991906123e3565b9050610d4a815161ffff80821692601083901c821692602081901c831692603082901c60ff169260409290921c1690565b8551919f50939d50919b509950909750600160381b8116151590600160391b81161515906001603a1b8116151590509c9e9b9d50999b989a97998c151599985f9850919650945092505050565b5f80610e9f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1c91906121bd565b60405163c44b11f760e01b81526001600160a01b038681166004830152919091169063c44b11f790602401602060405180830381865afa158015610e62573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e8691906123e3565b51640fffffffff605082901c81169260749290921c1690565b9094909350915050565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2b91906121bd565b6040516301b2848560e51b81526001600160a01b038581166004830152919091169063365090a0906024015b602060405180830381865afa158015610f72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f9691906121bd565b9050806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff891906123fd565b9392505050565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561105d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061108191906121bd565b60405163cff027d960e01b81526001600160a01b038581166004830152919091169063cff027d990602401610f57565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561110f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113391906121bd565b6040516335ea6a7560e01b81526001600160a01b03858116600483015291909116906335ea6a75906024016101e060405180830381865afa15801561117a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061119e91906122c2565b61016001519392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611207573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122b91906121bd565b6040516337d83fcb60e11b81526001600160a01b0384811660048301529190911690636fb07f9690602401602060405180830381865afa158015611271573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112959190612414565b6001600160801b031692915050565b5f610b257f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611304573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132891906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa15801561136e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061139291906123e3565b5160b01c640fffffffff1690565b60605f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113ff573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061142391906121bd565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015611461573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611488919081019061242d565b90505f815167ffffffffffffffff8111156114a5576114a56121d8565b6040519080825280602002602001820160405280156114ea57816020015b60408051808201909152606081525f60208201528152602001906001900390816114c35790505b5090505f5b825181101561170d57739f8f72aa9304c8b593d555f12ef6589cc3a579a26001600160a01b0316838281518110611528576115286124da565b60200260200101516001600160a01b0316036115b25760405180604001604052806040518060400160405280600381526020016226a5a960e91b815250815260200184838151811061157c5761157c6124da565b60200260200101516001600160a01b03168152508282815181106115a2576115a26124da565b6020026020010181905250611705565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03168382815181106115e2576115e26124da565b60200260200101516001600160a01b0316036116365760405180604001604052806040518060400160405280600381526020016208aa8960eb1b815250815260200184838151811061157c5761157c6124da565b6040518060400160405280848381518110611653576116536124da565b60200260200101516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611695573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526116bc91908101906124ee565b81526020018483815181106116d3576116d36124da565b60200260200101516001600160a01b03168152508282815181106116f9576116f96124da565b60200260200101819052505b6001016114ef565b509392505050565b5f6118337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611775573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061179991906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa1580156117df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061180391906123e3565b51600160381b8116151591600160391b82161515916001603a1b8116151591671000000000000000909116151590565b95945050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611899573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118bd91906121bd565b60405163c952485d60e01b81526001600160a01b038481166004830152919091169063c952485d90602401602060405180830381865afa158015611903573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2591906123fd565b5f805f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ab91906121bd565b60405163cff027d960e01b81526001600160a01b0387811660048301529192509082169063cff027d990602401602060405180830381865afa1580156119f3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1791906121bd565b6040516301b2848560e51b81526001600160a01b0387811660048301525f919084169063365090a090602401602060405180830381865afa158015611a5e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a8291906121bd565b935093509350509193909250565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aee573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b1291906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa158015611b58573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b7c91906123e3565b9050610ff8815167800000000000000016151590565b60605f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bf1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c1591906121bd565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015611c53573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c7a919081019061242d565b90505f815167ffffffffffffffff811115611c9757611c976121d8565b604051908082528060200260200182016040528015611cdc57816020015b60408051808201909152606081525f6020820152815260200190600190039081611cb55790505b5090505f5b825181101561170d575f846001600160a01b031663cff027d9858481518110611d0c57611d0c6124da565b60200260200101516040518263ffffffff1660e01b8152600401611d3f91906001600160a01b0391909116815260200190565b602060405180830381865afa158015611d5a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d7e91906121bd565b90506040518060400160405280826001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611dc6573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611ded91908101906124ee565b8152602001826001600160a01b0316815250838381518110611e1157611e116124da565b602090810291909101015250600101611ce1565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ea791906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa158015611eed573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f1191906123e3565b9050610ff88151600160fc1b16151590565b5f610b257f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fa791906121bd565b60405163c44b11f760e01b81526001600160a01b038581166004830152919091169063c44b11f790602401602060405180830381865afa158015611fed573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061201191906123e3565b5167400000000000000016151590565b6040805180820190915260028152610dcd60f21b60208201525f90608083106120665760405162461bcd60e51b815260040161205d919061257d565b60405180910390fd5b50509051600191821b82011c16151590565b6001600160a01b038116811461208c575f80fd5b50565b5f80604083850312156120a0575f80fd5b82356120ab81612078565b915060208301356120bb81612078565b809150509250929050565b5f602082840312156120d6575f80fd5b8135610ff881612078565b5f5b838110156120fb5781810151838201526020016120e3565b50505f910152565b5f815180845261211a8160208601602086016120e1565b601f01601f19169290920160200192915050565b5f60208083018184528085518083526040925060408601915060408160051b8701018488015f5b8381101561219f57888303603f190185528151805187855261217988860182612103565b918901516001600160a01b03169489019490945294870194925090860190600101612155565b509098975050505050505050565b80516121b881612078565b919050565b5f602082840312156121cd575f80fd5b8151610ff881612078565b634e487b7160e01b5f52604160045260245ffd5b6040516101e0810167ffffffffffffffff81118282101715612210576122106121d8565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561223f5761223f6121d8565b604052919050565b5f60208284031215612257575f80fd5b6040516020810181811067ffffffffffffffff8211171561227a5761227a6121d8565b6040529151825250919050565b80516001600160801b03811681146121b8575f80fd5b805164ffffffffff811681146121b8575f80fd5b805161ffff811681146121b8575f80fd5b5f6101e082840312156122d3575f80fd5b6122db6121ec565b6122e58484612247565b81526122f360208401612287565b602082015261230460408401612287565b604082015261231560608401612287565b606082015261232660808401612287565b608082015261233760a08401612287565b60a082015261234860c0840161229d565b60c082015261235960e084016122b1565b60e082015261010061236c8185016121ad565b9082015261012061237e8482016121ad565b908201526101406123908482016121ad565b908201526101606123a28482016121ad565b908201526101806123b4848201612287565b908201526101a06123c6848201612287565b908201526101c06123d8848201612287565b908201529392505050565b5f602082840312156123f3575f80fd5b610ff88383612247565b5f6020828403121561240d575f80fd5b5051919050565b5f60208284031215612424575f80fd5b610ff882612287565b5f602080838503121561243e575f80fd5b825167ffffffffffffffff80821115612455575f80fd5b818501915085601f830112612468575f80fd5b81518181111561247a5761247a6121d8565b8060051b915061248b848301612216565b81815291830184019184810190888411156124a4575f80fd5b938501935b838510156124ce57845192506124be83612078565b82825293850193908501906124a9565b98975050505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156124fe575f80fd5b815167ffffffffffffffff80821115612515575f80fd5b818401915084601f830112612528575f80fd5b81518181111561253a5761253a6121d8565b61254d601f8201601f1916602001612216565b9150808252856020828501011115612563575f80fd5b6125748160208401602086016120e1565b50949350505050565b602081525f610ff8602083018461210356fea164736f6c6343000816000a60c060405234801562000010575f80fd5b50604051620027e5380380620027e5833981016040819052620000339162000067565b6001600160a01b039182166080521660a0526200009d565b80516001600160a01b038116811462000062575f80fd5b919050565b5f806040838503121562000079575f80fd5b62000084836200004b565b915062000094602084016200004b565b90509250929050565b60805160a051612712620000d35f395f81816101960152611b3801525f818160bb015281816119820152611a0b01526127125ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636f90b9d1116100635780636f90b9d114610136578063825ffd92146101565780639201de5514610171578063d22cf68a14610191578063ec489c21146101b8575f80fd5b80630496f53a146100945780633c1740ed146100b657806351974cc0146100f5578063586c144214610116575b5f80fd5b6100a3670de0b6b3a764000081565b6040519081526020015b60405180910390f35b6100dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ad565b610108610103366004611cd5565b6101d9565b6040516100ad929190611d0c565b610129610124366004611d86565b610655565b6040516100ad9190611da1565b610149610144366004611d86565b610723565b6040516100ad9190611e3a565b6100dd739f8f72aa9304c8b593d555f12ef6589cc3a579a281565b61018461017f366004611f11565b610b25565b6040516100ad9190611f28565b6100dd7f000000000000000000000000000000000000000000000000000000000000000081565b6101cb6101c6366004611d86565b610c51565b6040516100ad929190611f3a565b60605f80846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610219573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023d919061220e565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa15801561027b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526102a29190810190612298565b604051634417a58360e01b81526001600160a01b0387811660048301529192505f91841690634417a58390602401602060405180830381865afa1580156102eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061030f9190612385565b60405163eddf1b7960e01b81526001600160a01b0388811660048301529192505f9185169063eddf1b7990602401602060405180830381865afa158015610358573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037c919061239f565b90505f6001600160a01b038816610393575f610396565b83515b67ffffffffffffffff8111156103ae576103ae612229565b6040519080825280602002602001820160405280156103fe57816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f199092019101816103cc5790505b5090505f5b8451811015610647575f866001600160a01b03166335ea6a7587848151811061042e5761042e6123b6565b60200260200101516040518263ffffffff1660e01b815260040161046191906001600160a01b0391909116815260200190565b6101e060405180830381865afa15801561047d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a19190612405565b90508582815181106104b5576104b56123b6565b60200260200101518383815181106104cf576104cf6123b6565b60209081029190910101516001600160a01b039182169052610100820151604051630ed1279f60e11b81528c83166004820152911690631da24f3e90602401602060405180830381865afa158015610529573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061054d919061239f565b83838151811061055f5761055f6123b6565b60209081029190910181015101526105778583611bd8565b838381518110610589576105896123b6565b60209081029190910101519015156040909101526105a78583611c2f565b1561063e57610140810151604051630ed1279f60e11b81526001600160a01b038c8116600483015290911690631da24f3e90602401602060405180830381865afa1580156105f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061061b919061239f565b83838151811061062d5761062d6123b6565b602002602001015160600181815250505b50600101610403565b509890975095505050505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610694573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106b8919061220e565b9050806001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156106f5573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261071c9190810190612298565b9392505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610762573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610786919061220e565b6040805161010080825261202082019092529192505f9190816020015b6107ab611c7b565b8152602001906001900390816107a35790505090505f8060015b6101008160ff161015610a6b5760405163b286f46760e01b815260ff821660048201525f906001600160a01b0387169063b286f46790602401606060405180830381865afa158015610819573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061083d9190612526565b9050806020015161ffff165f14610a3a5760405180604001604052808360ff1681526020016040518060c00160405280845f015161ffff168152602001846020015161ffff168152602001846040015161ffff168152602001896001600160a01b031663b0771dba876040518263ffffffff1660e01b81526004016108cb919060ff91909116815260200190565b602060405180830381865afa1580156108e6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061090a9190612590565b6001600160801b03168152604051632083e18360e01b815260ff871660048201526020909101906001600160a01b038b1690632083e183906024015f60405180830381865afa15801561095f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261098691908101906125a9565b815260405163903a2c7160e01b815260ff871660048201526020909101906001600160a01b038b169063903a2c7190602401602060405180830381865afa1580156109d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f79190612590565b6001600160801b0316815250815250858560ff1681518110610a1b57610a1b6123b6565b602002602001018190525083610a3090612638565b93505f9250610a46565b610a4383612638565b92505b60028360ff161115610a585750610a6b565b5080610a6381612638565b9150506107c5565b505f8260ff1667ffffffffffffffff811115610a8957610a89612229565b604051908082528060200260200182016040528015610ac257816020015b610aaf611c7b565b815260200190600190039081610aa75790505b5090505f5b8360ff168160ff161015610b1a57848160ff1681518110610aea57610aea6123b6565b6020026020010151828260ff1681518110610b0757610b076123b6565b6020908102919091010152600101610ac7565b509695505050505050565b60605f5b60208160ff16108015610b5d5750828160ff1660208110610b4c57610b4c6123b6565b1a60f81b6001600160f81b03191615155b15610b745780610b6c81612638565b915050610b29565b5f8160ff1667ffffffffffffffff811115610b9157610b91612229565b6040519080825280601f01601f191660200182016040528015610bbb576020820181803683370190505b5090505f91505b60208260ff16108015610bf65750838260ff1660208110610be557610be56123b6565b1a60f81b6001600160f81b03191615155b1561071c57838260ff1660208110610c1057610c106123b6565b1a60f81b818360ff1681518110610c2957610c296123b6565b60200101906001600160f81b03191690815f1a90535081610c4981612638565b925050610bc2565b6060610c7d60405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b5f836001600160a01b031663fca513a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cba573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cde919061220e565b90505f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d1d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d41919061220e565b90505f856001600160a01b031663e860accb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d80573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da4919061220e565b90505f826001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610de2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e099190810190612298565b90505f815167ffffffffffffffff811115610e2657610e26612229565b604051908082528060200260200182016040528015610fa357816020015b60408051610540810182525f8082526060602080840182905293830181905282018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a082018190526102c082018190526102e08201819052610300820181905261032082018190526103408201819052610360820181905261038082018190526103a082018190526103c082018190526103e08201819052610400820181905261042082018190526104408201819052610460820181905261048082018190526104a082018190526104c082018190526104e08201819052610500820181905261052082015282525f19909201910181610e445790505b5090505f5b8251811015611955575f828281518110610fc457610fc46123b6565b60200260200101519050838281518110610fe057610fe06123b6565b60209081029190910101516001600160a01b039081168083526040516335ea6a7560e01b815260048101919091525f918816906335ea6a75906024016101e060405180830381865afa158015611038573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061105c9190612405565b60208101516001600160801b03908116610180850152606082015181166101a085015260408083015182166101c086015260808301519091166101e085015260c082015164ffffffffff166102008501526101008201516001600160a01b03908116610220860152610140830151811661024086015261016083015181166102608601528451915163b3596f0760e01b815291811660048301529192509089169063b3596f0790602401602060405180830381865afa158015611121573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611145919061239f565b6102c08301528151604051630495f95f60e51b81526001600160a01b039182166004820152908916906392bf2be090602401602060405180830381865afa158015611192573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b6919061220e565b6001600160a01b039081166102e084015282516102208401516040516370a0823160e01b815290831660048201529116906370a0823190602401602060405180830381865afa15801561120b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122f919061239f565b826102800181815250508161024001516001600160a01b031663b1bf962d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561127a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129e919061239f565b6102a083015281516001600160a01b0316739f8f72aa9304c8b593d555f12ef6589cc3a579a119016113ba575f825f01516001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132e919061239f565b90505f835f01516001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401602060405180830381865afa158015611370573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611394919061239f565b905061139f82610b25565b60408501526113ad81610b25565b6020850152506114929050565b815f01516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156113f8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261141f91908101906125a9565b8260400181905250815f01516001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611465573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261148c91908101906125a9565b60208301525b8051805161ffff604082811c821660e087015260ff603084901c166060870152602083901c821660c0870152601083901c821660a0870152911660808086018290529015156101008601528251671000000000000000811615156103808701526704000000000000008116151561012087015267020000000000000081161515610160870152670100000000000000161515610140860152610260850151855183516304c7a22760e21b81526001600160a01b039182166004820152935191169263131e889c9260248083019391928290030181865afa925050508015611596575060408051601f3d908101601f1916820190925261159391810190612662565b60015b156115c457602081015161034085015260408101516103008501526060810151610320850152516103608401525b825160405163c952485d60e01b81526001600160a01b0391821660048201529089169063c952485d90602401602060405180830381865afa15801561160b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061162f919061239f565b6001600160801b0316610520840152805160d41c64ffffffffff1683610440018181525050866001600160a01b03166369b169e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611690573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116b4919061239f565b6104608401528051640fffffffff605082901c81169160741c166104a085015261048084015282516040516335fb4fbd60e21b81526001600160a01b0391821660048201529088169063d7ed3ef490602401602060405180830381865afa92505050801561173f575060408051601f3d908101601f1916820190925261173c918101906126c6565b60015b611780573d80801561176c576040519150601f19603f3d011682016040523d82523d5f602084013e611771565b606091505b50506001610420840152611789565b15156104208401525b805167400000000000000016151515156103a08401526101a08201516001600160801b039081166103e08501526101c08301518116610400850152610180830151166103c0840152805167200000000000000016151515156104c0840152825160405163f7e1430760e01b81526001600160a01b0391821660048201529088169063f7e1430790602401602060405180830381865afa92505050801561184c575060408051601f3d908101601f19168201909252611849918101906126c6565b60015b61188c573d808015611879576040519150601f19603f3d011682016040523d82523d5f602084013e61187e565b606091505b50505f6104e0840152611895565b15156104e08401525b82516040516337d83fcb60e11b81526001600160a01b03918216600482015290891690636fb07f9690602401602060405180830381865afa9250505080156118fa575060408051601f3d908101601f191682019092526118f791810190612590565b60015b61193a573d808015611927576040519150601f19603f3d011682016040523d82523d5f602084013e61192c565b606091505b50505f61050084015261194a565b6001600160801b03166105008401525b505050600101610fa8565b5061198060405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119dc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a00919061239f565b8160400181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a8991906126e5565b60ff16606082015260408051638c89b64f60e01b815290516001600160a01b03881691638c89b64f9160048083019260209291908290030181865afa925050508015611af2575060408051601f3d908101601f19168201909252611aef9181019061239f565b60015b611bc1573d808015611b1f576040519150601f19603f3d011682016040523d82523d5f602084013e611b24565b606091505b50670de0b6b3a7640000825f0181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b92573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bb6919061239f565b602083015250611bca565b80825260208201525b909890975095505050505050565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c1d5760405162461bcd60e51b8152600401611c149190611f28565b60405180910390fd5b50509051600191821b82011c16151590565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c6b5760405162461bcd60e51b8152600401611c149190611f28565b50509051600191821b1c16151590565b6040805180820182525f808252825160c08101845281815260208181018390529381018290526060808201839052608082015260a0810191909152909182015290565b6001600160a01b0381168114611cd2575f80fd5b50565b5f8060408385031215611ce6575f80fd5b8235611cf181611cbe565b91506020830135611d0181611cbe565b809150509250929050565b604080825283518282018190525f9190606090818501906020808901865b83811015611d6c57815180516001600160a01b031686528381015184870152878101511515888701528601518686015260809094019390820190600101611d2a565b5050505080935050505060ff831660208301529392505050565b5f60208284031215611d96575f80fd5b813561071c81611cbe565b602080825282518282018190525f9190848201906040850190845b81811015611de15783516001600160a01b031683529284019291840191600101611dbc565b50909695505050505050565b5f5b83811015611e07578181015183820152602001611def565b50505f910152565b5f8151808452611e26816020860160208601611ded565b601f01601f19169290920160200192915050565b5f60208083018184528085518083526040925060408601915060408160051b8701018488015f5b83811015611f0357888303603f190185528151805160ff168452870151878401879052805161ffff9081168886015281890151811660608087019190915288830151909116608080870191909152908201516001600160801b0390811660a0808801919091529183015160c0808801529190611ee1610100880184611e0f565b93909101511660e0959095019490945294870194925090860190600101611e61565b509098975050505050505050565b5f60208284031215611f21575f80fd5b5035919050565b602081525f61071c6020830184611e0f565b5f60a080830160a0845280865180835260c0925060c08601915060c08160051b8701016020808a015f5b848110156121bc5789840360bf19018652815180516001600160a01b03168552610540848201518186880152611f9c82880182611e0f565b91505060408083015187830382890152611fb68382611e0f565b606085810151908a0152608080860151908a01528c8501518d8a01528b8501518c8a015260e080860151908a0152610100808601511515908a0152610120808601511515908a0152610140808601511515908a0152610160808601511515908a0152610180808601516001600160801b03908116918b01919091526101a0808701518216908b01526101c0808701518216908b01526101e0808701518216908b01526102008087015164ffffffffff16908b0152610220808701516001600160a01b03908116918c0191909152610240808801518216908c0152610260808801518216908c015261028080880151908c01526102a080880151908c01526102c080880151908c01526102e080880151909116908b015261030080870151908b015261032080870151908b015261034080870151908b015261036080870151908b0152610380808701511515908b01526103a0808701511515908b01526103c0808701518216908b01526103e0808701518216908b0152610400808701518216908b0152610420808701511515908b015261044080870151908b015261046080870151908b015261048080870151908b01526104a080870151908b01526104c0808701511515908b01526104e0808701511515908b0152610500808701518216908b0152610520958601511694909801939093525050509482019490820190600101611f64565b50508196506121f18189018a80518252602081015160208301526040810151604083015260ff60608201511660608301525050565b5050505050509392505050565b805161220981611cbe565b919050565b5f6020828403121561221e575f80fd5b815161071c81611cbe565b634e487b7160e01b5f52604160045260245ffd5b6040516101e0810167ffffffffffffffff8111828210171561226157612261612229565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561229057612290612229565b604052919050565b5f60208083850312156122a9575f80fd5b825167ffffffffffffffff808211156122c0575f80fd5b818501915085601f8301126122d3575f80fd5b8151818111156122e5576122e5612229565b8060051b91506122f6848301612267565b818152918301840191848101908884111561230f575f80fd5b938501935b83851015612339578451925061232983611cbe565b8282529385019390850190612314565b98975050505050505050565b5f60208284031215612355575f80fd5b6040516020810181811067ffffffffffffffff8211171561237857612378612229565b6040529151825250919050565b5f60208284031215612395575f80fd5b61071c8383612345565b5f602082840312156123af575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b80516001600160801b0381168114612209575f80fd5b805164ffffffffff81168114612209575f80fd5b805161ffff81168114612209575f80fd5b5f6101e08284031215612416575f80fd5b61241e61223d565b6124288484612345565b8152612436602084016123ca565b6020820152612447604084016123ca565b6040820152612458606084016123ca565b6060820152612469608084016123ca565b608082015261247a60a084016123ca565b60a082015261248b60c084016123e0565b60c082015261249c60e084016123f4565b60e08201526101006124af8185016121fe565b908201526101206124c18482016121fe565b908201526101406124d38482016121fe565b908201526101606124e58482016121fe565b908201526101806124f78482016123ca565b908201526101a06125098482016123ca565b908201526101c061251b8482016123ca565b908201529392505050565b5f60608284031215612536575f80fd5b6040516060810181811067ffffffffffffffff8211171561255957612559612229565b604052612565836123f4565b8152612573602084016123f4565b6020820152612584604084016123f4565b60408201529392505050565b5f602082840312156125a0575f80fd5b61071c826123ca565b5f602082840312156125b9575f80fd5b815167ffffffffffffffff808211156125d0575f80fd5b818401915084601f8301126125e3575f80fd5b8151818111156125f5576125f5612229565b612608601f8201601f1916602001612267565b915080825285602082850101111561261e575f80fd5b61262f816020840160208601611ded565b50949350505050565b5f60ff821660ff810361265957634e487b7160e01b5f52601160045260245ffd5b60010192915050565b5f60808284031215612672575f80fd5b6040516080810181811067ffffffffffffffff8211171561269557612695612229565b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b5f602082840312156126d6575f80fd5b8151801515811461071c575f80fd5b5f602082840312156126f5575f80fd5b815160ff8116811461071c575f80fdfea164736f6c6343000816000a0000000000000000000000004172e6aaec070acb31aace343a58c93e4c70f44d000000000000000000000000c76dfb89ff298145b417d221b2c747d84952e01d000000000000000000000000824364077993847f71293b24cca8567c00c2de11
Deployed Bytecode
0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80630cf19f2c14602a575b5f80fd5b608d604080516080810182525f80825260208201819052918101829052606081019190915250604080516080810182525f546001600160a01b03908116825260015481166020830152600254811692820192909252600354909116606082015290565b60405160cf919081516001600160a01b039081168252602080840151821690830152604080840151821690830152606092830151169181019190915260800190565b60405180910390f3fea164736f6c6343000816000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004172e6aaec070acb31aace343a58c93e4c70f44d000000000000000000000000c76dfb89ff298145b417d221b2c747d84952e01d000000000000000000000000824364077993847f71293b24cca8567c00c2de11
-----Decoded View---------------
Arg [0] : poolAddressesProvider (address): 0x4172E6aAEC070ACB31aaCE343A58c93E4C70f44D
Arg [1] : networkBaseTokenPriceInUsdProxyAggregator (address): 0xc76dFb89fF298145b417d221B2c747d84952e01d
Arg [2] : marketReferenceCurrencyPriceInUsdProxyAggregator (address): 0x824364077993847f71293B24ccA8567c00c2de11
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004172e6aaec070acb31aace343a58c93e4c70f44d
Arg [1] : 000000000000000000000000c76dfb89ff298145b417d221b2c747d84952e01d
Arg [2] : 000000000000000000000000824364077993847f71293b24cca8567c00c2de11
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.