Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GhoAaveSteward
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import {IPoolDataProvider} from '@aave/core-v3/contracts/interfaces/IPoolDataProvider.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol';
import {DataTypes} from '@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol';
import {ReserveConfiguration} from '@aave/core-v3/contracts/protocol/libraries/configuration/ReserveConfiguration.sol';
import {IPoolConfigurator, IDefaultInterestRateStrategyV2} from './dependencies/AaveV3-1.sol';
import {IGhoAaveSteward} from './interfaces/IGhoAaveSteward.sol';
import {RiskCouncilControlled} from './RiskCouncilControlled.sol';
/**
* @title GhoAaveSteward
* @author Aave Labs
* @notice Helper contract for managing parameters of the GHO reserve
* @dev Only the Risk Council is able to action contract's functions, based on specific conditions that have been agreed upon with the community.
* @dev Requires role RiskAdmin on the Aave V3 Ethereum Pool
*/
contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward {
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
uint256 internal constant BPS_MAX = 100_00;
/// @inheritdoc IGhoAaveSteward
address public immutable POOL_DATA_PROVIDER;
/// @inheritdoc IGhoAaveSteward
uint256 public constant MINIMUM_DELAY = 1 days;
/// @inheritdoc IGhoAaveSteward
address public immutable POOL_ADDRESSES_PROVIDER;
/// @inheritdoc IGhoAaveSteward
address public immutable GHO_TOKEN;
BorrowRateConfig internal _borrowRateConfig;
GhoDebounce internal _ghoTimelocks;
/**
* @dev Only methods that are not timelocked can be called if marked by this modifier.
*/
modifier notTimelocked(uint40 timelock) {
require(block.timestamp - timelock > MINIMUM_DELAY, 'DEBOUNCE_NOT_RESPECTED');
_;
}
/**
* @dev Constructor
* @param owner The address of the contract's owner
* @param addressesProvider The address of the PoolAddressesProvider of Aave V3 Ethereum Pool
* @param poolDataProvider The pool data provider of the pool to be controlled by the steward
* @param ghoToken The address of the GhoToken
* @param riskCouncil The address of the risk council
* @param borrowRateConfig The configuration conditions for GHO borrow rate changes
*/
constructor(
address owner,
address addressesProvider,
address poolDataProvider,
address ghoToken,
address riskCouncil,
BorrowRateConfig memory borrowRateConfig
) RiskCouncilControlled(riskCouncil) {
require(owner != address(0), 'INVALID_OWNER');
require(addressesProvider != address(0), 'INVALID_ADDRESSES_PROVIDER');
require(poolDataProvider != address(0), 'INVALID_DATA_PROVIDER');
require(ghoToken != address(0), 'INVALID_GHO_TOKEN');
POOL_ADDRESSES_PROVIDER = addressesProvider;
POOL_DATA_PROVIDER = poolDataProvider;
GHO_TOKEN = ghoToken;
_borrowRateConfig = borrowRateConfig;
_transferOwnership(owner);
}
/// @inheritdoc IGhoAaveSteward
function updateGhoBorrowRate(
uint16 optimalUsageRatio,
uint32 baseVariableBorrowRate,
uint32 variableRateSlope1,
uint32 variableRateSlope2
) external onlyRiskCouncil notTimelocked(_ghoTimelocks.ghoBorrowRateLastUpdate) {
IDefaultInterestRateStrategyV2.InterestRateData
memory rateParams = IDefaultInterestRateStrategyV2.InterestRateData({
optimalUsageRatio: optimalUsageRatio,
baseVariableBorrowRate: baseVariableBorrowRate,
variableRateSlope1: variableRateSlope1,
variableRateSlope2: variableRateSlope2
});
_validateRatesUpdate(rateParams);
_ghoTimelocks.ghoBorrowRateLastUpdate = uint40(block.timestamp);
IPoolConfigurator(IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPoolConfigurator())
.setReserveInterestRateData(GHO_TOKEN, abi.encode(rateParams));
}
/// @inheritdoc IGhoAaveSteward
function updateGhoBorrowCap(
uint256 newBorrowCap
) external onlyRiskCouncil notTimelocked(_ghoTimelocks.ghoBorrowCapLastUpdate) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(
IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPool()
).getConfiguration(GHO_TOKEN);
uint256 currentBorrowCap = configuration.getBorrowCap();
require(newBorrowCap != currentBorrowCap, 'NO_CHANGE_IN_BORROW_CAP');
require(
_isDifferenceLowerThanMax(currentBorrowCap, newBorrowCap, currentBorrowCap),
'INVALID_BORROW_CAP_UPDATE'
);
_ghoTimelocks.ghoBorrowCapLastUpdate = uint40(block.timestamp);
IPoolConfigurator(IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPoolConfigurator())
.setBorrowCap(GHO_TOKEN, newBorrowCap);
}
/// @inheritdoc IGhoAaveSteward
function updateGhoSupplyCap(
uint256 newSupplyCap
) external onlyRiskCouncil notTimelocked(_ghoTimelocks.ghoSupplyCapLastUpdate) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(
IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPool()
).getConfiguration(GHO_TOKEN);
uint256 currentSupplyCap = configuration.getSupplyCap();
require(newSupplyCap != currentSupplyCap, 'NO_CHANGE_IN_SUPPLY_CAP');
require(
_isDifferenceLowerThanMax(currentSupplyCap, newSupplyCap, currentSupplyCap),
'INVALID_SUPPLY_CAP_UPDATE'
);
_ghoTimelocks.ghoSupplyCapLastUpdate = uint40(block.timestamp);
IPoolConfigurator(IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPoolConfigurator())
.setSupplyCap(GHO_TOKEN, newSupplyCap);
}
/// @inheritdoc IGhoAaveSteward
function setBorrowRateConfig(
uint16 optimalUsageRatioMaxChange,
uint32 baseVariableBorrowRateMaxChange,
uint32 variableRateSlope1MaxChange,
uint32 variableRateSlope2MaxChange
) external onlyOwner {
_borrowRateConfig.optimalUsageRatioMaxChange = optimalUsageRatioMaxChange;
_borrowRateConfig.baseVariableBorrowRateMaxChange = baseVariableBorrowRateMaxChange;
_borrowRateConfig.variableRateSlope1MaxChange = variableRateSlope1MaxChange;
_borrowRateConfig.variableRateSlope2MaxChange = variableRateSlope2MaxChange;
}
/// @inheritdoc IGhoAaveSteward
function getBorrowRateConfig() external view returns (BorrowRateConfig memory) {
return _borrowRateConfig;
}
/// @inheritdoc IGhoAaveSteward
function getGhoTimelocks() external view returns (GhoDebounce memory) {
return _ghoTimelocks;
}
/// @inheritdoc IGhoAaveSteward
function RISK_COUNCIL() public view override returns (address) {
return _riskCouncil;
}
/**
* @dev Validates the interest rates update
* @param newRates The new interest rate data
*/
function _validateRatesUpdate(
IDefaultInterestRateStrategyV2.InterestRateData memory newRates
) internal view {
address rateStrategyAddress = IPoolDataProvider(POOL_DATA_PROVIDER)
.getInterestRateStrategyAddress(GHO_TOKEN);
IDefaultInterestRateStrategyV2.InterestRateData
memory currentRates = IDefaultInterestRateStrategyV2(rateStrategyAddress)
.getInterestRateDataBps(GHO_TOKEN);
require(
newRates.optimalUsageRatio != currentRates.optimalUsageRatio ||
newRates.baseVariableBorrowRate != currentRates.baseVariableBorrowRate ||
newRates.variableRateSlope1 != currentRates.variableRateSlope1 ||
newRates.variableRateSlope2 != currentRates.variableRateSlope2,
'NO_CHANGE_IN_RATES'
);
require(
_updateWithinAllowedRange(
currentRates.optimalUsageRatio,
newRates.optimalUsageRatio,
_borrowRateConfig.optimalUsageRatioMaxChange,
false
),
'INVALID_OPTIMAL_USAGE_RATIO'
);
require(
_updateWithinAllowedRange(
currentRates.baseVariableBorrowRate,
newRates.baseVariableBorrowRate,
_borrowRateConfig.baseVariableBorrowRateMaxChange,
false
),
'INVALID_BORROW_RATE_UPDATE'
);
require(
_updateWithinAllowedRange(
currentRates.variableRateSlope1,
newRates.variableRateSlope1,
_borrowRateConfig.variableRateSlope1MaxChange,
false
),
'INVALID_VARIABLE_RATE_SLOPE1'
);
require(
_updateWithinAllowedRange(
currentRates.variableRateSlope2,
newRates.variableRateSlope2,
_borrowRateConfig.variableRateSlope2MaxChange,
false
),
'INVALID_VARIABLE_RATE_SLOPE2'
);
}
/**
* @dev Ensures that the change difference is lower than max.
* @param from current value
* @param to new value
* @param max maximum difference between from and to
* @return bool true if difference between values lower than max, false otherwise
*/
function _isDifferenceLowerThanMax(
uint256 from,
uint256 to,
uint256 max
) internal pure returns (bool) {
return from < to ? to - from <= max : from - to <= max;
}
/**
* @notice Ensures the risk param update is within the allowed range
* @param from current risk param value
* @param to new updated risk param value
* @param maxPercentChange the max percent change allowed
* @param isChangeRelative true, if maxPercentChange is relative in value, false if maxPercentChange
* is absolute in value.
* @return bool true, if difference is within the maxPercentChange
*/
function _updateWithinAllowedRange(
uint256 from,
uint256 to,
uint256 maxPercentChange,
bool isChangeRelative
) internal pure returns (bool) {
// diff denotes the difference between the from and to values, ensuring it is a positive value always
uint256 diff = from > to ? from - to : to - from;
// maxDiff denotes the max permitted difference on both the upper and lower bounds, if the maxPercentChange is relative in value
// we calculate the max permitted difference using the maxPercentChange and the from value, otherwise if the maxPercentChange is absolute in value
// the max permitted difference is the maxPercentChange itself
uint256 maxDiff = isChangeRelative ? (maxPercentChange * from) / BPS_MAX : maxPercentChange;
if (diff > maxDiff) return false;
return true;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: AGPL-3.0
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 efficiency mode category of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The eMode id of the reserve
*/
function getReserveEModeCategory(address asset) external view returns (uint256);
/**
* @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 The StableDebtToken address of the reserve
* @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);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
/**
* @title IPoolAddressesProvider
* @author Aave
* @notice Defines the basic interface for a Pool Addresses Provider.
*/
interface IPoolAddressesProvider {
/**
* @dev Emitted when the market identifier is updated.
* @param oldMarketId The old id of the market
* @param newMarketId The new id of the market
*/
event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);
/**
* @dev Emitted when the pool is updated.
* @param oldAddress The old address of the Pool
* @param newAddress The new address of the Pool
*/
event PoolUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the pool configurator is updated.
* @param oldAddress The old address of the PoolConfigurator
* @param newAddress The new address of the PoolConfigurator
*/
event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the price oracle is updated.
* @param oldAddress The old address of the PriceOracle
* @param newAddress The new address of the PriceOracle
*/
event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the ACL manager is updated.
* @param oldAddress The old address of the ACLManager
* @param newAddress The new address of the ACLManager
*/
event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the ACL admin is updated.
* @param oldAddress The old address of the ACLAdmin
* @param newAddress The new address of the ACLAdmin
*/
event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the price oracle sentinel is updated.
* @param oldAddress The old address of the PriceOracleSentinel
* @param newAddress The new address of the PriceOracleSentinel
*/
event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the pool data provider is updated.
* @param oldAddress The old address of the PoolDataProvider
* @param newAddress The new address of the PoolDataProvider
*/
event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when a new proxy is created.
* @param id The identifier of the proxy
* @param proxyAddress The address of the created proxy contract
* @param implementationAddress The address of the implementation contract
*/
event ProxyCreated(
bytes32 indexed id,
address indexed proxyAddress,
address indexed implementationAddress
);
/**
* @dev Emitted when a new non-proxied contract address is registered.
* @param id The identifier of the contract
* @param oldAddress The address of the old contract
* @param newAddress The address of the new contract
*/
event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the implementation of the proxy registered with id is updated
* @param id The identifier of the contract
* @param proxyAddress The address of the proxy contract
* @param oldImplementationAddress The address of the old implementation contract
* @param newImplementationAddress The address of the new implementation contract
*/
event AddressSetAsProxy(
bytes32 indexed id,
address indexed proxyAddress,
address oldImplementationAddress,
address indexed newImplementationAddress
);
/**
* @notice Returns the id of the Aave market to which this contract points to.
* @return The market id
*/
function getMarketId() external view returns (string memory);
/**
* @notice Associates an id with a specific PoolAddressesProvider.
* @dev This can be used to create an onchain registry of PoolAddressesProviders to
* identify and validate multiple Aave markets.
* @param newMarketId The market id
*/
function setMarketId(string calldata newMarketId) external;
/**
* @notice Returns an address by its identifier.
* @dev The returned address might be an EOA or a contract, potentially proxied
* @dev It returns ZERO if there is no registered address with the given id
* @param id The id
* @return The address of the registered for the specified id
*/
function getAddress(bytes32 id) external view returns (address);
/**
* @notice General function to update the implementation of a proxy registered with
* certain `id`. If there is no proxy registered, it will instantiate one and
* set as implementation the `newImplementationAddress`.
* @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit
* setter function, in order to avoid unexpected consequences
* @param id The id
* @param newImplementationAddress The address of the new implementation
*/
function setAddressAsProxy(bytes32 id, address newImplementationAddress) external;
/**
* @notice Sets an address for an id replacing the address saved in the addresses map.
* @dev IMPORTANT Use this function carefully, as it will do a hard replacement
* @param id The id
* @param newAddress The address to set
*/
function setAddress(bytes32 id, address newAddress) external;
/**
* @notice Returns the address of the Pool proxy.
* @return The Pool proxy address
*/
function getPool() external view returns (address);
/**
* @notice Updates the implementation of the Pool, or creates a proxy
* setting the new `pool` implementation when the function is called for the first time.
* @param newPoolImpl The new Pool implementation
*/
function setPoolImpl(address newPoolImpl) external;
/**
* @notice Returns the address of the PoolConfigurator proxy.
* @return The PoolConfigurator proxy address
*/
function getPoolConfigurator() external view returns (address);
/**
* @notice Updates the implementation of the PoolConfigurator, or creates a proxy
* setting the new `PoolConfigurator` implementation when the function is called for the first time.
* @param newPoolConfiguratorImpl The new PoolConfigurator implementation
*/
function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;
/**
* @notice Returns the address of the price oracle.
* @return The address of the PriceOracle
*/
function getPriceOracle() external view returns (address);
/**
* @notice Updates the address of the price oracle.
* @param newPriceOracle The address of the new PriceOracle
*/
function setPriceOracle(address newPriceOracle) external;
/**
* @notice Returns the address of the ACL manager.
* @return The address of the ACLManager
*/
function getACLManager() external view returns (address);
/**
* @notice Updates the address of the ACL manager.
* @param newAclManager The address of the new ACLManager
*/
function setACLManager(address newAclManager) external;
/**
* @notice Returns the address of the ACL admin.
* @return The address of the ACL admin
*/
function getACLAdmin() external view returns (address);
/**
* @notice Updates the address of the ACL admin.
* @param newAclAdmin The address of the new ACL admin
*/
function setACLAdmin(address newAclAdmin) external;
/**
* @notice Returns the address of the price oracle sentinel.
* @return The address of the PriceOracleSentinel
*/
function getPriceOracleSentinel() external view returns (address);
/**
* @notice Updates the address of the price oracle sentinel.
* @param newPriceOracleSentinel The address of the new PriceOracleSentinel
*/
function setPriceOracleSentinel(address newPriceOracleSentinel) external;
/**
* @notice Returns the address of the data provider.
* @return The address of the DataProvider
*/
function getPoolDataProvider() external view returns (address);
/**
* @notice Updates the address of the data provider.
* @param newDataProvider The address of the new DataProvider
*/
function setPoolDataProvider(address newDataProvider) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
/**
* @title IPool
* @author Aave
* @notice Defines the basic interface for an Aave Pool.
*/
interface IPool {
/**
* @dev Emitted on mintUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens
* @param amount The amount of supplied assets
* @param referralCode The referral code used
*/
event MintUnbacked(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on backUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param backer The address paying for the backing
* @param amount The amount added as backing
* @param fee The amount paid in fees
*/
event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee);
/**
* @dev Emitted on supply()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supply, receiving the aTokens
* @param amount The amount supplied
* @param referralCode The referral code used
*/
event Supply(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on withdraw()
* @param reserve The address of the underlying asset being withdrawn
* @param user The address initiating the withdrawal, owner of aTokens
* @param to The address that will receive the underlying
* @param amount The amount to be withdrawn
*/
event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);
/**
* @dev Emitted on borrow() and flashLoan() when debt needs to be opened
* @param reserve The address of the underlying asset being borrowed
* @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
* initiator of the transaction on flashLoan()
* @param onBehalfOf The address that will be getting the debt
* @param amount The amount borrowed out
* @param interestRateMode The rate mode: 1 for Stable, 2 for Variable
* @param borrowRate The numeric rate at which the user has borrowed, expressed in ray
* @param referralCode The referral code used
*/
event Borrow(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 borrowRate,
uint16 indexed referralCode
);
/**
* @dev Emitted on repay()
* @param reserve The address of the underlying asset of the reserve
* @param user The beneficiary of the repayment, getting his debt reduced
* @param repayer The address of the user initiating the repay(), providing the funds
* @param amount The amount repaid
* @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly
*/
event Repay(
address indexed reserve,
address indexed user,
address indexed repayer,
uint256 amount,
bool useATokens
);
/**
* @dev Emitted on swapBorrowRateMode()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user swapping his rate mode
* @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable
*/
event SwapBorrowRateMode(
address indexed reserve,
address indexed user,
DataTypes.InterestRateMode interestRateMode
);
/**
* @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets
* @param asset The address of the underlying asset of the reserve
* @param totalDebt The total isolation mode debt for the reserve
*/
event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);
/**
* @dev Emitted when the user selects a certain asset category for eMode
* @param user The address of the user
* @param categoryId The category id
*/
event UserEModeSet(address indexed user, uint8 categoryId);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on rebalanceStableBorrowRate()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user for which the rebalance has been executed
*/
event RebalanceStableBorrowRate(address indexed reserve, address indexed user);
/**
* @dev Emitted on flashLoan()
* @param target The address of the flash loan receiver contract
* @param initiator The address initiating the flash loan
* @param asset The address of the asset being flash borrowed
* @param amount The amount flash borrowed
* @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt
* @param premium The fee flash borrowed
* @param referralCode The referral code used
*/
event FlashLoan(
address indexed target,
address initiator,
address indexed asset,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 premium,
uint16 indexed referralCode
);
/**
* @dev Emitted when a borrower is liquidated.
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param liquidatedCollateralAmount The amount of collateral received by the liquidator
* @param liquidator The address of the liquidator
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
event LiquidationCall(
address indexed collateralAsset,
address indexed debtAsset,
address indexed user,
uint256 debtToCover,
uint256 liquidatedCollateralAmount,
address liquidator,
bool receiveAToken
);
/**
* @dev Emitted when the state of a reserve is updated.
* @param reserve The address of the underlying asset of the reserve
* @param liquidityRate The next liquidity rate
* @param stableBorrowRate The next stable borrow rate
* @param variableBorrowRate The next variable borrow rate
* @param liquidityIndex The next liquidity index
* @param variableBorrowIndex The next variable borrow index
*/
event ReserveDataUpdated(
address indexed reserve,
uint256 liquidityRate,
uint256 stableBorrowRate,
uint256 variableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex
);
/**
* @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.
* @param reserve The address of the reserve
* @param amountMinted The amount minted to the treasury
*/
event MintedToTreasury(address indexed reserve, uint256 amountMinted);
/**
* @notice Mints an `amount` of aTokens to the `onBehalfOf`
* @param asset The address of the underlying asset to mint
* @param amount The amount to mint
* @param onBehalfOf The address that will receive the aTokens
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function mintUnbacked(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @notice Back the current unbacked underlying with `amount` and pay `fee`.
* @param asset The address of the underlying asset to back
* @param amount The amount to back
* @param fee The amount paid in fees
* @return The backed amount
*/
function backUnbacked(
address asset,
uint256 amount,
uint256 fee
) external returns (uint256);
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function supply(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @notice Supply with transfer approval of asset to be supplied done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param deadline The deadline timestamp that the permit is valid
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
*/
function supplyWithPermit(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external;
/**
* @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param asset The address of the underlying asset to withdraw
* @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to The address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
* @return The final amount withdrawn
*/
function withdraw(
address asset,
uint256 amount,
address to
) external returns (uint256);
/**
* @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already supplied enough collateral, or he was given enough allowance by a credit delegator on the
* corresponding debt token (StableDebtToken or VariableDebtToken)
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 stable/variable debt tokens, depending on the `interestRateMode`
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
*/
function borrow(
address asset,
uint256 amount,
uint256 interestRateMode,
uint16 referralCode,
address onBehalfOf
) external;
/**
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @return The final amount repaid
*/
function repay(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf
) external returns (uint256);
/**
* @notice Repay with transfer approval of asset to be repaid done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @param deadline The deadline timestamp that the permit is valid
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
* @return The final amount repaid
*/
function repayWithPermit(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external returns (uint256);
/**
* @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
* equivalent debt tokens
* - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens
* @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
* balance is not enough to cover the whole debt
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @return The final amount repaid
*/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa
* @param asset The address of the underlying asset borrowed
* @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable
*/
function swapBorrowRateMode(address asset, uint256 interestRateMode) external;
/**
* @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
* - Users can be rebalanced if the following conditions are satisfied:
* 1. Usage ratio is above 95%
* 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too
* much has been borrowed at a stable rate and suppliers are not earning enough
* @param asset The address of the underlying asset borrowed
* @param user The address of the user to be rebalanced
*/
function rebalanceStableBorrowRate(address asset, address user) external;
/**
* @notice Allows suppliers to enable/disable a specific supplied asset as collateral
* @param asset The address of the underlying asset supplied
* @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
*/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;
/**
* @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
* @param assets The addresses of the assets being flash-borrowed
* @param amounts The amounts of the assets being flash-borrowed
* @param interestRateModes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
* @param asset The address of the asset being flash-borrowed
* @param amount The amount of the asset being flash-borrowed
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
* @return totalDebtBase The total debt of the user in the base currency used by the price feed
* @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
* @return currentLiquidationThreshold The liquidation threshold of the user
* @return ltv The loan to value of The user
* @return healthFactor The current health factor of the user
*/
function getUserAccountData(address user)
external
view
returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
/**
* @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an
* interest rate strategy
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param aTokenAddress The address of the aToken that will be assigned to the reserve
* @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve
* @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
* @param interestRateStrategyAddress The address of the interest rate strategy contract
*/
function initReserve(
address asset,
address aTokenAddress,
address stableDebtAddress,
address variableDebtAddress,
address interestRateStrategyAddress
) external;
/**
* @notice Drop a reserve
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
*/
function dropReserve(address asset) external;
/**
* @notice Updates the address of the interest rate strategy contract
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The address of the interest rate strategy contract
*/
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external;
/**
* @notice Sets the configuration bitmap of the reserve as a whole
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param configuration The new configuration bitmap
*/
function setConfiguration(address asset, DataTypes.ReserveConfigurationMap calldata configuration)
external;
/**
* @notice Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
*/
function getConfiguration(address asset)
external
view
returns (DataTypes.ReserveConfigurationMap memory);
/**
* @notice Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
*/
function getUserConfiguration(address user)
external
view
returns (DataTypes.UserConfigurationMap memory);
/**
* @notice Returns the normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset) external view returns (uint256);
/**
* @notice Returns the normalized variable debt per unit of asset
* @dev WARNING: This function is intended to be used primarily by the protocol itself to get a
* "dynamic" variable index based on time, current stored index and virtual rate at the current
* moment (approx. a borrower would get if opening a position). This means that is always used in
* combination with variable debt supply/balances.
* If using this function externally, consider that is possible to have an increasing normalized
* variable debt that is not equivalent to how the variable debt index would be updated in storage
* (e.g. only updates with non-zero variable debt supply)
* @param asset The address of the underlying asset of the reserve
* @return The reserve normalized variable debt
*/
function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);
/**
* @notice Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve
*/
function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);
/**
* @notice Validates and finalizes an aToken transfer
* @dev Only callable by the overlying aToken of the `asset`
* @param asset The address of the underlying asset of the aToken
* @param from The user from which the aTokens are transferred
* @param to The user receiving the aTokens
* @param amount The amount being transferred/withdrawn
* @param balanceFromBefore The aToken balance of the `from` user before the transfer
* @param balanceToBefore The aToken balance of the `to` user before the transfer
*/
function finalizeTransfer(
address asset,
address from,
address to,
uint256 amount,
uint256 balanceFromBefore,
uint256 balanceToBefore
) external;
/**
* @notice Returns the list of the underlying assets of all the initialized reserves
* @dev It does not include dropped reserves
* @return The addresses of the underlying assets of the initialized reserves
*/
function getReservesList() external view returns (address[] memory);
/**
* @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct
* @param id The id of the reserve as stored in the DataTypes.ReserveData struct
* @return The address of the reserve associated with id
*/
function getReserveAddressById(uint16 id) external view returns (address);
/**
* @notice Returns the PoolAddressesProvider connected to this contract
* @return The address of the PoolAddressesProvider
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Updates the protocol fee on the bridging
* @param bridgeProtocolFee The part of the premium sent to the protocol treasury
*/
function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;
/**
* @notice Updates flash loan premiums. Flash loan premium consists of two parts:
* - A part is sent to aToken holders as extra, one time accumulated interest
* - A part is collected by the protocol treasury
* @dev The total premium is calculated on the total borrowed amount
* @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`
* @dev Only callable by the PoolConfigurator contract
* @param flashLoanPremiumTotal The total premium, expressed in bps
* @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps
*/
function updateFlashloanPremiums(
uint128 flashLoanPremiumTotal,
uint128 flashLoanPremiumToProtocol
) external;
/**
* @notice Configures a new category for the eMode.
* @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.
* The category 0 is reserved as it's the default for volatile assets
* @param id The id of the category
* @param config The configuration of the category
*/
function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external;
/**
* @notice Returns the data of an eMode category
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory);
/**
* @notice Allows a user to use the protocol in eMode
* @param categoryId The id of the category
*/
function setUserEMode(uint8 categoryId) external;
/**
* @notice Returns the eMode the user is using
* @param user The address of the user
* @return The eMode id
*/
function getUserEMode(address user) external view returns (uint256);
/**
* @notice Resets the isolation mode total debt of the given asset to zero
* @dev It requires the given asset has zero debt ceiling
* @param asset The address of the underlying asset to reset the isolationModeTotalDebt
*/
function resetIsolationModeTotalDebt(address asset) external;
/**
* @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate
* @return The percentage of available liquidity to borrow, expressed in bps
*/
function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256);
/**
* @notice Returns the total fee on flash loans
* @return The total fee on flashloans
*/
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
/**
* @notice Returns the part of the bridge fees sent to protocol
* @return The bridge fee sent to the protocol treasury
*/
function BRIDGE_PROTOCOL_FEE() external view returns (uint256);
/**
* @notice Returns the part of the flashloan fees sent to protocol
* @return The flashloan fee sent to the protocol treasury
*/
function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);
/**
* @notice Returns the maximum number of reserves supported to be listed in this Pool
* @return The maximum number of reserves supported
*/
function MAX_NUMBER_RESERVES() external view returns (uint16);
/**
* @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
* @param assets The list of reserves for which the minting needs to be executed
*/
function mintToTreasury(address[] calldata assets) external;
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(
address token,
address to,
uint256 amount
) external;
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @dev Deprecated: Use the `supply` function instead
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function deposit(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
library DataTypes {
struct ReserveData {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
//the current stable borrow rate. Expressed in ray
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
//stableDebtToken address
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62-63: reserved
//bit 64-79: reserve factor
//bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167 liquidation protocol fee
//bit 168-175 eMode category
//bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252-255 unused
uint256 data;
}
struct UserConfigurationMap {
/**
* @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
* The first bit indicates if an asset is used as collateral by the user, the second whether an
* asset is borrowed by the user.
*/
uint256 data;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// each eMode category may or may not have a custom oracle to override the individual assets price oracles
address priceSource;
string label;
}
enum InterestRateMode {
NONE,
STABLE,
VARIABLE
}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currPrincipalStableDebt;
uint256 currAvgStableBorrowRate;
uint256 currTotalStableDebt;
uint256 nextAvgStableBorrowRate;
uint256 nextTotalStableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address stableDebtTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
uint40 stableDebtLastUpdateTimestamp;
}
struct ExecuteLiquidationCallParams {
uint256 reservesCount;
uint256 debtToCover;
address collateralAsset;
address debtAsset;
address user;
bool receiveAToken;
address priceOracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteSupplyParams {
address asset;
uint256 amount;
address onBehalfOf;
uint16 referralCode;
}
struct ExecuteBorrowParams {
address asset;
address user;
address onBehalfOf;
uint256 amount;
InterestRateMode interestRateMode;
uint16 referralCode;
bool releaseUnderlying;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteRepayParams {
address asset;
uint256 amount;
InterestRateMode interestRateMode;
address onBehalfOf;
bool useATokens;
}
struct ExecuteWithdrawParams {
address asset;
uint256 amount;
address to;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteSetUserEModeParams {
uint256 reservesCount;
address oracle;
uint8 categoryId;
}
struct FinalizeTransferParams {
address asset;
address from;
address to;
uint256 amount;
uint256 balanceFromBefore;
uint256 balanceToBefore;
uint256 reservesCount;
address oracle;
uint8 fromEModeCategory;
}
struct FlashloanParams {
address receiverAddress;
address[] assets;
uint256[] amounts;
uint256[] interestRateModes;
address onBehalfOf;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address addressesProvider;
uint8 userEModeCategory;
bool isAuthorizedFlashBorrower;
}
struct FlashloanSimpleParams {
address receiverAddress;
address asset;
uint256 amount;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
}
struct FlashLoanRepaymentParams {
uint256 amount;
uint256 totalPremium;
uint256 flashLoanPremiumToProtocol;
address asset;
address receiverAddress;
uint16 referralCode;
}
struct CalculateUserAccountDataParams {
UserConfigurationMap userConfig;
uint256 reservesCount;
address user;
address oracle;
uint8 userEModeCategory;
}
struct ValidateBorrowParams {
ReserveCache reserveCache;
UserConfigurationMap userConfig;
address asset;
address userAddress;
uint256 amount;
InterestRateMode interestRateMode;
uint256 maxStableLoanPercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
bool isolationModeActive;
address isolationModeCollateralAddress;
uint256 isolationModeDebtCeiling;
}
struct ValidateLiquidationCallParams {
ReserveCache debtReserveCache;
uint256 totalDebt;
uint256 healthFactor;
address priceOracleSentinel;
}
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalStableDebt;
uint256 totalVariableDebt;
uint256 averageStableBorrowRate;
uint256 reserveFactor;
address reserve;
address aToken;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address stableDebtAddress;
address variableDebtAddress;
address interestRateStrategyAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import {Errors} from '../helpers/Errors.sol';
import {DataTypes} from '../types/DataTypes.sol';
/**
* @title ReserveConfiguration library
* @author Aave
* @notice Implements the bitmap logic to handle the reserve configuration
*/
library ReserveConfiguration {
uint256 internal constant LTV_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000; // prettier-ignore
uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF; // prettier-ignore
uint256 internal constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF; // prettier-ignore
uint256 internal constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF; // prettier-ignore
uint256 internal constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant SILOED_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant FLASHLOAN_ENABLED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant EMODE_CATEGORY_MASK = 0xFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant UNBACKED_MINT_CAP_MASK = 0xFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 internal constant DEBT_CEILING_MASK = 0xF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
/// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed
uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32;
uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48;
uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56;
uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57;
uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 internal constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60;
uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61;
uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62;
uint256 internal constant FLASHLOAN_ENABLED_START_BIT_POSITION = 63;
uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116;
uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152;
uint256 internal constant EMODE_CATEGORY_START_BIT_POSITION = 168;
uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176;
uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212;
uint256 internal constant MAX_VALID_LTV = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535;
uint256 internal constant MAX_VALID_DECIMALS = 255;
uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735;
uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735;
uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535;
uint256 internal constant MAX_VALID_EMODE_CATEGORY = 255;
uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735;
uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775;
uint256 public constant DEBT_CEILING_DECIMALS = 2;
uint16 public constant MAX_RESERVES_COUNT = 128;
/**
* @notice Sets the Loan to Value of the reserve
* @param self The reserve configuration
* @param ltv The new ltv
*/
function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV);
self.data = (self.data & LTV_MASK) | ltv;
}
/**
* @notice Gets the Loan to Value of the reserve
* @param self The reserve configuration
* @return The loan to value
*/
function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) {
return self.data & ~LTV_MASK;
}
/**
* @notice Sets the liquidation threshold of the reserve
* @param self The reserve configuration
* @param threshold The new liquidation threshold
*/
function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold)
internal
pure
{
require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD);
self.data =
(self.data & LIQUIDATION_THRESHOLD_MASK) |
(threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation threshold of the reserve
* @param self The reserve configuration
* @return The liquidation threshold
*/
function getLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
}
/**
* @notice Sets the liquidation bonus of the reserve
* @param self The reserve configuration
* @param bonus The new liquidation bonus
*/
function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus)
internal
pure
{
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS);
self.data =
(self.data & LIQUIDATION_BONUS_MASK) |
(bonus << LIQUIDATION_BONUS_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation bonus of the reserve
* @param self The reserve configuration
* @return The liquidation bonus
*/
function getLiquidationBonus(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION;
}
/**
* @notice Sets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @param decimals The decimals
*/
function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals)
internal
pure
{
require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS);
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
}
/**
* @notice Gets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @return The decimals of the asset
*/
function getDecimals(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
}
/**
* @notice Sets the active state of the reserve
* @param self The reserve configuration
* @param active The active state
*/
function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
self.data =
(self.data & ACTIVE_MASK) |
(uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
}
/**
* @notice Gets the active state of the reserve
* @param self The reserve configuration
* @return The active state
*/
function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~ACTIVE_MASK) != 0;
}
/**
* @notice Sets the frozen state of the reserve
* @param self The reserve configuration
* @param frozen The frozen state
*/
function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
self.data =
(self.data & FROZEN_MASK) |
(uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
}
/**
* @notice Gets the frozen state of the reserve
* @param self The reserve configuration
* @return The frozen state
*/
function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~FROZEN_MASK) != 0;
}
/**
* @notice Sets the paused state of the reserve
* @param self The reserve configuration
* @param paused The paused state
*/
function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure {
self.data =
(self.data & PAUSED_MASK) |
(uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION);
}
/**
* @notice Gets the paused state of the reserve
* @param self The reserve configuration
* @return The paused state
*/
function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ~PAUSED_MASK) != 0;
}
/**
* @notice Sets the borrowable in isolation flag for the reserve.
* @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed
* amount will be accumulated in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @param borrowable True if the asset is borrowable
*/
function setBorrowableInIsolation(DataTypes.ReserveConfigurationMap memory self, bool borrowable)
internal
pure
{
self.data =
(self.data & BORROWABLE_IN_ISOLATION_MASK) |
(uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION);
}
/**
* @notice Gets the borrowable in isolation flag for the reserve.
* @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with
* isolated collateral is accounted for in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @return The borrowable in isolation flag
*/
function getBorrowableInIsolation(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0;
}
/**
* @notice Sets the siloed borrowing flag for the reserve.
* @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset.
* @param self The reserve configuration
* @param siloed True if the asset is siloed
*/
function setSiloedBorrowing(DataTypes.ReserveConfigurationMap memory self, bool siloed)
internal
pure
{
self.data =
(self.data & SILOED_BORROWING_MASK) |
(uint256(siloed ? 1 : 0) << SILOED_BORROWING_START_BIT_POSITION);
}
/**
* @notice Gets the siloed borrowing flag for the reserve.
* @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset.
* @param self The reserve configuration
* @return The siloed borrowing flag
*/
function getSiloedBorrowing(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~SILOED_BORROWING_MASK) != 0;
}
/**
* @notice Enables or disables borrowing on the reserve
* @param self The reserve configuration
* @param enabled True if the borrowing needs to be enabled, false otherwise
*/
function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
internal
pure
{
self.data =
(self.data & BORROWING_MASK) |
(uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
}
/**
* @notice Gets the borrowing state of the reserve
* @param self The reserve configuration
* @return The borrowing state
*/
function getBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~BORROWING_MASK) != 0;
}
/**
* @notice Enables or disables stable rate borrowing on the reserve
* @param self The reserve configuration
* @param enabled True if the stable rate borrowing needs to be enabled, false otherwise
*/
function setStableRateBorrowingEnabled(
DataTypes.ReserveConfigurationMap memory self,
bool enabled
) internal pure {
self.data =
(self.data & STABLE_BORROWING_MASK) |
(uint256(enabled ? 1 : 0) << STABLE_BORROWING_ENABLED_START_BIT_POSITION);
}
/**
* @notice Gets the stable rate borrowing state of the reserve
* @param self The reserve configuration
* @return The stable rate borrowing state
*/
function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~STABLE_BORROWING_MASK) != 0;
}
/**
* @notice Sets the reserve factor of the reserve
* @param self The reserve configuration
* @param reserveFactor The reserve factor
*/
function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor)
internal
pure
{
require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR);
self.data =
(self.data & RESERVE_FACTOR_MASK) |
(reserveFactor << RESERVE_FACTOR_START_BIT_POSITION);
}
/**
* @notice Gets the reserve factor of the reserve
* @param self The reserve configuration
* @return The reserve factor
*/
function getReserveFactor(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
}
/**
* @notice Sets the borrow cap of the reserve
* @param self The reserve configuration
* @param borrowCap The borrow cap
*/
function setBorrowCap(DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap)
internal
pure
{
require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.INVALID_BORROW_CAP);
self.data = (self.data & BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION);
}
/**
* @notice Gets the borrow cap of the reserve
* @param self The reserve configuration
* @return The borrow cap
*/
function getBorrowCap(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the supply cap of the reserve
* @param self The reserve configuration
* @param supplyCap The supply cap
*/
function setSupplyCap(DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap)
internal
pure
{
require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.INVALID_SUPPLY_CAP);
self.data = (self.data & SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION);
}
/**
* @notice Gets the supply cap of the reserve
* @param self The reserve configuration
* @return The supply cap
*/
function getSupplyCap(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the debt ceiling in isolation mode for the asset
* @param self The reserve configuration
* @param ceiling The maximum debt ceiling for the asset
*/
function setDebtCeiling(DataTypes.ReserveConfigurationMap memory self, uint256 ceiling)
internal
pure
{
require(ceiling <= MAX_VALID_DEBT_CEILING, Errors.INVALID_DEBT_CEILING);
self.data = (self.data & DEBT_CEILING_MASK) | (ceiling << DEBT_CEILING_START_BIT_POSITION);
}
/**
* @notice Gets the debt ceiling for the asset if the asset is in isolation mode
* @param self The reserve configuration
* @return The debt ceiling (0 = isolation mode disabled)
*/
function getDebtCeiling(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~DEBT_CEILING_MASK) >> DEBT_CEILING_START_BIT_POSITION;
}
/**
* @notice Sets the liquidation protocol fee of the reserve
* @param self The reserve configuration
* @param liquidationProtocolFee The liquidation protocol fee
*/
function setLiquidationProtocolFee(
DataTypes.ReserveConfigurationMap memory self,
uint256 liquidationProtocolFee
) internal pure {
require(
liquidationProtocolFee <= MAX_VALID_LIQUIDATION_PROTOCOL_FEE,
Errors.INVALID_LIQUIDATION_PROTOCOL_FEE
);
self.data =
(self.data & LIQUIDATION_PROTOCOL_FEE_MASK) |
(liquidationProtocolFee << LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION);
}
/**
* @dev Gets the liquidation protocol fee
* @param self The reserve configuration
* @return The liquidation protocol fee
*/
function getLiquidationProtocolFee(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return
(self.data & ~LIQUIDATION_PROTOCOL_FEE_MASK) >> LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION;
}
/**
* @notice Sets the unbacked mint cap of the reserve
* @param self The reserve configuration
* @param unbackedMintCap The unbacked mint cap
*/
function setUnbackedMintCap(
DataTypes.ReserveConfigurationMap memory self,
uint256 unbackedMintCap
) internal pure {
require(unbackedMintCap <= MAX_VALID_UNBACKED_MINT_CAP, Errors.INVALID_UNBACKED_MINT_CAP);
self.data =
(self.data & UNBACKED_MINT_CAP_MASK) |
(unbackedMintCap << UNBACKED_MINT_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the unbacked mint cap of the reserve
* @param self The reserve configuration
* @return The unbacked mint cap
*/
function getUnbackedMintCap(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~UNBACKED_MINT_CAP_MASK) >> UNBACKED_MINT_CAP_START_BIT_POSITION;
}
/**
* @notice Sets the eMode asset category
* @param self The reserve configuration
* @param category The asset category when the user selects the eMode
*/
function setEModeCategory(DataTypes.ReserveConfigurationMap memory self, uint256 category)
internal
pure
{
require(category <= MAX_VALID_EMODE_CATEGORY, Errors.INVALID_EMODE_CATEGORY);
self.data = (self.data & EMODE_CATEGORY_MASK) | (category << EMODE_CATEGORY_START_BIT_POSITION);
}
/**
* @dev Gets the eMode asset category
* @param self The reserve configuration
* @return The eMode category for the asset
*/
function getEModeCategory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_START_BIT_POSITION;
}
/**
* @notice Sets the flashloanable flag for the reserve
* @param self The reserve configuration
* @param flashLoanEnabled True if the asset is flashloanable, false otherwise
*/
function setFlashLoanEnabled(DataTypes.ReserveConfigurationMap memory self, bool flashLoanEnabled)
internal
pure
{
self.data =
(self.data & FLASHLOAN_ENABLED_MASK) |
(uint256(flashLoanEnabled ? 1 : 0) << FLASHLOAN_ENABLED_START_BIT_POSITION);
}
/**
* @notice Gets the flashloanable flag for the reserve
* @param self The reserve configuration
* @return The flashloanable flag
*/
function getFlashLoanEnabled(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~FLASHLOAN_ENABLED_MASK) != 0;
}
/**
* @notice Gets the configuration flags of the reserve
* @param self The reserve configuration
* @return The state flag representing active
* @return The state flag representing frozen
* @return The state flag representing borrowing enabled
* @return The state flag representing stableRateBorrowing enabled
* @return The state flag representing paused
*/
function getFlags(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (
bool,
bool,
bool,
bool,
bool
)
{
uint256 dataLocal = self.data;
return (
(dataLocal & ~ACTIVE_MASK) != 0,
(dataLocal & ~FROZEN_MASK) != 0,
(dataLocal & ~BORROWING_MASK) != 0,
(dataLocal & ~STABLE_BORROWING_MASK) != 0,
(dataLocal & ~PAUSED_MASK) != 0
);
}
/**
* @notice Gets the configuration parameters of the reserve from storage
* @param self The reserve configuration
* @return The state param representing ltv
* @return The state param representing liquidation threshold
* @return The state param representing liquidation bonus
* @return The state param representing reserve decimals
* @return The state param representing reserve factor
* @return The state param representing eMode category
*/
function getParams(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (
uint256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
uint256 dataLocal = self.data;
return (
dataLocal & ~LTV_MASK,
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION,
(dataLocal & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_START_BIT_POSITION
);
}
/**
* @notice Gets the caps parameters of the reserve from storage
* @param self The reserve configuration
* @return The state param representing borrow cap
* @return The state param representing supply cap.
*/
function getCaps(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256, uint256)
{
uint256 dataLocal = self.data;
return (
(dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import {Address} from 'solidity-utils/contracts/oz-common/Address.sol';
import {SafeCast} from '@openzeppelin/contracts/utils/math/SafeCast.sol';
import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol';
import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol';
import {ConfiguratorInputTypes} from '@aave/core-v3/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol';
library DataTypes {
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalStableDebt;
uint256 totalVariableDebt;
uint256 averageStableBorrowRate;
uint256 reserveFactor;
address reserve;
bool usingVirtualBalance;
uint256 virtualUnderlyingBalance;
}
}
/**
* @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_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator'
string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid'
string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid'
string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio'
string public constant INVALID_MAX_RATE = '92'; // The expect maximum borrow rate is invalid
string public constant SLOPE_2_MUST_BE_GTE_SLOPE_1 = '95'; // Variable interest rate slope 2 can not be lower than slope 1
}
/**
* @title PercentageMath library
* @author Aave
* @notice Provides functions to perform percentage calculations
* @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR
* @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
*/
library PercentageMath {
// Maximum percentage factor (100.00%)
uint256 internal constant PERCENTAGE_FACTOR = 1e4;
// Half percentage factor (50.00%)
uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4;
/**
* @notice Executes a percentage multiplication
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param value The value of which the percentage needs to be calculated
* @param percentage The percentage of the value to be calculated
* @return result value percentmul percentage
*/
function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
// to avoid overflow, value <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage
assembly {
if iszero(
or(
iszero(percentage),
iszero(gt(value, div(sub(not(0), HALF_PERCENTAGE_FACTOR), percentage)))
)
) {
revert(0, 0)
}
result := div(add(mul(value, percentage), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR)
}
}
/**
* @notice Executes a percentage division
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param value The value of which the percentage needs to be calculated
* @param percentage The percentage of the value to be calculated
* @return result value percentdiv percentage
*/
function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
// to avoid overflow, value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR
assembly {
if or(
iszero(percentage),
iszero(iszero(gt(value, div(sub(not(0), div(percentage, 2)), PERCENTAGE_FACTOR))))
) {
revert(0, 0)
}
result := div(add(mul(value, PERCENTAGE_FACTOR), div(percentage, 2)), percentage)
}
}
}
/**
* @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)
}
}
}
}
/// @notice This interface contains the only ARM-related functions that might be used on-chain by other CCIP contracts.
interface IARM {
/// @notice A Merkle root tagged with the address of the commit store contract it is destined for.
struct TaggedRoot {
address commitStore;
bytes32 root;
}
/// @notice Callers MUST NOT cache the return value as a blessed tagged root could become unblessed.
function isBlessed(TaggedRoot calldata taggedRoot) external view returns (bool);
/// @notice When the ARM is "cursed", CCIP pauses until the curse is lifted.
function isCursed() external view returns (bool);
}
/**
* @title IPoolConfigurator
* @author Aave
* @notice Defines the basic interface for a Pool configurator.
* @dev Reduced interface from https://github.com/aave-dao/aave-v3-origin/blob/main/src/core/contracts/interfaces/IPoolConfigurator.sol
*/
interface IPoolConfigurator {
/**
* @notice Sets interest rate data for a reserve
* @param asset The address of the underlying asset of the reserve
* @param rateData bytes-encoded rate data. In this format in order to allow the rate strategy contract
* to de-structure custom data
*/
function setReserveInterestRateData(address asset, bytes calldata rateData) external;
/**
* @notice Updates the borrow cap of a reserve.
* @param asset The address of the underlying asset of the reserve
* @param newBorrowCap The new borrow cap of the reserve
*/
function setBorrowCap(address asset, uint256 newBorrowCap) external;
/**
* @notice Updates the supply cap of a reserve.
* @param asset The address of the underlying asset of the reserve
* @param newSupplyCap The new supply cap of the reserve
*/
function setSupplyCap(address asset, uint256 newSupplyCap) external;
}
/**
* @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 stableBorrowRate The stable borrow rate expressed in ray
* @return variableBorrowRate The variable borrow rate expressed in ray
*/
function calculateInterestRates(
DataTypes.CalculateInterestRatesParams memory params
) external view returns (uint256, uint256, uint256);
}
/**
* @title IDefaultInterestRateStrategyV2
* @author BGD Labs
* @notice Interface of the default interest rate strategy used by the Aave protocol
*/
interface IDefaultInterestRateStrategyV2 is IReserveInterestRateStrategy {
struct CalcInterestRatesLocalVars {
uint256 availableLiquidity;
uint256 totalDebt;
uint256 currentVariableBorrowRate;
uint256 currentLiquidityRate;
uint256 borrowUsageRatio;
uint256 supplyUsageRatio;
uint256 availableLiquidityPlusDebt;
}
/**
* @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 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;
}
/**
* @title DefaultReserveInterestRateStrategyV2 contract
* @author BGD Labs
* @notice Default interest rate strategy used by the Aave protocol
* @dev Strategies are pool-specific: each contract CAN'T be used across different Aave pools
* due to the caching of the PoolAddressesProvider and the usage of underlying addresses as
* index of the _interestRateData
*/
contract DefaultReserveInterestRateStrategyV2 is IDefaultInterestRateStrategyV2 {
using WadRayMath for uint256;
using PercentageMath for uint256;
/// @inheritdoc IDefaultInterestRateStrategyV2
IPoolAddressesProvider public immutable ADDRESSES_PROVIDER;
/// @inheritdoc IDefaultInterestRateStrategyV2
uint256 public constant MAX_BORROW_RATE = 1000_00;
/// @inheritdoc IDefaultInterestRateStrategyV2
uint256 public constant MIN_OPTIMAL_POINT = 1_00;
/// @inheritdoc IDefaultInterestRateStrategyV2
uint256 public constant MAX_OPTIMAL_POINT = 99_00;
/// @dev Map of reserves address and their interest rate data (reserveAddress => interestRateData)
mapping(address => InterestRateData) internal _interestRateData;
modifier onlyPoolConfigurator() {
require(
msg.sender == ADDRESSES_PROVIDER.getPoolConfigurator(),
Errors.CALLER_NOT_POOL_CONFIGURATOR
);
_;
}
/**
* @dev Constructor.
* @param provider The address of the PoolAddressesProvider of the associated Aave pool
*/
constructor(address provider) {
require(provider != address(0), Errors.INVALID_ADDRESSES_PROVIDER);
ADDRESSES_PROVIDER = IPoolAddressesProvider(provider);
}
/// @inheritdoc IReserveInterestRateStrategy
function setInterestRateParams(
address reserve,
bytes calldata rateData
) external onlyPoolConfigurator {
_setInterestRateParams(reserve, abi.decode(rateData, (InterestRateData)));
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function setInterestRateParams(
address reserve,
InterestRateData calldata rateData
) external onlyPoolConfigurator {
_setInterestRateParams(reserve, rateData);
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getInterestRateDataBps(address reserve) external view returns (InterestRateData memory) {
return _interestRateData[reserve];
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getOptimalUsageRatio(address reserve) external view returns (uint256) {
return _bpsToRay(uint256(_interestRateData[reserve].optimalUsageRatio));
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getVariableRateSlope1(address reserve) external view returns (uint256) {
return _bpsToRay(uint256(_interestRateData[reserve].variableRateSlope1));
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getVariableRateSlope2(address reserve) external view returns (uint256) {
return _bpsToRay(uint256(_interestRateData[reserve].variableRateSlope2));
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getBaseVariableBorrowRate(address reserve) external view override returns (uint256) {
return _bpsToRay(uint256(_interestRateData[reserve].baseVariableBorrowRate));
}
/// @inheritdoc IDefaultInterestRateStrategyV2
function getMaxVariableBorrowRate(address reserve) external view override returns (uint256) {
return
_bpsToRay(
uint256(
_interestRateData[reserve].baseVariableBorrowRate +
_interestRateData[reserve].variableRateSlope1 +
_interestRateData[reserve].variableRateSlope2
)
);
}
/// @inheritdoc IReserveInterestRateStrategy
function calculateInterestRates(
DataTypes.CalculateInterestRatesParams memory params
) external view virtual override returns (uint256, uint256, uint256) {
InterestRateDataRay memory rateData = _rayifyRateData(_interestRateData[params.reserve]);
// @note This is a short circuit to allow mintable assets (ex. GHO), which by definition cannot be supplied
// and thus do not use virtual underlying balances.
if (!params.usingVirtualBalance) {
return (0, 0, rateData.baseVariableBorrowRate);
}
CalcInterestRatesLocalVars memory vars;
vars.totalDebt = params.totalStableDebt + params.totalVariableDebt;
vars.currentLiquidityRate = 0;
vars.currentVariableBorrowRate = rateData.baseVariableBorrowRate;
if (vars.totalDebt != 0) {
vars.availableLiquidity =
params.virtualUnderlyingBalance +
params.liquidityAdded -
params.liquidityTaken;
vars.availableLiquidityPlusDebt = vars.availableLiquidity + vars.totalDebt;
vars.borrowUsageRatio = vars.totalDebt.rayDiv(vars.availableLiquidityPlusDebt);
vars.supplyUsageRatio = vars.totalDebt.rayDiv(
vars.availableLiquidityPlusDebt + params.unbacked
);
} else {
return (0, 0, vars.currentVariableBorrowRate);
}
if (vars.borrowUsageRatio > rateData.optimalUsageRatio) {
uint256 excessBorrowUsageRatio = (vars.borrowUsageRatio - rateData.optimalUsageRatio).rayDiv(
WadRayMath.RAY - rateData.optimalUsageRatio
);
vars.currentVariableBorrowRate +=
rateData.variableRateSlope1 +
rateData.variableRateSlope2.rayMul(excessBorrowUsageRatio);
} else {
vars.currentVariableBorrowRate += rateData
.variableRateSlope1
.rayMul(vars.borrowUsageRatio)
.rayDiv(rateData.optimalUsageRatio);
}
vars.currentLiquidityRate = _getOverallBorrowRate(
params.totalStableDebt,
params.totalVariableDebt,
vars.currentVariableBorrowRate,
params.averageStableBorrowRate
).rayMul(vars.supplyUsageRatio).percentMul(
PercentageMath.PERCENTAGE_FACTOR - params.reserveFactor
);
return (vars.currentLiquidityRate, 0, vars.currentVariableBorrowRate);
}
/**
* @dev Calculates the overall borrow rate as the weighted average between the total variable debt and total stable
* debt
* @param totalStableDebt The total borrowed from the reserve at a stable rate
* @param totalVariableDebt The total borrowed from the reserve at a variable rate
* @param currentVariableBorrowRate The current variable borrow rate of the reserve
* @param currentAverageStableBorrowRate The current weighted average of all the stable rate loans
* @return The weighted averaged borrow rate
*/
function _getOverallBorrowRate(
uint256 totalStableDebt,
uint256 totalVariableDebt,
uint256 currentVariableBorrowRate,
uint256 currentAverageStableBorrowRate
) internal pure returns (uint256) {
uint256 totalDebt = totalStableDebt + totalVariableDebt;
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
uint256 overallBorrowRate = (weightedVariableRate + weightedStableRate).rayDiv(
totalDebt.wadToRay()
);
return overallBorrowRate;
}
/**
* @dev Doing validations and data update for an asset
* @param reserve address of the underlying asset of the reserve
* @param rateData Encoded reserve interest rate data to apply
*/
function _setInterestRateParams(address reserve, InterestRateData memory rateData) internal {
require(reserve != address(0), Errors.ZERO_ADDRESS_NOT_VALID);
require(
rateData.optimalUsageRatio <= MAX_OPTIMAL_POINT &&
rateData.optimalUsageRatio >= MIN_OPTIMAL_POINT,
Errors.INVALID_OPTIMAL_USAGE_RATIO
);
require(
rateData.variableRateSlope1 <= rateData.variableRateSlope2,
Errors.SLOPE_2_MUST_BE_GTE_SLOPE_1
);
// The maximum rate should not be above certain threshold
require(
uint256(rateData.baseVariableBorrowRate) +
uint256(rateData.variableRateSlope1) +
uint256(rateData.variableRateSlope2) <=
MAX_BORROW_RATE,
Errors.INVALID_MAX_RATE
);
_interestRateData[reserve] = rateData;
emit RateDataUpdate(
reserve,
rateData.optimalUsageRatio,
rateData.baseVariableBorrowRate,
rateData.variableRateSlope1,
rateData.variableRateSlope2
);
}
/**
* @dev Transforms an InterestRateData struct to an InterestRateDataRay struct by multiplying all values
* by 1e23, turning them into ray values
*
* @param data The InterestRateData struct to transform
*
* @return The resulting InterestRateDataRay struct
*/
function _rayifyRateData(
InterestRateData memory data
) internal pure returns (InterestRateDataRay memory) {
return
InterestRateDataRay({
optimalUsageRatio: _bpsToRay(uint256(data.optimalUsageRatio)),
baseVariableBorrowRate: _bpsToRay(uint256(data.baseVariableBorrowRate)),
variableRateSlope1: _bpsToRay(uint256(data.variableRateSlope1)),
variableRateSlope2: _bpsToRay(uint256(data.variableRateSlope2))
});
}
// @dev helper function added here, as generally the protocol doesn't use bps
function _bpsToRay(uint256 n) internal pure returns (uint256) {
return n * 1e23;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/**
* @title IGhoAaveSteward
* @author Aave Labs
* @notice Defines the basic interface of the GhoAaveSteward
*/
interface IGhoAaveSteward {
/**
* @notice Struct storing the last update by the steward of each borrow rate param
*/
struct GhoDebounce {
uint40 ghoBorrowCapLastUpdate;
uint40 ghoSupplyCapLastUpdate;
uint40 ghoBorrowRateLastUpdate;
}
/**
* @notice Struct storing the configuration for the borrow rate params
*/
struct BorrowRateConfig {
uint16 optimalUsageRatioMaxChange;
uint32 baseVariableBorrowRateMaxChange;
uint32 variableRateSlope1MaxChange;
uint32 variableRateSlope2MaxChange;
}
/**
* @notice Updates the borrow rate of GHO, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes parameters up to the maximum allowed change according to risk config
* @dev Only callable by Risk Council
* @dev Values are all expressed in BPS
* @param optimalUsageRatio The new optimal usage ratio
* @param baseVariableBorrowRate The new base variable borrow rate
* @param variableRateSlope1 The new variable rate slope 1
* @param variableRateSlope2 The new variable rate slope 2
*/
function updateGhoBorrowRate(
uint16 optimalUsageRatio,
uint32 baseVariableBorrowRate,
uint32 variableRateSlope1,
uint32 variableRateSlope2
) external;
/**
* @notice Updates the GHO borrow cap, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to 100% upwards or downwards
* @dev Only callable by Risk Council
* @param newBorrowCap The new borrow cap (in whole tokens)
*/
function updateGhoBorrowCap(uint256 newBorrowCap) external;
/**
* @notice Updates the GHO supply cap, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to 100% upwards or downwards
* @dev Only callable by Risk Council
* @param newSupplyCap The new supply cap (in whole tokens)
*/
function updateGhoSupplyCap(uint256 newSupplyCap) external;
/**
* @notice Updates the configuration conditions for borrow rate changes
* @dev Values are all expressed in BPS
* @param optimalUsageRatioMaxChange The new allowed max percentage change for optimal usage ratio
* @param baseVariableBorrowRateMaxChange The new allowed max percentage change for base variable borrow rate
* @param variableRateSlope1MaxChange The new allowed max percentage change for variable rate slope 1
* @param variableRateSlope2MaxChange The new allowed max percentage change for variable rate slope 2
*/
function setBorrowRateConfig(
uint16 optimalUsageRatioMaxChange,
uint32 baseVariableBorrowRateMaxChange,
uint32 variableRateSlope1MaxChange,
uint32 variableRateSlope2MaxChange
) external;
/**
* @notice Returns the configuration conditions for a GHO borrow rate change
* @return struct containing the borrow rate configuration
*/
function getBorrowRateConfig() external view returns (BorrowRateConfig memory);
/**
* @notice Returns timestamp of the last update of GHO parameters
* @return The GhoDebounce struct describing the last update of GHO parameters
*/
function getGhoTimelocks() external view returns (GhoDebounce memory);
/**
* @notice The address of pool data provider of the POOL the steward controls
*/
function POOL_DATA_PROVIDER() external view returns (address);
/**
* @notice Returns the minimum delay that must be respected between parameters update.
* @return The minimum delay between parameter updates (in seconds)
*/
function MINIMUM_DELAY() external view returns (uint256);
/**
* @notice Returns the address of the Pool Addresses Provider of the Aave V3 Ethereum Pool
* @return The address of the PoolAddressesProvider of Aave V3 Ethereum Pool
*/
function POOL_ADDRESSES_PROVIDER() external view returns (address);
/**
* @notice Returns the address of the Gho Token
* @return The address of the GhoToken
*/
function GHO_TOKEN() external view returns (address);
/**
* @notice Returns the address of the risk council
* @return The address of the RiskCouncil
*/
function RISK_COUNCIL() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/**
* @title RiskCouncilControlled
* @author Aave Labs
* @notice Helper contract for controlling access to Steward and other functions restricted to Risk Council
*/
abstract contract RiskCouncilControlled {
address internal immutable _riskCouncil;
/**
* @dev Constructor
* @param riskCouncil The address of the risk council
*/
constructor(address riskCouncil) {
require(riskCouncil != address(0), 'INVALID_RISK_COUNCIL');
_riskCouncil = riskCouncil;
}
/**
* @dev Only Risk Council can call functions marked by this modifier.
*/
modifier onlyRiskCouncil() {
require(_riskCouncil == msg.sender, 'INVALID_CALLER');
_;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title Errors library
* @author Aave
* @notice Defines the error messages emitted by the different contracts of the Aave protocol
*/
library Errors {
string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin'
string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin'
string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin'
string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin'
string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin'
string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge'
string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered'
string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider'
string public constant NOT_CONTRACT = '9'; // 'Address is not a contract'
string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator'
string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken'
string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid'
string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function'
string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list'
string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached'
string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets'
string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset'
string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0'
string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium'
string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve'
string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category'
string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee'
string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool'
string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint'
string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn'
string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0'
string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve'
string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen'
string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused'
string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled'
string public constant STABLE_BORROWING_NOT_ENABLED = '31'; // 'Stable borrowing is not enabled'
string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance'
string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected'
string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0'
string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold'
string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow'
string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed'
string public constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '38'; // 'The requested amount is greater than the max loan size in stable rate mode'
string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type'
string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed'
string public constant NO_OUTSTANDING_STABLE_DEBT = '41'; // 'User does not have outstanding stable rate debt on this reserve'
string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve'
string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0'
string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met'
string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold'
string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated'
string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency'
string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters'
string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded'
string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded'
string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded'
string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded'
string public constant UNDERLYING_CLAIMABLE_RIGHTS_NOT_ZERO = '54'; // 'Claimable rights over underlying not zero (aToken supply or accruedToTreasury)'
string public constant STABLE_DEBT_NOT_ZERO = '55'; // 'Stable debt supply is not zero'
string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero'
string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed'
string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category'
string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed'
string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode'
string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized'
string public constant USER_IN_ISOLATION_MODE = '62'; // 'User is in isolation mode'
string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve'
string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve'
string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve'
string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve'
string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve'
string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve'
string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve'
string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve'
string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve'
string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve'
string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve
string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index'
string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address'
string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not'
string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid'
string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration'
string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature'
string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported'
string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero'
string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed'
string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio'
string public constant INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = '84'; // 'Invalid optimal stable to total debt ratio'
string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued'
string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list'
string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match'
string public constant STABLE_BORROWING_ENABLED = '88'; // 'Stable borrowing is enabled'
string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one'
string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0
string public constant FLASHLOAN_DISABLED = '91'; // FlashLoaning for this asset is disabled
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
// From commit https://github.com/OpenZeppelin/openzeppelin-contracts/commit/8b778fa20d6d76340c5fac1ed66c80273f05b95a
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, 'Address: insufficient balance');
(bool success, ) = recipient.call{value: amount}('');
require(success, 'Address: unable to send value, recipient may have reverted');
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, 'Address: low-level call failed');
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, 'Address: low-level call with value failed');
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, 'Address: insufficient balance for call');
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data)
internal
view
returns (bytes memory)
{
return functionStaticCall(target, data, 'Address: low-level static call failed');
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, 'Address: low-level delegate call failed');
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), 'Address: call to non-contract');
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
library ConfiguratorInputTypes {
struct InitReserveInput {
address aTokenImpl;
address stableDebtTokenImpl;
address variableDebtTokenImpl;
uint8 underlyingAssetDecimals;
address interestRateStrategyAddress;
address underlyingAsset;
address treasury;
address incentivesController;
string aTokenName;
string aTokenSymbol;
string variableDebtTokenName;
string variableDebtTokenSymbol;
string stableDebtTokenName;
string stableDebtTokenSymbol;
bytes params;
}
struct UpdateATokenInput {
address asset;
address treasury;
address incentivesController;
string name;
string symbol;
address implementation;
bytes params;
}
struct UpdateDebtTokenInput {
address asset;
address incentivesController;
string name;
string symbol;
address implementation;
bytes params;
}
}{
"remappings": [
"@aave/core-v3/=lib/aave-v3-core/",
"@aave/periphery-v3/=lib/aave-v3-periphery/",
"@aave/=lib/aave-token/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"aave-stk-v1-5/=lib/aave-stk-v1-5/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/",
"aave-address-book/=lib/aave-address-book/src/",
"aave-helpers/=lib/aave-stk-v1-5/lib/aave-helpers/",
"aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/",
"aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-periphery/",
"erc4626-tests/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/lib/erc4626-tests/",
"openzeppelin-contracts/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/",
"solidity-utils/=lib/solidity-utils/src/",
"aave-token/=lib/aave-token/contracts/",
"safety-module/=lib/safety-module/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"addressesProvider","type":"address"},{"internalType":"address","name":"poolDataProvider","type":"address"},{"internalType":"address","name":"ghoToken","type":"address"},{"internalType":"address","name":"riskCouncil","type":"address"},{"components":[{"internalType":"uint16","name":"optimalUsageRatioMaxChange","type":"uint16"},{"internalType":"uint32","name":"baseVariableBorrowRateMaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope1MaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope2MaxChange","type":"uint32"}],"internalType":"struct IGhoAaveSteward.BorrowRateConfig","name":"borrowRateConfig","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"GHO_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_ADDRESSES_PROVIDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_DATA_PROVIDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RISK_COUNCIL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBorrowRateConfig","outputs":[{"components":[{"internalType":"uint16","name":"optimalUsageRatioMaxChange","type":"uint16"},{"internalType":"uint32","name":"baseVariableBorrowRateMaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope1MaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope2MaxChange","type":"uint32"}],"internalType":"struct IGhoAaveSteward.BorrowRateConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGhoTimelocks","outputs":[{"components":[{"internalType":"uint40","name":"ghoBorrowCapLastUpdate","type":"uint40"},{"internalType":"uint40","name":"ghoSupplyCapLastUpdate","type":"uint40"},{"internalType":"uint40","name":"ghoBorrowRateLastUpdate","type":"uint40"}],"internalType":"struct IGhoAaveSteward.GhoDebounce","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"optimalUsageRatioMaxChange","type":"uint16"},{"internalType":"uint32","name":"baseVariableBorrowRateMaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope1MaxChange","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope2MaxChange","type":"uint32"}],"name":"setBorrowRateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newBorrowCap","type":"uint256"}],"name":"updateGhoBorrowCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"optimalUsageRatio","type":"uint16"},{"internalType":"uint32","name":"baseVariableBorrowRate","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope1","type":"uint32"},{"internalType":"uint32","name":"variableRateSlope2","type":"uint32"}],"name":"updateGhoBorrowRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSupplyCap","type":"uint256"}],"name":"updateGhoSupplyCap","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101006040523480156200001257600080fd5b5060405162001a6c38038062001a6c833981016040819052620000359162000325565b81620000413362000290565b6001600160a01b0381166200009d5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f5249534b5f434f554e43494c00000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b039081166080528616620000eb5760405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22fa7aba722a960991b604482015260640162000094565b6001600160a01b038516620001435760405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f4144445245535345535f50524f5649444552000000000000604482015260640162000094565b6001600160a01b0384166200019b5760405162461bcd60e51b815260206004820152601560248201527f494e56414c49445f444154415f50524f56494445520000000000000000000000604482015260640162000094565b6001600160a01b038316620001e75760405162461bcd60e51b815260206004820152601160248201527024a72b20a624a22fa3a427afaa27a5a2a760791b604482015260640162000094565b6001600160a01b0385811660c05284811660a052831660e05280516001805460208401516040850151606086015161ffff90951665ffffffffffff19909316929092176201000063ffffffff9283160217600160301b600160701b03191666010000000000009282169290920263ffffffff60501b1916919091176a01000000000000000000009190931602919091179055620002848662000290565b5050505050506200042e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620002f857600080fd5b919050565b805161ffff81168114620002f857600080fd5b805163ffffffff81168114620002f857600080fd5b6000806000806000808688036101208112156200034157600080fd5b6200034c88620002e0565b96506200035c60208901620002e0565b95506200036c60408901620002e0565b94506200037c60608901620002e0565b93506200038c60808901620002e0565b92506080609f1982011215620003a157600080fd5b50604051608081016001600160401b0381118282101715620003d357634e487b7160e01b600052604160045260246000fd5b604052620003e460a08901620002fd565b8152620003f460c0890162000310565b60208201526200040760e0890162000310565b60408201526200041b610100890162000310565b6060820152809150509295509295509295565b60805160a05160c05160e051611594620004d86000396000818161025701528181610468015281816106570152818161086101528181610a4301528181610c0401528181610e050152610eb40152600081816101c5015281816103d1015281816105c9015281816107ca015281816109b50152610b7d0152600081816102180152610e30015260008181610106015281816103400152818161074b0152610a8501526115946000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063ae5676401161008c578063c7b672cf11610066578063c7b672cf14610279578063d254c1231461028c578063e32a9a3714610318578063f2fde38b1461032b57600080fd5b8063ae56764014610213578063b1b43ae51461023a578063b1c660f71461025257600080fd5b8063311cd5a4116100c8578063311cd5a4146101c0578063715018a6146101e75780638da5cb5b146101ef578063950973c51461020057600080fd5b806310ee6eee146100ef57806311aa1670146101045780631af816d914610143575b600080fd5b6101026100fd36600461121c565b61033e565b005b7f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b6101b3604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260015461ffff8116825263ffffffff62010000820481166020840152600160301b8204811693830193909352600160501b9004909116606082015290565b60405161013a9190611235565b6101267f000000000000000000000000000000000000000000000000000000000000000081565b6101026106cb565b6000546001600160a01b0316610126565b61010261020e36600461129e565b6106df565b6101267f000000000000000000000000000000000000000000000000000000000000000081565b6102446201518081565b60405190815260200161013a565b6101267f000000000000000000000000000000000000000000000000000000000000000081565b61010261028736600461121c565b610749565b6102e86040805160608101825260008082526020820181905291810191909152506040805160608101825260025464ffffffffff808216835265010000000000820481166020840152600160501b909104169181019190915290565b60408051825164ffffffffff9081168252602080850151821690830152928201519092169082015260600161013a565b61010261032636600461129e565b610a83565b61010261033936600461130f565b610c9a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316331461038f5760405162461bcd60e51b815260040161038690611333565b60405180910390fd5b60025465010000000000900464ffffffffff16620151806103b08242611371565b116103cd5760405162461bcd60e51b815260040161038690611388565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045191906113b8565b60405163c44b11f760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152919091169063c44b11f790602401602060405180830381865afa1580156104b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dd91906113d5565b805190915060741c640fffffffff168381141561053c5760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f535550504c595f4341500000000000000000006044820152606401610386565b610547818583610d13565b6105935760405162461bcd60e51b815260206004820152601960248201527f494e56414c49445f535550504c595f4341505f555044415445000000000000006044820152606401610386565b6002805469ffffffffff00000000001916650100000000004264ffffffffff16021790556040805163318d6fe560e11b815290517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163631adfca9160048083019260209291908290030181865afa15801561061c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064091906113b8565b60405163571f03e560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260248201879052919091169063571f03e5906044015b600060405180830381600087803b1580156106ad57600080fd5b505af11580156106c1573d6000803e3d6000fd5b5050505050505050565b6106d3610d44565b6106dd6000610d9e565b565b6106e7610d44565b6001805461ffff9590951665ffffffffffff19909516949094176201000063ffffffff94851602176dffffffffffffffff0000000000001916600160301b9284169290920263ffffffff60501b191691909117600160501b9190921602179055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146107915760405162461bcd60e51b815260040161038690611333565b60025464ffffffffff16620151806107a98242611371565b116107c65760405162461bcd60e51b815260040161038690611388565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a91906113b8565b60405163c44b11f760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152919091169063c44b11f790602401602060405180830381865afa1580156108b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d691906113d5565b805190915060501c640fffffffff16838114156109355760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f424f52524f575f4341500000000000000000006044820152606401610386565b610940818583610d13565b61098c5760405162461bcd60e51b815260206004820152601960248201527f494e56414c49445f424f52524f575f4341505f555044415445000000000000006044820152606401610386565b6002805464ffffffffff19164264ffffffffff161790556040805163318d6fe560e11b815290517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163631adfca9160048083019260209291908290030181865afa158015610a08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2c91906113b8565b60405163d14a098360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260248201879052919091169063d14a098390604401610693565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610acb5760405162461bcd60e51b815260040161038690611333565b600254600160501b900464ffffffffff1662015180610aea8242611371565b11610b075760405162461bcd60e51b815260040161038690611388565b600060405180608001604052808761ffff1681526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff168152509050610b4b81610dee565b6002805464ffffffffff60501b1916600160501b4264ffffffffff16021790556040805163318d6fe560e11b815290517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163631adfca9160048083019260209291908290030181865afa158015610bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf491906113b8565b6001600160a01b0316636aabe21d7f000000000000000000000000000000000000000000000000000000000000000083604051602001610c349190611235565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610c60929190611425565b600060405180830381600087803b158015610c7a57600080fd5b505af1158015610c8e573d6000803e3d6000fd5b50505050505050505050565b610ca2610d44565b6001600160a01b038116610d075760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610386565b610d1081610d9e565b50565b6000828410610d2e5781610d278486611371565b1115610d3c565b81610d398585611371565b11155b949350505050565b6000546001600160a01b031633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610386565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516333a21b1560e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690636744362a90602401602060405180830381865afa158015610e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9d91906113b8565b6040516363ce721760e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015291925060009183169063c79ce42e90602401608060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d919061148a565b8051845191925061ffff9182169116141580610f5d5750806020015163ffffffff16836020015163ffffffff1614155b80610f7c5750806040015163ffffffff16836040015163ffffffff1614155b80610f9b5750806060015163ffffffff16836060015163ffffffff1614155b610fdc5760405162461bcd60e51b81526020600482015260126024820152714e4f5f4348414e47455f494e5f524154455360701b6044820152606401610386565b80518351600154610ff99261ffff908116928116911660006111b1565b6110455760405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4f5054494d414c5f55534147455f524154494f00000000006044820152606401610386565b602080820151908401516001546110709263ffffffff908116928116916201000090041660006111b1565b6110bc5760405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f424f52524f575f524154455f5550444154450000000000006044820152606401610386565b604080820151908401516001546110e89263ffffffff90811692811691600160301b90041660006111b1565b6111345760405162461bcd60e51b815260206004820152601c60248201527f494e56414c49445f5641524941424c455f524154455f534c4f504531000000006044820152606401610386565b606080820151908401516001546111609263ffffffff90811692811691600160501b90041660006111b1565b6111ac5760405162461bcd60e51b815260206004820152601c60248201527f494e56414c49445f5641524941424c455f524154455f534c4f504532000000006044820152606401610386565b505050565b6000808486116111ca576111c58686611371565b6111d4565b6111d48587611371565b90506000836111e357846111fa565b6127106111f0888761151d565b6111fa919061153c565b90508082111561120f57600092505050610d3c565b5060019695505050505050565b60006020828403121561122e57600080fd5b5035919050565b60808101611276828461ffff8151168252602081015163ffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b92915050565b61ffff81168114610d1057600080fd5b63ffffffff81168114610d1057600080fd5b600080600080608085870312156112b457600080fd5b84356112bf8161127c565b935060208501356112cf8161128c565b925060408501356112df8161128c565b915060608501356112ef8161128c565b939692955090935050565b6001600160a01b0381168114610d1057600080fd5b60006020828403121561132157600080fd5b813561132c816112fa565b9392505050565b6020808252600e908201526d24a72b20a624a22fa1a0a62622a960911b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156113835761138361135b565b500390565b60208082526016908201527511115093d55390d157d393d517d49154d41150d5115160521b604082015260600190565b6000602082840312156113ca57600080fd5b815161132c816112fa565b6000602082840312156113e757600080fd5b6040516020810181811067ffffffffffffffff8211171561141857634e487b7160e01b600052604160045260246000fd5b6040529151825250919050565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561146157858101830151858201606001528201611445565b81811115611473576000606083870101525b50601f01601f191692909201606001949350505050565b60006080828403121561149c57600080fd5b6040516080810181811067ffffffffffffffff821117156114cd57634e487b7160e01b600052604160045260246000fd5b60405282516114db8161127c565b815260208301516114eb8161128c565b602082015260408301516114fe8161128c565b604082015260608301516115118161128c565b60608201529392505050565b60008160001904831182151516156115375761153761135b565b500290565b60008261155957634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122076ca5f84557c01ca5edeed60638b9afa4899b362069938fb907975424f72d1a264736f6c634300080a00330000000000000000000000009390b1735def18560c509e2d0bc090e9d6ba257a000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d000000000000000000000000d82a47fdebb5bf5329b09441c3dab4b5df2153ad0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b6000000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f4
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063ae5676401161008c578063c7b672cf11610066578063c7b672cf14610279578063d254c1231461028c578063e32a9a3714610318578063f2fde38b1461032b57600080fd5b8063ae56764014610213578063b1b43ae51461023a578063b1c660f71461025257600080fd5b8063311cd5a4116100c8578063311cd5a4146101c0578063715018a6146101e75780638da5cb5b146101ef578063950973c51461020057600080fd5b806310ee6eee146100ef57806311aa1670146101045780631af816d914610143575b600080fd5b6101026100fd36600461121c565b61033e565b005b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b605b6040516001600160a01b0390911681526020015b60405180910390f35b6101b3604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260015461ffff8116825263ffffffff62010000820481166020840152600160301b8204811693830193909352600160501b9004909116606082015290565b60405161013a9190611235565b6101267f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d81565b6101026106cb565b6000546001600160a01b0316610126565b61010261020e36600461129e565b6106df565b6101267f000000000000000000000000d82a47fdebb5bf5329b09441c3dab4b5df2153ad81565b6102446201518081565b60405190815260200161013a565b6101267f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee81565b61010261028736600461121c565b610749565b6102e86040805160608101825260008082526020820181905291810191909152506040805160608101825260025464ffffffffff808216835265010000000000820481166020840152600160501b909104169181019190915290565b60408051825164ffffffffff9081168252602080850151821690830152928201519092169082015260600161013a565b61010261032636600461129e565b610a83565b61010261033936600461130f565b610c9a565b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b606001600160a01b0316331461038f5760405162461bcd60e51b815260040161038690611333565b60405180910390fd5b60025465010000000000900464ffffffffff16620151806103b08242611371565b116103cd5760405162461bcd60e51b815260040161038690611388565b60007f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d6001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045191906113b8565b60405163c44b11f760e01b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee81166004830152919091169063c44b11f790602401602060405180830381865afa1580156104b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dd91906113d5565b805190915060741c640fffffffff168381141561053c5760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f535550504c595f4341500000000000000000006044820152606401610386565b610547818583610d13565b6105935760405162461bcd60e51b815260206004820152601960248201527f494e56414c49445f535550504c595f4341505f555044415445000000000000006044820152606401610386565b6002805469ffffffffff00000000001916650100000000004264ffffffffff16021790556040805163318d6fe560e11b815290517f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d6001600160a01b03169163631adfca9160048083019260209291908290030181865afa15801561061c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064091906113b8565b60405163571f03e560e01b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee8116600483015260248201879052919091169063571f03e5906044015b600060405180830381600087803b1580156106ad57600080fd5b505af11580156106c1573d6000803e3d6000fd5b5050505050505050565b6106d3610d44565b6106dd6000610d9e565b565b6106e7610d44565b6001805461ffff9590951665ffffffffffff19909516949094176201000063ffffffff94851602176dffffffffffffffff0000000000001916600160301b9284169290920263ffffffff60501b191691909117600160501b9190921602179055565b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b606001600160a01b031633146107915760405162461bcd60e51b815260040161038690611333565b60025464ffffffffff16620151806107a98242611371565b116107c65760405162461bcd60e51b815260040161038690611388565b60007f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d6001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a91906113b8565b60405163c44b11f760e01b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee81166004830152919091169063c44b11f790602401602060405180830381865afa1580156108b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d691906113d5565b805190915060501c640fffffffff16838114156109355760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f424f52524f575f4341500000000000000000006044820152606401610386565b610940818583610d13565b61098c5760405162461bcd60e51b815260206004820152601960248201527f494e56414c49445f424f52524f575f4341505f555044415445000000000000006044820152606401610386565b6002805464ffffffffff19164264ffffffffff161790556040805163318d6fe560e11b815290517f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d6001600160a01b03169163631adfca9160048083019260209291908290030181865afa158015610a08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2c91906113b8565b60405163d14a098360e01b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee8116600483015260248201879052919091169063d14a098390604401610693565b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b606001600160a01b03163314610acb5760405162461bcd60e51b815260040161038690611333565b600254600160501b900464ffffffffff1662015180610aea8242611371565b11610b075760405162461bcd60e51b815260040161038690611388565b600060405180608001604052808761ffff1681526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff168152509050610b4b81610dee565b6002805464ffffffffff60501b1916600160501b4264ffffffffff16021790556040805163318d6fe560e11b815290517f000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d6001600160a01b03169163631adfca9160048083019260209291908290030181865afa158015610bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf491906113b8565b6001600160a01b0316636aabe21d7f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee83604051602001610c349190611235565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610c60929190611425565b600060405180830381600087803b158015610c7a57600080fd5b505af1158015610c8e573d6000803e3d6000fd5b50505050505050505050565b610ca2610d44565b6001600160a01b038116610d075760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610386565b610d1081610d9e565b50565b6000828410610d2e5781610d278486611371565b1115610d3c565b81610d398585611371565b11155b949350505050565b6000546001600160a01b031633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610386565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516333a21b1560e11b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee811660048301526000917f000000000000000000000000d82a47fdebb5bf5329b09441c3dab4b5df2153ad90911690636744362a90602401602060405180830381865afa158015610e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9d91906113b8565b6040516363ce721760e11b81526001600160a01b037f0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee8116600483015291925060009183169063c79ce42e90602401608060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d919061148a565b8051845191925061ffff9182169116141580610f5d5750806020015163ffffffff16836020015163ffffffff1614155b80610f7c5750806040015163ffffffff16836040015163ffffffff1614155b80610f9b5750806060015163ffffffff16836060015163ffffffff1614155b610fdc5760405162461bcd60e51b81526020600482015260126024820152714e4f5f4348414e47455f494e5f524154455360701b6044820152606401610386565b80518351600154610ff99261ffff908116928116911660006111b1565b6110455760405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4f5054494d414c5f55534147455f524154494f00000000006044820152606401610386565b602080820151908401516001546110709263ffffffff908116928116916201000090041660006111b1565b6110bc5760405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f424f52524f575f524154455f5550444154450000000000006044820152606401610386565b604080820151908401516001546110e89263ffffffff90811692811691600160301b90041660006111b1565b6111345760405162461bcd60e51b815260206004820152601c60248201527f494e56414c49445f5641524941424c455f524154455f534c4f504531000000006044820152606401610386565b606080820151908401516001546111609263ffffffff90811692811691600160501b90041660006111b1565b6111ac5760405162461bcd60e51b815260206004820152601c60248201527f494e56414c49445f5641524941424c455f524154455f534c4f504532000000006044820152606401610386565b505050565b6000808486116111ca576111c58686611371565b6111d4565b6111d48587611371565b90506000836111e357846111fa565b6127106111f0888761151d565b6111fa919061153c565b90508082111561120f57600092505050610d3c565b5060019695505050505050565b60006020828403121561122e57600080fd5b5035919050565b60808101611276828461ffff8151168252602081015163ffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b92915050565b61ffff81168114610d1057600080fd5b63ffffffff81168114610d1057600080fd5b600080600080608085870312156112b457600080fd5b84356112bf8161127c565b935060208501356112cf8161128c565b925060408501356112df8161128c565b915060608501356112ef8161128c565b939692955090935050565b6001600160a01b0381168114610d1057600080fd5b60006020828403121561132157600080fd5b813561132c816112fa565b9392505050565b6020808252600e908201526d24a72b20a624a22fa1a0a62622a960911b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156113835761138361135b565b500390565b60208082526016908201527511115093d55390d157d393d517d49154d41150d5115160521b604082015260600190565b6000602082840312156113ca57600080fd5b815161132c816112fa565b6000602082840312156113e757600080fd5b6040516020810181811067ffffffffffffffff8211171561141857634e487b7160e01b600052604160045260246000fd5b6040529151825250919050565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561146157858101830151858201606001528201611445565b81811115611473576000606083870101525b50601f01601f191692909201606001949350505050565b60006080828403121561149c57600080fd5b6040516080810181811067ffffffffffffffff821117156114cd57634e487b7160e01b600052604160045260246000fd5b60405282516114db8161127c565b815260208301516114eb8161128c565b602082015260408301516114fe8161128c565b604082015260608301516115118161128c565b60608201529392505050565b60008160001904831182151516156115375761153761135b565b500290565b60008261155957634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122076ca5f84557c01ca5edeed60638b9afa4899b362069938fb907975424f72d1a264736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009390b1735def18560c509e2d0bc090e9d6ba257a000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d000000000000000000000000d82a47fdebb5bf5329b09441c3dab4b5df2153ad0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b6000000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f4
-----Decoded View---------------
Arg [0] : owner (address): 0x9390B1735def18560c509E2d0bc090E9d6BA257a
Arg [1] : addressesProvider (address): 0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D
Arg [2] : poolDataProvider (address): 0xd82a47fdebB5bf5329b09441C3DaB4b5df2153Ad
Arg [3] : ghoToken (address): 0x6Bb7a212910682DCFdbd5BCBb3e28FB4E8da10Ee
Arg [4] : riskCouncil (address): 0x8513e6F37dBc52De87b166980Fa3F50639694B60
Arg [5] : borrowRateConfig (tuple):
Arg [1] : optimalUsageRatioMaxChange (uint16): 500
Arg [2] : baseVariableBorrowRateMaxChange (uint32): 500
Arg [3] : variableRateSlope1MaxChange (uint32): 500
Arg [4] : variableRateSlope2MaxChange (uint32): 500
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000009390b1735def18560c509e2d0bc090e9d6ba257a
Arg [1] : 000000000000000000000000e20fcbdbffc4dd138ce8b2e6fbb6cb49777ad64d
Arg [2] : 000000000000000000000000d82a47fdebb5bf5329b09441c3dab4b5df2153ad
Arg [3] : 0000000000000000000000006bb7a212910682dcfdbd5bcbb3e28fb4e8da10ee
Arg [4] : 0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b60
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [6] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [7] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [8] : 00000000000000000000000000000000000000000000000000000000000001f4
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.