Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/strategies/AaveStrategyVault.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IAToken} from "@aave/contracts/interfaces/IAToken.sol";
import {IPool} from "@aave/contracts/interfaces/IPool.sol";
import {ReserveConfiguration} from "@aave/contracts/protocol/libraries/configuration/ReserveConfiguration.sol";
import {WadRayMath} from "@aave/contracts/protocol/libraries/math/WadRayMath.sol";
import {DataTypes} from "@aave/contracts/protocol/libraries/types/DataTypes.sol";
import {ERC4626Upgradeable} from "@openzeppelin-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol";
import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Auth} from "@src/Auth.sol";
import {BaseVault} from "@src/utils/BaseVault.sol";
import {NonReentrantVault} from "@src/utils/NonReentrantVault.sol";
/// @title AaveStrategyVault
/// @custom:security-contact security@size.credit
/// @author Size (https://size.credit/)
/// @notice A strategy that invests assets in Aave v3 lending pools
/// @dev Extends NonReentrantVault for Aave v3 integration within the Very Liquid Vault system
/// @dev Reference https://github.com/superform-xyz/super-vaults/blob/8bc1d1bd1579f6fb9a047802256ed3a2bf15f602/src/aave-v3/AaveV3ERC4626Reinvest.sol
contract AaveStrategyVault is NonReentrantVault {
using SafeERC20 for IERC20;
using WadRayMath for uint256;
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
// STORAGE
/// @custom:storage-location erc7201:vlv.storage.AaveStrategyVault
struct AaveStrategyVaultStorage {
IPool _pool;
IAToken _aToken;
}
// keccak256(abi.encode(uint256(keccak256("vlv.storage.AaveStrategyVault")) - 1)) & ~bytes32(uint256(0xff));
bytes32 private constant AaveStrategyVaultStorageLocation =
0x45b1d4e37b305e5e54f1e5f5bf73580d91a37bacfc32009c29dd875ef148c600;
function _getAaveStrategyVaultStorage() private pure returns (AaveStrategyVaultStorage storage $) {
assembly {
$.slot := AaveStrategyVaultStorageLocation
}
}
// EVENTS
event PoolSet(address indexed pool);
event ATokenSet(address indexed aToken);
// CONSTRUCTOR / INITIALIZER
/// @notice Initializes the AaveStrategyVault with an Aave pool
/// @param auth_ The address of the Auth contract
/// @param asset_ The address of the asset
/// @param name_ The name of the vault
/// @param symbol_ The symbol of the vault
/// @param fundingAccount The address of the funding account for the first deposit, which will be treated as dead shares
/// @param firstDepositAmount The amount of the first deposit, which will be treated as dead shares
/// @param pool_ The address of the Aave pool
/// @dev Sets the Aave pool and retrieves the corresponding aToken address
function initialize(
Auth auth_,
IERC20 asset_,
string memory name_,
string memory symbol_,
address fundingAccount,
uint256 firstDepositAmount,
IPool pool_
) public virtual initializer {
if (address(pool_) == address(0)) revert NullAddress();
IAToken aToken_ = IAToken(pool_.getReserveData(address(asset_)).aTokenAddress);
if (address(aToken_) == address(0)) revert InvalidAsset(address(asset_));
AaveStrategyVaultStorage storage $ = _getAaveStrategyVaultStorage();
$._pool = pool_;
emit PoolSet(address(pool_));
$._aToken = aToken_;
emit ATokenSet(address($._aToken));
super.initialize(auth_, asset_, name_, symbol_, fundingAccount, firstDepositAmount);
}
// ERC4626 OVERRIDES
/// @inheritdoc ERC4626Upgradeable
/// @dev Checks Aave reserve configuration and supply cap to determine max deposit
/// @dev Updates Superform implementation to comply with https://github.com/aave-dao/aave-v3-origin/blob/v3.4.0/src/contracts/protocol/libraries/logic/ValidationLogic.sol#L79-L85
/// @return The maximum deposit amount allowed by Aave
function maxDeposit(address receiver) public view override(BaseVault) returns (uint256) {
// check if asset is paused
DataTypes.ReserveConfigurationMap memory config = pool().getReserveData(asset()).configuration;
if (!(config.getActive() && !config.getFrozen() && !config.getPaused())) return 0;
// handle supply cap
uint256 supplyCapInWholeTokens = config.getSupplyCap();
if (supplyCapInWholeTokens == 0) return super.maxDeposit(receiver);
uint256 tokenDecimals = config.getDecimals();
uint256 supplyCap = supplyCapInWholeTokens * 10 ** tokenDecimals;
DataTypes.ReserveDataLegacy memory reserve = pool().getReserveData(asset());
uint256 usedSupply =
(aToken().scaledTotalSupply() + uint256(reserve.accruedToTreasury)).rayMul(reserve.liquidityIndex);
if (usedSupply >= supplyCap) return 0;
return Math.min(supplyCap - usedSupply, super.maxDeposit(receiver));
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Converts the max deposit amount to shares
function maxMint(address receiver) public view override(BaseVault) returns (uint256) {
return Math.min(_convertToShares(maxDeposit(receiver), Math.Rounding.Floor), super.maxMint(receiver));
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Limited by both owner's balance and Aave pool liquidity
function maxWithdraw(address owner) public view override(BaseVault) returns (uint256) {
// check if asset is paused
DataTypes.ReserveConfigurationMap memory config = pool().getReserveData(asset()).configuration;
if (!(config.getActive() && !config.getPaused())) return 0;
uint256 cash = IERC20(asset()).balanceOf(address(aToken()));
uint256 assetsBalance = _convertToAssets(balanceOf(owner), Math.Rounding.Floor);
return Math.min(cash < assetsBalance ? cash : assetsBalance, super.maxWithdraw(owner));
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Limited by both owner's balance and Aave pool liquidity
function maxRedeem(address owner) public view override(BaseVault) returns (uint256) {
// check if asset is paused
DataTypes.ReserveConfigurationMap memory config = pool().getReserveData(asset()).configuration;
if (!(config.getActive() && !config.getPaused())) return 0;
uint256 cash = IERC20(asset()).balanceOf(address(aToken()));
uint256 cashInShares = _convertToShares(cash, Math.Rounding.Floor);
uint256 shareBalance = balanceOf(owner);
return Math.min(cashInShares < shareBalance ? cashInShares : shareBalance, super.maxRedeem(owner));
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Returns the aToken balance since aTokens represent the underlying asset with accrued interest
/// @dev Round down to avoid stealing assets in roundtrip operations https://github.com/a16z/erc4626-tests/issues/13
function totalAssets() public view virtual override(ERC4626Upgradeable, IERC4626) returns (uint256) {
/// @notice aTokens use rebasing to accrue interest, so the total assets is just the aToken balance
uint256 liquidityIndex = pool().getReserveNormalizedIncome(address(asset()));
return Math.mulDiv(aToken().scaledBalanceOf(address(this)), liquidityIndex, WadRayMath.RAY);
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Calls parent deposit then supplies the assets to the Aave pool
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal override {
super._deposit(caller, receiver, assets, shares);
IERC20(asset()).forceApprove(address(pool()), assets);
pool().supply(asset(), assets, address(this), 0);
}
/// @inheritdoc ERC4626Upgradeable
/// @dev Withdraws from the Aave pool then calls parent withdraw
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)
internal
override
{
// slither-disable-next-line unused-return
pool().withdraw(asset(), assets, address(this));
super._withdraw(caller, receiver, owner, assets, shares);
}
// VIEW FUNCTIONS
/// @notice Returns the Aave pool
/// @return The Aave pool
function pool() public view returns (IPool) {
return _getAaveStrategyVaultStorage()._pool;
}
/// @notice Returns the Aave aToken
/// @return The Aave aToken
function aToken() public view returns (IAToken) {
return _getAaveStrategyVaultStorage()._aToken;
}
}
"
},
"lib/aave-v3-origin/src/contracts/interfaces/IAToken.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
import {IInitializableAToken} from './IInitializableAToken.sol';
/**
* @title IAToken
* @author Aave
* @notice Defines the basic interface for an AToken.
*/
interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {
/**
* @dev Emitted during the transfer action
* @param from The user whose tokens are being transferred
* @param to The recipient
* @param value The scaled amount being transferred
* @param index The next liquidity index of the reserve
*/
event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
/**
* @notice Mints `amount` aTokens to `user`
* @param caller The address performing the mint
* @param onBehalfOf The address of the user that will receive the minted aTokens
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
* @return `true` if the the previous balance of the user was 0
*/
function mint(
address caller,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
* @dev In some instances, the mint event could be emitted from a burn transaction
* if the amount to burn is less than the interest that the user accrued
* @param from The address from which the aTokens will be burned
* @param receiverOfUnderlying The address that will receive the underlying
* @param amount The amount being burned
* @param index The next liquidity index of the reserve
*/
function burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external;
/**
* @notice Mints aTokens to the reserve treasury
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
*/
function mintToTreasury(uint256 amount, uint256 index) external;
/**
* @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* @param from The address getting liquidated, current owner of the aTokens
* @param to The recipient
* @param value The amount of tokens getting transferred
*/
function transferOnLiquidation(address from, address to, uint256 value) external;
/**
* @notice Transfers the underlying asset to `target`.
* @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan()
* @param target The recipient of the underlying
* @param amount The amount getting transferred
*/
function transferUnderlyingTo(address target, uint256 amount) external;
/**
* @notice Handles the underlying received by the aToken after the transfer has been completed.
* @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the
* transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying
* to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset.
* @param user The user executing the repayment
* @param onBehalfOf The address of the user who will get his debt reduced/removed
* @param amount The amount getting repaid
*/
function handleRepayment(address user, address onBehalfOf, uint256 amount) external;
/**
* @notice Allow passing a signed message to approve spending
* @dev implements the permit function as for
* https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
* @param owner The owner of the funds
* @param spender The spender
* @param value The amount
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @return The address of the underlying asset
*/
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
/**
* @notice Returns the address of the Aave treasury, receiving the fees on this aToken.
* @return Address of the Aave treasury
*/
function RESERVE_TREASURY_ADDRESS() external view returns (address);
/**
* @notice Get the domain separator for the token
* @dev Return cached value if chainId matches cache, otherwise recomputes separator
* @return The domain separator of the token at current chain
*/
function DOMAIN_SEPARATOR() external view returns (bytes32);
/**
* @notice Returns the nonce for owner.
* @param owner The address of the owner
* @return The nonce of the owner
*/
function nonces(address owner) external view returns (uint256);
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(address token, address to, uint256 amount) external;
}
"
},
"lib/aave-v3-origin/src/contracts/interfaces/IPool.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
/**
* @title IPool
* @author Aave
* @notice Defines the basic interface for an Aave Pool.
*/
interface IPool {
/**
* @dev Emitted on mintUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens
* @param amount The amount of supplied assets
* @param referralCode The referral code used
*/
event MintUnbacked(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on backUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param backer The address paying for the backing
* @param amount The amount added as backing
* @param fee The amount paid in fees
*/
event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee);
/**
* @dev Emitted on supply()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supply, receiving the aTokens
* @param amount The amount supplied
* @param referralCode The referral code used
*/
event Supply(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on withdraw()
* @param reserve The address of the underlying asset being withdrawn
* @param user The address initiating the withdrawal, owner of aTokens
* @param to The address that will receive the underlying
* @param amount The amount to be withdrawn
*/
event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);
/**
* @dev Emitted on borrow() and flashLoan() when debt needs to be opened
* @param reserve The address of the underlying asset being borrowed
* @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
* initiator of the transaction on flashLoan()
* @param onBehalfOf The address that will be getting the debt
* @param amount The amount borrowed out
* @param interestRateMode The rate mode: 2 for Variable, 1 is deprecated (changed on v3.2.0)
* @param borrowRate The numeric rate at which the user has borrowed, expressed in ray
* @param referralCode The referral code used
*/
event Borrow(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 borrowRate,
uint16 indexed referralCode
);
/**
* @dev Emitted on repay()
* @param reserve The address of the underlying asset of the reserve
* @param user The beneficiary of the repayment, getting his debt reduced
* @param repayer The address of the user initiating the repay(), providing the funds
* @param amount The amount repaid
* @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly
*/
event Repay(
address indexed reserve,
address indexed user,
address indexed repayer,
uint256 amount,
bool useATokens
);
/**
* @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets
* @param asset The address of the underlying asset of the reserve
* @param totalDebt The total isolation mode debt for the reserve
*/
event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);
/**
* @dev Emitted when the user selects a certain asset category for eMode
* @param user The address of the user
* @param categoryId The category id
*/
event UserEModeSet(address indexed user, uint8 categoryId);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
*/
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
/**
* @dev Emitted on flashLoan()
* @param target The address of the flash loan receiver contract
* @param initiator The address initiating the flash loan
* @param asset The address of the asset being flash borrowed
* @param amount The amount flash borrowed
* @param interestRateMode The flashloan mode: 0 for regular flashloan,
* 1 for Stable (Deprecated on v3.2.0), 2 for Variable
* @param premium The fee flash borrowed
* @param referralCode The referral code used
*/
event FlashLoan(
address indexed target,
address initiator,
address indexed asset,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 premium,
uint16 indexed referralCode
);
/**
* @dev Emitted when a borrower is liquidated.
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param liquidatedCollateralAmount The amount of collateral received by the liquidator
* @param liquidator The address of the liquidator
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
event LiquidationCall(
address indexed collateralAsset,
address indexed debtAsset,
address indexed user,
uint256 debtToCover,
uint256 liquidatedCollateralAmount,
address liquidator,
bool receiveAToken
);
/**
* @dev Emitted when the state of a reserve is updated.
* @param reserve The address of the underlying asset of the reserve
* @param liquidityRate The next liquidity rate
* @param stableBorrowRate The next stable borrow rate @note deprecated on v3.2.0
* @param variableBorrowRate The next variable borrow rate
* @param liquidityIndex The next liquidity index
* @param variableBorrowIndex The next variable borrow index
*/
event ReserveDataUpdated(
address indexed reserve,
uint256 liquidityRate,
uint256 stableBorrowRate,
uint256 variableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex
);
/**
* @dev Emitted when the deficit of a reserve is covered.
* @param reserve The address of the underlying asset of the reserve
* @param caller The caller that triggered the DeficitCovered event
* @param amountCovered The amount of deficit covered
*/
event DeficitCovered(address indexed reserve, address caller, uint256 amountCovered);
/**
* @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.
* @param reserve The address of the reserve
* @param amountMinted The amount minted to the treasury
*/
event MintedToTreasury(address indexed reserve, uint256 amountMinted);
/**
* @dev Emitted when deficit is realized on a liquidation.
* @param user The user address where the bad debt will be burned
* @param debtAsset The address of the underlying borrowed asset to be burned
* @param amountCreated The amount of deficit created
*/
event DeficitCreated(address indexed user, address indexed debtAsset, uint256 amountCreated);
/**
* @notice Mints an `amount` of aTokens to the `onBehalfOf`
* @param asset The address of the underlying asset to mint
* @param amount The amount to mint
* @param onBehalfOf The address that will receive the aTokens
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function mintUnbacked(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @notice Back the current unbacked underlying with `amount` and pay `fee`.
* @param asset The address of the underlying asset to back
* @param amount The amount to back
* @param fee The amount paid in fees
* @return The backed amount
*/
function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256);
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
/**
* @notice Supply with transfer approval of asset to be supplied done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param deadline The deadline timestamp that the permit is valid
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
*/
function supplyWithPermit(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external;
/**
* @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param asset The address of the underlying asset to withdraw
* @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to The address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
* @return The final amount withdrawn
*/
function withdraw(address asset, uint256 amount, address to) external returns (uint256);
/**
* @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already supplied enough collateral, or he was given enough allowance by a credit delegator on the VariableDebtToken
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 variable debt tokens
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
*/
function borrow(
address asset,
uint256 amount,
uint256 interestRateMode,
uint16 referralCode,
address onBehalfOf
) external;
/**
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* - E.g. User repays 100 USDC, burning 100 variable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @return The final amount repaid
*/
function repay(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf
) external returns (uint256);
/**
* @notice Repay with transfer approval of asset to be repaid done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @param deadline The deadline timestamp that the permit is valid
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
* @return The final amount repaid
*/
function repayWithPermit(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external returns (uint256);
/**
* @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
* equivalent debt tokens
* - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens
* @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
* balance is not enough to cover the whole debt
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode DEPRECATED in v3.2.0
* @return The final amount repaid
*/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @notice Allows suppliers to enable/disable a specific supplied asset as collateral
* @param asset The address of the underlying asset supplied
* @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
*/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;
/**
* @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
* @param assets The addresses of the assets being flash-borrowed
* @param amounts The amounts of the assets being flash-borrowed
* @param interestRateModes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Deprecated on v3.2.0
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using 2 on `modes`
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
* @param asset The address of the asset being flash-borrowed
* @param amount The amount of the asset being flash-borrowed
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
* @return totalDebtBase The total debt of the user in the base currency used by the price feed
* @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
* @return currentLiquidationThreshold The liquidation threshold of the user
* @return ltv The loan to value of The user
* @return healthFactor The current health factor of the user
*/
function getUserAccountData(
address user
)
external
view
returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
/**
* @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an
* interest rate strategy
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param aTokenAddress The address of the aToken that will be assigned to the reserve
* @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
* @param interestRateStrategyAddress The address of the interest rate strategy contract
*/
function initReserve(
address asset,
address aTokenAddress,
address variableDebtAddress,
address interestRateStrategyAddress
) external;
/**
* @notice Drop a reserve
* @dev Only callable by the PoolConfigurator contract
* @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve.
* @param asset The address of the underlying asset of the reserve
*/
function dropReserve(address asset) external;
/**
* @notice Updates the address of the interest rate strategy contract
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The address of the interest rate strategy contract
*/
function setReserveInterestRateStrategyAddress(
address asset,
address rateStrategyAddress
) external;
/**
* @notice Accumulates interest to all indexes of the reserve
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncIndexesState(address asset) external;
/**
* @notice Updates interest rates on the reserve data
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncRatesState(address asset) external;
/**
* @notice Sets the configuration bitmap of the reserve as a whole
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param configuration The new configuration bitmap
*/
function setConfiguration(
address asset,
DataTypes.ReserveConfigurationMap calldata configuration
) external;
/**
* @notice Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
*/
function getConfiguration(
address asset
) external view returns (DataTypes.ReserveConfigurationMap memory);
/**
* @notice Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
*/
function getUserConfiguration(
address user
) external view returns (DataTypes.UserConfigurationMap memory);
/**
* @notice Returns the normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset) external view returns (uint256);
/**
* @notice Returns the normalized variable debt per unit of asset
* @dev WARNING: This function is intended to be used primarily by the protocol itself to get a
* "dynamic" variable index based on time, current stored index and virtual rate at the current
* moment (approx. a borrower would get if opening a position). This means that is always used in
* combination with variable debt supply/balances.
* If using this function externally, consider that is possible to have an increasing normalized
* variable debt that is not equivalent to how the variable debt index would be updated in storage
* (e.g. only updates with non-zero variable debt supply)
* @param asset The address of the underlying asset of the reserve
* @return The reserve normalized variable debt
*/
function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);
/**
* @notice Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve
*/
function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory);
/**
* @notice Returns the virtual underlying balance of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve virtual underlying balance
*/
function getVirtualUnderlyingBalance(address asset) external view returns (uint128);
/**
* @notice Validates and finalizes an aToken transfer
* @dev Only callable by the overlying aToken of the `asset`
* @param asset The address of the underlying asset of the aToken
* @param from The user from which the aTokens are transferred
* @param to The user receiving the aTokens
* @param amount The amount being transferred/withdrawn
* @param balanceFromBefore The aToken balance of the `from` user before the transfer
* @param balanceToBefore The aToken balance of the `to` user before the transfer
*/
function finalizeTransfer(
address asset,
address from,
address to,
uint256 amount,
uint256 balanceFromBefore,
uint256 balanceToBefore
) external;
/**
* @notice Returns the list of the underlying assets of all the initialized reserves
* @dev It does not include dropped reserves
* @return The addresses of the underlying assets of the initialized reserves
*/
function getReservesList() external view returns (address[] memory);
/**
* @notice Returns the number of initialized reserves
* @dev It includes dropped reserves
* @return The count
*/
function getReservesCount() external view returns (uint256);
/**
* @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct
* @param id The id of the reserve as stored in the DataTypes.ReserveData struct
* @return The address of the reserve associated with id
*/
function getReserveAddressById(uint16 id) external view returns (address);
/**
* @notice Returns the PoolAddressesProvider connected to this contract
* @return The address of the PoolAddressesProvider
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Updates the protocol fee on the bridging
* @param bridgeProtocolFee The part of the premium sent to the protocol treasury
*/
function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;
/**
* @notice Updates flash loan premiums. Flash loan premium consists of two parts:
* - A part is sent to aToken holders as extra, one time accumulated interest
* - A part is collected by the protocol treasury
* @dev The total premium is calculated on the total borrowed amount
* @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`
* @dev Only callable by the PoolConfigurator contract
* @param flashLoanPremiumTotal The total premium, expressed in bps
* @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps
*/
function updateFlashloanPremiums(
uint128 flashLoanPremiumTotal,
uint128 flashLoanPremiumToProtocol
) external;
/**
* @notice Configures a new or alters an existing collateral configuration of an eMode.
* @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.
* The category 0 is reserved as it's the default for volatile assets
* @param id The id of the category
* @param config The configuration of the category
*/
function configureEModeCategory(
uint8 id,
DataTypes.EModeCategoryBaseConfiguration memory config
) external;
/**
* @notice Replaces the current eMode collateralBitmap.
* @param id The id of the category
* @param collateralBitmap The collateralBitmap of the category
*/
function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external;
/**
* @notice Replaces the current eMode borrowableBitmap.
* @param id The id of the category
* @param borrowableBitmap The borrowableBitmap of the category
*/
function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external;
/**
* @notice Returns the data of an eMode category
* @dev DEPRECATED use independent getters instead
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(
uint8 id
) external view returns (DataTypes.EModeCategoryLegacy memory);
/**
* @notice Returns the label of an eMode category
* @param id The id of the category
* @return The label of the category
*/
function getEModeCategoryLabel(uint8 id) external view returns (string memory);
/**
* @notice Returns the collateral config of an eMode category
* @param id The id of the category
* @return The ltv,lt,lb of the category
*/
function getEModeCategoryCollateralConfig(
uint8 id
) external view returns (DataTypes.CollateralConfig memory);
/**
* @notice Returns the collateralBitmap of an eMode category
* @param id The id of the category
* @return The collateralBitmap of the category
*/
function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128);
/**
* @notice Returns the borrowableBitmap of an eMode category
* @param id The id of the category
* @return The borrowableBitmap of the category
*/
function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128);
/**
* @notice Allows a user to use the protocol in eMode
* @param categoryId The id of the category
*/
function setUserEMode(uint8 categoryId) external;
/**
* @notice Returns the eMode the user is using
* @param user The address of the user
* @return The eMode id
*/
function getUserEMode(address user) external view returns (uint256);
/**
* @notice Resets the isolation mode total debt of the given asset to zero
* @dev It requires the given asset has zero debt ceiling
* @param asset The address of the underlying asset to reset the isolationModeTotalDebt
*/
function resetIsolationModeTotalDebt(address asset) external;
/**
* @notice Sets the liquidation grace period of the given asset
* @dev To enable a liquidation grace period, a timestamp in the future should be set,
* To disable a liquidation grace period, any timestamp in the past works, like 0
* @param asset The address of the underlying asset to set the liquidationGracePeriod
* @param until Timestamp when the liquidation grace period will end
**/
function setLiquidationGracePeriod(address asset, uint40 until) external;
/**
* @notice Returns the liquidation grace period of the given asset
* @param asset The address of the underlying asset
* @return Timestamp when the liquidation grace period will end
**/
function getLiquidationGracePeriod(address asset) external view returns (uint40);
/**
* @notice Returns the total fee on flash loans
* @return The total fee on flashloans
*/
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
/**
* @notice Returns the part of the bridge fees sent to protocol
* @return The bridge fee sent to the protocol treasury
*/
function BRIDGE_PROTOCOL_FEE() external view returns (uint256);
/**
* @notice Returns the part of the flashloan fees sent to protocol
* @return The flashloan fee sent to the protocol treasury
*/
function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);
/**
* @notice Returns the maximum number of reserves supported to be listed in this Pool
* @return The maximum number of reserves supported
*/
function MAX_NUMBER_RESERVES() external view returns (uint16);
/**
* @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
* @param assets The list of reserves for which the minting needs to be executed
*/
function mintToTreasury(address[] calldata assets) external;
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(address token, address to, uint256 amount) external;
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @dev Deprecated: Use the `supply` function instead
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
/**
* @notice It covers the deficit of a specified reserve by burning:
* - the equivalent aToken `amount` for assets with virtual accounting enabled
* - the equivalent `amount` of underlying for assets with virtual accounting disabled (e.g. GHO)
* @dev The deficit of a reserve can occur due to situations where borrowed assets are not repaid, leading to bad debt.
* @param asset The address of the underlying asset to cover the deficit.
* @param amount The amount to be covered, in aToken or underlying on non-virtual accounted assets
*/
function eliminateReserveDeficit(address asset, uint256 amount) external;
/**
* @notice Returns the current deficit of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The current deficit of the reserve
*/
function getReserveDeficit(address asset) external view returns (uint256);
/**
* @notice Returns the aToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the aToken
*/
function getReserveAToken(address asset) external view returns (address);
/**
* @notice Returns the variableDebtToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the variableDebtToken
*/
function getReserveVariableDebtToken(address asset) external view returns (address);
/**
* @notice Gets the address of the external FlashLoanLogic
*/
function getFlashLoanLogic() external view returns (address);
/**
* @notice Gets the address of the external BorrowLogic
*/
function getBorrowLogic() external view returns (address);
/**
* @notice Gets the address of the external BridgeLogic
*/
function getBridgeLogic() external view returns (address);
/**
* @notice Gets the address of the external EModeLogic
*/
function getEModeLogic() external view returns (address);
/**
* @notice Gets the address of the external LiquidationLogic
*/
function getLiquidationLogic() external view returns (address);
/**
* @notice Gets the address of the external PoolLogic
*/
function getPoolLogic() external view returns (address);
/**
* @notice Gets the address of the external SupplyLogic
*/
function getSupplyLogic() external view returns (address);
}
"
},
"lib/aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Errors} from '../helpers/Errors.sol';
import {DataTypes} from '../types/DataTypes.sol';
/**
* @title ReserveConfiguration library
* @author Aave
* @notice Implements the bitmap logic to handle the reserve configuration
*/
library ReserveConfiguration {
uint256 internal constant LTV_MASK = 0x000000000000000000000000000000000000000000000000000000000000FFFF; // prettier-ignore
uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0x00000000000000000000000000000000000000000000000000000000FFFF0000; // prettier-ignore
uint256 internal constant LIQUIDATION_BONUS_MASK = 0x0000000000000000000000000000000000000000000000000000FFFF00000000; // prettier-ignore
uint256 internal constant DECIMALS_MASK = 0x00000000000000000000000000000000000000000000000000FF000000000000; // prettier-ignore
uint256 internal constant ACTIVE_MASK = 0x0000000000000000000000000000000000000000000000000100000000000000; // prettier-ignore
uint256 internal constant FROZEN_MASK = 0x0000000000000000000000000000000000000000000000000200000000000000; // prettier-ignore
uint256 internal constant BORROWING_MASK = 0x0000000000000000000000000000000000000000000000000400000000000000; // prettier-ignore
// @notice there is an unoccupied hole of 1 bit at position 59 from pre 3.2 stableBorrowRateEnabled
uint256 internal constant PAUSED_MASK = 0x0000000000000000000000000000000000000000000000001000000000000000; // prettier-ignore
uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0x0000000000000000000000000000000000000000000000002000000000000000; // prettier-ignore
uint256 internal constant SILOED_BORROWING_MASK = 0x0000000000000000000000000000000000000000000000004000000000000000; // prettier-ignore
uint256 internal constant FLASHLOAN_ENABLED_MASK = 0x0000000000000000000000000000000000000000000000008000000000000000; // prettier-ignore
uint256 internal constant RESERVE_FACTOR_MASK = 0x00000000000000000000000000000000000000000000FFFF0000000000000000; // prettier-ignore
uint256 internal constant BORROW_CAP_MASK = 0x00000000000000000000000000000000000FFFFFFFFF00000000000000000000; // prettier-ignore
uint256 internal constant SUPPLY_CAP_MASK = 0x00000000000000000000000000FFFFFFFFF00000000000000000000000000000; // prettier-ignore
uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0x0000000000000000000000FFFF00000000000000000000000000000000000000; // prettier-ignore
//@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory
uint256 internal constant UNBACKED_MINT_CAP_MASK = 0x00000000000FFFFFFFFF00000000000000000000000000000000000000000000; // prettier-ignore
uint256 internal constant DEBT_CEILING_MASK = 0x0FFFFFFFFFF00000000000000000000000000000000000000000000000000000; // prettier-ignore
uint256 internal constant VIRTUAL_ACC_ACTIVE_MASK = 0x1000000000000000000000000000000000000000000000000000000000000000; // prettier-ignore
/// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed
uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32;
uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48;
uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56;
uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57;
uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60;
uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61;
uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62;
uint256 internal constant FLASHLOAN_ENABLED_START_BIT_POSITION = 63;
uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116;
uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152;
//@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory
uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176;
uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212;
uint256 internal constant VIRTUAL_ACC_START_BIT_POSITION = 252;
uint256 internal constant MAX_VALID_LTV = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535;
uint256 internal constant MAX_VALID_DECIMALS = 255;
uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735;
uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735;
uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535;
uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735;
uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775;
uint256 public constant DEBT_CEILING_DECIMALS = 2;
uint16 public constant MAX_RESERVES_COUNT = 128;
/**
* @notice Sets the Loan to Value of the reserve
* @param self The reserve configuration
* @param ltv The new ltv
*/
function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV);
self.data = (self.data & ~LTV_MASK) | ltv;
}
/**
* @notice Gets the Loan to Value of the reserve
* @param self The reserve configuration
* @return The loan to value
*/
function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) {
return self.data & LTV_MASK;
}
/**
* @notice Sets the liquidation threshold of the reserve
* @param self The reserve configuration
* @param threshold The new liquidation threshold
*/
function setLiquidationThreshold(
DataTypes.ReserveConfigurationMap memory self,
uint256 threshold
) internal pure {
require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD);
self.data =
(self.data & ~LIQUIDATION_THRESHOLD_MASK) |
(threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation threshold of the reserve
* @param self The reserve configuration
* @return The liquidation threshold
*/
function getLiquidationThreshold(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
}
/**
* @notice Sets the liquidation bonus of the reserve
* @param self The reserve configuration
* @param bonus The new liquidation bonus
*/
function setLiquidationBonus(
DataTypes.ReserveConfigurationMap memory self,
uint256 bonus
) internal pure {
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS);
self.data =
(self.data & ~LIQUIDATION_BONUS_MASK) |
(bonus << LIQUIDATION_BONUS_START_BIT_POSITION);
}
/**
* @notice Gets the liquidation bonus of the reserve
* @param self The reserve configuration
* @return The liquidation bonus
*/
function getLiquidationBonus(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION;
}
/**
* @notice Sets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @param decimals The decimals
*/
function setDecimals(
DataTypes.ReserveConfigurationMap memory self,
uint256 decimals
) internal pure {
require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS);
self.data = (self.data & ~DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
}
/**
* @notice Gets the decimals of the underlying asset of the reserve
* @param self The reserve configuration
* @return The decimals of the asset
*/
function getDecimals(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (uint256) {
return (self.data & DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
}
/**
* @notice Sets the active state of the reserve
* @param self The reserve configuration
* @param active The active state
*/
function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
self.data =
(self.data & ~ACTIVE_MASK) |
(uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
}
/**
* @notice Gets the active state of the reserve
* @param self The reserve configuration
* @return The active state
*/
function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & ACTIVE_MASK) != 0;
}
/**
* @notice Sets the frozen state of the reserve
* @param self The reserve configuration
* @param frozen The frozen state
*/
function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
self.data =
(self.data & ~FROZEN_MASK) |
(uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
}
/**
* @notice Gets the frozen state of the reserve
* @param self The reserve configuration
* @return The frozen state
*/
function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & FROZEN_MASK) != 0;
}
/**
* @notice Sets the paused state of the reserve
* @param self The reserve configuration
* @param paused The paused state
*/
function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure {
self.data =
(self.data & ~PAUSED_MASK) |
(uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION);
}
/**
* @notice Gets the paused state of the reserve
* @param self The reserve configuration
* @return The paused state
*/
function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) {
return (self.data & PAUSED_MASK) != 0;
}
/**
* @notice Sets the borrowable in isolation flag for the reserve.
* @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed
* amount will be accumulated in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @param borrowable True if the asset is borrowable
*/
function setBorrowableInIsolation(
DataTypes.ReserveConfigurationMap memory self,
bool borrowable
) internal pure {
self.data =
(self.data & ~BORROWABLE_IN_ISOLATION_MASK) |
(uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION);
}
/**
* @notice Gets the borrowable in isolation flag for the reserve.
* @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with
* isolated collateral is accounted for in the isolated collateral's total debt exposure.
* @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep
* consistency in the debt ceiling calculations.
* @param self The reserve configuration
* @return The borrowable in isolation flag
*/
function getBorrowableInIsolation(
DataTypes.ReserveConfigurationMap memory self
) internal pure returns (bool) {
return (self.data & BORROWABLE_IN_ISOLATION_MASK) != 0;
}
/**
* @notice Sets the siloed borrowing flag for the reserve.
* @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset.
* @param self The reserve configuration
* @param siloed True if the asset is siloed
*/
function setSiloedBorrowing(
DataTypes.ReserveConfigurationMap memory self,
Submitted on: 2025-10-28 18:53:22
Comments
Log in to comment.
No comments yet.