Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DefaultReserveInterestRateStrategy
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 100000 runs
Other Settings:
berlin EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.10;
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
import {DataTypes} from '../libraries/types/DataTypes.sol';
import {Errors} from '../libraries/helpers/Errors.sol';
import {IDefaultInterestRateStrategy} from '../../interfaces/IDefaultInterestRateStrategy.sol';
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
/**
* @title DefaultReserveInterestRateStrategy contract
* @author Aave
* @notice Implements the calculation of the interest rates depending on the reserve state
* @dev The model of interest rate is based on 2 slopes, one before the `OPTIMAL_USAGE_RATIO`
* point of usage and another from that one to 100%.
* - An instance of this same contract, can't be used across different Aave markets, due to the caching
* of the PoolAddressesProvider
*/
contract DefaultReserveInterestRateStrategy is IDefaultInterestRateStrategy {
using WadRayMath for uint256;
using PercentageMath for uint256;
/// @inheritdoc IDefaultInterestRateStrategy
uint256 public immutable OPTIMAL_USAGE_RATIO;
/// @inheritdoc IDefaultInterestRateStrategy
uint256 public immutable OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO;
/// @inheritdoc IDefaultInterestRateStrategy
uint256 public immutable MAX_EXCESS_USAGE_RATIO;
/// @inheritdoc IDefaultInterestRateStrategy
uint256 public immutable MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO;
IPoolAddressesProvider public immutable ADDRESSES_PROVIDER;
// Base variable borrow rate when usage rate = 0. Expressed in ray
uint256 internal immutable _baseVariableBorrowRate;
// Slope of the variable interest curve when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO. Expressed in ray
uint256 internal immutable _variableRateSlope1;
// Slope of the variable interest curve when usage ratio > OPTIMAL_USAGE_RATIO. Expressed in ray
uint256 internal immutable _variableRateSlope2;
// Slope of the stable interest curve when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO. Expressed in ray
uint256 internal immutable _stableRateSlope1;
// Slope of the stable interest curve when usage ratio > OPTIMAL_USAGE_RATIO. Expressed in ray
uint256 internal immutable _stableRateSlope2;
// Premium on top of `_variableRateSlope1` for base stable borrowing rate
uint256 internal immutable _baseStableRateOffset;
// Additional premium applied to stable rate when stable debt surpass `OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO`
uint256 internal immutable _stableRateExcessOffset;
/**
* @dev Constructor.
* @param provider The address of the PoolAddressesProvider contract
* @param optimalUsageRatio The optimal usage ratio
* @param baseVariableBorrowRate The base variable borrow rate
* @param variableRateSlope1 The variable rate slope below optimal usage ratio
* @param variableRateSlope2 The variable rate slope above optimal usage ratio
* @param stableRateSlope1 The stable rate slope below optimal usage ratio
* @param stableRateSlope2 The stable rate slope above optimal usage ratio
* @param baseStableRateOffset The premium on top of variable rate for base stable borrowing rate
* @param stableRateExcessOffset The premium on top of stable rate when there stable debt surpass the threshold
* @param optimalStableToTotalDebtRatio The optimal stable debt to total debt ratio of the reserve
*/
constructor(
IPoolAddressesProvider provider,
uint256 optimalUsageRatio,
uint256 baseVariableBorrowRate,
uint256 variableRateSlope1,
uint256 variableRateSlope2,
uint256 stableRateSlope1,
uint256 stableRateSlope2,
uint256 baseStableRateOffset,
uint256 stableRateExcessOffset,
uint256 optimalStableToTotalDebtRatio
) {
require(WadRayMath.RAY >= optimalUsageRatio, Errors.INVALID_OPTIMAL_USAGE_RATIO);
require(
WadRayMath.RAY >= optimalStableToTotalDebtRatio,
Errors.INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO
);
OPTIMAL_USAGE_RATIO = optimalUsageRatio;
MAX_EXCESS_USAGE_RATIO = WadRayMath.RAY - optimalUsageRatio;
OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = optimalStableToTotalDebtRatio;
MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO = WadRayMath.RAY - optimalStableToTotalDebtRatio;
ADDRESSES_PROVIDER = provider;
_baseVariableBorrowRate = baseVariableBorrowRate;
_variableRateSlope1 = variableRateSlope1;
_variableRateSlope2 = variableRateSlope2;
_stableRateSlope1 = stableRateSlope1;
_stableRateSlope2 = stableRateSlope2;
_baseStableRateOffset = baseStableRateOffset;
_stableRateExcessOffset = stableRateExcessOffset;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getVariableRateSlope1() external view returns (uint256) {
return _variableRateSlope1;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getVariableRateSlope2() external view returns (uint256) {
return _variableRateSlope2;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getStableRateSlope1() external view returns (uint256) {
return _stableRateSlope1;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getStableRateSlope2() external view returns (uint256) {
return _stableRateSlope2;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getStableRateExcessOffset() external view returns (uint256) {
return _stableRateExcessOffset;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getBaseStableBorrowRate() public view returns (uint256) {
return _variableRateSlope1 + _baseStableRateOffset;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getBaseVariableBorrowRate() external view override returns (uint256) {
return _baseVariableBorrowRate;
}
/// @inheritdoc IDefaultInterestRateStrategy
function getMaxVariableBorrowRate() external view override returns (uint256) {
return _baseVariableBorrowRate + _variableRateSlope1 + _variableRateSlope2;
}
struct CalcInterestRatesLocalVars {
uint256 availableLiquidity;
uint256 totalDebt;
uint256 currentVariableBorrowRate;
uint256 currentStableBorrowRate;
uint256 currentLiquidityRate;
uint256 borrowUsageRatio;
uint256 supplyUsageRatio;
uint256 stableToTotalDebtRatio;
uint256 availableLiquidityPlusDebt;
}
/// @inheritdoc IReserveInterestRateStrategy
function calculateInterestRates(
DataTypes.CalculateInterestRatesParams memory params
) public view override returns (uint256, uint256, uint256) {
CalcInterestRatesLocalVars memory vars;
vars.totalDebt = params.totalStableDebt + params.totalVariableDebt;
vars.currentLiquidityRate = 0;
vars.currentVariableBorrowRate = _baseVariableBorrowRate;
vars.currentStableBorrowRate = getBaseStableBorrowRate();
if (vars.totalDebt != 0) {
vars.stableToTotalDebtRatio = params.totalStableDebt.rayDiv(vars.totalDebt);
vars.availableLiquidity =
IERC20(params.reserve).balanceOf(params.aToken) +
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
);
}
if (vars.borrowUsageRatio > OPTIMAL_USAGE_RATIO) {
uint256 excessBorrowUsageRatio = (vars.borrowUsageRatio - OPTIMAL_USAGE_RATIO).rayDiv(
MAX_EXCESS_USAGE_RATIO
);
vars.currentStableBorrowRate +=
_stableRateSlope1 +
_stableRateSlope2.rayMul(excessBorrowUsageRatio);
vars.currentVariableBorrowRate +=
_variableRateSlope1 +
_variableRateSlope2.rayMul(excessBorrowUsageRatio);
} else {
vars.currentStableBorrowRate += _stableRateSlope1.rayMul(vars.borrowUsageRatio).rayDiv(
OPTIMAL_USAGE_RATIO
);
vars.currentVariableBorrowRate += _variableRateSlope1.rayMul(vars.borrowUsageRatio).rayDiv(
OPTIMAL_USAGE_RATIO
);
}
if (vars.stableToTotalDebtRatio > OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO) {
uint256 excessStableDebtRatio = (vars.stableToTotalDebtRatio -
OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO).rayDiv(MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO);
vars.currentStableBorrowRate += _stableRateExcessOffset.rayMul(excessStableDebtRatio);
}
vars.currentLiquidityRate = _getOverallBorrowRate(
params.totalStableDebt,
params.totalVariableDebt,
vars.currentVariableBorrowRate,
params.averageStableBorrowRate
).rayMul(vars.supplyUsageRatio).percentMul(
PercentageMath.PERCENTAGE_FACTOR - params.reserveFactor
);
return (
vars.currentLiquidityRate,
vars.currentStableBorrowRate,
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;
if (totalDebt == 0) return 0;
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
uint256 overallBorrowRate = (weightedVariableRate + weightedStableRate).rayDiv(
totalDebt.wadToRay()
);
return overallBorrowRate;
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IReserveInterestRateStrategy} from './IReserveInterestRateStrategy.sol';
import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
/**
* @title IDefaultInterestRateStrategy
* @author Aave
* @notice Defines the basic interface of the DefaultReserveInterestRateStrategy
*/
interface IDefaultInterestRateStrategy is IReserveInterestRateStrategy {
/**
* @notice Returns the usage ratio at which the pool aims to obtain most competitive borrow rates.
* @return The optimal usage ratio, expressed in ray.
*/
function OPTIMAL_USAGE_RATIO() external view returns (uint256);
/**
* @notice Returns the optimal stable to total debt ratio of the reserve.
* @return The optimal stable to total debt ratio, expressed in ray.
*/
function OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO() external view returns (uint256);
/**
* @notice Returns the excess usage ratio above the optimal.
* @dev It's always equal to 1-optimal usage ratio (added as constant for gas optimizations)
* @return The max excess usage ratio, expressed in ray.
*/
function MAX_EXCESS_USAGE_RATIO() external view returns (uint256);
/**
* @notice Returns the excess stable debt ratio above the optimal.
* @dev It's always equal to 1-optimal stable to total debt ratio (added as constant for gas optimizations)
* @return The max excess stable to total debt ratio, expressed in ray.
*/
function MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO() external view returns (uint256);
/**
* @notice Returns the address of the PoolAddressesProvider
* @return The address of the PoolAddressesProvider contract
*/
function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);
/**
* @notice Returns the variable rate slope below optimal usage ratio
* @dev It's the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO
* @return The variable rate slope, expressed in ray
*/
function getVariableRateSlope1() external view returns (uint256);
/**
* @notice Returns the variable rate slope above optimal usage ratio
* @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO
* @return The variable rate slope, expressed in ray
*/
function getVariableRateSlope2() external view returns (uint256);
/**
* @notice Returns the stable rate slope below optimal usage ratio
* @dev It's the stable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO
* @return The stable rate slope, expressed in ray
*/
function getStableRateSlope1() external view returns (uint256);
/**
* @notice Returns the stable rate slope above optimal usage ratio
* @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO
* @return The stable rate slope, expressed in ray
*/
function getStableRateSlope2() external view returns (uint256);
/**
* @notice Returns the stable rate excess offset
* @dev It's an additional premium applied to the stable when stable debt > OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO
* @return The stable rate excess offset, expressed in ray
*/
function getStableRateExcessOffset() external view returns (uint256);
/**
* @notice Returns the base stable borrow rate
* @return The base stable borrow rate, expressed in ray
*/
function getBaseStableBorrowRate() external view returns (uint256);
/**
* @notice Returns the base variable borrow rate
* @return The base variable borrow rate, expressed in ray
*/
function getBaseVariableBorrowRate() external view returns (uint256);
/**
* @notice Returns the maximum variable borrow rate
* @return The maximum variable borrow rate, expressed in ray
*/
function getMaxVariableBorrowRate() external view returns (uint256);
}// 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 {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
/**
* @title IReserveInterestRateStrategy
* @author Aave
* @notice Interface for the calculation of the interest rates
*/
interface IReserveInterestRateStrategy {
/**
* @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 rays
* @return stableBorrowRate The stable borrow rate expressed in rays
* @return variableBorrowRate The variable borrow rate expressed in rays
*/
function calculateInterestRates(
DataTypes.CalculateInterestRatesParams memory params
) external view returns (uint256, uint256, uint256);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title Errors library
* @author Aave
* @notice Defines the error messages emitted by the different contracts of the Aave protocol
*/
library Errors {
string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin'
string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin'
string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin'
string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin'
string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin'
string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge'
string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered'
string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider'
string public constant NOT_CONTRACT = '9'; // 'Address is not a contract'
string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator'
string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken'
string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid'
string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function'
string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list'
string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached'
string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets'
string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset'
string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0'
string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium'
string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve'
string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category'
string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee'
string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool'
string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint'
string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn'
string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0'
string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve'
string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen'
string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused'
string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled'
string public constant STABLE_BORROWING_NOT_ENABLED = '31'; // 'Stable borrowing is not enabled'
string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance'
string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected'
string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0'
string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold'
string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow'
string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed'
string public constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '38'; // 'The requested amount is greater than the max loan size in stable rate mode'
string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type'
string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed'
string public constant NO_OUTSTANDING_STABLE_DEBT = '41'; // 'User does not have outstanding stable rate debt on this reserve'
string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve'
string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0'
string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met'
string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold'
string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated'
string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency'
string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters'
string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded'
string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded'
string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded'
string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded'
string public constant UNDERLYING_CLAIMABLE_RIGHTS_NOT_ZERO = '54'; // 'Claimable rights over underlying not zero (aToken supply or accruedToTreasury)'
string public constant STABLE_DEBT_NOT_ZERO = '55'; // 'Stable debt supply is not zero'
string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero'
string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed'
string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category'
string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed'
string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode'
string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized'
string public constant USER_IN_ISOLATION_MODE_OR_LTV_ZERO = '62'; // 'User is in isolation mode or ltv is zero'
string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve'
string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve'
string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve'
string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve'
string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve'
string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve'
string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve'
string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve'
string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve'
string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve'
string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve
string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index'
string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address'
string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not'
string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid'
string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration'
string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature'
string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported'
string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero'
string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed'
string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio'
string public constant INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = '84'; // 'Invalid optimal stable to total debt ratio'
string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued'
string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list'
string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match'
string public constant STABLE_BORROWING_ENABLED = '88'; // 'Stable borrowing is enabled'
string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one'
string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0
string public constant FLASHLOAN_DISABLED = '91'; // FlashLoaning for this asset is disabled
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title 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)
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title WadRayMath library
* @author Aave
* @notice Provides functions to perform calculations with Wad and Ray units
* @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers
* with 27 digits of precision)
* @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
*/
library WadRayMath {
// HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly
uint256 internal constant WAD = 1e18;
uint256 internal constant HALF_WAD = 0.5e18;
uint256 internal constant RAY = 1e27;
uint256 internal constant HALF_RAY = 0.5e27;
uint256 internal constant WAD_RAY_RATIO = 1e9;
/**
* @dev Multiplies two wad, rounding half up to the nearest wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @param b Wad
* @return c = a*b, in wad
*/
function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b
assembly {
if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) {
revert(0, 0)
}
c := div(add(mul(a, b), HALF_WAD), WAD)
}
}
/**
* @dev Divides two wad, rounding half up to the nearest wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @param b Wad
* @return c = a/b, in wad
*/
function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - halfB) / WAD
assembly {
if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) {
revert(0, 0)
}
c := div(add(mul(a, WAD), div(b, 2)), b)
}
}
/**
* @notice Multiplies two ray, rounding half up to the nearest ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @param b Ray
* @return c = a raymul b
*/
function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b
assembly {
if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) {
revert(0, 0)
}
c := div(add(mul(a, b), HALF_RAY), RAY)
}
}
/**
* @notice Divides two ray, rounding half up to the nearest ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @param b Ray
* @return c = a raydiv b
*/
function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
// to avoid overflow, a <= (type(uint256).max - halfB) / RAY
assembly {
if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) {
revert(0, 0)
}
c := div(add(mul(a, RAY), div(b, 2)), b)
}
}
/**
* @dev Casts ray down to wad
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Ray
* @return b = a converted to wad, rounded half up to the nearest wad
*/
function rayToWad(uint256 a) internal pure returns (uint256 b) {
assembly {
b := div(a, WAD_RAY_RATIO)
let remainder := mod(a, WAD_RAY_RATIO)
if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) {
b := add(b, 1)
}
}
}
/**
* @dev Converts wad up to ray
* @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
* @param a Wad
* @return b = a converted in ray
*/
function wadToRay(uint256 a) internal pure returns (uint256 b) {
// to avoid overflow, b/WAD_RAY_RATIO == a
assembly {
b := mul(a, WAD_RAY_RATIO)
if iszero(eq(div(b, WAD_RAY_RATIO), a)) {
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
library DataTypes {
struct ReserveData {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
//the current stable borrow rate. Expressed in ray
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
//stableDebtToken address
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62: siloed borrowing enabled
//bit 63: flashloaning enabled
//bit 64-79: reserve factor
//bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167 liquidation protocol fee
//bit 168-175 eMode category
//bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252-255 unused
uint256 data;
}
struct UserConfigurationMap {
/**
* @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
* The first bit indicates if an asset is used as collateral by the user, the second whether an
* asset is borrowed by the user.
*/
uint256 data;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// each eMode category may or may not have a custom oracle to override the individual assets price oracles
address priceSource;
string label;
}
enum InterestRateMode {NONE, STABLE, VARIABLE}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currPrincipalStableDebt;
uint256 currAvgStableBorrowRate;
uint256 currTotalStableDebt;
uint256 nextAvgStableBorrowRate;
uint256 nextTotalStableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address stableDebtTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
uint40 stableDebtLastUpdateTimestamp;
}
struct ExecuteLiquidationCallParams {
uint256 reservesCount;
uint256 debtToCover;
address collateralAsset;
address debtAsset;
address user;
bool receiveAToken;
address priceOracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteSupplyParams {
address asset;
uint256 amount;
address onBehalfOf;
uint16 referralCode;
}
struct ExecuteBorrowParams {
address asset;
address user;
address onBehalfOf;
uint256 amount;
InterestRateMode interestRateMode;
uint16 referralCode;
bool releaseUnderlying;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteRepayParams {
address asset;
uint256 amount;
InterestRateMode interestRateMode;
address onBehalfOf;
bool useATokens;
}
struct ExecuteWithdrawParams {
address asset;
uint256 amount;
address to;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteSetUserEModeParams {
uint256 reservesCount;
address oracle;
uint8 categoryId;
}
struct FinalizeTransferParams {
address asset;
address from;
address to;
uint256 amount;
uint256 balanceFromBefore;
uint256 balanceToBefore;
uint256 reservesCount;
address oracle;
uint8 fromEModeCategory;
}
struct FlashloanParams {
address receiverAddress;
address[] assets;
uint256[] amounts;
uint256[] interestRateModes;
address onBehalfOf;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address addressesProvider;
uint8 userEModeCategory;
bool isAuthorizedFlashBorrower;
}
struct FlashloanSimpleParams {
address receiverAddress;
address asset;
uint256 amount;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
}
struct FlashLoanRepaymentParams {
uint256 amount;
uint256 totalPremium;
uint256 flashLoanPremiumToProtocol;
address asset;
address receiverAddress;
uint16 referralCode;
}
struct CalculateUserAccountDataParams {
UserConfigurationMap userConfig;
uint256 reservesCount;
address user;
address oracle;
uint8 userEModeCategory;
}
struct ValidateBorrowParams {
ReserveCache reserveCache;
UserConfigurationMap userConfig;
address asset;
address userAddress;
uint256 amount;
InterestRateMode interestRateMode;
uint256 maxStableLoanPercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
bool isolationModeActive;
address isolationModeCollateralAddress;
uint256 isolationModeDebtCeiling;
}
struct ValidateLiquidationCallParams {
ReserveCache debtReserveCache;
uint256 totalDebt;
uint256 healthFactor;
address priceOracleSentinel;
}
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalStableDebt;
uint256 totalVariableDebt;
uint256 averageStableBorrowRate;
uint256 reserveFactor;
address reserve;
address aToken;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address stableDebtAddress;
address variableDebtAddress;
address interestRateStrategyAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}{
"optimizer": {
"enabled": true,
"runs": 100000
},
"evmVersion": "berlin",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IPoolAddressesProvider","name":"provider","type":"address"},{"internalType":"uint256","name":"optimalUsageRatio","type":"uint256"},{"internalType":"uint256","name":"baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"baseStableRateOffset","type":"uint256"},{"internalType":"uint256","name":"stableRateExcessOffset","type":"uint256"},{"internalType":"uint256","name":"optimalStableToTotalDebtRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ADDRESSES_PROVIDER","outputs":[{"internalType":"contract IPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EXCESS_USAGE_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPTIMAL_USAGE_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"unbacked","type":"uint256"},{"internalType":"uint256","name":"liquidityAdded","type":"uint256"},{"internalType":"uint256","name":"liquidityTaken","type":"uint256"},{"internalType":"uint256","name":"totalStableDebt","type":"uint256"},{"internalType":"uint256","name":"totalVariableDebt","type":"uint256"},{"internalType":"uint256","name":"averageStableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"},{"internalType":"address","name":"reserve","type":"address"},{"internalType":"address","name":"aToken","type":"address"}],"internalType":"struct DataTypes.CalculateInterestRatesParams","name":"params","type":"tuple"}],"name":"calculateInterestRates","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseStableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseVariableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxVariableBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStableRateExcessOffset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVariableRateSlope1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVariableRateSlope2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
61020060405234801561001157600080fd5b5060405162000f7538038062000f7583398101604081905261003291610146565b886b033b2e3c9fd0803ce8000000101560405180604001604052806002815260200161383360f01b815250906100845760405162461bcd60e51b815260040161007b91906101d1565b60405180910390fd5b50806b033b2e3c9fd0803ce80000001015604051806040016040528060028152602001610e0d60f21b815250906100ce5760405162461bcd60e51b815260040161007b91906101d1565b5060808990526100ea896b033b2e3c9fd0803ce8000000610226565b60c05260a0819052610108816b033b2e3c9fd0803ce8000000610226565b60e052506001600160a01b0390981661010052610120959095526101409390935261016091909152610180526101a0526101c052506101e05261024b565b6000806000806000806000806000806101408b8d03121561016657600080fd5b8a516001600160a01b038116811461017d57600080fd5b809a505060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b0151935060e08b015192506101008b015191506101208b015190509295989b9194979a5092959850565b600060208083528351808285015260005b818110156101fe578581018301518582016040015282016101e2565b81811115610210576000604083870101525b50601f01601f1916929092016040019392505050565b60008282101561024657634e487b7160e01b600052601160045260246000fd5b500390565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051610c0d62000368600039600081816102710152610821015260006108c601526000818161017201526105ec0152600081816102970152818161061701526106ec0152600081816102bd0152818161030c0152610654015260008181610142015281816103300152818161067f0152818161075e01526108e70152600081816101980152818161035101526103fa0152600060f40152600081816102e601526107cb01526000818161024501526105900152600081816101e80152818161079a01526107ec0152600081816101c10152818161055f015281816105b1015281816106c301526107380152610c0d6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063a58987091161008c578063bc62690811610066578063bc6269081461026f578063d5cd739114610295578063f4202409146102bb578063fe5fd698146102e157600080fd5b8063a589870914610212578063a9c622f814610240578063acd786861461026757600080fd5b806334762ca5116100c857806334762ca51461019657806354c365c6146101bc5780636fb92589146101e357806380031e371461020a57600080fd5b80630542975c146100ef5780630b3429a21461014057806314e32da414610170575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b604051908152602001610137565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b6101627f000000000000000000000000000000000000000000000000000000000000000081565b6101627f000000000000000000000000000000000000000000000000000000000000000081565b610162610308565b610225610220366004610adb565b610384565b60408051938452602084019290925290820152606001610137565b6101627f000000000000000000000000000000000000000000000000000000000000000081565b6101626108bf565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b6101627f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006103757f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610b8f565b61037f9190610b8f565b905090565b60008060006103d86040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b846080015185606001516103ec9190610b8f565b6020820152600060808201527f000000000000000000000000000000000000000000000000000000000000000060408201526104266108bf565b606082015260208101511561055d57602081015160608601516104489161090b565b60e08083019190915260408087015160208801519288015161010089015192517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291939216906370a0823190602401602060405180830381865afa1580156104d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f79190610ba7565b6105019190610b8f565b61050b9190610bc0565b808252602082015161051c91610b8f565b610100820181905260208201516105329161090b565b60a082015284516101008201516105579161054c91610b8f565b60208301519061090b565b60c08201525b7f00000000000000000000000000000000000000000000000000000000000000008160a0015111156106be5760006105e57f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008460a001516105df9190610bc0565b9061090b565b90506106117f00000000000000000000000000000000000000000000000000000000000000008261094a565b61063b907f0000000000000000000000000000000000000000000000000000000000000000610b8f565b8260600181815161064c9190610b8f565b9052506106797f00000000000000000000000000000000000000000000000000000000000000008261094a565b6106a3907f0000000000000000000000000000000000000000000000000000000000000000610b8f565b826040018181516106b49190610b8f565b9052506107989050565b6107197f00000000000000000000000000000000000000000000000000000000000000006105df8360a001517f000000000000000000000000000000000000000000000000000000000000000061094a90919063ffffffff16565b8160600181815161072a9190610b8f565b90525060a0810151610783907f0000000000000000000000000000000000000000000000000000000000000000906105df907f00000000000000000000000000000000000000000000000000000000000000009061094a565b816040018181516107949190610b8f565b9052505b7f00000000000000000000000000000000000000000000000000000000000000008160e00151111561085c57600061081a7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008460e001516105df9190610bc0565b90506108467f00000000000000000000000000000000000000000000000000000000000000008261094a565b826060018181516108579190610b8f565b905250505b6108a18560c001516127106108719190610bc0565b61089b8360c0015161089589606001518a6080015187604001518c60a001516109a1565b9061094a565b90610a08565b60808201819052606082015160409092015190969195509350915050565b600061037f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610b8f565b600081156b033b2e3c9fd0803ce80000006002840419048411171561092f57600080fd5b506b033b2e3c9fd0803ce80000009190910260028204010490565b600081157ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8390048411151761097f57600080fd5b506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b6000806109ae8587610b8f565b9050806109bf576000915050610a00565b60006109ce8561089588610a4b565b905060006109df856108958a610a4b565b905060006109f96109ef85610a4b565b6105df8486610b8f565b9450505050505b949350505050565b600081157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec7783900484111517610a3d57600080fd5b506127109102611388010490565b633b9aca008181029081048214610a6157600080fd5b919050565b604051610120810167ffffffffffffffff81118282101715610ab1577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a6157600080fd5b60006101208284031215610aee57600080fd5b610af6610a66565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c0820152610b4260e08401610ab7565b60e0820152610100610b55818501610ab7565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610ba257610ba2610b60565b500190565b600060208284031215610bb957600080fd5b5051919050565b600082821015610bd257610bd2610b60565b50039056fea26469706673582212202429128531aba381237b8b5630526b46e16fae03dbb463f5a83786873419101a64736f6c634300080a00330000000000000000000000001f29afbf1d124ee95cf1ebc04f7ff0219870a90600000000000000000000000000000000000000000295be96e6406697200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a56fa5b99019a5c80000000000000000000000000000000000000000000000014adf4b7320334b90000000000000000000000000000000000000000000000000a56fa5b99019a5c80000000000000000000000000000000000000000000000014adf4b7320334b90000000000000000000000000000000000000000000000000108b2a2c28029094000000000000000000000000000000000000000000000000295be96e64066972000000000000000000000000000000000000000000000000a56fa5b99019a5c8000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063a58987091161008c578063bc62690811610066578063bc6269081461026f578063d5cd739114610295578063f4202409146102bb578063fe5fd698146102e157600080fd5b8063a589870914610212578063a9c622f814610240578063acd786861461026757600080fd5b806334762ca5116100c857806334762ca51461019657806354c365c6146101bc5780636fb92589146101e357806380031e371461020a57600080fd5b80630542975c146100ef5780630b3429a21461014057806314e32da414610170575b600080fd5b6101167f0000000000000000000000001f29afbf1d124ee95cf1ebc04f7ff0219870a90681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b7f000000000000000000000000000000000000000000a56fa5b99019a5c80000005b604051908152602001610137565b7f0000000000000000000000000000000000000000014adf4b7320334b90000000610162565b7f0000000000000000000000000000000000000000000000000000000000000000610162565b6101627f00000000000000000000000000000000000000000295be96e64066972000000081565b6101627f000000000000000000000000000000000000000000a56fa5b99019a5c800000081565b610162610308565b610225610220366004610adb565b610384565b60408051938452602084019290925290820152606001610137565b6101627f000000000000000000000000000000000000000000a56fa5b99019a5c800000081565b6101626108bf565b7f000000000000000000000000000000000000000000295be96e64066972000000610162565b7f000000000000000000000000000000000000000000a56fa5b99019a5c8000000610162565b7f0000000000000000000000000000000000000000014adf4b7320334b90000000610162565b6101627f00000000000000000000000000000000000000000295be96e64066972000000081565b60007f0000000000000000000000000000000000000000014adf4b7320334b900000006103757f000000000000000000000000000000000000000000a56fa5b99019a5c80000007f0000000000000000000000000000000000000000000000000000000000000000610b8f565b61037f9190610b8f565b905090565b60008060006103d86040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b846080015185606001516103ec9190610b8f565b6020820152600060808201527f000000000000000000000000000000000000000000000000000000000000000060408201526104266108bf565b606082015260208101511561055d57602081015160608601516104489161090b565b60e08083019190915260408087015160208801519288015161010089015192517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291939216906370a0823190602401602060405180830381865afa1580156104d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f79190610ba7565b6105019190610b8f565b61050b9190610bc0565b808252602082015161051c91610b8f565b610100820181905260208201516105329161090b565b60a082015284516101008201516105579161054c91610b8f565b60208301519061090b565b60c08201525b7f00000000000000000000000000000000000000000295be96e6406697200000008160a0015111156106be5760006105e57f000000000000000000000000000000000000000000a56fa5b99019a5c80000007f00000000000000000000000000000000000000000295be96e6406697200000008460a001516105df9190610bc0565b9061090b565b90506106117f0000000000000000000000000000000000000000014adf4b7320334b900000008261094a565b61063b907f000000000000000000000000000000000000000000a56fa5b99019a5c8000000610b8f565b8260600181815161064c9190610b8f565b9052506106797f0000000000000000000000000000000000000000014adf4b7320334b900000008261094a565b6106a3907f000000000000000000000000000000000000000000a56fa5b99019a5c8000000610b8f565b826040018181516106b49190610b8f565b9052506107989050565b6107197f00000000000000000000000000000000000000000295be96e6406697200000006105df8360a001517f000000000000000000000000000000000000000000a56fa5b99019a5c800000061094a90919063ffffffff16565b8160600181815161072a9190610b8f565b90525060a0810151610783907f00000000000000000000000000000000000000000295be96e640669720000000906105df907f000000000000000000000000000000000000000000a56fa5b99019a5c80000009061094a565b816040018181516107949190610b8f565b9052505b7f000000000000000000000000000000000000000000a56fa5b99019a5c80000008160e00151111561085c57600061081a7f00000000000000000000000000000000000000000295be96e6406697200000007f000000000000000000000000000000000000000000a56fa5b99019a5c80000008460e001516105df9190610bc0565b90506108467f000000000000000000000000000000000000000000295be96e640669720000008261094a565b826060018181516108579190610b8f565b905250505b6108a18560c001516127106108719190610bc0565b61089b8360c0015161089589606001518a6080015187604001518c60a001516109a1565b9061094a565b90610a08565b60808201819052606082015160409092015190969195509350915050565b600061037f7f000000000000000000000000000000000000000000108b2a2c280290940000007f000000000000000000000000000000000000000000a56fa5b99019a5c8000000610b8f565b600081156b033b2e3c9fd0803ce80000006002840419048411171561092f57600080fd5b506b033b2e3c9fd0803ce80000009190910260028204010490565b600081157ffffffffffffffffffffffffffffffffffffffffffe6268e1b017bfe18bffffff8390048411151761097f57600080fd5b506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b6000806109ae8587610b8f565b9050806109bf576000915050610a00565b60006109ce8561089588610a4b565b905060006109df856108958a610a4b565b905060006109f96109ef85610a4b565b6105df8486610b8f565b9450505050505b949350505050565b600081157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec7783900484111517610a3d57600080fd5b506127109102611388010490565b633b9aca008181029081048214610a6157600080fd5b919050565b604051610120810167ffffffffffffffff81118282101715610ab1577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a6157600080fd5b60006101208284031215610aee57600080fd5b610af6610a66565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c0820152610b4260e08401610ab7565b60e0820152610100610b55818501610ab7565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610ba257610ba2610b60565b500190565b600060208284031215610bb957600080fd5b5051919050565b600082821015610bd257610bd2610b60565b50039056fea26469706673582212202429128531aba381237b8b5630526b46e16fae03dbb463f5a83786873419101a64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001f29afbf1d124ee95cf1ebc04f7ff0219870a90600000000000000000000000000000000000000000295be96e6406697200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a56fa5b99019a5c80000000000000000000000000000000000000000000000014adf4b7320334b90000000000000000000000000000000000000000000000000a56fa5b99019a5c80000000000000000000000000000000000000000000000014adf4b7320334b90000000000000000000000000000000000000000000000000108b2a2c28029094000000000000000000000000000000000000000000000000295be96e64066972000000000000000000000000000000000000000000000000a56fa5b99019a5c8000000
-----Decoded View---------------
Arg [0] : provider (address): 0x1F29AfbF1d124ee95CF1eBC04F7FF0219870A906
Arg [1] : optimalUsageRatio (uint256): 800000000000000000000000000
Arg [2] : baseVariableBorrowRate (uint256): 0
Arg [3] : variableRateSlope1 (uint256): 200000000000000000000000000
Arg [4] : variableRateSlope2 (uint256): 400000000000000000000000000
Arg [5] : stableRateSlope1 (uint256): 200000000000000000000000000
Arg [6] : stableRateSlope2 (uint256): 400000000000000000000000000
Arg [7] : baseStableRateOffset (uint256): 20000000000000000000000000
Arg [8] : stableRateExcessOffset (uint256): 50000000000000000000000000
Arg [9] : optimalStableToTotalDebtRatio (uint256): 200000000000000000000000000
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000001f29afbf1d124ee95cf1ebc04f7ff0219870a906
Arg [1] : 00000000000000000000000000000000000000000295be96e640669720000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000000000000000000000a56fa5b99019a5c8000000
Arg [4] : 0000000000000000000000000000000000000000014adf4b7320334b90000000
Arg [5] : 000000000000000000000000000000000000000000a56fa5b99019a5c8000000
Arg [6] : 0000000000000000000000000000000000000000014adf4b7320334b90000000
Arg [7] : 000000000000000000000000000000000000000000108b2a2c28029094000000
Arg [8] : 000000000000000000000000000000000000000000295be96e64066972000000
Arg [9] : 000000000000000000000000000000000000000000a56fa5b99019a5c8000000
Loading...
Loading
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.