Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
UiIncentiveDataProviderV3
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 100000 runs
Other Settings:
berlin EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {IERC20Detailed} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; import {IncentivizedERC20} from '@aave/core-v3/contracts/protocol/tokenization/base/IncentivizedERC20.sol'; import {UserConfiguration} from '@aave/core-v3/contracts/protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol'; import {IRewardsController} from '../rewards/interfaces/IRewardsController.sol'; import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.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.ReserveData memory baseData = pool.getReserveData(reserves[i]); // Get aTokens rewards information // TODO: check that this is deployed correctly on contract and remove casting 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 = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = IEACAggregatorProxy( 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 = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).latestAnswer(); vRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.vIncentiveData = IncentiveData( baseData.variableDebtTokenAddress, address(vTokenIncentiveController), vRewardsInformation ); // Get sTokens rewards information IRewardsController sTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.stableDebtTokenAddress).getIncentivesController()) ); RewardInfo[] memory sRewardsInformation; if (address(sTokenIncentiveController) != address(0)) { address[] memory sTokenRewardAddresses = sTokenIncentiveController.getRewardsByAsset( baseData.stableDebtTokenAddress ); sRewardsInformation = new RewardInfo[](sTokenRewardAddresses.length); for (uint256 j = 0; j < sTokenRewardAddresses.length; ++j) { RewardInfo memory rewardInformation; rewardInformation.rewardTokenAddress = sTokenRewardAddresses[j]; ( rewardInformation.tokenIncentivesIndex, rewardInformation.emissionPerSecond, rewardInformation.incentivesLastUpdateTimestamp, rewardInformation.emissionEndTimestamp ) = sTokenIncentiveController.getRewardsData( baseData.stableDebtTokenAddress, rewardInformation.rewardTokenAddress ); rewardInformation.precision = sTokenIncentiveController.getAssetDecimals( baseData.stableDebtTokenAddress ); rewardInformation.rewardTokenDecimals = IERC20Detailed( rewardInformation.rewardTokenAddress ).decimals(); rewardInformation.rewardTokenSymbol = IERC20Detailed(rewardInformation.rewardTokenAddress) .symbol(); // Get price of reward token from Chainlink Proxy Oracle rewardInformation.rewardOracleAddress = sTokenIncentiveController.getRewardOracle( rewardInformation.rewardTokenAddress ); rewardInformation.priceFeedDecimals = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).latestAnswer(); sRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.sIncentiveData = IncentiveData( baseData.stableDebtTokenAddress, address(sTokenIncentiveController), sRewardsInformation ); } 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.ReserveData 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 = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = IEACAggregatorProxy( 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 = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).latestAnswer(); vUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].vTokenIncentivesUserData = UserIncentiveData( baseData.variableDebtTokenAddress, address(aTokenIncentiveController), vUserRewardsInformation ); } // stable debt token IRewardsController sTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.stableDebtTokenAddress).getIncentivesController()) ); if (address(sTokenIncentiveController) != address(0)) { // get all rewards information from the asset address[] memory sTokenRewardAddresses = sTokenIncentiveController.getRewardsByAsset( baseData.stableDebtTokenAddress ); UserRewardInfo[] memory sUserRewardsInformation = new UserRewardInfo[]( sTokenRewardAddresses.length ); for (uint256 j = 0; j < sTokenRewardAddresses.length; ++j) { UserRewardInfo memory userRewardInformation; userRewardInformation.rewardTokenAddress = sTokenRewardAddresses[j]; userRewardInformation.tokenIncentivesUserIndex = sTokenIncentiveController .getUserAssetIndex( user, baseData.stableDebtTokenAddress, userRewardInformation.rewardTokenAddress ); userRewardInformation.userUnclaimedRewards = sTokenIncentiveController .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 = sTokenIncentiveController.getRewardOracle( userRewardInformation.rewardTokenAddress ); userRewardInformation.priceFeedDecimals = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).latestAnswer(); sUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].sTokenIncentivesUserData = UserIncentiveData( baseData.stableDebtTokenAddress, address(aTokenIncentiveController), sUserRewardsInformation ); } } return (userReservesIncentivesData); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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: AGPL-3.0 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: AGPL-3.0 pragma solidity ^0.8.0; 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.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted 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: AGPL-3.0 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: AGPL-3.0 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: AGPL-3.0 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: 1 for Stable, 2 for Variable * @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 swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ event SwapBorrowRateMode( address indexed reserve, address indexed user, DataTypes.InterestRateMode interestRateMode ); /** * @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 rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed */ event RebalanceStableBorrowRate(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 debt, 2 for Variable debt * @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 * @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 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); /** * @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 * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @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/stable 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 The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @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 The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @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/stable 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 The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa * @param asset The address of the underlying asset borrowed * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ function swapBorrowRateMode(address asset, uint256 interestRateMode) external; /** * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too * much has been borrowed at a stable rate and suppliers are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced */ function rebalanceStableBorrowRate(address asset, address user) external; /** * @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 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 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 on `modes` 1 or 2 * @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 stableDebtAddress The address of the StableDebtToken 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 stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @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 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.ReserveData memory); /** * @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 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 category for the 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.EModeCategory memory config) external; /** * @notice Returns the data of an eMode category * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); /** * @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 Returns the percentage of available liquidity that can be borrowed at once at stable rate * @return The percentage of available liquidity to borrow, expressed in bps */ function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); /** * @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; }
// SPDX-License-Identifier: AGPL-3.0 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: BUSL-1.1 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 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000; // prettier-ignore uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF; // prettier-ignore uint256 internal constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF; // prettier-ignore uint256 internal constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF; // prettier-ignore uint256 internal constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant SILOED_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant FLASHLOAN_ENABLED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant EMODE_CATEGORY_MASK = 0xFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant UNBACKED_MINT_CAP_MASK = 0xFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant DEBT_CEILING_MASK = 0xF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // 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 STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59; 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; uint256 internal constant EMODE_CATEGORY_START_BIT_POSITION = 168; uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176; uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212; 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_EMODE_CATEGORY = 255; 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 Enables or disables stable rate borrowing on the reserve * @param self The reserve configuration * @param enabled True if the stable rate borrowing needs to be enabled, false otherwise */ function setStableRateBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self, bool enabled ) internal pure { self.data = (self.data & STABLE_BORROWING_MASK) | (uint256(enabled ? 1 : 0) << STABLE_BORROWING_ENABLED_START_BIT_POSITION); } /** * @notice Gets the stable rate borrowing state of the reserve * @param self The reserve configuration * @return The stable rate borrowing state */ function getStableRateBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~STABLE_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 eMode asset category * @param self The reserve configuration * @param category The asset category when the user selects the eMode */ function setEModeCategory( DataTypes.ReserveConfigurationMap memory self, uint256 category ) internal pure { require(category <= MAX_VALID_EMODE_CATEGORY, Errors.INVALID_EMODE_CATEGORY); self.data = (self.data & EMODE_CATEGORY_MASK) | (category << EMODE_CATEGORY_START_BIT_POSITION); } /** * @dev Gets the eMode asset category * @param self The reserve configuration * @return The eMode category for the asset */ function getEModeCategory( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_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 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 stableRateBorrowing enabled * @return The state flag representing paused */ function getFlags( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool, bool, bool, bool, bool) { uint256 dataLocal = self.data; return ( (dataLocal & ~ACTIVE_MASK) != 0, (dataLocal & ~FROZEN_MASK) != 0, (dataLocal & ~BORROWING_MASK) != 0, (dataLocal & ~STABLE_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 * @return The state param representing eMode category */ function getParams( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256, 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, (dataLocal & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_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: BUSL-1.1 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: BUSL-1.1 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 STABLE_BORROWING_NOT_ENABLED = '31'; // 'Stable 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 AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '38'; // 'The requested amount is greater than the max loan size in stable rate mode' 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_STABLE_DEBT = '41'; // 'User does not have outstanding stable rate debt on this reserve' 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 STABLE_DEBT_NOT_ZERO = '55'; // 'Stable debt supply is not zero' 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 INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = '84'; // 'Invalid optimal stable to total debt 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 STABLE_BORROWING_ENABLED = '88'; // 'Stable borrowing is enabled' 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 }
// 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: BUSL-1.1 pragma solidity ^0.8.0; library DataTypes { 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; //the current stable borrow rate. Expressed in ray 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; //stableDebtToken address 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 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: 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 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-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; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles address priceSource; string label; } enum InterestRateMode {NONE, STABLE, VARIABLE} struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currPrincipalStableDebt; uint256 currAvgStableBorrowRate; uint256 currTotalStableDebt; uint256 nextAvgStableBorrowRate; uint256 nextTotalStableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; uint40 stableDebtLastUpdateTimestamp; } 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 maxStableRateBorrowSizePercent; 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 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 maxStableRateBorrowSizePercent; uint256 reservesCount; address addressesProvider; 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 maxStableLoanPercent; 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 totalStableDebt; uint256 totalVariableDebt; uint256 averageStableBorrowRate; uint256 reserveFactor; address reserve; address aToken; } struct InitReserveParams { address asset; address aTokenAddress; address stableDebtAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: BUSL-1.1 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. StableDebtTokens use * this field to store the user's stable rate. */ 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: AGPL-3.0 pragma solidity ^0.8.10; interface IEACAggregatorProxy { function decimals() external view returns (uint8); 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 timestamp); event NewRound(uint256 indexed roundId, address indexed startedBy); }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; interface IUiIncentiveDataProviderV3 { struct AggregatedReserveIncentiveData { address underlyingAsset; IncentiveData aIncentiveData; IncentiveData vIncentiveData; IncentiveData sIncentiveData; } 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; UserIncentiveData sTokenIncentivesUserData; } 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: AGPL-3.0 pragma solidity ^0.8.10; import {IRewardsDistributor} from './IRewardsDistributor.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; import {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.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 IEACAggregatorProxy interface */ function setRewardOracle(address reward, IEACAggregatorProxy 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. * IEACAggregatorProxy rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend. * Must follow Chainlink Aggregator IEACAggregatorProxy 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: AGPL-3.0 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: AGPL-3.0 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: AGPL-3.0 pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol'; library RewardsDataTypes { struct RewardsConfigInput { uint88 emissionPerSecond; uint256 totalSupply; uint32 distributionEnd; address asset; address reward; ITransferStrategyBase transferStrategy; IEACAggregatorProxy 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; } }
{ "optimizer": { "enabled": true, "runs": 100000 }, "evmVersion": "berlin", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getFullReservesIncentiveData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"aIncentiveData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"vIncentiveData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"sIncentiveData","type":"tuple"}],"internalType":"struct IUiIncentiveDataProviderV3.AggregatedReserveIncentiveData[]","name":"","type":"tuple[]"},{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"aTokenIncentivesUserData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"vTokenIncentivesUserData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"sTokenIncentivesUserData","type":"tuple"}],"internalType":"struct IUiIncentiveDataProviderV3.UserReserveIncentiveData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"}],"name":"getReservesIncentivesData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"aIncentiveData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"vIncentiveData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"uint256","name":"emissionPerSecond","type":"uint256"},{"internalType":"uint256","name":"incentivesLastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesIndex","type":"uint256"},{"internalType":"uint256","name":"emissionEndTimestamp","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"precision","type":"uint8"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.RewardInfo[]","name":"rewardsTokenInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.IncentiveData","name":"sIncentiveData","type":"tuple"}],"internalType":"struct IUiIncentiveDataProviderV3.AggregatedReserveIncentiveData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserReservesIncentivesData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"aTokenIncentivesUserData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"vTokenIncentivesUserData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"incentiveControllerAddress","type":"address"},{"components":[{"internalType":"string","name":"rewardTokenSymbol","type":"string"},{"internalType":"address","name":"rewardOracleAddress","type":"address"},{"internalType":"address","name":"rewardTokenAddress","type":"address"},{"internalType":"uint256","name":"userUnclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"tokenIncentivesUserIndex","type":"uint256"},{"internalType":"int256","name":"rewardPriceFeed","type":"int256"},{"internalType":"uint8","name":"priceFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"rewardTokenDecimals","type":"uint8"}],"internalType":"struct IUiIncentiveDataProviderV3.UserRewardInfo[]","name":"userRewardsInformation","type":"tuple[]"}],"internalType":"struct IUiIncentiveDataProviderV3.UserIncentiveData","name":"sTokenIncentivesUserData","type":"tuple"}],"internalType":"struct IUiIncentiveDataProviderV3.UserReserveIncentiveData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613efd806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634763753614610046578063799bdcf514610070578063976fafc514610090575b600080fd5b6100596100543660046134ef565b6100b0565b604051610067929190613979565b60405180910390f35b61008361007e3660046134ef565b6100d1565b60405161006791906139a7565b6100a361009e3660046139ba565b6100e4565b60405161006791906139d7565b6060806100bc846100f5565b6100c68585611af0565b915091509250929050565b60606100dd8383611af0565b9392505050565b60606100ef826100f5565b92915050565b606060008273ffffffffffffffffffffffffffffffffffffffff1663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016891906139fa565b905060008173ffffffffffffffffffffffffffffffffffffffff1663d1946dbc6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156101b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526101fd9190810190613abf565b90506000815167ffffffffffffffff81111561021b5761021b613a17565b60405190808252806020026020018201604052801561025457816020015b610241613413565b8152602001906001900390816102395790505b50905060005b8251811015611ae757600082828151811061027757610277613b71565b6020026020010151905083828151811061029357610293613b71565b6020026020010151816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008573ffffffffffffffffffffffffffffffffffffffff166335ea6a7586858151811061030257610302613b71565b60200260200101516040518263ffffffff1660e01b8152600401610342919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6101e060405180830381865afa158015610360573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103849190613c29565b9050600081610100015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fc91906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff821615610af4576101008301516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015610491573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104d79190810190613abf565b9050805167ffffffffffffffff8111156104f3576104f3613a17565b6040519080825280602002602001820160405280156105b657816020015b6105a360405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8152602001906001900390816105115790505b50915060005b8151811015610af15761065760405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b82828151811061066957610669613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101008801516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa1580156106f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071c9190613d4c565b60c08501526080840152606083015260a08201526101008601516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa1580156107a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c79190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa15801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108619190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109089190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a091906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190613e4e565b60e082015283518190859084908110610ad457610ad4613b71565b60200260200101819052505080610aea90613e67565b90506105bc565b50505b604051806060016040528084610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152508460200181905250600083610140015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbe91906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff8216156112b6576101408501516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015610c53573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c999190810190613abf565b9050805167ffffffffffffffff811115610cb557610cb5613a17565b604051908082528060200260200182016040528015610d7857816020015b610d6560405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b815260200190600190039081610cd35790505b50915060005b81518110156112b357610e1960405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b828281518110610e2b57610e2b613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101408a01516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa158015610eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ede9190613d4c565b60c08501526080840152606083015260a08201526101408801516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa158015610f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f899190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611084573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110ca9190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa15801561113e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116291906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa1580156111d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f69190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190613e4e565b60e08201528351819085908490811061129657611296613b71565b602002602001018190525050806112ac90613e67565b9050610d7e565b50505b604051806060016040528086610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152508660400181905250600085610120015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561135c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138091906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff821615611a78576101208701516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015611415573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261145b9190810190613abf565b9050805167ffffffffffffffff81111561147757611477613a17565b60405190808252806020026020018201604052801561153a57816020015b61152760405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8152602001906001900390816114955790505b50915060005b8151811015611a75576115db60405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8282815181106115ed576115ed613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101208c01516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa15801561167c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a09190613d4c565b60c08501526080840152606083015260a08201526101208a01516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa158015611727573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174b9190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa1580156117c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e59190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611846573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261188c9190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa158015611900573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192491906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015611994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b89190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3d9190613e4e565b60e082015283518190859084908110611a5857611a58613b71565b60200260200101819052505080611a6e90613e67565b9050611540565b50505b604051806060016040528088610120015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815250886060018190525050505050505050508080611adf90613e67565b91505061025a565b50949350505050565b606060008373ffffffffffffffffffffffffffffffffffffffff1663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6391906139fa565b905060008173ffffffffffffffffffffffffffffffffffffffff1663d1946dbc6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bb2573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bf89190810190613abf565b9050600073ffffffffffffffffffffffffffffffffffffffff8516611c1e576000611c21565b81515b67ffffffffffffffff811115611c3957611c39613a17565b604051908082528060200260200182016040528015611c7257816020015b611c5f613413565b815260200190600190039081611c575790505b50905060005b82518110156134095760008473ffffffffffffffffffffffffffffffffffffffff166335ea6a75858481518110611cb157611cb1613b71565b60200260200101516040518263ffffffff1660e01b8152600401611cf1919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6101e060405180830381865afa158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d339190613c29565b9050838281518110611d4757611d47613b71565b6020026020010151838381518110611d6157611d61613b71565b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600081610100015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015611df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1591906139fa565b905073ffffffffffffffffffffffffffffffffffffffff8116156124ea576101008201516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa158015611ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611eee9190810190613abf565b90506000815167ffffffffffffffff811115611f0c57611f0c613a17565b604051908082528060200260200182016040528015611f9a57816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f2a5790505b50905060005b8251811015612479576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e0810191909152838281518110611ffc57611ffc613b71565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff908116604080840182905261010089015190517f533f542a0000000000000000000000000000000000000000000000000000000081528f84166004820152908316602482015260448101919091529086169063533f542a90606401602060405180830381865afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190613e4e565b608082015260408082015190517fb022418c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa158015612137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215b9190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d79190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612237573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261227d9190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa1580156122f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231591906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa158015612384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a89190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190613e4e565b60a08201528251819084908490811061245c5761245c613b71565b6020026020010181905250508061247290613e67565b9050611fa0565b50604051806060016040528085610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001828152508686815181106124d8576124d8613b71565b60200260200101516020018190525050505b600082610140015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561253c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256091906139fa565b905073ffffffffffffffffffffffffffffffffffffffff811615612c6a576101408301516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa1580156125f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526126399190810190613abf565b90506000815167ffffffffffffffff81111561265757612657613a17565b6040519080825280602002602001820160405280156126e557816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816126755790505b50905060005b8251811015612bf9576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e081019190915283828151811061274757612747613b71565b6020026020010151816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1663533f542a8e89610140015184604001516040518463ffffffff1660e01b81526004016127f79392919073ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b602060405180830381865afa158015612814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128389190613e4e565b608082015260408082015190517fb022418c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa1580156128b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128db9190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129579190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156129b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526129fd9190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa158015612a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9591906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa158015612b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b289190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa158015612b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc19190613e4e565b60a082015282518190849084908110612bdc57612bdc613b71565b60200260200101819052505080612bf290613e67565b90506126eb565b50604051806060016040528086610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200182815250878781518110612c5857612c58613b71565b60200260200101516040018190525050505b600083610120015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce091906139fa565b905073ffffffffffffffffffffffffffffffffffffffff8116156133f2576101208401516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa158015612d73573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612db99190810190613abf565b90506000815167ffffffffffffffff811115612dd757612dd7613a17565b604051908082528060200260200182016040528015612e6557816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612df55790505b50905060005b8251811015613381576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e0810191909152838281518110612ec757612ec7613b71565b6020026020010151816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1663533f542a8f8a610120015184604001516040518463ffffffff1660e01b8152600401612f779392919073ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b602060405180830381865afa158015612f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb89190613e4e565b8160800181815250508473ffffffffffffffffffffffffffffffffffffffff1663b022418c8f83604001516040518363ffffffff1660e01b815260040161302292919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b602060405180830381865afa15801561303f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130639190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561313f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526131859190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa1580156131f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321d91906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa15801561328c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b09190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa158015613325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133499190613e4e565b60a08201528251819084908490811061336457613364613b71565b6020026020010181905250508061337a90613e67565b9050612e6b565b50604051806060016040528087610120015173ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff168152602001828152508888815181106133e0576133e0613b71565b60200260200101516060018190525050505b50505050808061340190613e67565b915050611c78565b5095945050505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200161348b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b81526040805160608082018352600080835260208084018290528385018390528086019390935283518083018552818152928301528183015291015290565b73ffffffffffffffffffffffffffffffffffffffff811681146134ec57600080fd5b50565b6000806040838503121561350257600080fd5b823561350d816134ca565b9150602083013561351d816134ca565b809150509250929050565b60005b8381101561354357818101518382015260200161352b565b83811115613552576000848401525b50505050565b60008151808452613570816020860160208601613528565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080840173ffffffffffffffffffffffffffffffffffffffff8085511686526020818187015116818801526040915081860151848389015283815180865260809550858a019150858160051b8b0101848401935060005b828110156136f3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808c83030184528451610160815181855261364182860182613558565b915050878201516136698986018273ffffffffffffffffffffffffffffffffffffffff169052565b508882015173ffffffffffffffffffffffffffffffffffffffff16848a01528a8201518b850152898201518a85015260a0808301519085015260c0808301519085015260e080830151908501526101008083015160ff90811691860191909152610120808401518216908601526101409283015116919093015293850193928501926001016135fc565b509a9950505050505050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156137ac5782840389528151608073ffffffffffffffffffffffffffffffffffffffff8251168652868201518188880152613760828801826135a2565b9150506040808301518783038289015261377a83826135a2565b925050506060808301519250868203818801525061379881836135a2565b9a87019a9550505090840190600101613720565b5091979650505050505050565b6000606080840173ffffffffffffffffffffffffffffffffffffffff80855116865260208181870151168188015260408087015185828a015284815180875260809650868b019150868160051b8c0101858401935060005b828110156138bf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808d83030184528451610100815181855261385682860182613558565b91505089898301511689850152898883015116888501528b8201518c8501528a8201518b85015260a080830151818601525060c08083015161389c8287018260ff169052565b505060e09182015160ff1693909101929092529386019392860192600101613811565b509b9a5050505050505050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156137ac5782840389528151608073ffffffffffffffffffffffffffffffffffffffff825116865286820151818888015261392d828801826137b9565b9150506040808301518783038289015261394783826137b9565b925050506060808301519250868203818801525061396581836137b9565b9a87019a95505050908401906001016138ed565b60408152600061398c6040830185613702565b828103602084015261399e81856138cf565b95945050505050565b6020815260006100dd60208301846138cf565b6000602082840312156139cc57600080fd5b81356100dd816134ca565b6020815260006100dd6020830184613702565b80516139f5816134ca565b919050565b600060208284031215613a0c57600080fd5b81516100dd816134ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613a6a57613a6a613a17565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ab757613ab7613a17565b604052919050565b60006020808385031215613ad257600080fd5b825167ffffffffffffffff80821115613aea57600080fd5b818501915085601f830112613afe57600080fd5b815181811115613b1057613b10613a17565b8060051b9150613b21848301613a70565b8181529183018401918481019088841115613b3b57600080fd5b938501935b83851015613b655784519250613b55836134ca565b8282529385019390850190613b40565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613bb257600080fd5b6040516020810181811067ffffffffffffffff82111715613bd557613bd5613a17565b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff811681146139f557600080fd5b805164ffffffffff811681146139f557600080fd5b805161ffff811681146139f557600080fd5b60006101e08284031215613c3c57600080fd5b613c44613a46565b613c4e8484613ba0565b8152613c5c60208401613be2565b6020820152613c6d60408401613be2565b6040820152613c7e60608401613be2565b6060820152613c8f60808401613be2565b6080820152613ca060a08401613be2565b60a0820152613cb160c08401613c02565b60c0820152613cc260e08401613c17565b60e0820152610100613cd58185016139ea565b90820152610120613ce78482016139ea565b90820152610140613cf98482016139ea565b90820152610160613d0b8482016139ea565b90820152610180613d1d848201613be2565b908201526101a0613d2f848201613be2565b908201526101c0613d41848201613be2565b908201529392505050565b60008060008060808587031215613d6257600080fd5b505082516020840151604085015160609095015191969095509092509050565b600060208284031215613d9457600080fd5b815160ff811681146100dd57600080fd5b600060208284031215613db757600080fd5b815167ffffffffffffffff80821115613dcf57600080fd5b818401915084601f830112613de357600080fd5b815181811115613df557613df5613a17565b613e2660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a70565b9150808252856020828501011115613e3d57600080fd5b611ae7816020840160208601613528565b600060208284031215613e6057600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613ec0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122065b416ea03e11eeeaee102f04aa2abb315f5cc8d5a1123f32e5d4499d579f1d164736f6c634300080a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c80634763753614610046578063799bdcf514610070578063976fafc514610090575b600080fd5b6100596100543660046134ef565b6100b0565b604051610067929190613979565b60405180910390f35b61008361007e3660046134ef565b6100d1565b60405161006791906139a7565b6100a361009e3660046139ba565b6100e4565b60405161006791906139d7565b6060806100bc846100f5565b6100c68585611af0565b915091509250929050565b60606100dd8383611af0565b9392505050565b60606100ef826100f5565b92915050565b606060008273ffffffffffffffffffffffffffffffffffffffff1663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016891906139fa565b905060008173ffffffffffffffffffffffffffffffffffffffff1663d1946dbc6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156101b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526101fd9190810190613abf565b90506000815167ffffffffffffffff81111561021b5761021b613a17565b60405190808252806020026020018201604052801561025457816020015b610241613413565b8152602001906001900390816102395790505b50905060005b8251811015611ae757600082828151811061027757610277613b71565b6020026020010151905083828151811061029357610293613b71565b6020026020010151816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008573ffffffffffffffffffffffffffffffffffffffff166335ea6a7586858151811061030257610302613b71565b60200260200101516040518263ffffffff1660e01b8152600401610342919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6101e060405180830381865afa158015610360573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103849190613c29565b9050600081610100015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fc91906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff821615610af4576101008301516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015610491573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104d79190810190613abf565b9050805167ffffffffffffffff8111156104f3576104f3613a17565b6040519080825280602002602001820160405280156105b657816020015b6105a360405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8152602001906001900390816105115790505b50915060005b8151811015610af15761065760405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b82828151811061066957610669613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101008801516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa1580156106f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071c9190613d4c565b60c08501526080840152606083015260a08201526101008601516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa1580156107a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c79190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa15801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108619190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109089190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a091906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190613e4e565b60e082015283518190859084908110610ad457610ad4613b71565b60200260200101819052505080610aea90613e67565b90506105bc565b50505b604051806060016040528084610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152508460200181905250600083610140015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbe91906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff8216156112b6576101408501516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015610c53573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c999190810190613abf565b9050805167ffffffffffffffff811115610cb557610cb5613a17565b604051908082528060200260200182016040528015610d7857816020015b610d6560405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b815260200190600190039081610cd35790505b50915060005b81518110156112b357610e1960405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b828281518110610e2b57610e2b613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101408a01516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa158015610eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ede9190613d4c565b60c08501526080840152606083015260a08201526101408801516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa158015610f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f899190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611084573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110ca9190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa15801561113e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116291906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa1580156111d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f69190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190613e4e565b60e08201528351819085908490811061129657611296613b71565b602002602001018190525050806112ac90613e67565b9050610d7e565b50505b604051806060016040528086610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152508660400181905250600085610120015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561135c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138091906139fa565b9050606073ffffffffffffffffffffffffffffffffffffffff821615611a78576101208701516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091841690636657732f90602401600060405180830381865afa158015611415573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261145b9190810190613abf565b9050805167ffffffffffffffff81111561147757611477613a17565b60405190808252806020026020018201604052801561153a57816020015b61152760405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8152602001906001900390816114955790505b50915060005b8151811015611a75576115db60405180610160016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff168152602001600060ff168152602001600060ff1681525090565b8282815181106115ed576115ed613b71565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081169183018290526101208c01516040517f7eff4ba800000000000000000000000000000000000000000000000000000000815290821660048201526024810192909252861690637eff4ba890604401608060405180830381865afa15801561167c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a09190613d4c565b60c08501526080840152606083015260a08201526101208a01516040517f9efd6f7200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690639efd6f7290602401602060405180830381865afa158015611727573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174b9190613d82565b60ff16610120820152602080820151604080517f313ce567000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263313ce567926004808401938290030181865afa1580156117c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e59190613d82565b81610100019060ff16908160ff1681525050806020015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611846573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261188c9190810190613da5565b815260208101516040517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa158015611900573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192491906139fa565b73ffffffffffffffffffffffffffffffffffffffff16604080830182905280517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015611994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b89190613d82565b81610140019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3d9190613e4e565b60e082015283518190859084908110611a5857611a58613b71565b60200260200101819052505080611a6e90613e67565b9050611540565b50505b604051806060016040528088610120015173ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815250886060018190525050505050505050508080611adf90613e67565b91505061025a565b50949350505050565b606060008373ffffffffffffffffffffffffffffffffffffffff1663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6391906139fa565b905060008173ffffffffffffffffffffffffffffffffffffffff1663d1946dbc6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bb2573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bf89190810190613abf565b9050600073ffffffffffffffffffffffffffffffffffffffff8516611c1e576000611c21565b81515b67ffffffffffffffff811115611c3957611c39613a17565b604051908082528060200260200182016040528015611c7257816020015b611c5f613413565b815260200190600190039081611c575790505b50905060005b82518110156134095760008473ffffffffffffffffffffffffffffffffffffffff166335ea6a75858481518110611cb157611cb1613b71565b60200260200101516040518263ffffffff1660e01b8152600401611cf1919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6101e060405180830381865afa158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d339190613c29565b9050838281518110611d4757611d47613b71565b6020026020010151838381518110611d6157611d61613b71565b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600081610100015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015611df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1591906139fa565b905073ffffffffffffffffffffffffffffffffffffffff8116156124ea576101008201516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa158015611ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611eee9190810190613abf565b90506000815167ffffffffffffffff811115611f0c57611f0c613a17565b604051908082528060200260200182016040528015611f9a57816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f2a5790505b50905060005b8251811015612479576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e0810191909152838281518110611ffc57611ffc613b71565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff908116604080840182905261010089015190517f533f542a0000000000000000000000000000000000000000000000000000000081528f84166004820152908316602482015260448101919091529086169063533f542a90606401602060405180830381865afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190613e4e565b608082015260408082015190517fb022418c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8e8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa158015612137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215b9190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d79190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612237573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261227d9190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa1580156122f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231591906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa158015612384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a89190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190613e4e565b60a08201528251819084908490811061245c5761245c613b71565b6020026020010181905250508061247290613e67565b9050611fa0565b50604051806060016040528085610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001828152508686815181106124d8576124d8613b71565b60200260200101516020018190525050505b600082610140015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561253c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256091906139fa565b905073ffffffffffffffffffffffffffffffffffffffff811615612c6a576101408301516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa1580156125f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526126399190810190613abf565b90506000815167ffffffffffffffff81111561265757612657613a17565b6040519080825280602002602001820160405280156126e557816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816126755790505b50905060005b8251811015612bf9576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e081019190915283828151811061274757612747613b71565b6020026020010151816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1663533f542a8e89610140015184604001516040518463ffffffff1660e01b81526004016127f79392919073ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b602060405180830381865afa158015612814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128389190613e4e565b608082015260408082015190517fb022418c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8f8116600483015291821660248201529086169063b022418c90604401602060405180830381865afa1580156128b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128db9190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129579190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156129b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526129fd9190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa158015612a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9591906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa158015612b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b289190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa158015612b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc19190613e4e565b60a082015282518190849084908110612bdc57612bdc613b71565b60200260200101819052505080612bf290613e67565b90506126eb565b50604051806060016040528086610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200182815250878781518110612c5857612c58613b71565b60200260200101516040018190525050505b600083610120015173ffffffffffffffffffffffffffffffffffffffff166375d264136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce091906139fa565b905073ffffffffffffffffffffffffffffffffffffffff8116156133f2576101208401516040517f6657732f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600091831690636657732f90602401600060405180830381865afa158015612d73573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612db99190810190613abf565b90506000815167ffffffffffffffff811115612dd757612dd7613a17565b604051908082528060200260200182016040528015612e6557816020015b60408051610100810182526060808252600060208084018290529383018190529082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612df55790505b50905060005b8251811015613381576040805161010081018252606080825260006020830181905292820183905281018290526080810182905260a0810182905260c0810182905260e0810191909152838281518110612ec757612ec7613b71565b6020026020010151816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1663533f542a8f8a610120015184604001516040518463ffffffff1660e01b8152600401612f779392919073ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b602060405180830381865afa158015612f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb89190613e4e565b8160800181815250508473ffffffffffffffffffffffffffffffffffffffff1663b022418c8f83604001516040518363ffffffff1660e01b815260040161302292919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b602060405180830381865afa15801561303f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130639190613e4e565b816060018181525050806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190613d82565b8160e0019060ff16908160ff1681525050806040015173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561313f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526131859190810190613da5565b815260408082015190517f2a17bf6000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015290861690632a17bf6090602401602060405180830381865afa1580156131f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321d91906139fa565b73ffffffffffffffffffffffffffffffffffffffff166020808301829052604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567926004808401939192918290030181865afa15801561328c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b09190613d82565b60ff1660c0820152602080820151604080517f50d25bcd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926350d25bcd926004808401938290030181865afa158015613325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133499190613e4e565b60a08201528251819084908490811061336457613364613b71565b6020026020010181905250508061337a90613e67565b9050612e6b565b50604051806060016040528087610120015173ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff168152602001828152508888815181106133e0576133e0613b71565b60200260200101516060018190525050505b50505050808061340190613e67565b915050611c78565b5095945050505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200161348b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b81526040805160608082018352600080835260208084018290528385018390528086019390935283518083018552818152928301528183015291015290565b73ffffffffffffffffffffffffffffffffffffffff811681146134ec57600080fd5b50565b6000806040838503121561350257600080fd5b823561350d816134ca565b9150602083013561351d816134ca565b809150509250929050565b60005b8381101561354357818101518382015260200161352b565b83811115613552576000848401525b50505050565b60008151808452613570816020860160208601613528565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080840173ffffffffffffffffffffffffffffffffffffffff8085511686526020818187015116818801526040915081860151848389015283815180865260809550858a019150858160051b8b0101848401935060005b828110156136f3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808c83030184528451610160815181855261364182860182613558565b915050878201516136698986018273ffffffffffffffffffffffffffffffffffffffff169052565b508882015173ffffffffffffffffffffffffffffffffffffffff16848a01528a8201518b850152898201518a85015260a0808301519085015260c0808301519085015260e080830151908501526101008083015160ff90811691860191909152610120808401518216908601526101409283015116919093015293850193928501926001016135fc565b509a9950505050505050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156137ac5782840389528151608073ffffffffffffffffffffffffffffffffffffffff8251168652868201518188880152613760828801826135a2565b9150506040808301518783038289015261377a83826135a2565b925050506060808301519250868203818801525061379881836135a2565b9a87019a9550505090840190600101613720565b5091979650505050505050565b6000606080840173ffffffffffffffffffffffffffffffffffffffff80855116865260208181870151168188015260408087015185828a015284815180875260809650868b019150868160051b8c0101858401935060005b828110156138bf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808d83030184528451610100815181855261385682860182613558565b91505089898301511689850152898883015116888501528b8201518c8501528a8201518b85015260a080830151818601525060c08083015161389c8287018260ff169052565b505060e09182015160ff1693909101929092529386019392860192600101613811565b509b9a5050505050505050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156137ac5782840389528151608073ffffffffffffffffffffffffffffffffffffffff825116865286820151818888015261392d828801826137b9565b9150506040808301518783038289015261394783826137b9565b925050506060808301519250868203818801525061396581836137b9565b9a87019a95505050908401906001016138ed565b60408152600061398c6040830185613702565b828103602084015261399e81856138cf565b95945050505050565b6020815260006100dd60208301846138cf565b6000602082840312156139cc57600080fd5b81356100dd816134ca565b6020815260006100dd6020830184613702565b80516139f5816134ca565b919050565b600060208284031215613a0c57600080fd5b81516100dd816134ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613a6a57613a6a613a17565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ab757613ab7613a17565b604052919050565b60006020808385031215613ad257600080fd5b825167ffffffffffffffff80821115613aea57600080fd5b818501915085601f830112613afe57600080fd5b815181811115613b1057613b10613a17565b8060051b9150613b21848301613a70565b8181529183018401918481019088841115613b3b57600080fd5b938501935b83851015613b655784519250613b55836134ca565b8282529385019390850190613b40565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613bb257600080fd5b6040516020810181811067ffffffffffffffff82111715613bd557613bd5613a17565b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff811681146139f557600080fd5b805164ffffffffff811681146139f557600080fd5b805161ffff811681146139f557600080fd5b60006101e08284031215613c3c57600080fd5b613c44613a46565b613c4e8484613ba0565b8152613c5c60208401613be2565b6020820152613c6d60408401613be2565b6040820152613c7e60608401613be2565b6060820152613c8f60808401613be2565b6080820152613ca060a08401613be2565b60a0820152613cb160c08401613c02565b60c0820152613cc260e08401613c17565b60e0820152610100613cd58185016139ea565b90820152610120613ce78482016139ea565b90820152610140613cf98482016139ea565b90820152610160613d0b8482016139ea565b90820152610180613d1d848201613be2565b908201526101a0613d2f848201613be2565b908201526101c0613d41848201613be2565b908201529392505050565b60008060008060808587031215613d6257600080fd5b505082516020840151604085015160609095015191969095509092509050565b600060208284031215613d9457600080fd5b815160ff811681146100dd57600080fd5b600060208284031215613db757600080fd5b815167ffffffffffffffff80821115613dcf57600080fd5b818401915084601f830112613de357600080fd5b815181811115613df557613df5613a17565b613e2660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a70565b9150808252856020828501011115613e3d57600080fd5b611ae7816020840160208601613528565b600060208284031215613e6057600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613ec0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122065b416ea03e11eeeaee102f04aa2abb315f5cc8d5a1123f32e5d4499d579f1d164736f6c634300080a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.