Source Code
Overview
S Balance
S Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 16279182 | 258 days ago | Contract Creation | 0 S |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
UiPoolDataProviderV3
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.10;
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol';
import {IPool} from '../interfaces/IPool.sol';
import {IAaveOracle} from '../interfaces/IAaveOracle.sol';
import {IAToken} from '../interfaces/IAToken.sol';
import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol';
import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol';
import {AaveProtocolDataProvider} from './AaveProtocolDataProvider.sol';
import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.sol';
import {IERC20DetailedBytes} from './interfaces/IERC20DetailedBytes.sol';
import {IUiPoolDataProviderV3} from './interfaces/IUiPoolDataProviderV3.sol';
contract UiPoolDataProviderV3 is IUiPoolDataProviderV3 {
using WadRayMath for uint256;
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
using UserConfiguration for DataTypes.UserConfigurationMap;
IEACAggregatorProxy public immutable networkBaseTokenPriceInUsdProxyAggregator;
IEACAggregatorProxy public immutable marketReferenceCurrencyPriceInUsdProxyAggregator;
uint256 public constant ETH_CURRENCY_UNIT = 1 ether;
address public constant MKR_ADDRESS = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
constructor(
IEACAggregatorProxy _networkBaseTokenPriceInUsdProxyAggregator,
IEACAggregatorProxy _marketReferenceCurrencyPriceInUsdProxyAggregator
) {
networkBaseTokenPriceInUsdProxyAggregator = _networkBaseTokenPriceInUsdProxyAggregator;
marketReferenceCurrencyPriceInUsdProxyAggregator = _marketReferenceCurrencyPriceInUsdProxyAggregator;
}
function getReservesList(
IPoolAddressesProvider provider
) external view override returns (address[] memory) {
IPool pool = IPool(provider.getPool());
return pool.getReservesList();
}
function getReservesData(
IPoolAddressesProvider provider
) external view override returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory) {
IAaveOracle oracle = IAaveOracle(provider.getPriceOracle());
IPool pool = IPool(provider.getPool());
AaveProtocolDataProvider poolDataProvider = AaveProtocolDataProvider(
provider.getPoolDataProvider()
);
address[] memory reserves = pool.getReservesList();
AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
for (uint256 i = 0; i < reserves.length; i++) {
AggregatedReserveData memory reserveData = reservesData[i];
reserveData.underlyingAsset = reserves[i];
// reserve current state
DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(
reserveData.underlyingAsset
);
//the liquidity index. Expressed in ray
reserveData.liquidityIndex = baseData.liquidityIndex;
//variable borrow index. Expressed in ray
reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
//the current supply rate. Expressed in ray
reserveData.liquidityRate = baseData.currentLiquidityRate;
//the current variable borrow rate. Expressed in ray
reserveData.variableBorrowRate = baseData.currentVariableBorrowRate;
reserveData.lastUpdateTimestamp = baseData.lastUpdateTimestamp;
reserveData.aTokenAddress = baseData.aTokenAddress;
reserveData.variableDebtTokenAddress = baseData.variableDebtTokenAddress;
//address of the interest rate strategy
reserveData.interestRateStrategyAddress = baseData.interestRateStrategyAddress;
reserveData.priceInMarketReferenceCurrency = oracle.getAssetPrice(
reserveData.underlyingAsset
);
reserveData.priceOracle = oracle.getSourceOfAsset(reserveData.underlyingAsset);
reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf(
reserveData.aTokenAddress
);
reserveData.totalScaledVariableDebt = IVariableDebtToken(reserveData.variableDebtTokenAddress)
.scaledTotalSupply();
// Due we take the symbol from underlying token we need a special case for $MKR as symbol() returns bytes32
if (address(reserveData.underlyingAsset) == address(MKR_ADDRESS)) {
bytes32 symbol = IERC20DetailedBytes(reserveData.underlyingAsset).symbol();
bytes32 name = IERC20DetailedBytes(reserveData.underlyingAsset).name();
reserveData.symbol = bytes32ToString(symbol);
reserveData.name = bytes32ToString(name);
} else {
reserveData.symbol = IERC20Detailed(reserveData.underlyingAsset).symbol();
reserveData.name = IERC20Detailed(reserveData.underlyingAsset).name();
}
//stores the reserve configuration
DataTypes.ReserveConfigurationMap memory reserveConfigurationMap = baseData.configuration;
(
reserveData.baseLTVasCollateral,
reserveData.reserveLiquidationThreshold,
reserveData.reserveLiquidationBonus,
reserveData.decimals,
reserveData.reserveFactor
) = reserveConfigurationMap.getParams();
reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0;
(
reserveData.isActive,
reserveData.isFrozen,
reserveData.borrowingEnabled,
reserveData.isPaused
) = reserveConfigurationMap.getFlags();
// interest rates
try
IDefaultInterestRateStrategyV2(reserveData.interestRateStrategyAddress).getInterestRateData(
reserveData.underlyingAsset
)
returns (IDefaultInterestRateStrategyV2.InterestRateDataRay memory res) {
reserveData.baseVariableBorrowRate = res.baseVariableBorrowRate;
reserveData.variableRateSlope1 = res.variableRateSlope1;
reserveData.variableRateSlope2 = res.variableRateSlope2;
reserveData.optimalUsageRatio = res.optimalUsageRatio;
} catch {}
// v3 only
reserveData.debtCeiling = reserveConfigurationMap.getDebtCeiling();
reserveData.debtCeilingDecimals = poolDataProvider.getDebtCeilingDecimals();
(reserveData.borrowCap, reserveData.supplyCap) = reserveConfigurationMap.getCaps();
try poolDataProvider.getFlashLoanEnabled(reserveData.underlyingAsset) returns (
bool flashLoanEnabled
) {
reserveData.flashLoanEnabled = flashLoanEnabled;
} catch (bytes memory) {
reserveData.flashLoanEnabled = true;
}
reserveData.isSiloedBorrowing = reserveConfigurationMap.getSiloedBorrowing();
reserveData.unbacked = baseData.unbacked;
reserveData.isolationModeTotalDebt = baseData.isolationModeTotalDebt;
reserveData.accruedToTreasury = baseData.accruedToTreasury;
reserveData.borrowableInIsolation = reserveConfigurationMap.getBorrowableInIsolation();
try poolDataProvider.getIsVirtualAccActive(reserveData.underlyingAsset) returns (
bool virtualAccActive
) {
reserveData.virtualAccActive = virtualAccActive;
} catch (bytes memory) {
reserveData.virtualAccActive = false;
}
try pool.getVirtualUnderlyingBalance(reserveData.underlyingAsset) returns (
uint128 virtualUnderlyingBalance
) {
reserveData.virtualUnderlyingBalance = virtualUnderlyingBalance;
} catch (bytes memory) {
reserveData.virtualUnderlyingBalance = 0;
}
}
BaseCurrencyInfo memory baseCurrencyInfo;
baseCurrencyInfo.networkBaseTokenPriceInUsd = networkBaseTokenPriceInUsdProxyAggregator
.latestAnswer();
baseCurrencyInfo.networkBaseTokenPriceDecimals = networkBaseTokenPriceInUsdProxyAggregator
.decimals();
try oracle.BASE_CURRENCY_UNIT() returns (uint256 baseCurrencyUnit) {
baseCurrencyInfo.marketReferenceCurrencyUnit = baseCurrencyUnit;
baseCurrencyInfo.marketReferenceCurrencyPriceInUsd = int256(baseCurrencyUnit);
} catch (bytes memory /*lowLevelData*/) {
baseCurrencyInfo.marketReferenceCurrencyUnit = ETH_CURRENCY_UNIT;
baseCurrencyInfo
.marketReferenceCurrencyPriceInUsd = marketReferenceCurrencyPriceInUsdProxyAggregator
.latestAnswer();
}
return (reservesData, baseCurrencyInfo);
}
/// @inheritdoc IUiPoolDataProviderV3
function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory) {
IPool pool = IPool(provider.getPool());
Emode[] memory tempCategories = new Emode[](256);
uint8 eModesFound = 0;
uint8 missCounter = 0;
for (uint8 i = 1; i < 256; i++) {
DataTypes.CollateralConfig memory cfg = pool.getEModeCategoryCollateralConfig(i);
if (cfg.liquidationThreshold != 0) {
tempCategories[eModesFound] = Emode({
eMode: DataTypes.EModeCategory({
ltv: cfg.ltv,
liquidationThreshold: cfg.liquidationThreshold,
liquidationBonus: cfg.liquidationBonus,
label: pool.getEModeCategoryLabel(i),
collateralBitmap: pool.getEModeCategoryCollateralBitmap(i),
borrowableBitmap: pool.getEModeCategoryBorrowableBitmap(i)
}),
id: i
});
++eModesFound;
missCounter = 0;
} else {
++missCounter;
}
// assumes there will never be a gap > 2 when setting eModes
if (missCounter > 2) break;
}
Emode[] memory categories = new Emode[](eModesFound);
for (uint8 i = 0; i < eModesFound; i++) {
categories[i] = tempCategories[i];
}
return categories;
}
function getUserReservesData(
IPoolAddressesProvider provider,
address user
) external view override returns (UserReserveData[] memory, uint8) {
IPool pool = IPool(provider.getPool());
address[] memory reserves = pool.getReservesList();
DataTypes.UserConfigurationMap memory userConfig = pool.getUserConfiguration(user);
uint8 userEmodeCategoryId = uint8(pool.getUserEMode(user));
UserReserveData[] memory userReservesData = new UserReserveData[](
user != address(0) ? reserves.length : 0
);
for (uint256 i = 0; i < reserves.length; i++) {
DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]);
// user reserve data
userReservesData[i].underlyingAsset = reserves[i];
userReservesData[i].scaledATokenBalance = IAToken(baseData.aTokenAddress).scaledBalanceOf(
user
);
userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i);
if (userConfig.isBorrowing(i)) {
userReservesData[i].scaledVariableDebt = IVariableDebtToken(
baseData.variableDebtTokenAddress
).scaledBalanceOf(user);
}
}
return (userReservesData, userEmodeCategoryId);
}
function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
uint8 i = 0;
while (i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IERC20} from './IERC20.sol';
interface IERC20Detailed is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IPoolAddressesProvider
* @author Aave
* @notice Defines the basic interface for a Pool Addresses Provider.
*/
interface IPoolAddressesProvider {
/**
* @dev Emitted when the market identifier is updated.
* @param oldMarketId The old id of the market
* @param newMarketId The new id of the market
*/
event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);
/**
* @dev Emitted when the pool is updated.
* @param oldAddress The old address of the Pool
* @param newAddress The new address of the Pool
*/
event PoolUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the pool configurator is updated.
* @param oldAddress The old address of the PoolConfigurator
* @param newAddress The new address of the PoolConfigurator
*/
event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the price oracle is updated.
* @param oldAddress The old address of the PriceOracle
* @param newAddress The new address of the PriceOracle
*/
event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the ACL manager is updated.
* @param oldAddress The old address of the ACLManager
* @param newAddress The new address of the ACLManager
*/
event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the ACL admin is updated.
* @param oldAddress The old address of the ACLAdmin
* @param newAddress The new address of the ACLAdmin
*/
event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the price oracle sentinel is updated.
* @param oldAddress The old address of the PriceOracleSentinel
* @param newAddress The new address of the PriceOracleSentinel
*/
event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the pool data provider is updated.
* @param oldAddress The old address of the PoolDataProvider
* @param newAddress The new address of the PoolDataProvider
*/
event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when a new proxy is created.
* @param id The identifier of the proxy
* @param proxyAddress The address of the created proxy contract
* @param implementationAddress The address of the implementation contract
*/
event ProxyCreated(
bytes32 indexed id,
address indexed proxyAddress,
address indexed implementationAddress
);
/**
* @dev Emitted when a new non-proxied contract address is registered.
* @param id The identifier of the contract
* @param oldAddress The address of the old contract
* @param newAddress The address of the new contract
*/
event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the implementation of the proxy registered with id is updated
* @param id The identifier of the contract
* @param proxyAddress The address of the proxy contract
* @param oldImplementationAddress The address of the old implementation contract
* @param newImplementationAddress The address of the new implementation contract
*/
event AddressSetAsProxy(
bytes32 indexed id,
address indexed proxyAddress,
address oldImplementationAddress,
address indexed newImplementationAddress
);
/**
* @notice Returns the id of the Aave market to which this contract points to.
* @return The market id
*/
function getMarketId() external view returns (string memory);
/**
* @notice Associates an id with a specific PoolAddressesProvider.
* @dev This can be used to create an onchain registry of PoolAddressesProviders to
* identify and validate multiple Aave markets.
* @param newMarketId The market id
*/
function setMarketId(string calldata newMarketId) external;
/**
* @notice Returns an address by its identifier.
* @dev The returned address might be an EOA or a contract, potentially proxied
* @dev It returns ZERO if there is no registered address with the given id
* @param id The id
* @return The address of the registered for the specified id
*/
function getAddress(bytes32 id) external view returns (address);
/**
* @notice General function to update the implementation of a proxy registered with
* certain `id`. If there is no proxy registered, it will instantiate one and
* set as implementation the `newImplementationAddress`.
* @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit
* setter function, in order to avoid unexpected consequences
* @param id The id
* @param newImplementationAddress The address of the new implementation
*/
function setAddressAsProxy(bytes32 id, address newImplementationAddress) external;
/**
* @notice Sets an address for an id replacing the address saved in the addresses map.
* @dev IMPORTANT Use this function carefully, as it will do a hard replacement
* @param id The id
* @param newAddress The address to set
*/
function setAddress(bytes32 id, address newAddress) external;
/**
* @notice Returns the address of the Pool proxy.
* @return The Pool proxy address
*/
function getPool() external view returns (address);
/**
* @notice Updates the implementation of the Pool, or creates a proxy
* setting the new `pool` implementation when the function is called for the first time.
* @param newPoolImpl The new Pool implementation
*/
function setPoolImpl(address newPoolImpl) external;
/**
* @notice Returns the address of the PoolConfigurator proxy.
* @return The PoolConfigurator proxy address
*/
function getPoolConfigurator() external view returns (address);
/**
* @notice Updates the implementation of the PoolConfigurator, or creates a proxy
* setting the new `PoolConfigurator` implementation when the function is called for the first time.
* @param newPoolConfiguratorImpl The new PoolConfigurator implementation
*/
function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;
/**
* @notice Returns the address of the price oracle.
* @return The address of the PriceOracle
*/
function getPriceOracle() external view returns (address);
/**
* @notice Updates the address of the price oracle.
* @param newPriceOracle The address of the new PriceOracle
*/
function setPriceOracle(address newPriceOracle) external;
/**
* @notice Returns the address of the ACL manager.
* @return The address of the ACLManager
*/
function getACLManager() external view returns (address);
/**
* @notice Updates the address of the ACL manager.
* @param newAclManager The address of the new ACLManager
*/
function setACLManager(address newAclManager) external;
/**
* @notice Returns the address of the ACL admin.
* @return The address of the ACL admin
*/
function getACLAdmin() external view returns (address);
/**
* @notice Updates the address of the ACL admin.
* @param newAclAdmin The address of the new ACL admin
*/
function setACLAdmin(address newAclAdmin) external;
/**
* @notice Returns the address of the price oracle sentinel.
* @return The address of the PriceOracleSentinel
*/
function getPriceOracleSentinel() external view returns (address);
/**
* @notice Updates the address of the price oracle sentinel.
* @param newPriceOracleSentinel The address of the new PriceOracleSentinel
*/
function setPriceOracleSentinel(address newPriceOracleSentinel) external;
/**
* @notice Returns the address of the data provider.
* @return The address of the DataProvider
*/
function getPoolDataProvider() external view returns (address);
/**
* @notice Updates the address of the data provider.
* @param newDataProvider The address of the new DataProvider
*/
function setPoolDataProvider(address newDataProvider) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
/**
* @title IPool
* @author Aave
* @notice Defines the basic interface for an Aave Pool.
*/
interface IPool {
/**
* @dev Emitted on mintUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens
* @param amount The amount of supplied assets
* @param referralCode The referral code used
*/
event MintUnbacked(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on backUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param backer The address paying for the backing
* @param amount The amount added as backing
* @param fee The amount paid in fees
*/
event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee);
/**
* @dev Emitted on supply()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supply, receiving the aTokens
* @param amount The amount supplied
* @param referralCode The referral code used
*/
event Supply(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on withdraw()
* @param reserve The address of the underlying asset being withdrawn
* @param user The address initiating the withdrawal, owner of aTokens
* @param to The address that will receive the underlying
* @param amount The amount to be withdrawn
*/
event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);
/**
* @dev Emitted on borrow() and flashLoan() when debt needs to be opened
* @param reserve The address of the underlying asset being borrowed
* @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
* initiator of the transaction on flashLoan()
* @param onBehalfOf The address that will be getting the debt
* @param amount The amount borrowed out
* @param interestRateMode The rate mode: 2 for Variable, 1 is deprecated (changed on v3.2.0)
* @param borrowRate The numeric rate at which the user has borrowed, expressed in ray
* @param referralCode The referral code used
*/
event Borrow(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 borrowRate,
uint16 indexed referralCode
);
/**
* @dev Emitted on repay()
* @param reserve The address of the underlying asset of the reserve
* @param user The beneficiary of the repayment, getting his debt reduced
* @param repayer The address of the user initiating the repay(), providing the funds
* @param amount The amount repaid
* @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly
*/
event Repay(
address indexed reserve,
address indexed user,
address indexed repayer,
uint256 amount,
bool useATokens
);
/**
* @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets
* @param asset The address of the underlying asset of the reserve
* @param totalDebt The total isolation mode debt for the reserve
*/
event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);
/**
* @dev Emitted when the user selects a certain asset category for eMode
* @param user The address of the user
* @param categoryId The category id
*/
event UserEModeSet(address indexed user, uint8 categoryId);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on flashLoan()
* @param target The address of the flash loan receiver contract
* @param initiator The address initiating the flash loan
* @param asset The address of the asset being flash borrowed
* @param amount The amount flash borrowed
* @param interestRateMode The flashloan mode: 0 for regular flashloan,
* 1 for Stable (Deprecated on v3.2.0), 2 for Variable
* @param premium The fee flash borrowed
* @param referralCode The referral code used
*/
event FlashLoan(
address indexed target,
address initiator,
address indexed asset,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 premium,
uint16 indexed referralCode
);
/**
* @dev Emitted when a borrower is liquidated.
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param liquidatedCollateralAmount The amount of collateral received by the liquidator
* @param liquidator The address of the liquidator
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
event LiquidationCall(
address indexed collateralAsset,
address indexed debtAsset,
address indexed user,
uint256 debtToCover,
uint256 liquidatedCollateralAmount,
address liquidator,
bool receiveAToken
);
/**
* @dev Emitted when the state of a reserve is updated.
* @param reserve The address of the underlying asset of the reserve
* @param liquidityRate The next liquidity rate
* @param stableBorrowRate The next stable borrow rate @note deprecated on v3.2.0
* @param variableBorrowRate The next variable borrow rate
* @param liquidityIndex The next liquidity index
* @param variableBorrowIndex The next variable borrow index
*/
event ReserveDataUpdated(
address indexed reserve,
uint256 liquidityRate,
uint256 stableBorrowRate,
uint256 variableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex
);
/**
* @dev Emitted when the 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 VariableDebtToken
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 variable debt tokens
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
*/
function borrow(
address asset,
uint256 amount,
uint256 interestRateMode,
uint16 referralCode,
address onBehalfOf
) external;
/**
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* - E.g. User repays 100 USDC, burning 100 variable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @return The final amount repaid
*/
function repay(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf
) external returns (uint256);
/**
* @notice Repay with transfer approval of asset to be repaid done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @param deadline The deadline timestamp that the permit is valid
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
* @return The final amount repaid
*/
function repayWithPermit(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external returns (uint256);
/**
* @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
* equivalent debt tokens
* - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens
* @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
* balance is not enough to cover the whole debt
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode DEPRECATED in v3.2.0
* @return The final amount repaid
*/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @notice Allows suppliers to enable/disable a specific supplied asset as collateral
* @param asset The address of the underlying asset supplied
* @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
*/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;
/**
* @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
* @param assets The addresses of the assets being flash-borrowed
* @param amounts The amounts of the assets being flash-borrowed
* @param interestRateModes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Deprecated on v3.2.0
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using 2 on `modes`
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
* @param asset The address of the asset being flash-borrowed
* @param amount The amount of the asset being flash-borrowed
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
* @return totalDebtBase The total debt of the user in the base currency used by the price feed
* @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
* @return currentLiquidationThreshold The liquidation threshold of the user
* @return ltv The loan to value of The user
* @return healthFactor The current health factor of the user
*/
function getUserAccountData(
address user
)
external
view
returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
/**
* @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an
* interest rate strategy
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param aTokenAddress The address of the aToken that will be assigned to the reserve
* @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
* @param interestRateStrategyAddress The address of the interest rate strategy contract
*/
function initReserve(
address asset,
address aTokenAddress,
address variableDebtAddress,
address interestRateStrategyAddress
) external;
/**
* @notice Drop a reserve
* @dev Only callable by the PoolConfigurator contract
* @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve.
* @param asset The address of the underlying asset of the reserve
*/
function dropReserve(address asset) external;
/**
* @notice Updates the address of the interest rate strategy contract
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The address of the interest rate strategy contract
*/
function setReserveInterestRateStrategyAddress(
address asset,
address rateStrategyAddress
) external;
/**
* @notice Accumulates interest to all indexes of the reserve
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncIndexesState(address asset) external;
/**
* @notice Updates interest rates on the reserve data
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncRatesState(address asset) external;
/**
* @notice Sets the configuration bitmap of the reserve as a whole
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param configuration The new configuration bitmap
*/
function setConfiguration(
address asset,
DataTypes.ReserveConfigurationMap calldata configuration
) external;
/**
* @notice Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
*/
function getConfiguration(
address asset
) external view returns (DataTypes.ReserveConfigurationMap memory);
/**
* @notice Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
*/
function getUserConfiguration(
address user
) external view returns (DataTypes.UserConfigurationMap memory);
/**
* @notice Returns the normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset) external view returns (uint256);
/**
* @notice Returns the normalized variable debt per unit of asset
* @dev WARNING: This function is intended to be used primarily by the protocol itself to get a
* "dynamic" variable index based on time, current stored index and virtual rate at the current
* moment (approx. a borrower would get if opening a position). This means that is always used in
* combination with variable debt supply/balances.
* If using this function externally, consider that is possible to have an increasing normalized
* variable debt that is not equivalent to how the variable debt index would be updated in storage
* (e.g. only updates with non-zero variable debt supply)
* @param asset The address of the underlying asset of the reserve
* @return The reserve normalized variable debt
*/
function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);
/**
* @notice Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve
*/
function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory);
/**
* @notice Returns the state and configuration of the reserve, including extra data included with Aave v3.1
* @dev DEPRECATED use independent getters instead (getReserveData, getLiquidationGracePeriod)
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve with virtual accounting
*/
function getReserveDataExtended(
address asset
) external view returns (DataTypes.ReserveData memory);
/**
* @notice Returns the virtual underlying balance of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve virtual underlying balance
*/
function getVirtualUnderlyingBalance(address asset) external view returns (uint128);
/**
* @notice Validates and finalizes an aToken transfer
* @dev Only callable by the overlying aToken of the `asset`
* @param asset The address of the underlying asset of the aToken
* @param from The user from which the aTokens are transferred
* @param to The user receiving the aTokens
* @param amount The amount being transferred/withdrawn
* @param balanceFromBefore The aToken balance of the `from` user before the transfer
* @param balanceToBefore The aToken balance of the `to` user before the transfer
*/
function finalizeTransfer(
address asset,
address from,
address to,
uint256 amount,
uint256 balanceFromBefore,
uint256 balanceToBefore
) external;
/**
* @notice Returns the list of the underlying assets of all the initialized reserves
* @dev It does not include dropped reserves
* @return The addresses of the underlying assets of the initialized reserves
*/
function getReservesList() external view returns (address[] memory);
/**
* @notice Returns the number of initialized reserves
* @dev It includes dropped reserves
* @return The count
*/
function getReservesCount() external view returns (uint256);
/**
* @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct
* @param id The id of the reserve as stored in the DataTypes.ReserveData struct
* @return The address of the reserve associated with id
*/
function getReserveAddressById(uint16 id) external view returns (address);
/**
* @notice Returns the PoolAddressesProvider connected to this contract
* @return The address of the PoolAddressesProvider
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Updates the protocol fee on the bridging
* @param bridgeProtocolFee The part of the premium sent to the protocol treasury
*/
function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;
/**
* @notice Updates flash loan premiums. Flash loan premium consists of two parts:
* - A part is sent to aToken holders as extra, one time accumulated interest
* - A part is collected by the protocol treasury
* @dev The total premium is calculated on the total borrowed amount
* @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`
* @dev Only callable by the PoolConfigurator contract
* @param flashLoanPremiumTotal The total premium, expressed in bps
* @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps
*/
function updateFlashloanPremiums(
uint128 flashLoanPremiumTotal,
uint128 flashLoanPremiumToProtocol
) external;
/**
* @notice Configures a new or alters an existing collateral configuration of an eMode.
* @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.
* The category 0 is reserved as it's the default for volatile assets
* @param id The id of the category
* @param config The configuration of the category
*/
function configureEModeCategory(
uint8 id,
DataTypes.EModeCategoryBaseConfiguration memory config
) external;
/**
* @notice Replaces the current eMode collateralBitmap.
* @param id The id of the category
* @param collateralBitmap The collateralBitmap of the category
*/
function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external;
/**
* @notice Replaces the current eMode borrowableBitmap.
* @param id The id of the category
* @param borrowableBitmap The borrowableBitmap of the category
*/
function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external;
/**
* @notice Returns the data of an eMode category
* @dev DEPRECATED use independent getters instead
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(
uint8 id
) external view returns (DataTypes.EModeCategoryLegacy memory);
/**
* @notice Returns the label of an eMode category
* @param id The id of the category
* @return The label of the category
*/
function getEModeCategoryLabel(uint8 id) external view returns (string memory);
/**
* @notice Returns the collateral config of an eMode category
* @param id The id of the category
* @return The ltv,lt,lb of the category
*/
function getEModeCategoryCollateralConfig(
uint8 id
) external view returns (DataTypes.CollateralConfig memory);
/**
* @notice Returns the collateralBitmap of an eMode category
* @param id The id of the category
* @return The collateralBitmap of the category
*/
function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128);
/**
* @notice Returns the borrowableBitmap of an eMode category
* @param id The id of the category
* @return The borrowableBitmap of the category
*/
function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128);
/**
* @notice Allows a user to use the protocol in eMode
* @param categoryId The id of the category
*/
function setUserEMode(uint8 categoryId) external;
/**
* @notice Returns the eMode the user is using
* @param user The address of the user
* @return The eMode id
*/
function getUserEMode(address user) external view returns (uint256);
/**
* @notice Resets the isolation mode total debt of the given asset to zero
* @dev It requires the given asset has zero debt ceiling
* @param asset The address of the underlying asset to reset the isolationModeTotalDebt
*/
function resetIsolationModeTotalDebt(address asset) external;
/**
* @notice Sets the liquidation grace period of the given asset
* @dev To enable a liquidation grace period, a timestamp in the future should be set,
* To disable a liquidation grace period, any timestamp in the past works, like 0
* @param asset The address of the underlying asset to set the liquidationGracePeriod
* @param until Timestamp when the liquidation grace period will end
**/
function setLiquidationGracePeriod(address asset, uint40 until) external;
/**
* @notice Returns the liquidation grace period of the given asset
* @param asset The address of the underlying asset
* @return Timestamp when the liquidation grace period will end
**/
function getLiquidationGracePeriod(address asset) external returns (uint40);
/**
* @notice Returns the total fee on flash loans
* @return The total fee on flashloans
*/
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
/**
* @notice Returns the part of the bridge fees sent to protocol
* @return The bridge fee sent to the protocol treasury
*/
function BRIDGE_PROTOCOL_FEE() external view returns (uint256);
/**
* @notice Returns the part of the flashloan fees sent to protocol
* @return The flashloan fee sent to the protocol treasury
*/
function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);
/**
* @notice Returns the maximum number of reserves supported to be listed in this Pool
* @return The maximum number of reserves supported
*/
function MAX_NUMBER_RESERVES() external view returns (uint16);
/**
* @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
* @param assets The list of reserves for which the minting needs to be executed
*/
function mintToTreasury(address[] calldata assets) external;
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(address token, address to, uint256 amount) external;
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @dev Deprecated: Use the `supply` function instead
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
/**
* @notice Gets the address of the external FlashLoanLogic
*/
function getFlashLoanLogic() external view returns (address);
/**
* @notice Gets the address of the external BorrowLogic
*/
function getBorrowLogic() external view returns (address);
/**
* @notice Gets the address of the external BridgeLogic
*/
function getBridgeLogic() external view returns (address);
/**
* @notice Gets the address of the external EModeLogic
*/
function getEModeLogic() external view returns (address);
/**
* @notice Gets the address of the external LiquidationLogic
*/
function getLiquidationLogic() external view returns (address);
/**
* @notice Gets the address of the external PoolLogic
*/
function getPoolLogic() external view returns (address);
/**
* @notice Gets the address of the external SupplyLogic
*/
function getSupplyLogic() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IPriceOracleGetter} from './IPriceOracleGetter.sol';
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
/**
* @title IAaveOracle
* @author Aave
* @notice Defines the basic interface for the Aave Oracle
*/
interface IAaveOracle is IPriceOracleGetter {
/**
* @dev Emitted after the base currency is set
* @param baseCurrency The base currency of used for price quotes
* @param baseCurrencyUnit The unit of the base currency
*/
event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit);
/**
* @dev Emitted after the price source of an asset is updated
* @param asset The address of the asset
* @param source The price source of the asset
*/
event AssetSourceUpdated(address indexed asset, address indexed source);
/**
* @dev Emitted after the address of fallback oracle is updated
* @param fallbackOracle The address of the fallback oracle
*/
event FallbackOracleUpdated(address indexed fallbackOracle);
/**
* @notice Returns the PoolAddressesProvider
* @return The address of the PoolAddressesProvider contract
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Sets or replaces price sources of assets
* @param assets The addresses of the assets
* @param sources The addresses of the price sources
*/
function setAssetSources(address[] calldata assets, address[] calldata sources) external;
/**
* @notice Sets the fallback oracle
* @param fallbackOracle The address of the fallback oracle
*/
function setFallbackOracle(address fallbackOracle) external;
/**
* @notice Returns a list of prices from a list of assets addresses
* @param assets The list of assets addresses
* @return The prices of the given assets
*/
function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory);
/**
* @notice Returns the address of the source for an asset address
* @param asset The address of the asset
* @return The address of the source
*/
function getSourceOfAsset(address asset) external view returns (address);
/**
* @notice Returns the address of the fallback oracle
* @return The address of the fallback oracle
*/
function getFallbackOracle() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
import {IInitializableAToken} from './IInitializableAToken.sol';
/**
* @title IAToken
* @author Aave
* @notice Defines the basic interface for an AToken.
*/
interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {
/**
* @dev Emitted during the transfer action
* @param from The user whose tokens are being transferred
* @param to The recipient
* @param value The scaled amount being transferred
* @param index The next liquidity index of the reserve
*/
event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
/**
* @notice Mints `amount` aTokens to `user`
* @param caller The address performing the mint
* @param onBehalfOf The address of the user that will receive the minted aTokens
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
* @return `true` if the the previous balance of the user was 0
*/
function mint(
address caller,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
* @dev In some instances, the mint event could be emitted from a burn transaction
* if the amount to burn is less than the interest that the user accrued
* @param from The address from which the aTokens will be burned
* @param receiverOfUnderlying The address that will receive the underlying
* @param amount The amount being burned
* @param index The next liquidity index of the reserve
*/
function burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external;
/**
* @notice Mints aTokens to the reserve treasury
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
*/
function mintToTreasury(uint256 amount, uint256 index) external;
/**
* @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* @param from The address getting liquidated, current owner of the aTokens
* @param to The recipient
* @param value The amount of tokens getting transferred
*/
function transferOnLiquidation(address from, address to, uint256 value) external;
/**
* @notice Transfers the underlying asset to `target`.
* @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan()
* @param target The recipient of the underlying
* @param amount The amount getting transferred
*/
function transferUnderlyingTo(address target, uint256 amount) external;
/**
* @notice Handles the underlying received by the aToken after the transfer has been completed.
* @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the
* transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying
* to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset.
* @param user The user executing the repayment
* @param onBehalfOf The address of the user who will get his debt reduced/removed
* @param amount The amount getting repaid
*/
function handleRepayment(address user, address onBehalfOf, uint256 amount) external;
/**
* @notice Allow passing a signed message to approve spending
* @dev implements the permit function as for
* https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
* @param owner The owner of the funds
* @param spender The spender
* @param value The amount
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @return The address of the underlying asset
*/
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
/**
* @notice Returns the address of the Aave treasury, receiving the fees on this aToken.
* @return Address of the Aave treasury
*/
function RESERVE_TREASURY_ADDRESS() external view returns (address);
/**
* @notice Get the domain separator for the token
* @dev Return cached value if chainId matches cache, otherwise recomputes separator
* @return The domain separator of the token at current chain
*/
function DOMAIN_SEPARATOR() external view returns (bytes32);
/**
* @notice Returns the nonce for owner.
* @param owner The address of the owner
* @return The nonce of the owner
*/
function nonces(address owner) external view returns (uint256);
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(address token, address to, uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
import {IInitializableDebtToken} from './IInitializableDebtToken.sol';
/**
* @title IVariableDebtToken
* @author Aave
* @notice Defines the basic interface for a variable debt token.
*/
interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken {
/**
* @notice Mints debt token to the `onBehalfOf` address
* @param user The address receiving the borrowed underlying, being the delegatee in case
* of credit delegate, or same as `onBehalfOf` otherwise
* @param onBehalfOf The address receiving the debt tokens
* @param amount The amount of debt being minted
* @param index The variable debt index of the reserve
* @return True if the previous balance of the user is 0, false otherwise
* @return The scaled total debt of the reserve
*/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool, uint256);
/**
* @notice Burns user variable debt
* @dev In some instances, a burn transaction will emit a mint event
* if the amount to burn is less than the interest that the user accrued
* @param from The address from which the debt will be burned
* @param amount The amount getting burned
* @param index The variable debt index of the reserve
* @return The scaled total debt of the reserve
*/
function burn(address from, uint256 amount, uint256 index) external returns (uint256);
/**
* @notice Returns the address of the underlying asset of this debtToken (E.g. WETH for variableDebtWETH)
* @return The address of the underlying asset
*/
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IReserveInterestRateStrategy} from './IReserveInterestRateStrategy.sol';
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
/**
* @title IDefaultInterestRateStrategyV2
* @author BGD Labs
* @notice Interface of the default interest rate strategy used by the Aave protocol
*/
interface IDefaultInterestRateStrategyV2 is IReserveInterestRateStrategy {
/**
* @notice Holds the interest rate data for a given reserve
*
* @dev Since values are in bps, they are multiplied by 1e23 in order to become rays with 27 decimals. This
* in turn means that the maximum supported interest rate is 4294967295 (2**32-1) bps or 42949672.95%.
*
* @param optimalUsageRatio The optimal usage ratio, in bps
* @param baseVariableBorrowRate The base variable borrow rate, in bps
* @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps
* @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps
*/
struct InterestRateData {
uint16 optimalUsageRatio;
uint32 baseVariableBorrowRate;
uint32 variableRateSlope1;
uint32 variableRateSlope2;
}
/**
* @notice The interest rate data, where all values are in ray (fixed-point 27 decimal numbers) for a given reserve,
* used in in-memory calculations.
*
* @param optimalUsageRatio The optimal usage ratio
* @param baseVariableBorrowRate The base variable borrow rate
* @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio
* @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio
*/
struct InterestRateDataRay {
uint256 optimalUsageRatio;
uint256 baseVariableBorrowRate;
uint256 variableRateSlope1;
uint256 variableRateSlope2;
}
/**
* @notice emitted when new interest rate data is set in a reserve
*
* @param reserve address of the reserve that has new interest rate data set
* @param optimalUsageRatio The optimal usage ratio, in bps
* @param baseVariableBorrowRate The base variable borrow rate, in bps
* @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps
* @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps
*/
event RateDataUpdate(
address indexed reserve,
uint256 optimalUsageRatio,
uint256 baseVariableBorrowRate,
uint256 variableRateSlope1,
uint256 variableRateSlope2
);
/**
* @notice Returns the address of the PoolAddressesProvider
* @return The address of the PoolAddressesProvider contract
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Returns the maximum value achievable for variable borrow rate, in bps
* @return The maximum rate
*/
function MAX_BORROW_RATE() external view returns (uint256);
/**
* @notice Returns the minimum optimal point, in bps
* @return The optimal point
*/
function MIN_OPTIMAL_POINT() external view returns (uint256);
/**
* @notice Returns the maximum optimal point, in bps
* @return The optimal point
*/
function MAX_OPTIMAL_POINT() external view returns (uint256);
/**
* notice Returns the full InterestRateData object for the given reserve, in ray
*
* @param reserve The reserve to get the data of
*
* @return The InterestRateDataRay object for the given reserve
*/
function getInterestRateData(address reserve) external view returns (InterestRateDataRay memory);
/**
* notice Returns the full InterestRateDataRay object for the given reserve, in bps
*
* @param reserve The reserve to get the data of
*
* @return The InterestRateData object for the given reserve
*/
function getInterestRateDataBps(address reserve) external view returns (InterestRateData memory);
/**
* @notice Returns the optimal usage rate for the given reserve in ray
*
* @param reserve The reserve to get the optimal usage rate of
*
* @return The optimal usage rate is the level of borrow / collateral at which the borrow rate
*/
function getOptimalUsageRatio(address reserve) external view returns (uint256);
/**
* @notice Returns the variable rate slope below optimal usage ratio in ray
* @dev It's the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO
*
* @param reserve The reserve to get the variable rate slope 1 of
*
* @return The variable rate slope
*/
function getVariableRateSlope1(address reserve) external view returns (uint256);
/**
* @notice Returns the variable rate slope above optimal usage ratio in ray
* @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO
*
* @param reserve The reserve to get the variable rate slope 2 of
*
* @return The variable rate slope
*/
function getVariableRateSlope2(address reserve) external view returns (uint256);
/**
* @notice Returns the base variable borrow rate, in ray
*
* @param reserve The reserve to get the base variable borrow rate of
*
* @return The base variable borrow rate
*/
function getBaseVariableBorrowRate(address reserve) external view returns (uint256);
/**
* @notice Returns the maximum variable borrow rate, in ray
*
* @param reserve The reserve to get the maximum variable borrow rate of
*
* @return The maximum variable borrow rate
*/
function getMaxVariableBorrowRate(address reserve) external view returns (uint256);
/**
* @notice Sets interest rate data for an Aave rate strategy
* @param reserve The reserve to update
* @param rateData The reserve interest rate data to apply to the given reserve
* Being specific to this custom implementation, with custom struct type,
* overloading the function on the generic interface
*/
function setInterestRateParams(address reserve, InterestRateData calldata rateData) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol';
import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol';
import {IPool} from '../interfaces/IPool.sol';
import {IPoolDataProvider} from '../interfaces/IPoolDataProvider.sol';
/**
* @title AaveProtocolDataProvider
* @author Aave
* @notice Peripheral contract to collect and pre-process information from the Pool.
*/
contract AaveProtocolDataProvider is IPoolDataProvider {
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
using UserConfiguration for DataTypes.UserConfigurationMap;
using WadRayMath for uint256;
address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @inheritdoc IPoolDataProvider
IPoolAddressesProvider public immutable ADDRESSES_PROVIDER;
/**
* @notice Constructor
* @param addressesProvider The address of the PoolAddressesProvider contract
*/
constructor(IPoolAddressesProvider addressesProvider) {
ADDRESSES_PROVIDER = addressesProvider;
}
/// @inheritdoc IPoolDataProvider
function getAllReservesTokens() external view override returns (TokenData[] memory) {
IPool pool = IPool(ADDRESSES_PROVIDER.getPool());
address[] memory reserves = pool.getReservesList();
TokenData[] memory reservesTokens = new TokenData[](reserves.length);
for (uint256 i = 0; i < reserves.length; i++) {
if (reserves[i] == MKR) {
reservesTokens[i] = TokenData({symbol: 'MKR', tokenAddress: reserves[i]});
continue;
}
if (reserves[i] == ETH) {
reservesTokens[i] = TokenData({symbol: 'ETH', tokenAddress: reserves[i]});
continue;
}
reservesTokens[i] = TokenData({
symbol: IERC20Detailed(reserves[i]).symbol(),
tokenAddress: reserves[i]
});
}
return reservesTokens;
}
/// @inheritdoc IPoolDataProvider
function getAllATokens() external view override returns (TokenData[] memory) {
IPool pool = IPool(ADDRESSES_PROVIDER.getPool());
address[] memory reserves = pool.getReservesList();
TokenData[] memory aTokens = new TokenData[](reserves.length);
for (uint256 i = 0; i < reserves.length; i++) {
DataTypes.ReserveDataLegacy memory reserveData = pool.getReserveData(reserves[i]);
aTokens[i] = TokenData({
symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(),
tokenAddress: reserveData.aTokenAddress
});
}
return aTokens;
}
/// @inheritdoc IPoolDataProvider
function getReserveConfigurationData(
address asset
)
external
view
override
returns (
uint256 decimals,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
uint256 reserveFactor,
bool usageAsCollateralEnabled,
bool borrowingEnabled,
bool stableBorrowRateEnabled,
bool isActive,
bool isFrozen
)
{
DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool())
.getConfiguration(asset);
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
.getParams();
(isActive, isFrozen, borrowingEnabled, ) = configuration.getFlags();
// @notice all stable debt related parameters deprecated in v3.2.0
stableBorrowRateEnabled = false;
usageAsCollateralEnabled = liquidationThreshold != 0;
}
/// @inheritdoc IPoolDataProvider
function getReserveCaps(
address asset
) external view override returns (uint256 borrowCap, uint256 supplyCap) {
(borrowCap, supplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps();
}
/// @inheritdoc IPoolDataProvider
function getPaused(address asset) external view override returns (bool isPaused) {
(, , , isPaused) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getFlags();
}
/// @inheritdoc IPoolDataProvider
function getSiloedBorrowing(address asset) external view override returns (bool) {
return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getSiloedBorrowing();
}
/// @inheritdoc IPoolDataProvider
function getLiquidationProtocolFee(address asset) external view override returns (uint256) {
return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getLiquidationProtocolFee();
}
/// @inheritdoc IPoolDataProvider
function getUnbackedMintCap(address asset) external view override returns (uint256) {
return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getUnbackedMintCap();
}
/// @inheritdoc IPoolDataProvider
function getDebtCeiling(address asset) external view override returns (uint256) {
return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getDebtCeiling();
}
/// @inheritdoc IPoolDataProvider
function getDebtCeilingDecimals() external pure override returns (uint256) {
return ReserveConfiguration.DEBT_CEILING_DECIMALS;
}
/// @inheritdoc IPoolDataProvider
function getReserveData(
address asset
)
external
view
override
returns (
uint256 unbacked,
uint256 accruedToTreasuryScaled,
uint256 totalAToken,
uint256,
uint256 totalVariableDebt,
uint256 liquidityRate,
uint256 variableBorrowRate,
uint256,
uint256,
uint256 liquidityIndex,
uint256 variableBorrowIndex,
uint40 lastUpdateTimestamp
)
{
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
// @notice all stable debt related parameters deprecated in v3.2.0
return (
reserve.unbacked,
reserve.accruedToTreasury,
IERC20Detailed(reserve.aTokenAddress).totalSupply(),
0,
IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(),
reserve.currentLiquidityRate,
reserve.currentVariableBorrowRate,
0,
0,
reserve.liquidityIndex,
reserve.variableBorrowIndex,
reserve.lastUpdateTimestamp
);
}
/// @inheritdoc IPoolDataProvider
function getATokenTotalSupply(address asset) external view override returns (uint256) {
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
return IERC20Detailed(reserve.aTokenAddress).totalSupply();
}
/// @inheritdoc IPoolDataProvider
function getTotalDebt(address asset) external view override returns (uint256) {
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
return IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply();
}
/// @inheritdoc IPoolDataProvider
function getUserReserveData(
address asset,
address user
)
external
view
override
returns (
uint256 currentATokenBalance,
uint256 currentStableDebt,
uint256 currentVariableDebt,
uint256 principalStableDebt,
uint256 scaledVariableDebt,
uint256 stableBorrowRate,
uint256 liquidityRate,
uint40 stableRateLastUpdated,
bool usageAsCollateralEnabled
)
{
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
DataTypes.UserConfigurationMap memory userConfig = IPool(ADDRESSES_PROVIDER.getPool())
.getUserConfiguration(user);
currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user);
currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user);
// @notice all stable debt related parameters deprecated in v3.2.0
currentStableDebt = principalStableDebt = stableBorrowRate = stableRateLastUpdated = 0;
scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user);
liquidityRate = reserve.currentLiquidityRate;
usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id);
}
/// @inheritdoc IPoolDataProvider
function getReserveTokensAddresses(
address asset
)
external
view
override
returns (
address aTokenAddress,
address stableDebtTokenAddress,
address variableDebtTokenAddress
)
{
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
// @notice all stable debt related parameters deprecated in v3.2.0
return (reserve.aTokenAddress, address(0), reserve.variableDebtTokenAddress);
}
/// @inheritdoc IPoolDataProvider
function getInterestRateStrategyAddress(
address asset
) external view override returns (address irStrategyAddress) {
DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(
asset
);
return (reserve.interestRateStrategyAddress);
}
/// @inheritdoc IPoolDataProvider
function getFlashLoanEnabled(address asset) external view override returns (bool) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool())
.getConfiguration(asset);
return configuration.getFlashLoanEnabled();
}
/// @inheritdoc IPoolDataProvider
function getIsVirtualAccActive(address asset) external view override returns (bool) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool())
.getConfiguration(asset);
return configuration.getIsVirtualAccActive();
}
/// @inheritdoc IPoolDataProvider
function getVirtualUnderlyingBalance(address asset) external view override returns (uint256) {
return IPool(ADDRESSES_PROVIDER.getPool()).getVirtualUnderlyingBalance(asset);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title WadRayMath library
* @author Aave
* @notice Provides functions to perform calculations with Wad and Ray units
* @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers
* with 27 digits of precision)
* @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
*/
library WadRayMath {
// HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly
uint256 internal constant WAD = 1e18;
uint256 internal constant HALF_WAD = 0.5e18;
uint256 internal constant RAY = 1e27;
uint256 internal constant HALF_RAY = 0.5e27;
uint256 internal constant WAD_RAY_RATIO = 1e9;
/**
* @dev Multiplies two wad, rounding half up to the nearest wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @param b Wad
* @return c = a*b, in wad
*/
function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b
assembly {
if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) {
revert(0, 0)
}
c := div(add(mul(a, b), HALF_WAD), WAD)
}
}
/**
* @dev Divides two wad, rounding half up to the nearest wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @param b Wad
* @return c = a/b, in wad
*/
function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - halfB) / WAD
assembly {
if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) {
revert(0, 0)
}
c := div(add(mul(a, WAD), div(b, 2)), b)
}
}
/**
* @notice Multiplies two ray, rounding half up to the nearest ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @param b Ray
* @return c = a raymul b
*/
function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b
assembly {
if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) {
revert(0, 0)
}
c := div(add(mul(a, b), HALF_RAY), RAY)
}
}
/**
* @notice Divides two ray, rounding half up to the nearest ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @param b Ray
* @return c = a raydiv b
*/
function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - halfB) / RAY
assembly {
if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) {
revert(0, 0)
}
c := div(add(mul(a, RAY), div(b, 2)), b)
}
}
/**
* @dev Casts ray down to wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @return b = a converted to wad, rounded half up to the nearest wad
*/
function rayToWad(uint256 a) internal pure returns (uint256 b) {
assembly {
b := div(a, WAD_RAY_RATIO)
let remainder := mod(a, WAD_RAY_RATIO)
if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) {
b := add(b, 1)
}
}
}
/**
* @dev Converts wad up to ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @return b = a converted in ray
*/
function wadToRay(uint256 a) internal pure returns (uint256 b) {
// to avoid overflow, b/WAD_RAY_RATIO == a
assembly {
b := mul(a, WAD_RAY_RATIO)
if iszero(eq(div(b, WAD_RAY_RATIO), a)) {
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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
// @notice there is an unoccupied hole of 1 bit at position 59 from pre 3.2 stableBorrowRateEnabled
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
// @notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory
uint256 internal constant UNBACKED_MINT_CAP_MASK = 0xFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant DEBT_CEILING_MASK = 0xF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant VIRTUAL_ACC_ACTIVE_MASK = 0xEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
/// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed
uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32;
uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48;
uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56;
uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57;
uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60;
uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61;
uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62;
uint256 internal constant FLASHLOAN_ENABLED_START_BIT_POSITION = 63;
uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116;
uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152;
//@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory
uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176;
uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212;
uint256 internal constant VIRTUAL_ACC_START_BIT_POSITION = 252;
uint256 internal constant MAX_VALID_LTV = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535;
uint256 internal constant MAX_VALID_DECIMALS = 255;
uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735;
uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735;
uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535;
uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735;
uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775;
uint256 public constant DEBT_CEILING_DECIMALS = 2;
uint16 public constant MAX_RESERVES_COUNT = 128;
/**
* @notice Sets the Loan to Value of the reserve
* @param self The reserve configuration
* @param ltv The new ltv
*/
function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV);
self.data = (self.data & LTV_MASK) | ltv;
}
/**
* @notice Gets the Loan to Value of the reserve
* @param self The reserve configuration
* @return The loan to value
*/
function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) {
return self.data & ~LTV_MASK;
}
/**
* @notice Sets the liquidation threshold of the reserve
* @param self The reserve configuration
* @param threshold The new liquidation threshold
*/
function setLiquidationThreshold(
DataTypes.ReserveConfigurationMap memory self,
uint256 threshold
) internal pure {
require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD);
self.data =
(self.data & LIQUIDATION_THRESHOLD_MASK) |
(threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation threshold of the reserve
* @param self The reserve configuration
* @return The liquidation threshold
*/
function getLiquidationThreshold(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
}
/**
* @notice Sets the liquidation bonus of the reserve
* @param self The reserve configuration
* @param bonus The new liquidation bonus
*/
function setLiquidationBonus(
DataTypes.ReserveConfigurationMap memory self,
uint256 bonus
) internal pure {
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS);
self.data =
(self.data & LIQUIDATION_BONUS_MASK) |
(bonus << LIQUIDATION_BONUS_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation bonus of the reserve
* @param self The reserve configuration
* @return The liquidation bonus
*/
function getLiquidationBonus(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION;
}
/**
* @notice Sets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @param decimals The decimals
*/
function setDecimals(
DataTypes.ReserveConfigurationMap memory self,
uint256 decimals
) internal pure {
require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS);
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
}
/**
* @notice Gets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @return The decimals of the asset
*/
function getDecimals(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
}
/**
* @notice Sets the active state of the reserve
* @param self The reserve configuration
* @param active The active state
*/
function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
self.data =
(self.data & ACTIVE_MASK) |
(uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
}
/**
* @notice Gets the active state of the reserve
* @param self The reserve configuration
* @return The active state
*/
function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~ACTIVE_MASK) != 0;
}
/**
* @notice Sets the frozen state of the reserve
* @param self The reserve configuration
* @param frozen The frozen state
*/
function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
self.data =
(self.data & FROZEN_MASK) |
(uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
}
/**
* @notice Gets the frozen state of the reserve
* @param self The reserve configuration
* @return The frozen state
*/
function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~FROZEN_MASK) != 0;
}
/**
* @notice Sets the paused state of the reserve
* @param self The reserve configuration
* @param paused The paused state
*/
function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure {
self.data =
(self.data & PAUSED_MASK) |
(uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION);
}
/**
* @notice Gets the paused state of the reserve
* @param self The reserve configuration
* @return The paused state
*/
function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~PAUSED_MASK) != 0;
}
/**
* @notice Sets the borrowable in isolation flag for the reserve.
* @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed
* amount will be accumulated in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @param borrowable True if the asset is borrowable
*/
function setBorrowableInIsolation(
DataTypes.ReserveConfigurationMap memory self,
bool borrowable
) internal pure {
self.data =
(self.data & BORROWABLE_IN_ISOLATION_MASK) |
(uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION);
}
/**
* @notice Gets the borrowable in isolation flag for the reserve.
* @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with
* isolated collateral is accounted for in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @return The borrowable in isolation flag
*/
function getBorrowableInIsolation(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0;
}
/**
* @notice Sets the siloed borrowing flag for the reserve.
* @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset.
* @param self The reserve configuration
* @param siloed True if the asset is siloed
*/
function setSiloedBorrowing(
DataTypes.ReserveConfigurationMap memory self,
bool siloed
) internal pure {
self.data =
(self.data & SILOED_BORROWING_MASK) |
(uint256(siloed ? 1 : 0) << SILOED_BORROWING_START_BIT_POSITION);
}
/**
* @notice Gets the siloed borrowing flag for the reserve.
* @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset.
* @param self The reserve configuration
* @return The siloed borrowing flag
*/
function getSiloedBorrowing(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & ~SILOED_BORROWING_MASK) != 0;
}
/**
* @notice Enables or disables borrowing on the reserve
* @param self The reserve configuration
* @param enabled True if the borrowing needs to be enabled, false otherwise
*/
function setBorrowingEnabled(
DataTypes.ReserveConfigurationMap memory self,
bool enabled
) internal pure {
self.data =
(self.data & BORROWING_MASK) |
(uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
}
/**
* @notice Gets the borrowing state of the reserve
* @param self The reserve configuration
* @return The borrowing state
*/
function getBorrowingEnabled(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & ~BORROWING_MASK) != 0;
}
/**
* @notice Sets the reserve factor of the reserve
* @param self The reserve configuration
* @param reserveFactor The reserve factor
*/
function setReserveFactor(
DataTypes.ReserveConfigurationMap memory self,
uint256 reserveFactor
) internal pure {
require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR);
self.data =
(self.data & RESERVE_FACTOR_MASK) |
(reserveFactor << RESERVE_FACTOR_START_BIT_POSITION);
}
/**
* @notice Gets the reserve factor of the reserve
* @param self The reserve configuration
* @return The reserve factor
*/
function getReserveFactor(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
}
/**
* @notice Sets the borrow cap of the reserve
* @param self The reserve configuration
* @param borrowCap The borrow cap
*/
function setBorrowCap(
DataTypes.ReserveConfigurationMap memory self,
uint256 borrowCap
) internal pure {
require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.INVALID_BORROW_CAP);
self.data = (self.data & BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION);
}
/**
* @notice Gets the borrow cap of the reserve
* @param self The reserve configuration
* @return The borrow cap
*/
function getBorrowCap(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the supply cap of the reserve
* @param self The reserve configuration
* @param supplyCap The supply cap
*/
function setSupplyCap(
DataTypes.ReserveConfigurationMap memory self,
uint256 supplyCap
) internal pure {
require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.INVALID_SUPPLY_CAP);
self.data = (self.data & SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION);
}
/**
* @notice Gets the supply cap of the reserve
* @param self The reserve configuration
* @return The supply cap
*/
function getSupplyCap(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the debt ceiling in isolation mode for the asset
* @param self The reserve configuration
* @param ceiling The maximum debt ceiling for the asset
*/
function setDebtCeiling(
DataTypes.ReserveConfigurationMap memory self,
uint256 ceiling
) internal pure {
require(ceiling <= MAX_VALID_DEBT_CEILING, Errors.INVALID_DEBT_CEILING);
self.data = (self.data & DEBT_CEILING_MASK) | (ceiling << DEBT_CEILING_START_BIT_POSITION);
}
/**
* @notice Gets the debt ceiling for the asset if the asset is in isolation mode
* @param self The reserve configuration
* @return The debt ceiling (0 = isolation mode disabled)
*/
function getDebtCeiling(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~DEBT_CEILING_MASK) >> DEBT_CEILING_START_BIT_POSITION;
}
/**
* @notice Sets the liquidation protocol fee of the reserve
* @param self The reserve configuration
* @param liquidationProtocolFee The liquidation protocol fee
*/
function setLiquidationProtocolFee(
DataTypes.ReserveConfigurationMap memory self,
uint256 liquidationProtocolFee
) internal pure {
require(
liquidationProtocolFee <= MAX_VALID_LIQUIDATION_PROTOCOL_FEE,
Errors.INVALID_LIQUIDATION_PROTOCOL_FEE
);
self.data =
(self.data & LIQUIDATION_PROTOCOL_FEE_MASK) |
(liquidationProtocolFee << LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION);
}
/**
* @dev Gets the liquidation protocol fee
* @param self The reserve configuration
* @return The liquidation protocol fee
*/
function getLiquidationProtocolFee(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return
(self.data & ~LIQUIDATION_PROTOCOL_FEE_MASK) >> LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION;
}
/**
* @notice Sets the unbacked mint cap of the reserve
* @param self The reserve configuration
* @param unbackedMintCap The unbacked mint cap
*/
function setUnbackedMintCap(
DataTypes.ReserveConfigurationMap memory self,
uint256 unbackedMintCap
) internal pure {
require(unbackedMintCap <= MAX_VALID_UNBACKED_MINT_CAP, Errors.INVALID_UNBACKED_MINT_CAP);
self.data =
(self.data & UNBACKED_MINT_CAP_MASK) |
(unbackedMintCap << UNBACKED_MINT_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the unbacked mint cap of the reserve
* @param self The reserve configuration
* @return The unbacked mint cap
*/
function getUnbackedMintCap(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & ~UNBACKED_MINT_CAP_MASK) >> UNBACKED_MINT_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the flashloanable flag for the reserve
* @param self The reserve configuration
* @param flashLoanEnabled True if the asset is flashloanable, false otherwise
*/
function setFlashLoanEnabled(
DataTypes.ReserveConfigurationMap memory self,
bool flashLoanEnabled
) internal pure {
self.data =
(self.data & FLASHLOAN_ENABLED_MASK) |
(uint256(flashLoanEnabled ? 1 : 0) << FLASHLOAN_ENABLED_START_BIT_POSITION);
}
/**
* @notice Gets the flashloanable flag for the reserve
* @param self The reserve configuration
* @return The flashloanable flag
*/
function getFlashLoanEnabled(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & ~FLASHLOAN_ENABLED_MASK) != 0;
}
/**
* @notice Sets the virtual account active/not state of the reserve
* @param self The reserve configuration
* @param active The active state
*/
function setVirtualAccActive(
DataTypes.ReserveConfigurationMap memory self,
bool active
) internal pure {
self.data =
(self.data & VIRTUAL_ACC_ACTIVE_MASK) |
(uint256(active ? 1 : 0) << VIRTUAL_ACC_START_BIT_POSITION);
}
/**
* @notice Gets the virtual account active/not state of the reserve
* @dev The state should be true for all normal assets and should be false
* only in special cases (ex. GHO) where an asset is minted instead of supplied.
* @param self The reserve configuration
* @return The active state
*/
function getIsVirtualAccActive(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & ~VIRTUAL_ACC_ACTIVE_MASK) != 0;
}
/**
* @notice Gets the configuration flags of the reserve
* @param self The reserve configuration
* @return The state flag representing active
* @return The state flag representing frozen
* @return The state flag representing borrowing enabled
* @return The state flag representing paused
*/
function getFlags(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool, bool, bool, bool) {
uint256 dataLocal = self.data;
return (
(dataLocal & ~ACTIVE_MASK) != 0,
(dataLocal & ~FROZEN_MASK) != 0,
(dataLocal & ~BORROWING_MASK) != 0,
(dataLocal & ~PAUSED_MASK) != 0
);
}
/**
* @notice Gets the configuration parameters of the reserve from storage
* @param self The reserve configuration
* @return The state param representing ltv
* @return The state param representing liquidation threshold
* @return The state param representing liquidation bonus
* @return The state param representing reserve decimals
* @return The state param representing reserve factor
*/
function getParams(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256, uint256, uint256, uint256, uint256) {
uint256 dataLocal = self.data;
return (
dataLocal & ~LTV_MASK,
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
);
}
/**
* @notice Gets the caps parameters of the reserve from storage
* @param self The reserve configuration
* @return The state param representing borrow cap
* @return The state param representing supply cap.
*/
function getCaps(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256, uint256) {
uint256 dataLocal = self.data;
return (
(dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Errors} from '../helpers/Errors.sol';
import {DataTypes} from '../types/DataTypes.sol';
import {ReserveConfiguration} from './ReserveConfiguration.sol';
/**
* @title UserConfiguration library
* @author Aave
* @notice Implements the bitmap logic to handle the user configuration
*/
library UserConfiguration {
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
uint256 internal constant BORROWING_MASK =
0x5555555555555555555555555555555555555555555555555555555555555555;
uint256 internal constant COLLATERAL_MASK =
0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
/**
* @notice Sets if the user is borrowing the reserve identified by reserveIndex
* @param self The configuration object
* @param reserveIndex The index of the reserve in the bitmap
* @param borrowing True if the user is borrowing the reserve, false otherwise
*/
function setBorrowing(
DataTypes.UserConfigurationMap storage self,
uint256 reserveIndex,
bool borrowing
) internal {
unchecked {
require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX);
uint256 bit = 1 << (reserveIndex << 1);
if (borrowing) {
self.data |= bit;
} else {
self.data &= ~bit;
}
}
}
/**
* @notice Sets if the user is using as collateral the reserve identified by reserveIndex
* @param self The configuration object
* @param reserveIndex The index of the reserve in the bitmap
* @param usingAsCollateral True if the user is using the reserve as collateral, false otherwise
*/
function setUsingAsCollateral(
DataTypes.UserConfigurationMap storage self,
uint256 reserveIndex,
bool usingAsCollateral
) internal {
unchecked {
require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX);
uint256 bit = 1 << ((reserveIndex << 1) + 1);
if (usingAsCollateral) {
self.data |= bit;
} else {
self.data &= ~bit;
}
}
}
/**
* @notice Returns if a user has been using the reserve for borrowing or as collateral
* @param self The configuration object
* @param reserveIndex The index of the reserve in the bitmap
* @return True if the user has been using a reserve for borrowing or as collateral, false otherwise
*/
function isUsingAsCollateralOrBorrowing(
DataTypes.UserConfigurationMap memory self,
uint256 reserveIndex
) internal pure returns (bool) {
unchecked {
require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX);
return (self.data >> (reserveIndex << 1)) & 3 != 0;
}
}
/**
* @notice Validate a user has been using the reserve for borrowing
* @param self The configuration object
* @param reserveIndex The index of the reserve in the bitmap
* @return True if the user has been using a reserve for borrowing, false otherwise
*/
function isBorrowing(
DataTypes.UserConfigurationMap memory self,
uint256 reserveIndex
) internal pure returns (bool) {
unchecked {
require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX);
return (self.data >> (reserveIndex << 1)) & 1 != 0;
}
}
/**
* @notice Validate a user has been using the reserve as collateral
* @param self The configuration object
* @param reserveIndex The index of the reserve in the bitmap
* @return True if the user has been using a reserve as collateral, false otherwise
*/
function isUsingAsCollateral(
DataTypes.UserConfigurationMap memory self,
uint256 reserveIndex
) internal pure returns (bool) {
unchecked {
require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX);
return (self.data >> ((reserveIndex << 1) + 1)) & 1 != 0;
}
}
/**
* @notice Checks if a user has been supplying only one reserve as collateral
* @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0
* @param self The configuration object
* @return True if the user has been supplying as collateral one reserve, false otherwise
*/
function isUsingAsCollateralOne(
DataTypes.UserConfigurationMap memory self
) internal pure returns (bool) {
uint256 collateralData = self.data & COLLATERAL_MASK;
return collateralData != 0 && (collateralData & (collateralData - 1) == 0);
}
/**
* @notice Checks if a user has been supplying any reserve as collateral
* @param self The configuration object
* @return True if the user has been supplying as collateral any reserve, false otherwise
*/
function isUsingAsCollateralAny(
DataTypes.UserConfigurationMap memory self
) internal pure returns (bool) {
return self.data & COLLATERAL_MASK != 0;
}
/**
* @notice Checks if a user has been borrowing only one asset
* @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0
* @param self The configuration object
* @return True if the user has been supplying as collateral one reserve, false otherwise
*/
function isBorrowingOne(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
uint256 borrowingData = self.data & BORROWING_MASK;
return borrowingData != 0 && (borrowingData & (borrowingData - 1) == 0);
}
/**
* @notice Checks if a user has been borrowing from any reserve
* @param self The configuration object
* @return True if the user has been borrowing any reserve, false otherwise
*/
function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
return self.data & BORROWING_MASK != 0;
}
/**
* @notice Checks if a user has not been using any reserve for borrowing or supply
* @param self The configuration object
* @return True if the user has not been borrowing or supplying any reserve, false otherwise
*/
function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
return self.data == 0;
}
/**
* @notice Returns the Isolation Mode state of the user
* @param self The configuration object
* @param reservesData The state of all the reserves
* @param reservesList The addresses of all the active reserves
* @return True if the user is in isolation mode, false otherwise
* @return The address of the only asset used as collateral
* @return The debt ceiling of the reserve
*/
function getIsolationModeState(
DataTypes.UserConfigurationMap memory self,
mapping(address => DataTypes.ReserveData) storage reservesData,
mapping(uint256 => address) storage reservesList
) internal view returns (bool, address, uint256) {
if (isUsingAsCollateralOne(self)) {
uint256 assetId = _getFirstAssetIdByMask(self, COLLATERAL_MASK);
address assetAddress = reservesList[assetId];
uint256 ceiling = reservesData[assetAddress].configuration.getDebtCeiling();
if (ceiling != 0) {
return (true, assetAddress, ceiling);
}
}
return (false, address(0), 0);
}
/**
* @notice Returns the siloed borrowing state for the user
* @param self The configuration object
* @param reservesData The data of all the reserves
* @param reservesList The reserve list
* @return True if the user has borrowed a siloed asset, false otherwise
* @return The address of the only borrowed asset
*/
function getSiloedBorrowingState(
DataTypes.UserConfigurationMap memory self,
mapping(address => DataTypes.ReserveData) storage reservesData,
mapping(uint256 => address) storage reservesList
) internal view returns (bool, address) {
if (isBorrowingOne(self)) {
uint256 assetId = _getFirstAssetIdByMask(self, BORROWING_MASK);
address assetAddress = reservesList[assetId];
if (reservesData[assetAddress].configuration.getSiloedBorrowing()) {
return (true, assetAddress);
}
}
return (false, address(0));
}
/**
* @notice Returns the address of the first asset flagged in the bitmap given the corresponding bitmask
* @param self The configuration object
* @return The index of the first asset flagged in the bitmap once the corresponding mask is applied
*/
function _getFirstAssetIdByMask(
DataTypes.UserConfigurationMap memory self,
uint256 mask
) internal pure returns (uint256) {
unchecked {
uint256 bitmapData = self.data & mask;
uint256 firstAssetPosition = bitmapData & ~(bitmapData - 1);
uint256 id;
while ((firstAssetPosition >>= 2) != 0) {
id += 1;
}
return id;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library DataTypes {
/**
* This exists specifically to maintain the `getReserveData()` interface, since the new, internal
* `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`.
*/
struct ReserveDataLegacy {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
// DEPRECATED on v3.2.0
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
// DEPRECATED on v3.2.0
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
struct ReserveData {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
// DEPRECATED on v3.2.0
uint128 __deprecatedStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed
uint40 liquidationGracePeriodUntil;
//aToken address
address aTokenAddress;
// DEPRECATED on v3.2.0
address __deprecatedStableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
//the amount of underlying accounted for by the protocol
uint128 virtualUnderlyingBalance;
}
struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: DEPRECATED: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62: siloed borrowing enabled
//bit 63: flashloaning enabled
//bit 64-79: reserve factor
//bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167: liquidation protocol fee
//bit 168-175: DEPRECATED: eMode category
//bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252: virtual accounting is enabled for the reserve
//bit 253-255 unused
uint256 data;
}
struct UserConfigurationMap {
/**
* @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
* The first bit indicates if an asset is used as collateral by the user, the second whether an
* asset is borrowed by the user.
*/
uint256 data;
}
// DEPRECATED: kept for backwards compatibility, might be removed in a future version
struct EModeCategoryLegacy {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// DEPRECATED
address priceSource;
string label;
}
struct CollateralConfig {
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
}
struct EModeCategoryBaseConfiguration {
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
string label;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
uint128 collateralBitmap;
string label;
uint128 borrowableBitmap;
}
enum InterestRateMode {
NONE,
__DEPRECATED,
VARIABLE
}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
}
struct ExecuteLiquidationCallParams {
uint256 reservesCount;
uint256 debtToCover;
address collateralAsset;
address debtAsset;
address user;
bool receiveAToken;
address priceOracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteSupplyParams {
address asset;
uint256 amount;
address onBehalfOf;
uint16 referralCode;
}
struct ExecuteBorrowParams {
address asset;
address user;
address onBehalfOf;
uint256 amount;
InterestRateMode interestRateMode;
uint16 referralCode;
bool releaseUnderlying;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteRepayParams {
address asset;
uint256 amount;
InterestRateMode interestRateMode;
address onBehalfOf;
bool useATokens;
}
struct ExecuteWithdrawParams {
address asset;
uint256 amount;
address to;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteSetUserEModeParams {
uint256 reservesCount;
address oracle;
uint8 categoryId;
}
struct FinalizeTransferParams {
address asset;
address from;
address to;
uint256 amount;
uint256 balanceFromBefore;
uint256 balanceToBefore;
uint256 reservesCount;
address oracle;
uint8 fromEModeCategory;
}
struct FlashloanParams {
address receiverAddress;
address[] assets;
uint256[] amounts;
uint256[] interestRateModes;
address onBehalfOf;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
uint256 reservesCount;
address addressesProvider;
address pool;
uint8 userEModeCategory;
bool isAuthorizedFlashBorrower;
}
struct FlashloanSimpleParams {
address receiverAddress;
address asset;
uint256 amount;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
}
struct FlashLoanRepaymentParams {
uint256 amount;
uint256 totalPremium;
uint256 flashLoanPremiumToProtocol;
address asset;
address receiverAddress;
uint16 referralCode;
}
struct CalculateUserAccountDataParams {
UserConfigurationMap userConfig;
uint256 reservesCount;
address user;
address oracle;
uint8 userEModeCategory;
}
struct ValidateBorrowParams {
ReserveCache reserveCache;
UserConfigurationMap userConfig;
address asset;
address userAddress;
uint256 amount;
InterestRateMode interestRateMode;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
bool isolationModeActive;
address isolationModeCollateralAddress;
uint256 isolationModeDebtCeiling;
}
struct ValidateLiquidationCallParams {
ReserveCache debtReserveCache;
uint256 totalDebt;
uint256 healthFactor;
address priceOracleSentinel;
}
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalDebt;
uint256 reserveFactor;
address reserve;
bool usingVirtualBalance;
uint256 virtualUnderlyingBalance;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address variableDebtAddress;
address interestRateStrategyAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
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: MIT
pragma solidity ^0.8.10;
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
interface IERC20DetailedBytes is IERC20 {
function name() external view returns (bytes32);
function symbol() external view returns (bytes32);
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol';
interface IUiPoolDataProviderV3 {
struct AggregatedReserveData {
address underlyingAsset;
string name;
string symbol;
uint256 decimals;
uint256 baseLTVasCollateral;
uint256 reserveLiquidationThreshold;
uint256 reserveLiquidationBonus;
uint256 reserveFactor;
bool usageAsCollateralEnabled;
bool borrowingEnabled;
bool isActive;
bool isFrozen;
// base data
uint128 liquidityIndex;
uint128 variableBorrowIndex;
uint128 liquidityRate;
uint128 variableBorrowRate;
uint40 lastUpdateTimestamp;
address aTokenAddress;
address variableDebtTokenAddress;
address interestRateStrategyAddress;
//
uint256 availableLiquidity;
uint256 totalScaledVariableDebt;
uint256 priceInMarketReferenceCurrency;
address priceOracle;
uint256 variableRateSlope1;
uint256 variableRateSlope2;
uint256 baseVariableBorrowRate;
uint256 optimalUsageRatio;
// v3 only
bool isPaused;
bool isSiloedBorrowing;
uint128 accruedToTreasury;
uint128 unbacked;
uint128 isolationModeTotalDebt;
bool flashLoanEnabled;
//
uint256 debtCeiling;
uint256 debtCeilingDecimals;
uint256 borrowCap;
uint256 supplyCap;
bool borrowableInIsolation;
// v3.1
bool virtualAccActive;
uint128 virtualUnderlyingBalance;
}
struct UserReserveData {
address underlyingAsset;
uint256 scaledATokenBalance;
bool usageAsCollateralEnabledOnUser;
uint256 scaledVariableDebt;
}
struct BaseCurrencyInfo {
uint256 marketReferenceCurrencyUnit;
int256 marketReferenceCurrencyPriceInUsd;
int256 networkBaseTokenPriceInUsd;
uint8 networkBaseTokenPriceDecimals;
}
struct Emode {
uint8 id;
DataTypes.EModeCategory eMode;
}
function getReservesList(
IPoolAddressesProvider provider
) external view returns (address[] memory);
function getReservesData(
IPoolAddressesProvider provider
) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory);
function getUserReservesData(
IPoolAddressesProvider provider,
address user
) external view returns (UserReserveData[] memory, uint8);
/**
* @dev Iterates the eModes mapping and returns all eModes found
* @notice The method assumes for id gaps <= 2 within the eMode definitions
* @return an array of eModes that were found in the eMode mapping
*/
function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IPriceOracleGetter
* @author Aave
* @notice Interface for the Aave price oracle.
*/
interface IPriceOracleGetter {
/**
* @notice Returns the base currency address
* @dev Address 0x0 is reserved for USD as base currency.
* @return Returns the base currency address.
*/
function BASE_CURRENCY() external view returns (address);
/**
* @notice Returns the base currency unit
* @dev 1 ether for ETH, 1e8 for USD.
* @return Returns the base currency unit.
*/
function BASE_CURRENCY_UNIT() external view returns (uint256);
/**
* @notice Returns the asset price in the base currency
* @param asset The address of the asset
* @return The price of the asset
*/
function getAssetPrice(address asset) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IScaledBalanceToken
* @author Aave
* @notice Defines the basic interface for a scaled-balance token.
*/
interface IScaledBalanceToken {
/**
* @dev Emitted after the mint action
* @param caller The address performing the mint
* @param onBehalfOf The address of the user that will receive the minted tokens
* @param value The scaled-up amount being minted (based on user entered amount and balance increase from interest)
* @param balanceIncrease The increase in scaled-up balance since the last action of 'onBehalfOf'
* @param index The next liquidity index of the reserve
*/
event Mint(
address indexed caller,
address indexed onBehalfOf,
uint256 value,
uint256 balanceIncrease,
uint256 index
);
/**
* @dev Emitted after the burn action
* @dev If the burn function does not involve a transfer of the underlying asset, the target defaults to zero address
* @param from The address from which the tokens will be burned
* @param target The address that will receive the underlying, if any
* @param value The scaled-up amount being burned (user entered amount - balance increase from interest)
* @param balanceIncrease The increase in scaled-up balance since the last action of 'from'
* @param index The next liquidity index of the reserve
*/
event Burn(
address indexed from,
address indexed target,
uint256 value,
uint256 balanceIncrease,
uint256 index
);
/**
* @notice Returns the scaled balance of the user.
* @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index
* at the moment of the update
* @param user The user whose balance is calculated
* @return The scaled balance of the user
*/
function scaledBalanceOf(address user) external view returns (uint256);
/**
* @notice Returns the scaled balance of the user and the scaled total supply.
* @param user The address of the user
* @return The scaled balance of the user
* @return The scaled total supply
*/
function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);
/**
* @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index)
* @return The scaled total supply
*/
function scaledTotalSupply() external view returns (uint256);
/**
* @notice Returns last index interest was accrued to the user's balance
* @param user The address of the user
* @return The last index interest was accrued to the user's balance, expressed in ray
*/
function getPreviousIndex(address user) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
import {IPool} from './IPool.sol';
/**
* @title IInitializableAToken
* @author Aave
* @notice Interface for the initialize function on AToken
*/
interface IInitializableAToken {
/**
* @dev Emitted when an aToken is initialized
* @param underlyingAsset The address of the underlying asset
* @param pool The address of the associated pool
* @param treasury The address of the treasury
* @param incentivesController The address of the incentives controller for this aToken
* @param aTokenDecimals The decimals of the underlying
* @param aTokenName The name of the aToken
* @param aTokenSymbol The symbol of the aToken
* @param params A set of encoded parameters for additional initialization
*/
event Initialized(
address indexed underlyingAsset,
address indexed pool,
address treasury,
address incentivesController,
uint8 aTokenDecimals,
string aTokenName,
string aTokenSymbol,
bytes params
);
/**
* @notice Initializes the aToken
* @param pool The pool contract that is initializing this contract
* @param treasury The address of the Aave treasury, receiving the fees on this aToken
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @param incentivesController The smart contract managing potential incentives distribution
* @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
* @param aTokenName The name of the aToken
* @param aTokenSymbol The symbol of the aToken
* @param params A set of encoded parameters for additional initialization
*/
function initialize(
IPool pool,
address treasury,
address underlyingAsset,
IAaveIncentivesController incentivesController,
uint8 aTokenDecimals,
string calldata aTokenName,
string calldata aTokenSymbol,
bytes calldata params
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
import {IPool} from './IPool.sol';
/**
* @title IInitializableDebtToken
* @author Aave
* @notice Interface for the initialize function common between debt tokens
*/
interface IInitializableDebtToken {
/**
* @dev Emitted when a debt token is initialized
* @param underlyingAsset The address of the underlying asset
* @param pool The address of the associated pool
* @param incentivesController The address of the incentives controller for this aToken
* @param debtTokenDecimals The decimals of the debt token
* @param debtTokenName The name of the debt token
* @param debtTokenSymbol The symbol of the debt token
* @param params A set of encoded parameters for additional initialization
*/
event Initialized(
address indexed underlyingAsset,
address indexed pool,
address incentivesController,
uint8 debtTokenDecimals,
string debtTokenName,
string debtTokenSymbol,
bytes params
);
/**
* @notice Initializes the debt token.
* @param pool The pool contract that is initializing this contract
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @param incentivesController The smart contract managing potential incentives distribution
* @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
* @param debtTokenName The name of the token
* @param debtTokenSymbol The symbol of the token
* @param params A set of encoded parameters for additional initialization
*/
function initialize(
IPool pool,
address underlyingAsset,
IAaveIncentivesController incentivesController,
uint8 debtTokenDecimals,
string memory debtTokenName,
string memory debtTokenSymbol,
bytes calldata params
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
/**
* @title IReserveInterestRateStrategy
* @author BGD Labs
* @notice Basic interface for any rate strategy used by the Aave protocol
*/
interface IReserveInterestRateStrategy {
/**
* @notice Sets interest rate data for an Aave rate strategy
* @param reserve The reserve to update
* @param rateData The abi encoded reserve interest rate data to apply to the given reserve
* Abstracted this way as rate strategies can be custom
*/
function setInterestRateParams(address reserve, bytes calldata rateData) external;
/**
* @notice Calculates the interest rates depending on the reserve's state and configurations
* @param params The parameters needed to calculate interest rates
* @return liquidityRate The liquidity rate expressed in ray
* @return variableBorrowRate The variable borrow rate expressed in ray
*/
function calculateInterestRates(
DataTypes.CalculateInterestRatesParams memory params
) external view returns (uint256, uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
/**
* @title IPoolDataProvider
* @author Aave
* @notice Defines the basic interface of a PoolDataProvider
*/
interface IPoolDataProvider {
struct TokenData {
string symbol;
address tokenAddress;
}
/**
* @notice Returns the address for the PoolAddressesProvider contract.
* @return The address for the PoolAddressesProvider contract
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Returns the list of the existing reserves in the pool.
* @dev Handling MKR and ETH in a different way since they do not have standard `symbol` functions.
* @return The list of reserves, pairs of symbols and addresses
*/
function getAllReservesTokens() external view returns (TokenData[] memory);
/**
* @notice Returns the list of the existing ATokens in the pool.
* @return The list of ATokens, pairs of symbols and addresses
*/
function getAllATokens() external view returns (TokenData[] memory);
/**
* @notice Returns the configuration data of the reserve
* @dev Not returning borrow and supply caps for compatibility, nor pause flag
* @param asset The address of the underlying asset of the reserve
* @return decimals The number of decimals of the reserve
* @return ltv The ltv of the reserve
* @return liquidationThreshold The liquidationThreshold of the reserve
* @return liquidationBonus The liquidationBonus of the reserve
* @return reserveFactor The reserveFactor of the reserve
* @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise
* @return borrowingEnabled True if borrowing is enabled, false otherwise
* @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise
* @return isActive True if it is active, false otherwise
* @return isFrozen True if it is frozen, false otherwise
*/
function getReserveConfigurationData(
address asset
)
external
view
returns (
uint256 decimals,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
uint256 reserveFactor,
bool usageAsCollateralEnabled,
bool borrowingEnabled,
bool stableBorrowRateEnabled,
bool isActive,
bool isFrozen
);
/**
* @notice Returns the caps parameters of the reserve
* @param asset The address of the underlying asset of the reserve
* @return borrowCap The borrow cap of the reserve
* @return supplyCap The supply cap of the reserve
*/
function getReserveCaps(
address asset
) external view returns (uint256 borrowCap, uint256 supplyCap);
/**
* @notice Returns if the pool is paused
* @param asset The address of the underlying asset of the reserve
* @return isPaused True if the pool is paused, false otherwise
*/
function getPaused(address asset) external view returns (bool isPaused);
/**
* @notice Returns the siloed borrowing flag
* @param asset The address of the underlying asset of the reserve
* @return True if the asset is siloed for borrowing
*/
function getSiloedBorrowing(address asset) external view returns (bool);
/**
* @notice Returns the protocol fee on the liquidation bonus
* @param asset The address of the underlying asset of the reserve
* @return The protocol fee on liquidation
*/
function getLiquidationProtocolFee(address asset) external view returns (uint256);
/**
* @notice Returns the unbacked mint cap of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The unbacked mint cap of the reserve
*/
function getUnbackedMintCap(address asset) external view returns (uint256);
/**
* @notice Returns the debt ceiling of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The debt ceiling of the reserve
*/
function getDebtCeiling(address asset) external view returns (uint256);
/**
* @notice Returns the debt ceiling decimals
* @return The debt ceiling decimals
*/
function getDebtCeilingDecimals() external pure returns (uint256);
/**
* @notice Returns the reserve data
* @param asset The address of the underlying asset of the reserve
* @return unbacked The amount of unbacked tokens
* @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted
* @return totalAToken The total supply of the aToken
* @return totalStableDebt The total stable debt of the reserve
* @return totalVariableDebt The total variable debt of the reserve
* @return liquidityRate The liquidity rate of the reserve
* @return variableBorrowRate The variable borrow rate of the reserve
* @return stableBorrowRate The stable borrow rate of the reserve
* @return averageStableBorrowRate The average stable borrow rate of the reserve
* @return liquidityIndex The liquidity index of the reserve
* @return variableBorrowIndex The variable borrow index of the reserve
* @return lastUpdateTimestamp The timestamp of the last update of the reserve
*/
function getReserveData(
address asset
)
external
view
returns (
uint256 unbacked,
uint256 accruedToTreasuryScaled,
uint256 totalAToken,
uint256 totalStableDebt,
uint256 totalVariableDebt,
uint256 liquidityRate,
uint256 variableBorrowRate,
uint256 stableBorrowRate,
uint256 averageStableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex,
uint40 lastUpdateTimestamp
);
/**
* @notice Returns the total supply of aTokens for a given asset
* @param asset The address of the underlying asset of the reserve
* @return The total supply of the aToken
*/
function getATokenTotalSupply(address asset) external view returns (uint256);
/**
* @notice Returns the total debt for a given asset
* @param asset The address of the underlying asset of the reserve
* @return The total debt for asset
*/
function getTotalDebt(address asset) external view returns (uint256);
/**
* @notice Returns the user data in a reserve
* @param asset The address of the underlying asset of the reserve
* @param user The address of the user
* @return currentATokenBalance The current AToken balance of the user
* @return currentStableDebt The current stable debt of the user
* @return currentVariableDebt The current variable debt of the user
* @return principalStableDebt The principal stable debt of the user
* @return scaledVariableDebt The scaled variable debt of the user
* @return stableBorrowRate The stable borrow rate of the user
* @return liquidityRate The liquidity rate of the reserve
* @return stableRateLastUpdated The timestamp of the last update of the user stable rate
* @return usageAsCollateralEnabled True if the user is using the asset as collateral, false
* otherwise
*/
function getUserReserveData(
address asset,
address user
)
external
view
returns (
uint256 currentATokenBalance,
uint256 currentStableDebt,
uint256 currentVariableDebt,
uint256 principalStableDebt,
uint256 scaledVariableDebt,
uint256 stableBorrowRate,
uint256 liquidityRate,
uint40 stableRateLastUpdated,
bool usageAsCollateralEnabled
);
/**
* @notice Returns the token addresses of the reserve
* @param asset The address of the underlying asset of the reserve
* @return aTokenAddress The AToken address of the reserve
* @return stableDebtTokenAddress DEPRECATED in v3.2.0
* @return variableDebtTokenAddress The VariableDebtToken address of the reserve
*/
function getReserveTokensAddresses(
address asset
)
external
view
returns (
address aTokenAddress,
address stableDebtTokenAddress,
address variableDebtTokenAddress
);
/**
* @notice Returns the address of the Interest Rate strategy
* @param asset The address of the underlying asset of the reserve
* @return irStrategyAddress The address of the Interest Rate strategy
*/
function getInterestRateStrategyAddress(
address asset
) external view returns (address irStrategyAddress);
/**
* @notice Returns whether the reserve has FlashLoans enabled or disabled
* @param asset The address of the underlying asset of the reserve
* @return True if FlashLoans are enabled, false otherwise
*/
function getFlashLoanEnabled(address asset) external view returns (bool);
/**
* @notice Returns whether virtual accounting is enabled/not for a reserve
* @param asset The address of the underlying asset of the reserve
* @return True if active, false otherwise
*/
function getIsVirtualAccActive(address asset) external view returns (bool);
/**
* @notice Returns the virtual underlying balance of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve virtual underlying balance
*/
function getVirtualUnderlyingBalance(address asset) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title Errors library
* @author Aave
* @notice Defines the error messages emitted by the different contracts of the Aave protocol
*/
library Errors {
string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin'
string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin'
string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin'
string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin'
string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin'
string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge'
string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered'
string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider'
string public constant NOT_CONTRACT = '9'; // 'Address is not a contract'
string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator'
string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken'
string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid'
string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function'
string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list'
string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached'
string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets'
string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset'
string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0'
string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium'
string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve'
string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category'
string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee'
string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool'
string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint'
string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn'
string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0'
string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve'
string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen'
string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused'
string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled'
string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance'
string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected'
string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0'
string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold'
string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow'
string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed'
string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type'
string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed'
string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve'
string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0'
string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met'
string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold'
string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated'
string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency'
string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters'
string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded'
string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded'
string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded'
string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded'
string public constant UNDERLYING_CLAIMABLE_RIGHTS_NOT_ZERO = '54'; // 'Claimable rights over underlying not zero (aToken supply or accruedToTreasury)'
string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero'
string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed'
string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category'
string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed'
string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode'
string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized'
string public constant USER_IN_ISOLATION_MODE_OR_LTV_ZERO = '62'; // 'User is in isolation mode or ltv is zero'
string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve'
string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve'
string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve'
string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve'
string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve'
string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve'
string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve'
string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve'
string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve'
string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve'
string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve
string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index'
string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address'
string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not'
string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid'
string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration'
string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature'
string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported'
string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero'
string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed'
string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio'
string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued'
string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list'
string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match'
string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one'
string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0
string public constant FLASHLOAN_DISABLED = '91'; // FlashLoaning for this asset is disabled
string public constant INVALID_MAX_RATE = '92'; // The expect maximum borrow rate is invalid
string public constant WITHDRAW_TO_ATOKEN = '93'; // Withdrawing to the aToken is not allowed
string public constant SUPPLY_TO_ATOKEN = '94'; // Supplying to the aToken is not allowed
string public constant SLOPE_2_MUST_BE_GTE_SLOPE_1 = '95'; // Variable interest rate slope 2 can not be lower than slope 1
string public constant CALLER_NOT_RISK_OR_POOL_OR_EMERGENCY_ADMIN = '96'; // 'The caller of the function is not a risk, pool or emergency admin'
string public constant LIQUIDATION_GRACE_SENTINEL_CHECK_FAILED = '97'; // 'Liquidation grace sentinel validation failed'
string public constant INVALID_GRACE_PERIOD = '98'; // Grace period above a valid range
string public constant INVALID_FREEZE_STATE = '99'; // Reserve is already in the passed freeze state
string public constant NOT_BORROWABLE_IN_EMODE = '100'; // Asset not borrowable in eMode
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IAaveIncentivesController
* @author Aave
* @notice Defines the basic interface for an Aave Incentives Controller.
* @dev It only contains one single function, needed as a hook on aToken and debtToken transfers.
*/
interface IAaveIncentivesController {
/**
* @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution.
* @dev The units of `totalSupply` and `userBalance` should be the same.
* @param user The address of the user whose asset balance has changed
* @param totalSupply The total supply of the asset prior to user balance change
* @param userBalance The previous user balance prior to balance change
*/
function handleAction(address user, uint256 totalSupply, uint256 userBalance) external;
}{
"remappings": [
"@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@pythnetwork/=lib/pyth-sdk-solidity/",
"@money-market/=contracts/moneyMarket/src/",
"@money-market-scripts/=contracts/moneyMarket/scripts/",
"@money-market-tests/=contracts/moneyMarket/tests/",
"@contracts/=contracts/",
"solidity-utils/=lib/solidity-utils/src/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/",
"pyth-sdk-solidity/=lib/pyth-sdk-solidity/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false,
"libraries": {
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/BorrowLogic.sol": {
"BorrowLogic": "0x8d2517e8eb3a288813F3d86Acf72583c93137cC7"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/BridgeLogic.sol": {
"BridgeLogic": "0x4Fa0B79Cd0382b8bf9F90755Ae2dB1004b67Ba12"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol": {
"ConfiguratorLogic": "0x616a5cAab4973a741E18Ba95B8Dfa766de34Fb71"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/EModeLogic.sol": {
"EModeLogic": "0xfC1E2b81f2b20D829E05BcEa902a9959CE083F0A"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/FlashLoanLogic.sol": {
"FlashLoanLogic": "0xEa33385DD1De5790b49752449B8C4f88e5013ac3"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/LiquidationLogic.sol": {
"LiquidationLogic": "0x634E2130c0B8EbF1a3eF111A0337f23cFF28d19A"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/PoolLogic.sol": {
"PoolLogic": "0xedeae456C72c464E917C690DE562eC02a7b426B4"
},
"contracts/moneyMarket/src/contracts/protocol/libraries/logic/SupplyLogic.sol": {
"SupplyLogic": "0x16D26622643973B3ea574280998572F220Ede139"
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IEACAggregatorProxy","name":"_networkBaseTokenPriceInUsdProxyAggregator","type":"address"},{"internalType":"contract IEACAggregatorProxy","name":"_marketReferenceCurrencyPriceInUsdProxyAggregator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ETH_CURRENCY_UNIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MKR_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_bytes32","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"}],"name":"getEModes","outputs":[{"components":[{"internalType":"uint8","name":"id","type":"uint8"},{"components":[{"internalType":"uint16","name":"ltv","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBonus","type":"uint16"},{"internalType":"uint128","name":"collateralBitmap","type":"uint128"},{"internalType":"string","name":"label","type":"string"},{"internalType":"uint128","name":"borrowableBitmap","type":"uint128"}],"internalType":"struct DataTypes.EModeCategory","name":"eMode","type":"tuple"}],"internalType":"struct IUiPoolDataProviderV3.Emode[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"}],"name":"getReservesData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"baseLTVasCollateral","type":"uint256"},{"internalType":"uint256","name":"reserveLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"reserveLiquidationBonus","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"},{"internalType":"bool","name":"borrowingEnabled","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isFrozen","type":"bool"},{"internalType":"uint128","name":"liquidityIndex","type":"uint128"},{"internalType":"uint128","name":"variableBorrowIndex","type":"uint128"},{"internalType":"uint128","name":"liquidityRate","type":"uint128"},{"internalType":"uint128","name":"variableBorrowRate","type":"uint128"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"address","name":"variableDebtTokenAddress","type":"address"},{"internalType":"address","name":"interestRateStrategyAddress","type":"address"},{"internalType":"uint256","name":"availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"totalScaledVariableDebt","type":"uint256"},{"internalType":"uint256","name":"priceInMarketReferenceCurrency","type":"uint256"},{"internalType":"address","name":"priceOracle","type":"address"},{"internalType":"uint256","name":"variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"optimalUsageRatio","type":"uint256"},{"internalType":"bool","name":"isPaused","type":"bool"},{"internalType":"bool","name":"isSiloedBorrowing","type":"bool"},{"internalType":"uint128","name":"accruedToTreasury","type":"uint128"},{"internalType":"uint128","name":"unbacked","type":"uint128"},{"internalType":"uint128","name":"isolationModeTotalDebt","type":"uint128"},{"internalType":"bool","name":"flashLoanEnabled","type":"bool"},{"internalType":"uint256","name":"debtCeiling","type":"uint256"},{"internalType":"uint256","name":"debtCeilingDecimals","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"bool","name":"borrowableInIsolation","type":"bool"},{"internalType":"bool","name":"virtualAccActive","type":"bool"},{"internalType":"uint128","name":"virtualUnderlyingBalance","type":"uint128"}],"internalType":"struct IUiPoolDataProviderV3.AggregatedReserveData[]","name":"","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"marketReferenceCurrencyUnit","type":"uint256"},{"internalType":"int256","name":"marketReferenceCurrencyPriceInUsd","type":"int256"},{"internalType":"int256","name":"networkBaseTokenPriceInUsd","type":"int256"},{"internalType":"uint8","name":"networkBaseTokenPriceDecimals","type":"uint8"}],"internalType":"struct IUiPoolDataProviderV3.BaseCurrencyInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"}],"name":"getReservesList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserReservesData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"uint256","name":"scaledATokenBalance","type":"uint256"},{"internalType":"bool","name":"usageAsCollateralEnabledOnUser","type":"bool"},{"internalType":"uint256","name":"scaledVariableDebt","type":"uint256"}],"internalType":"struct IUiPoolDataProviderV3.UserReserveData[]","name":"","type":"tuple[]"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketReferenceCurrencyPriceInUsdProxyAggregator","outputs":[{"internalType":"contract IEACAggregatorProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"networkBaseTokenPriceInUsdProxyAggregator","outputs":[{"internalType":"contract IEACAggregatorProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c060405234801561000f575f5ffd5b506040516128a33803806128a383398101604081905261002e91610060565b6001600160a01b039182166080521660a052610091565b80516001600160a01b038116811461005b575f5ffd5b919050565b5f5f60408385031215610071575f5ffd5b61007a83610045565b915061008860208401610045565b90509250929050565b60805160a0516127dd6100c65f395f81816101960152611b2e01525f818160bb015281816119780152611a0101526127dd5ff3fe608060405234801561000f575f5ffd5b5060043610610090575f3560e01c80636f90b9d1116100635780636f90b9d114610136578063825ffd92146101565780639201de5514610171578063d22cf68a14610191578063ec489c21146101b8575f5ffd5b80630496f53a146100945780633c1740ed146100b657806351974cc0146100f5578063586c144214610116575b5f5ffd5b6100a3670de0b6b3a764000081565b6040519081526020015b60405180910390f35b6100dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ad565b610108610103366004611c88565b6101d9565b6040516100ad929190611cbf565b610129610124366004611d3a565b610654565b6040516100ad9190611d55565b610149610144366004611d3a565b610722565b6040516100ad9190611dce565b6100dd739f8f72aa9304c8b593d555f12ef6589cc3a579a281565b61018461017f366004611eaa565b610b9f565b6040516100ad9190611ec1565b6100dd7f000000000000000000000000000000000000000000000000000000000000000081565b6101cb6101c6366004611d3a565b610cca565b6040516100ad929190611ed3565b60605f5f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610219573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023d91906122a3565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa15801561027b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526102a2919081019061232b565b604051634417a58360e01b81526001600160a01b0387811660048301529192505f91841690634417a58390602401602060405180830381865afa1580156102eb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061030f919061241c565b60405163eddf1b7960e01b81526001600160a01b0388811660048301529192505f9185169063eddf1b7990602401602060405180830381865afa158015610358573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037c9190612436565b90505f6001600160a01b038816610393575f610396565b83515b6001600160401b038111156103ad576103ad6122be565b6040519080825280602002602001820160405280156103fd57816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f199092019101816103cb5790505b5090505f5b8451811015610646575f866001600160a01b03166335ea6a7587848151811061042d5761042d61244d565b60200260200101516040518263ffffffff1660e01b815260040161046091906001600160a01b0391909116815260200190565b6101e060405180830381865afa15801561047c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a0919061249c565b90508582815181106104b4576104b461244d565b60200260200101518383815181106104ce576104ce61244d565b60209081029190910101516001600160a01b039182169052610100820151604051630ed1279f60e11b81528c83166004820152911690631da24f3e90602401602060405180830381865afa158015610528573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061054c9190612436565b83838151811061055e5761055e61244d565b60209081029190910181015101526105768583611bce565b8383815181106105885761058861244d565b60209081029190910101519015156040909101526105a68583611c25565b1561063d57610140810151604051630ed1279f60e11b81526001600160a01b038c8116600483015290911690631da24f3e90602401602060405180830381865afa1580156105f6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061061a9190612436565b83838151811061062c5761062c61244d565b602002602001015160600181815250505b50600101610402565b509890975095505050505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610693573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106b791906122a3565b9050806001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156106f4573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261071b919081019061232b565b9392505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610761573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061078591906122a3565b6040805161010080825261202082019092529192505f9190816020015b6107e86040805180820182525f808252825160c08101845281815260208181018390529381018290526060808201839052608082015260a0810191909152909182015290565b8152602001906001900390816107a25790505090505f8060015b6101008160ff161015610aa85760405163b286f46760e01b815260ff821660048201525f906001600160a01b0387169063b286f46790602401606060405180830381865afa158015610856573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a91906125c6565b9050806020015161ffff165f14610a775760405180604001604052808360ff1681526020016040518060c00160405280845f015161ffff168152602001846020015161ffff168152602001846040015161ffff168152602001896001600160a01b031663b0771dba876040518263ffffffff1660e01b8152600401610908919060ff91909116815260200190565b602060405180830381865afa158015610923573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109479190612631565b6001600160801b03168152604051632083e18360e01b815260ff871660048201526020909101906001600160a01b038b1690632083e183906024015f60405180830381865afa15801561099c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109c3919081019061264a565b815260405163903a2c7160e01b815260ff871660048201526020909101906001600160a01b038b169063903a2c7190602401602060405180830381865afa158015610a10573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a349190612631565b6001600160801b0316815250815250858560ff1681518110610a5857610a5861244d565b602002602001018190525083610a6d906126dc565b93505f9250610a83565b610a80836126dc565b92505b60028360ff161115610a955750610aa8565b5080610aa0816126dc565b915050610802565b505f8260ff166001600160401b03811115610ac557610ac56122be565b604051908082528060200260200182016040528015610b3c57816020015b610b296040805180820182525f808252825160c08101845281815260208181018390529381018290526060808201839052608082015260a0810191909152909182015290565b815260200190600190039081610ae35790505b5090505f5b8360ff168160ff161015610b9457848160ff1681518110610b6457610b6461244d565b6020026020010151828260ff1681518110610b8157610b8161244d565b6020908102919091010152600101610b41565b509695505050505050565b60605f5b60208160ff16108015610bd75750828160ff1660208110610bc657610bc661244d565b1a60f81b6001600160f81b03191615155b15610bee5780610be6816126dc565b915050610ba3565b5f8160ff166001600160401b03811115610c0a57610c0a6122be565b6040519080825280601f01601f191660200182016040528015610c34576020820181803683370190505b5090505f91505b60208260ff16108015610c6f5750838260ff1660208110610c5e57610c5e61244d565b1a60f81b6001600160f81b03191615155b1561071b57838260ff1660208110610c8957610c8961244d565b1a60f81b818360ff1681518110610ca257610ca261244d565b60200101906001600160f81b03191690815f1a90535081610cc2816126dc565b925050610c3b565b6060610cf660405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b5f836001600160a01b031663fca513a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5791906122a3565b90505f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d96573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dba91906122a3565b90505f856001600160a01b031663e860accb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1d91906122a3565b90505f826001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e82919081019061232b565b90505f81516001600160401b03811115610e9e57610e9e6122be565b60405190808252806020026020018201604052801561101357816020015b60408051610520810182525f8082526060602080840182905293830181905282018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a082018190526102c082018190526102e08201819052610300820181905261032082018190526103408201819052610360820181905261038082018190526103a082018190526103c082018190526103e08201819052610400820181905261042082018190526104408201819052610460820181905261048082018190526104a082018190526104c082018190526104e0820181905261050082015282525f19909201910181610ebc5790505b5090505f5b825181101561194b575f8282815181106110345761103461244d565b602002602001015190508382815181106110505761105061244d565b60209081029190910101516001600160a01b039081168083526040516335ea6a7560e01b815260048101919091525f918816906335ea6a75906024016101e060405180830381865afa1580156110a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cc919061249c565b60208101516001600160801b03908116610180850152606082015181166101a085015260408083015182166101c086015260808301519091166101e085015260c082015164ffffffffff166102008501526101008201516001600160a01b03908116610220860152610140830151811661024086015261016083015181166102608601528451915163b3596f0760e01b815291811660048301529192509089169063b3596f0790602401602060405180830381865afa158015611191573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b59190612436565b6102c08301528151604051630495f95f60e51b81526001600160a01b039182166004820152908916906392bf2be090602401602060405180830381865afa158015611202573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122691906122a3565b6001600160a01b039081166102e084015282516102208401516040516370a0823160e01b815290831660048201529116906370a0823190602401602060405180830381865afa15801561127b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129f9190612436565b826102800181815250508161024001516001600160a01b031663b1bf962d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112ea573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061130e9190612436565b6102a083015281516001600160a01b0316739f8f72aa9304c8b593d555f12ef6589cc3a579a1190161142a575f825f01516001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061139e9190612436565b90505f835f01516001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114049190612436565b905061140f82610b9f565b604085015261141d81610b9f565b6020850152506115029050565b815f01516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611468573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261148f919081019061264a565b8260400181905250815f01516001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156114d5573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114fc919081019061264a565b60208301525b8051805161ffff604082811c821660e087015260ff603084901c166060870152602083901c821660c0870152601083901c821660a0870152911660808086018290529015156101008601528251671000000000000000811615156103808701526704000000000000008116151561012087015267020000000000000081161515610160870152670100000000000000161515610140860152610260850151855183516304c7a22760e21b81526001600160a01b039182166004820152935191169263131e889c9260248083019391928290030181865afa925050508015611606575060408051601f3d908101601f1916820190925261160391810190612706565b60015b1561163457602081015161034085015260408101516103008501526060810151610320850152516103608401525b805160d41c64ffffffffff1683610440018181525050866001600160a01b03166369b169e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611686573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116aa9190612436565b6104608401528051640fffffffff605082901c81169160741c166104a085015261048084015282516040516335fb4fbd60e21b81526001600160a01b0391821660048201529088169063d7ed3ef490602401602060405180830381865afa925050508015611735575060408051601f3d908101601f1916820190925261173291810190612768565b60015b611776573d808015611762576040519150601f19603f3d011682016040523d82523d5f602084013e611767565b606091505b5050600161042084015261177f565b15156104208401525b805167400000000000000016151515156103a08401526101a08201516001600160801b039081166103e08501526101c08301518116610400850152610180830151166103c0840152805167200000000000000016151515156104c0840152825160405163f7e1430760e01b81526001600160a01b0391821660048201529088169063f7e1430790602401602060405180830381865afa925050508015611842575060408051601f3d908101601f1916820190925261183f91810190612768565b60015b611882573d80801561186f576040519150601f19603f3d011682016040523d82523d5f602084013e611874565b606091505b50505f6104e084015261188b565b15156104e08401525b82516040516337d83fcb60e11b81526001600160a01b03918216600482015290891690636fb07f9690602401602060405180830381865afa9250505080156118f0575060408051601f3d908101601f191682019092526118ed91810190612631565b60015b611930573d80801561191d576040519150601f19603f3d011682016040523d82523d5f602084013e611922565b606091505b50505f610500840152611940565b6001600160801b03166105008401525b505050600101611018565b5061197660405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f69190612436565b8160400181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a7f9190612787565b60ff16606082015260408051638c89b64f60e01b815290516001600160a01b03881691638c89b64f9160048083019260209291908290030181865afa925050508015611ae8575060408051601f3d908101601f19168201909252611ae591810190612436565b60015b611bb7573d808015611b15576040519150601f19603f3d011682016040523d82523d5f602084013e611b1a565b606091505b50670de0b6b3a7640000825f0181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b88573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bac9190612436565b602083015250611bc0565b80825260208201525b909890975095505050505050565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c135760405162461bcd60e51b8152600401611c0a9190611ec1565b60405180910390fd5b50509051600191821b82011c16151590565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c615760405162461bcd60e51b8152600401611c0a9190611ec1565b50509051600191821b1c16151590565b6001600160a01b0381168114611c85575f5ffd5b50565b5f5f60408385031215611c99575f5ffd5b8235611ca481611c71565b91506020830135611cb481611c71565b809150509250929050565b604080825283519082018190525f9060208501906060840190835b81811015611d2657835180516001600160a01b03168452602080820151818601526040808301511515908601526060918201519185019190915290930192608090920191600101611cda565b505060ff85166020850152915061071b9050565b5f60208284031215611d4a575f5ffd5b813561071b81611c71565b602080825282518282018190525f918401906040840190835b81811015611d955783516001600160a01b0316835260209384019390920191600101611d6e565b509095945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015611e9e57603f19878603018452815160ff8151168652602081015190506040602087015261ffff815116604087015261ffff602082015116606087015261ffff60408201511660808701526001600160801b0360608201511660a0870152608081015160c080880152611e6f610100880182611da0565b60a092909201516001600160801b031660e0979097019690965294506020938401939190910190600101611df4565b50929695505050505050565b5f60208284031215611eba575f5ffd5b5035919050565b602081525f61071b6020830184611da0565b5f60a0820160a0835280855180835260c08501915060c08160051b8601019250602087015f5b8281101561225a5786850360bf19018452815180516001600160a01b0316865260208101516105206020880152611f34610520880182611da0565b905060408201518782036040890152611f4d8282611da0565b915050606082015160608801526080820151608088015260a082015160a088015260c082015160c088015260e082015160e0880152610100820151611f9761010089018215159052565b50610120820151611fad61012089018215159052565b50610140820151611fc361014089018215159052565b50610160820151611fd961016089018215159052565b50610180820151611ff66101808901826001600160801b03169052565b506101a08201516120136101a08901826001600160801b03169052565b506101c08201516120306101c08901826001600160801b03169052565b506101e082015161204d6101e08901826001600160801b03169052565b5061020082015161206861020089018264ffffffffff169052565b506102208201516120856102208901826001600160a01b03169052565b506102408201516120a26102408901826001600160a01b03169052565b506102608201516120bf6102608901826001600160a01b03169052565b506102808201516102808801526102a08201516102a08801526102c08201516102c08801526102e08201516121006102e08901826001600160a01b03169052565b5061030082015161030088015261032082015161032088015261034082015161034088015261036082015161036088015261038082015161214661038089018215159052565b506103a082015161215c6103a089018215159052565b506103c08201516121796103c08901826001600160801b03169052565b506103e08201516121966103e08901826001600160801b03169052565b506104008201516121b36104008901826001600160801b03169052565b506104208201516121c961042089018215159052565b506104408201516104408801526104608201516104608801526104808201516104808801526104a08201516104a08801526104c082015161220f6104c089018215159052565b506104e08201516122256104e089018215159052565b5061050082015191506122446105008801836001600160801b03169052565b9550506020938401939190910190600101611ef9565b505050508091505061071b602083018480518252602081015160208301526040810151604083015260ff60608201511660608301525050565b805161229e81611c71565b919050565b5f602082840312156122b3575f5ffd5b815161071b81611c71565b634e487b7160e01b5f52604160045260245ffd5b6040516101e081016001600160401b03811182821017156122f5576122f56122be565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612323576123236122be565b604052919050565b5f6020828403121561233b575f5ffd5b81516001600160401b03811115612350575f5ffd5b8201601f81018413612360575f5ffd5b80516001600160401b03811115612379576123796122be565b8060051b612389602082016122fb565b918252602081840181019290810190878411156123a4575f5ffd5b6020850194505b838510156123d257845192506123c083611c71565b828252602094850194909101906123ab565b979650505050505050565b5f602082840312156123ed575f5ffd5b604051602081016001600160401b038111828210171561240f5761240f6122be565b6040529151825250919050565b5f6020828403121561242c575f5ffd5b61071b83836123dd565b5f60208284031215612446575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b80516001600160801b038116811461229e575f5ffd5b805164ffffffffff8116811461229e575f5ffd5b805161ffff8116811461229e575f5ffd5b5f6101e08284031280156124ae575f5ffd5b506124b76122d2565b6124c184846123dd565b81526124cf60208401612461565b60208201526124e060408401612461565b60408201526124f160608401612461565b606082015261250260808401612461565b608082015261251360a08401612461565b60a082015261252460c08401612477565b60c082015261253560e0840161248b565b60e08201526125476101008401612293565b61010082015261255a6101208401612293565b61012082015261256d6101408401612293565b6101408201526125806101608401612293565b6101608201526125936101808401612461565b6101808201526125a66101a08401612461565b6101a08201526125b96101c08401612461565b6101c08201529392505050565b5f60608284031280156125d7575f5ffd5b50604051606081016001600160401b03811182821017156125fa576125fa6122be565b6040526126068361248b565b81526126146020840161248b565b60208201526126256040840161248b565b60408201529392505050565b5f60208284031215612641575f5ffd5b61071b82612461565b5f6020828403121561265a575f5ffd5b81516001600160401b0381111561266f575f5ffd5b8201601f8101841361267f575f5ffd5b80516001600160401b03811115612698576126986122be565b6126ab601f8201601f19166020016122fb565b8181528560208385010111156126bf575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f60ff821660ff81036126fd57634e487b7160e01b5f52601160045260245ffd5b60010192915050565b5f6080828403128015612717575f5ffd5b50604051608081016001600160401b038111828210171561273a5761273a6122be565b6040908152835182526020808501519083015283810151908201526060928301519281019290925250919050565b5f60208284031215612778575f5ffd5b8151801515811461071b575f5ffd5b5f60208284031215612797575f5ffd5b815160ff8116811461071b575f5ffdfea264697066735822122026d773042848ccfbd5dd197e8f212a475bc15fac4833244523cf05eecdee5efe64736f6c634300081c003300000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c321400000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c3214
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610090575f3560e01c80636f90b9d1116100635780636f90b9d114610136578063825ffd92146101565780639201de5514610171578063d22cf68a14610191578063ec489c21146101b8575f5ffd5b80630496f53a146100945780633c1740ed146100b657806351974cc0146100f5578063586c144214610116575b5f5ffd5b6100a3670de0b6b3a764000081565b6040519081526020015b60405180910390f35b6100dd7f00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c321481565b6040516001600160a01b0390911681526020016100ad565b610108610103366004611c88565b6101d9565b6040516100ad929190611cbf565b610129610124366004611d3a565b610654565b6040516100ad9190611d55565b610149610144366004611d3a565b610722565b6040516100ad9190611dce565b6100dd739f8f72aa9304c8b593d555f12ef6589cc3a579a281565b61018461017f366004611eaa565b610b9f565b6040516100ad9190611ec1565b6100dd7f00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c321481565b6101cb6101c6366004611d3a565b610cca565b6040516100ad929190611ed3565b60605f5f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610219573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023d91906122a3565b90505f816001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa15801561027b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526102a2919081019061232b565b604051634417a58360e01b81526001600160a01b0387811660048301529192505f91841690634417a58390602401602060405180830381865afa1580156102eb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061030f919061241c565b60405163eddf1b7960e01b81526001600160a01b0388811660048301529192505f9185169063eddf1b7990602401602060405180830381865afa158015610358573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037c9190612436565b90505f6001600160a01b038816610393575f610396565b83515b6001600160401b038111156103ad576103ad6122be565b6040519080825280602002602001820160405280156103fd57816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f199092019101816103cb5790505b5090505f5b8451811015610646575f866001600160a01b03166335ea6a7587848151811061042d5761042d61244d565b60200260200101516040518263ffffffff1660e01b815260040161046091906001600160a01b0391909116815260200190565b6101e060405180830381865afa15801561047c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a0919061249c565b90508582815181106104b4576104b461244d565b60200260200101518383815181106104ce576104ce61244d565b60209081029190910101516001600160a01b039182169052610100820151604051630ed1279f60e11b81528c83166004820152911690631da24f3e90602401602060405180830381865afa158015610528573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061054c9190612436565b83838151811061055e5761055e61244d565b60209081029190910181015101526105768583611bce565b8383815181106105885761058861244d565b60209081029190910101519015156040909101526105a68583611c25565b1561063d57610140810151604051630ed1279f60e11b81526001600160a01b038c8116600483015290911690631da24f3e90602401602060405180830381865afa1580156105f6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061061a9190612436565b83838151811061062c5761062c61244d565b602002602001015160600181815250505b50600101610402565b509890975095505050505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610693573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106b791906122a3565b9050806001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa1580156106f4573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261071b919081019061232b565b9392505050565b60605f826001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610761573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061078591906122a3565b6040805161010080825261202082019092529192505f9190816020015b6107e86040805180820182525f808252825160c08101845281815260208181018390529381018290526060808201839052608082015260a0810191909152909182015290565b8152602001906001900390816107a25790505090505f8060015b6101008160ff161015610aa85760405163b286f46760e01b815260ff821660048201525f906001600160a01b0387169063b286f46790602401606060405180830381865afa158015610856573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a91906125c6565b9050806020015161ffff165f14610a775760405180604001604052808360ff1681526020016040518060c00160405280845f015161ffff168152602001846020015161ffff168152602001846040015161ffff168152602001896001600160a01b031663b0771dba876040518263ffffffff1660e01b8152600401610908919060ff91909116815260200190565b602060405180830381865afa158015610923573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109479190612631565b6001600160801b03168152604051632083e18360e01b815260ff871660048201526020909101906001600160a01b038b1690632083e183906024015f60405180830381865afa15801561099c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109c3919081019061264a565b815260405163903a2c7160e01b815260ff871660048201526020909101906001600160a01b038b169063903a2c7190602401602060405180830381865afa158015610a10573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a349190612631565b6001600160801b0316815250815250858560ff1681518110610a5857610a5861244d565b602002602001018190525083610a6d906126dc565b93505f9250610a83565b610a80836126dc565b92505b60028360ff161115610a955750610aa8565b5080610aa0816126dc565b915050610802565b505f8260ff166001600160401b03811115610ac557610ac56122be565b604051908082528060200260200182016040528015610b3c57816020015b610b296040805180820182525f808252825160c08101845281815260208181018390529381018290526060808201839052608082015260a0810191909152909182015290565b815260200190600190039081610ae35790505b5090505f5b8360ff168160ff161015610b9457848160ff1681518110610b6457610b6461244d565b6020026020010151828260ff1681518110610b8157610b8161244d565b6020908102919091010152600101610b41565b509695505050505050565b60605f5b60208160ff16108015610bd75750828160ff1660208110610bc657610bc661244d565b1a60f81b6001600160f81b03191615155b15610bee5780610be6816126dc565b915050610ba3565b5f8160ff166001600160401b03811115610c0a57610c0a6122be565b6040519080825280601f01601f191660200182016040528015610c34576020820181803683370190505b5090505f91505b60208260ff16108015610c6f5750838260ff1660208110610c5e57610c5e61244d565b1a60f81b6001600160f81b03191615155b1561071b57838260ff1660208110610c8957610c8961244d565b1a60f81b818360ff1681518110610ca257610ca261244d565b60200101906001600160f81b03191690815f1a90535081610cc2816126dc565b925050610c3b565b6060610cf660405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b5f836001600160a01b031663fca513a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5791906122a3565b90505f846001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d96573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dba91906122a3565b90505f856001600160a01b031663e860accb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1d91906122a3565b90505f826001600160a01b031663d1946dbc6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e5b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e82919081019061232b565b90505f81516001600160401b03811115610e9e57610e9e6122be565b60405190808252806020026020018201604052801561101357816020015b60408051610520810182525f8082526060602080840182905293830181905282018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a082018190526102c082018190526102e08201819052610300820181905261032082018190526103408201819052610360820181905261038082018190526103a082018190526103c082018190526103e08201819052610400820181905261042082018190526104408201819052610460820181905261048082018190526104a082018190526104c082018190526104e0820181905261050082015282525f19909201910181610ebc5790505b5090505f5b825181101561194b575f8282815181106110345761103461244d565b602002602001015190508382815181106110505761105061244d565b60209081029190910101516001600160a01b039081168083526040516335ea6a7560e01b815260048101919091525f918816906335ea6a75906024016101e060405180830381865afa1580156110a8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cc919061249c565b60208101516001600160801b03908116610180850152606082015181166101a085015260408083015182166101c086015260808301519091166101e085015260c082015164ffffffffff166102008501526101008201516001600160a01b03908116610220860152610140830151811661024086015261016083015181166102608601528451915163b3596f0760e01b815291811660048301529192509089169063b3596f0790602401602060405180830381865afa158015611191573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b59190612436565b6102c08301528151604051630495f95f60e51b81526001600160a01b039182166004820152908916906392bf2be090602401602060405180830381865afa158015611202573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122691906122a3565b6001600160a01b039081166102e084015282516102208401516040516370a0823160e01b815290831660048201529116906370a0823190602401602060405180830381865afa15801561127b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129f9190612436565b826102800181815250508161024001516001600160a01b031663b1bf962d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112ea573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061130e9190612436565b6102a083015281516001600160a01b0316739f8f72aa9304c8b593d555f12ef6589cc3a579a1190161142a575f825f01516001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061139e9190612436565b90505f835f01516001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114049190612436565b905061140f82610b9f565b604085015261141d81610b9f565b6020850152506115029050565b815f01516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611468573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261148f919081019061264a565b8260400181905250815f01516001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156114d5573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114fc919081019061264a565b60208301525b8051805161ffff604082811c821660e087015260ff603084901c166060870152602083901c821660c0870152601083901c821660a0870152911660808086018290529015156101008601528251671000000000000000811615156103808701526704000000000000008116151561012087015267020000000000000081161515610160870152670100000000000000161515610140860152610260850151855183516304c7a22760e21b81526001600160a01b039182166004820152935191169263131e889c9260248083019391928290030181865afa925050508015611606575060408051601f3d908101601f1916820190925261160391810190612706565b60015b1561163457602081015161034085015260408101516103008501526060810151610320850152516103608401525b805160d41c64ffffffffff1683610440018181525050866001600160a01b03166369b169e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611686573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116aa9190612436565b6104608401528051640fffffffff605082901c81169160741c166104a085015261048084015282516040516335fb4fbd60e21b81526001600160a01b0391821660048201529088169063d7ed3ef490602401602060405180830381865afa925050508015611735575060408051601f3d908101601f1916820190925261173291810190612768565b60015b611776573d808015611762576040519150601f19603f3d011682016040523d82523d5f602084013e611767565b606091505b5050600161042084015261177f565b15156104208401525b805167400000000000000016151515156103a08401526101a08201516001600160801b039081166103e08501526101c08301518116610400850152610180830151166103c0840152805167200000000000000016151515156104c0840152825160405163f7e1430760e01b81526001600160a01b0391821660048201529088169063f7e1430790602401602060405180830381865afa925050508015611842575060408051601f3d908101601f1916820190925261183f91810190612768565b60015b611882573d80801561186f576040519150601f19603f3d011682016040523d82523d5f602084013e611874565b606091505b50505f6104e084015261188b565b15156104e08401525b82516040516337d83fcb60e11b81526001600160a01b03918216600482015290891690636fb07f9690602401602060405180830381865afa9250505080156118f0575060408051601f3d908101601f191682019092526118ed91810190612631565b60015b611930573d80801561191d576040519150601f19603f3d011682016040523d82523d5f602084013e611922565b606091505b50505f610500840152611940565b6001600160801b03166105008401525b505050600101611018565b5061197660405180608001604052805f81526020015f81526020015f81526020015f60ff1681525090565b7f00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c32146001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f69190612436565b8160400181815250507f00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c32146001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a5b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a7f9190612787565b60ff16606082015260408051638c89b64f60e01b815290516001600160a01b03881691638c89b64f9160048083019260209291908290030181865afa925050508015611ae8575060408051601f3d908101601f19168201909252611ae591810190612436565b60015b611bb7573d808015611b15576040519150601f19603f3d011682016040523d82523d5f602084013e611b1a565b606091505b50670de0b6b3a7640000825f0181815250507f00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c32146001600160a01b03166350d25bcd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b88573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bac9190612436565b602083015250611bc0565b80825260208201525b909890975095505050505050565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c135760405162461bcd60e51b8152600401611c0a9190611ec1565b60405180910390fd5b50509051600191821b82011c16151590565b6040805180820190915260028152610dcd60f21b60208201525f9060808310611c615760405162461bcd60e51b8152600401611c0a9190611ec1565b50509051600191821b1c16151590565b6001600160a01b0381168114611c85575f5ffd5b50565b5f5f60408385031215611c99575f5ffd5b8235611ca481611c71565b91506020830135611cb481611c71565b809150509250929050565b604080825283519082018190525f9060208501906060840190835b81811015611d2657835180516001600160a01b03168452602080820151818601526040808301511515908601526060918201519185019190915290930192608090920191600101611cda565b505060ff85166020850152915061071b9050565b5f60208284031215611d4a575f5ffd5b813561071b81611c71565b602080825282518282018190525f918401906040840190835b81811015611d955783516001600160a01b0316835260209384019390920191600101611d6e565b509095945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015611e9e57603f19878603018452815160ff8151168652602081015190506040602087015261ffff815116604087015261ffff602082015116606087015261ffff60408201511660808701526001600160801b0360608201511660a0870152608081015160c080880152611e6f610100880182611da0565b60a092909201516001600160801b031660e0979097019690965294506020938401939190910190600101611df4565b50929695505050505050565b5f60208284031215611eba575f5ffd5b5035919050565b602081525f61071b6020830184611da0565b5f60a0820160a0835280855180835260c08501915060c08160051b8601019250602087015f5b8281101561225a5786850360bf19018452815180516001600160a01b0316865260208101516105206020880152611f34610520880182611da0565b905060408201518782036040890152611f4d8282611da0565b915050606082015160608801526080820151608088015260a082015160a088015260c082015160c088015260e082015160e0880152610100820151611f9761010089018215159052565b50610120820151611fad61012089018215159052565b50610140820151611fc361014089018215159052565b50610160820151611fd961016089018215159052565b50610180820151611ff66101808901826001600160801b03169052565b506101a08201516120136101a08901826001600160801b03169052565b506101c08201516120306101c08901826001600160801b03169052565b506101e082015161204d6101e08901826001600160801b03169052565b5061020082015161206861020089018264ffffffffff169052565b506102208201516120856102208901826001600160a01b03169052565b506102408201516120a26102408901826001600160a01b03169052565b506102608201516120bf6102608901826001600160a01b03169052565b506102808201516102808801526102a08201516102a08801526102c08201516102c08801526102e08201516121006102e08901826001600160a01b03169052565b5061030082015161030088015261032082015161032088015261034082015161034088015261036082015161036088015261038082015161214661038089018215159052565b506103a082015161215c6103a089018215159052565b506103c08201516121796103c08901826001600160801b03169052565b506103e08201516121966103e08901826001600160801b03169052565b506104008201516121b36104008901826001600160801b03169052565b506104208201516121c961042089018215159052565b506104408201516104408801526104608201516104608801526104808201516104808801526104a08201516104a08801526104c082015161220f6104c089018215159052565b506104e08201516122256104e089018215159052565b5061050082015191506122446105008801836001600160801b03169052565b9550506020938401939190910190600101611ef9565b505050508091505061071b602083018480518252602081015160208301526040810151604083015260ff60608201511660608301525050565b805161229e81611c71565b919050565b5f602082840312156122b3575f5ffd5b815161071b81611c71565b634e487b7160e01b5f52604160045260245ffd5b6040516101e081016001600160401b03811182821017156122f5576122f56122be565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612323576123236122be565b604052919050565b5f6020828403121561233b575f5ffd5b81516001600160401b03811115612350575f5ffd5b8201601f81018413612360575f5ffd5b80516001600160401b03811115612379576123796122be565b8060051b612389602082016122fb565b918252602081840181019290810190878411156123a4575f5ffd5b6020850194505b838510156123d257845192506123c083611c71565b828252602094850194909101906123ab565b979650505050505050565b5f602082840312156123ed575f5ffd5b604051602081016001600160401b038111828210171561240f5761240f6122be565b6040529151825250919050565b5f6020828403121561242c575f5ffd5b61071b83836123dd565b5f60208284031215612446575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b80516001600160801b038116811461229e575f5ffd5b805164ffffffffff8116811461229e575f5ffd5b805161ffff8116811461229e575f5ffd5b5f6101e08284031280156124ae575f5ffd5b506124b76122d2565b6124c184846123dd565b81526124cf60208401612461565b60208201526124e060408401612461565b60408201526124f160608401612461565b606082015261250260808401612461565b608082015261251360a08401612461565b60a082015261252460c08401612477565b60c082015261253560e0840161248b565b60e08201526125476101008401612293565b61010082015261255a6101208401612293565b61012082015261256d6101408401612293565b6101408201526125806101608401612293565b6101608201526125936101808401612461565b6101808201526125a66101a08401612461565b6101a08201526125b96101c08401612461565b6101c08201529392505050565b5f60608284031280156125d7575f5ffd5b50604051606081016001600160401b03811182821017156125fa576125fa6122be565b6040526126068361248b565b81526126146020840161248b565b60208201526126256040840161248b565b60408201529392505050565b5f60208284031215612641575f5ffd5b61071b82612461565b5f6020828403121561265a575f5ffd5b81516001600160401b0381111561266f575f5ffd5b8201601f8101841361267f575f5ffd5b80516001600160401b03811115612698576126986122be565b6126ab601f8201601f19166020016122fb565b8181528560208385010111156126bf575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f60ff821660ff81036126fd57634e487b7160e01b5f52601160045260245ffd5b60010192915050565b5f6080828403128015612717575f5ffd5b50604051608081016001600160401b038111828210171561273a5761273a6122be565b6040908152835182526020808501519083015283810151908201526060928301519281019290925250919050565b5f60208284031215612778575f5ffd5b8151801515811461071b575f5ffd5b5f60208284031215612797575f5ffd5b815160ff8116811461071b575f5ffdfea264697066735822122026d773042848ccfbd5dd197e8f212a475bc15fac4833244523cf05eecdee5efe64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c321400000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c3214
-----Decoded View---------------
Arg [0] : _networkBaseTokenPriceInUsdProxyAggregator (address): 0x79fa150c700adeaf618475E8CB17933e7A9c3214
Arg [1] : _marketReferenceCurrencyPriceInUsdProxyAggregator (address): 0x79fa150c700adeaf618475E8CB17933e7A9c3214
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c3214
Arg [1] : 00000000000000000000000079fa150c700adeaf618475e8cb17933e7a9c3214
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.