Source Code
Overview
S Balance
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
21706131 | 17 days ago | Contract Creation | 0 S |
Loading...
Loading
This contract contains unverified libraries: BorrowLogic, BridgeLogic, ConfiguratorLogic, EModeLogic, FlashLoanLogic, LiquidationLogic, PoolLogic, SupplyLogic
Contract Source Code Verified (Exact Match)
Contract Name:
AaveV3MiscBatch
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {AaveV3MiscProcedure} from '../../../contracts/procedures/AaveV3MiscProcedure.sol'; import '../../../interfaces/IMarketReportTypes.sol'; contract AaveV3MiscBatch is AaveV3MiscProcedure { MiscReport internal _report; constructor( bool l2Flag, address poolAddressesProvider, address sequencerUptimeOracle, uint256 gracePeriod ) { MiscReport memory miscReport = _deploySentinelAndDefaultIR( l2Flag, poolAddressesProvider, sequencerUptimeOracle, gracePeriod ); _report.priceOracleSentinel = miscReport.priceOracleSentinel; _report.defaultInterestRateStrategy = miscReport.defaultInterestRateStrategy; } function getMiscReport() external view returns (MiscReport memory) { return _report; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; import {PriceOracleSentinel, ISequencerOracle} from '../../../contracts/misc/PriceOracleSentinel.sol'; import {DefaultReserveInterestRateStrategyV2} from '../../../contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; import {IErrors} from '../../interfaces/IErrors.sol'; contract AaveV3MiscProcedure is IErrors { function _deploySentinelAndDefaultIR( bool l2Flag, address poolAddressesProvider, address sequencerUptimeOracle, uint256 gracePeriod ) internal returns (MiscReport memory miscReport) { if (poolAddressesProvider == address(0)) revert ProviderNotFound(); if (l2Flag && sequencerUptimeOracle != address(0) && gracePeriod != 0) { miscReport.priceOracleSentinel = address( new PriceOracleSentinel( IPoolAddressesProvider(poolAddressesProvider), ISequencerOracle(sequencerUptimeOracle), gracePeriod ) ); } miscReport.defaultInterestRateStrategy = address( new DefaultReserveInterestRateStrategyV2(poolAddressesProvider) ); return miscReport; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../contracts/interfaces/IPoolAddressesProvider.sol'; import '../../contracts/interfaces/IPoolAddressesProviderRegistry.sol'; import '../../contracts/interfaces/IPool.sol'; import '../../contracts/interfaces/IPoolConfigurator.sol'; import '../../contracts/interfaces/IAaveOracle.sol'; import '../../contracts/interfaces/IAToken.sol'; import '../../contracts/interfaces/IVariableDebtToken.sol'; import '../../contracts/interfaces/IACLManager.sol'; import '../../contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import '../../contracts/helpers/AaveProtocolDataProvider.sol'; import '../../contracts/helpers/UiPoolDataProviderV3.sol'; import '../../contracts/helpers/UiIncentiveDataProviderV3.sol'; import '../../contracts/rewards/interfaces/IEmissionManager.sol'; import '../../contracts/rewards/interfaces/IRewardsController.sol'; import '../../contracts/helpers/WalletBalanceProvider.sol'; import '../../contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol'; import '../../contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol'; import '../../contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol'; import '../../contracts/helpers/interfaces/IWrappedTokenGatewayV3.sol'; import '../../contracts/helpers/L2Encoder.sol'; import {ICollector} from '../../contracts/treasury/ICollector.sol'; import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; struct ContractsReport { IPoolAddressesProviderRegistry poolAddressesProviderRegistry; IPoolAddressesProvider poolAddressesProvider; IPool poolProxy; IPool poolImplementation; IPoolConfigurator poolConfiguratorProxy; IPoolConfigurator poolConfiguratorImplementation; AaveProtocolDataProvider protocolDataProvider; IAaveOracle aaveOracle; IACLManager aclManager; ICollector treasury; IDefaultInterestRateStrategyV2 defaultInterestRateStrategy; ProxyAdmin proxyAdmin; ICollector treasuryImplementation; IWrappedTokenGatewayV3 wrappedTokenGateway; WalletBalanceProvider walletBalanceProvider; UiIncentiveDataProviderV3 uiIncentiveDataProvider; UiPoolDataProviderV3 uiPoolDataProvider; ParaSwapLiquiditySwapAdapter paraSwapLiquiditySwapAdapter; ParaSwapRepayAdapter paraSwapRepayAdapter; ParaSwapWithdrawSwapAdapter paraSwapWithdrawSwapAdapter; L2Encoder l2Encoder; IAToken aToken; IVariableDebtToken variableDebtToken; IEmissionManager emissionManager; IRewardsController rewardsControllerImplementation; IRewardsController rewardsControllerProxy; } struct MarketReport { address poolAddressesProviderRegistry; address poolAddressesProvider; address poolProxy; address poolImplementation; address poolConfiguratorProxy; address poolConfiguratorImplementation; address protocolDataProvider; address aaveOracle; address defaultInterestRateStrategy; address priceOracleSentinel; address aclManager; address treasury; address proxyAdmin; address treasuryImplementation; address wrappedTokenGateway; address walletBalanceProvider; address uiIncentiveDataProvider; address uiPoolDataProvider; address paraSwapLiquiditySwapAdapter; address paraSwapRepayAdapter; address paraSwapWithdrawSwapAdapter; address l2Encoder; address aToken; address variableDebtToken; address emissionManager; address rewardsControllerImplementation; address rewardsControllerProxy; address configEngine; address transparentProxyFactory; address staticATokenFactoryImplementation; address staticATokenFactoryProxy; address staticATokenImplementation; address revenueSplitter; } struct LibrariesReport { address borrowLogic; address bridgeLogic; address configuratorLogic; address eModeLogic; address flashLoanLogic; address liquidationLogic; address poolLogic; address supplyLogic; } struct Roles { address marketOwner; address poolAdmin; address emergencyAdmin; } struct MarketConfig { address networkBaseTokenPriceInUsdProxyAggregator; address marketReferenceCurrencyPriceInUsdProxyAggregator; string marketId; uint8 oracleDecimals; address paraswapAugustusRegistry; address l2SequencerUptimeFeed; uint256 l2PriceOracleSentinelGracePeriod; uint256 providerId; bytes32 salt; address wrappedNativeToken; address proxyAdmin; uint128 flashLoanPremiumTotal; uint128 flashLoanPremiumToProtocol; address incentivesProxy; address treasury; // let empty for deployment of collector, otherwise reuse treasury address address treasuryPartner; // let empty for single treasury, or add treasury partner for revenue split between two organizations. uint16 treasurySplitPercent; // ignored if treasuryPartner is empty, otherwise the split percent for the first treasury (recipientA, values between 00_01 and 100_00) } struct DeployFlags { bool l2; } struct PoolReport { address poolImplementation; address poolConfiguratorImplementation; } struct MiscReport { address priceOracleSentinel; address defaultInterestRateStrategy; } struct ConfigEngineReport { address configEngine; address listingEngine; address eModeEngine; address borrowEngine; address collateralEngine; address priceFeedEngine; address rateEngine; address capsEngine; } struct StaticATokenReport { address transparentProxyFactory; address staticATokenImplementation; address staticATokenFactoryImplementation; address staticATokenFactoryProxy; } struct InitialReport { address poolAddressesProvider; address poolAddressesProviderRegistry; } struct SetupReport { address poolProxy; address poolConfiguratorProxy; address rewardsControllerProxy; address aclManager; } struct PeripheryReport { address aaveOracle; address proxyAdmin; address treasury; address treasuryImplementation; address emissionManager; address rewardsControllerImplementation; address revenueSplitter; } struct ParaswapReport { address paraSwapLiquiditySwapAdapter; address paraSwapRepayAdapter; address paraSwapWithdrawSwapAdapter; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {Errors} from '../protocol/libraries/helpers/Errors.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPriceOracleSentinel} from '../interfaces/IPriceOracleSentinel.sol'; import {ISequencerOracle} from '../interfaces/ISequencerOracle.sol'; import {IACLManager} from '../interfaces/IACLManager.sol'; /** * @title PriceOracleSentinel * @author Aave * @notice It validates if operations are allowed depending on the PriceOracle health. * @dev Once the PriceOracle gets up after an outage/downtime, users can make their positions healthy during a grace * period. So the PriceOracle is considered completely up once its up and the grace period passed. */ contract PriceOracleSentinel is IPriceOracleSentinel { /** * @dev Only pool admin can call functions marked by this modifier. */ modifier onlyPoolAdmin() { IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager()); require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); _; } /** * @dev Only risk or pool admin can call functions marked by this modifier. */ modifier onlyRiskOrPoolAdmins() { IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager()); require( aclManager.isRiskAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_RISK_OR_POOL_ADMIN ); _; } IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; ISequencerOracle internal _sequencerOracle; uint256 internal _gracePeriod; /** * @dev Constructor * @param provider The address of the PoolAddressesProvider * @param oracle The address of the SequencerOracle * @param gracePeriod The duration of the grace period in seconds */ constructor(IPoolAddressesProvider provider, ISequencerOracle oracle, uint256 gracePeriod) { ADDRESSES_PROVIDER = provider; _sequencerOracle = oracle; _gracePeriod = gracePeriod; } /// @inheritdoc IPriceOracleSentinel function isBorrowAllowed() external view override returns (bool) { return _isUpAndGracePeriodPassed(); } /// @inheritdoc IPriceOracleSentinel function isLiquidationAllowed() external view override returns (bool) { return _isUpAndGracePeriodPassed(); } /** * @notice Checks the sequencer oracle is healthy: is up and grace period passed. * @return True if the SequencerOracle is up and the grace period passed, false otherwise */ function _isUpAndGracePeriodPassed() internal view returns (bool) { (, int256 answer, uint256 startedAt, , ) = _sequencerOracle.latestRoundData(); return answer == 0 && block.timestamp - startedAt > _gracePeriod; } /// @inheritdoc IPriceOracleSentinel function setSequencerOracle(address newSequencerOracle) external onlyPoolAdmin { _sequencerOracle = ISequencerOracle(newSequencerOracle); emit SequencerOracleUpdated(newSequencerOracle); } /// @inheritdoc IPriceOracleSentinel function setGracePeriod(uint256 newGracePeriod) external onlyRiskOrPoolAdmins { _gracePeriod = newGracePeriod; emit GracePeriodUpdated(newGracePeriod); } /// @inheritdoc IPriceOracleSentinel function getSequencerOracle() external view returns (address) { return address(_sequencerOracle); } /// @inheritdoc IPriceOracleSentinel function getGracePeriod() external view returns (uint256) { return _gracePeriod; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {PercentageMath} from '../protocol/libraries/math/PercentageMath.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {Errors} from '../protocol/libraries/helpers/Errors.sol'; import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol'; import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; /** * @title DefaultReserveInterestRateStrategyV2 contract * @author BGD Labs * @notice Default interest rate strategy used by the Aave protocol * @dev Strategies are pool-specific: each contract CAN'T be used across different Aave pools * due to the caching of the PoolAddressesProvider and the usage of underlying addresses as * index of the _interestRateData */ contract DefaultReserveInterestRateStrategyV2 is IDefaultInterestRateStrategyV2 { using WadRayMath for uint256; using PercentageMath for uint256; struct CalcInterestRatesLocalVars { uint256 availableLiquidity; uint256 currentVariableBorrowRate; uint256 currentLiquidityRate; uint256 borrowUsageRatio; uint256 supplyUsageRatio; uint256 availableLiquidityPlusDebt; } /// @inheritdoc IDefaultInterestRateStrategyV2 IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; /// @inheritdoc IDefaultInterestRateStrategyV2 uint256 public constant MAX_BORROW_RATE = 1000_00; /// @inheritdoc IDefaultInterestRateStrategyV2 uint256 public constant MIN_OPTIMAL_POINT = 1_00; /// @inheritdoc IDefaultInterestRateStrategyV2 uint256 public constant MAX_OPTIMAL_POINT = 99_00; /// @dev Map of reserves address and their interest rate data (reserveAddress => interestRateData) mapping(address => InterestRateData) internal _interestRateData; modifier onlyPoolConfigurator() { require( msg.sender == ADDRESSES_PROVIDER.getPoolConfigurator(), Errors.CALLER_NOT_POOL_CONFIGURATOR ); _; } /** * @dev Constructor. * @param provider The address of the PoolAddressesProvider of the associated Aave pool */ constructor(address provider) { require(provider != address(0), Errors.INVALID_ADDRESSES_PROVIDER); ADDRESSES_PROVIDER = IPoolAddressesProvider(provider); } /// @inheritdoc IReserveInterestRateStrategy function setInterestRateParams( address reserve, bytes calldata rateData ) external onlyPoolConfigurator { _setInterestRateParams(reserve, abi.decode(rateData, (InterestRateData))); } /// @inheritdoc IDefaultInterestRateStrategyV2 function setInterestRateParams( address reserve, InterestRateData calldata rateData ) external onlyPoolConfigurator { _setInterestRateParams(reserve, rateData); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getInterestRateData(address reserve) external view returns (InterestRateDataRay memory) { return _rayifyRateData(_interestRateData[reserve]); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getInterestRateDataBps(address reserve) external view returns (InterestRateData memory) { return _interestRateData[reserve]; } /// @inheritdoc IDefaultInterestRateStrategyV2 function getOptimalUsageRatio(address reserve) external view returns (uint256) { return _bpsToRay(uint256(_interestRateData[reserve].optimalUsageRatio)); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getVariableRateSlope1(address reserve) external view returns (uint256) { return _bpsToRay(uint256(_interestRateData[reserve].variableRateSlope1)); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getVariableRateSlope2(address reserve) external view returns (uint256) { return _bpsToRay(uint256(_interestRateData[reserve].variableRateSlope2)); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getBaseVariableBorrowRate(address reserve) external view override returns (uint256) { return _bpsToRay(uint256(_interestRateData[reserve].baseVariableBorrowRate)); } /// @inheritdoc IDefaultInterestRateStrategyV2 function getMaxVariableBorrowRate(address reserve) external view override returns (uint256) { return _bpsToRay( uint256( _interestRateData[reserve].baseVariableBorrowRate + _interestRateData[reserve].variableRateSlope1 + _interestRateData[reserve].variableRateSlope2 ) ); } /// @inheritdoc IReserveInterestRateStrategy function calculateInterestRates( DataTypes.CalculateInterestRatesParams memory params ) external view virtual override returns (uint256, uint256) { InterestRateDataRay memory rateData = _rayifyRateData(_interestRateData[params.reserve]); // @note This is a short circuit to allow mintable assets (ex. GHO), which by definition cannot be supplied // and thus do not use virtual underlying balances. if (!params.usingVirtualBalance) { return (0, rateData.baseVariableBorrowRate); } CalcInterestRatesLocalVars memory vars; vars.currentLiquidityRate = 0; vars.currentVariableBorrowRate = rateData.baseVariableBorrowRate; if (params.totalDebt != 0) { vars.availableLiquidity = params.virtualUnderlyingBalance + params.liquidityAdded - params.liquidityTaken; vars.availableLiquidityPlusDebt = vars.availableLiquidity + params.totalDebt; vars.borrowUsageRatio = params.totalDebt.rayDiv(vars.availableLiquidityPlusDebt); vars.supplyUsageRatio = params.totalDebt.rayDiv( vars.availableLiquidityPlusDebt + params.unbacked ); } else { return (0, vars.currentVariableBorrowRate); } if (vars.borrowUsageRatio > rateData.optimalUsageRatio) { uint256 excessBorrowUsageRatio = (vars.borrowUsageRatio - rateData.optimalUsageRatio).rayDiv( WadRayMath.RAY - rateData.optimalUsageRatio ); vars.currentVariableBorrowRate += rateData.variableRateSlope1 + rateData.variableRateSlope2.rayMul(excessBorrowUsageRatio); } else { vars.currentVariableBorrowRate += rateData .variableRateSlope1 .rayMul(vars.borrowUsageRatio) .rayDiv(rateData.optimalUsageRatio); } vars.currentLiquidityRate = vars .currentVariableBorrowRate .rayMul(vars.supplyUsageRatio) .percentMul(PercentageMath.PERCENTAGE_FACTOR - params.reserveFactor); return (vars.currentLiquidityRate, vars.currentVariableBorrowRate); } /** * @dev Doing validations and data update for an asset * @param reserve address of the underlying asset of the reserve * @param rateData Encoded reserve interest rate data to apply */ function _setInterestRateParams(address reserve, InterestRateData memory rateData) internal { require(reserve != address(0), Errors.ZERO_ADDRESS_NOT_VALID); require( rateData.optimalUsageRatio <= MAX_OPTIMAL_POINT && rateData.optimalUsageRatio >= MIN_OPTIMAL_POINT, Errors.INVALID_OPTIMAL_USAGE_RATIO ); require( rateData.variableRateSlope1 <= rateData.variableRateSlope2, Errors.SLOPE_2_MUST_BE_GTE_SLOPE_1 ); // The maximum rate should not be above certain threshold require( uint256(rateData.baseVariableBorrowRate) + uint256(rateData.variableRateSlope1) + uint256(rateData.variableRateSlope2) <= MAX_BORROW_RATE, Errors.INVALID_MAX_RATE ); _interestRateData[reserve] = rateData; emit RateDataUpdate( reserve, rateData.optimalUsageRatio, rateData.baseVariableBorrowRate, rateData.variableRateSlope1, rateData.variableRateSlope2 ); } /** * @dev Transforms an InterestRateData struct to an InterestRateDataRay struct by multiplying all values * by 1e23, turning them into ray values * * @param data The InterestRateData struct to transform * * @return The resulting InterestRateDataRay struct */ function _rayifyRateData( InterestRateData memory data ) internal pure returns (InterestRateDataRay memory) { return InterestRateDataRay({ optimalUsageRatio: _bpsToRay(uint256(data.optimalUsageRatio)), baseVariableBorrowRate: _bpsToRay(uint256(data.baseVariableBorrowRate)), variableRateSlope1: _bpsToRay(uint256(data.variableRateSlope1)), variableRateSlope2: _bpsToRay(uint256(data.variableRateSlope2)) }); } // @dev helper function added here, as generally the protocol doesn't use bps function _bpsToRay(uint256 n) internal pure returns (uint256) { return n * 1e23; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IErrors { error L2MustBeEnabled(); error L2MustBeDisabled(); error ProviderNotFound(); error ProxyAdminNotFound(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPoolAddressesProviderRegistry * @author Aave * @notice Defines the basic interface for an Aave Pool Addresses Provider Registry. */ interface IPoolAddressesProviderRegistry { /** * @dev Emitted when a new AddressesProvider is registered. * @param addressesProvider The address of the registered PoolAddressesProvider * @param id The id of the registered PoolAddressesProvider */ event AddressesProviderRegistered(address indexed addressesProvider, uint256 indexed id); /** * @dev Emitted when an AddressesProvider is unregistered. * @param addressesProvider The address of the unregistered PoolAddressesProvider * @param id The id of the unregistered PoolAddressesProvider */ event AddressesProviderUnregistered(address indexed addressesProvider, uint256 indexed id); /** * @notice Returns the list of registered addresses providers * @return The list of addresses providers */ function getAddressesProvidersList() external view returns (address[] memory); /** * @notice Returns the id of a registered PoolAddressesProvider * @param addressesProvider The address of the PoolAddressesProvider * @return The id of the PoolAddressesProvider or 0 if is not registered */ function getAddressesProviderIdByAddress( address addressesProvider ) external view returns (uint256); /** * @notice Returns the address of a registered PoolAddressesProvider * @param id The id of the market * @return The address of the PoolAddressesProvider with the given id or zero address if it is not registered */ function getAddressesProviderAddressById(uint256 id) external view returns (address); /** * @notice Registers an addresses provider * @dev The PoolAddressesProvider must not already be registered in the registry * @dev The id must not be used by an already registered PoolAddressesProvider * @param provider The address of the new PoolAddressesProvider * @param id The id for the new PoolAddressesProvider, referring to the market it belongs to */ function registerAddressesProvider(address provider, uint256 id) external; /** * @notice Removes an addresses provider from the list of registered addresses providers * @param provider The PoolAddressesProvider address */ function unregisterAddressesProvider(address provider) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, * 1 for Stable (Deprecated on v3.2.0), 2 for Variable * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate @note deprecated on v3.2.0 * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the VariableDebtToken * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 variable debt tokens * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0 * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode DEPRECATED in v3.2.0 * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Deprecated on v3.2.0 * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using 2 on `modes` * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve. * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Accumulates interest to all indexes of the reserve * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncIndexesState(address asset) external; /** * @notice Updates interest rates on the reserve data * @dev Only callable by the PoolConfigurator contract * @dev To be used when required by the configurator, for example when updating interest rates strategy data * @param asset The address of the underlying asset of the reserve */ function syncRatesState(address asset) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve */ function getConfiguration( address asset ) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @notice Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user */ function getUserConfiguration( address user ) external view returns (DataTypes.UserConfigurationMap memory); /** * @notice Returns the normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory); /** * @notice Returns the state and configuration of the reserve, including extra data included with Aave v3.1 * @dev DEPRECATED use independent getters instead (getReserveData, getLiquidationGracePeriod) * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve with virtual accounting */ function getReserveDataExtended( address asset ) external view returns (DataTypes.ReserveData memory); /** * @notice Returns the virtual underlying balance of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve virtual underlying balance */ function getVirtualUnderlyingBalance(address asset) external view returns (uint128); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the number of initialized reserves * @dev It includes dropped reserves * @return The count */ function getReservesCount() external view returns (uint256); /** * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct * @param id The id of the reserve as stored in the DataTypes.ReserveData struct * @return The address of the reserve associated with id */ function getReserveAddressById(uint16 id) external view returns (address); /** * @notice Returns the PoolAddressesProvider connected to this contract * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Updates the protocol fee on the bridging * @param bridgeProtocolFee The part of the premium sent to the protocol treasury */ function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; /** * @notice Updates flash loan premiums. Flash loan premium consists of two parts: * - A part is sent to aToken holders as extra, one time accumulated interest * - A part is collected by the protocol treasury * @dev The total premium is calculated on the total borrowed amount * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` * @dev Only callable by the PoolConfigurator contract * @param flashLoanPremiumTotal The total premium, expressed in bps * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps */ function updateFlashloanPremiums( uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol ) external; /** * @notice Configures a new or alters an existing collateral configuration of an eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory( uint8 id, DataTypes.EModeCategoryBaseConfiguration memory config ) external; /** * @notice Replaces the current eMode collateralBitmap. * @param id The id of the category * @param collateralBitmap The collateralBitmap of the category */ function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external; /** * @notice Replaces the current eMode borrowableBitmap. * @param id The id of the category * @param borrowableBitmap The borrowableBitmap of the category */ function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external; /** * @notice Returns the data of an eMode category * @dev DEPRECATED use independent getters instead * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData( uint8 id ) external view returns (DataTypes.EModeCategoryLegacy memory); /** * @notice Returns the label of an eMode category * @param id The id of the category * @return The label of the category */ function getEModeCategoryLabel(uint8 id) external view returns (string memory); /** * @notice Returns the collateral config of an eMode category * @param id The id of the category * @return The ltv,lt,lb of the category */ function getEModeCategoryCollateralConfig( uint8 id ) external view returns (DataTypes.CollateralConfig memory); /** * @notice Returns the collateralBitmap of an eMode category * @param id The id of the category * @return The collateralBitmap of the category */ function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); /** * @notice Returns the borrowableBitmap of an eMode category * @param id The id of the category * @return The borrowableBitmap of the category */ function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Sets the liquidation grace period of the given asset * @dev To enable a liquidation grace period, a timestamp in the future should be set, * To disable a liquidation grace period, any timestamp in the past works, like 0 * @param asset The address of the underlying asset to set the liquidationGracePeriod * @param until Timestamp when the liquidation grace period will end **/ function setLiquidationGracePeriod(address asset, uint40 until) external; /** * @notice Returns the liquidation grace period of the given asset * @param asset The address of the underlying asset * @return Timestamp when the liquidation grace period will end **/ function getLiquidationGracePeriod(address asset) external returns (uint40); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Gets the address of the external FlashLoanLogic */ function getFlashLoanLogic() external view returns (address); /** * @notice Gets the address of the external BorrowLogic */ function getBorrowLogic() external view returns (address); /** * @notice Gets the address of the external BridgeLogic */ function getBridgeLogic() external view returns (address); /** * @notice Gets the address of the external EModeLogic */ function getEModeLogic() external view returns (address); /** * @notice Gets the address of the external LiquidationLogic */ function getLiquidationLogic() external view returns (address); /** * @notice Gets the address of the external PoolLogic */ function getPoolLogic() external view returns (address); /** * @notice Gets the address of the external SupplyLogic */ function getSupplyLogic() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {ConfiguratorInputTypes} from '../protocol/libraries/types/ConfiguratorInputTypes.sol'; import {IDefaultInterestRateStrategyV2} from './IDefaultInterestRateStrategyV2.sol'; /** * @title IPoolConfigurator * @author Aave * @notice Defines the basic interface for a Pool configurator. */ interface IPoolConfigurator { /** * @dev Emitted when a reserve is initialized. * @param asset The address of the underlying asset of the reserve * @param aToken The address of the associated aToken contract * @param stableDebtToken, DEPRECATED in v3.2.0 * @param variableDebtToken The address of the associated variable rate debt token * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve */ event ReserveInitialized( address indexed asset, address indexed aToken, address stableDebtToken, address variableDebtToken, address interestRateStrategyAddress ); /** * @dev Emitted when borrowing is enabled or disabled on a reserve. * @param asset The address of the underlying asset of the reserve * @param enabled True if borrowing is enabled, false otherwise */ event ReserveBorrowing(address indexed asset, bool enabled); /** * @dev Emitted when flashloans are enabled or disabled on a reserve. * @param asset The address of the underlying asset of the reserve * @param enabled True if flashloans are enabled, false otherwise */ event ReserveFlashLoaning(address indexed asset, bool enabled); /** * @dev Emitted when the ltv is set for the frozen asset. * @param asset The address of the underlying asset of the reserve * @param ltv The loan to value of the asset when used as collateral */ event PendingLtvChanged(address indexed asset, uint256 ltv); /** * @dev Emitted when the collateralization risk parameters for the specified asset are updated. * @param asset The address of the underlying asset of the reserve * @param ltv The loan to value of the asset when used as collateral * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized * @param liquidationBonus The bonus liquidators receive to liquidate this asset */ event CollateralConfigurationChanged( address indexed asset, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus ); /** * @dev Emitted when a reserve is activated or deactivated * @param asset The address of the underlying asset of the reserve * @param active True if reserve is active, false otherwise */ event ReserveActive(address indexed asset, bool active); /** * @dev Emitted when a reserve is frozen or unfrozen * @param asset The address of the underlying asset of the reserve * @param frozen True if reserve is frozen, false otherwise */ event ReserveFrozen(address indexed asset, bool frozen); /** * @dev Emitted when a reserve is paused or unpaused * @param asset The address of the underlying asset of the reserve * @param paused True if reserve is paused, false otherwise */ event ReservePaused(address indexed asset, bool paused); /** * @dev Emitted when a reserve is dropped. * @param asset The address of the underlying asset of the reserve */ event ReserveDropped(address indexed asset); /** * @dev Emitted when a reserve factor is updated. * @param asset The address of the underlying asset of the reserve * @param oldReserveFactor The old reserve factor, expressed in bps * @param newReserveFactor The new reserve factor, expressed in bps */ event ReserveFactorChanged( address indexed asset, uint256 oldReserveFactor, uint256 newReserveFactor ); /** * @dev Emitted when the borrow cap of a reserve is updated. * @param asset The address of the underlying asset of the reserve * @param oldBorrowCap The old borrow cap * @param newBorrowCap The new borrow cap */ event BorrowCapChanged(address indexed asset, uint256 oldBorrowCap, uint256 newBorrowCap); /** * @dev Emitted when the supply cap of a reserve is updated. * @param asset The address of the underlying asset of the reserve * @param oldSupplyCap The old supply cap * @param newSupplyCap The new supply cap */ event SupplyCapChanged(address indexed asset, uint256 oldSupplyCap, uint256 newSupplyCap); /** * @dev Emitted when the liquidation protocol fee of a reserve is updated. * @param asset The address of the underlying asset of the reserve * @param oldFee The old liquidation protocol fee, expressed in bps * @param newFee The new liquidation protocol fee, expressed in bps */ event LiquidationProtocolFeeChanged(address indexed asset, uint256 oldFee, uint256 newFee); /** * @dev Emitted when the liquidation grace period is updated. * @param asset The address of the underlying asset of the reserve * @param gracePeriodUntil Timestamp until when liquidations will not be allowed post-unpause */ event LiquidationGracePeriodChanged(address indexed asset, uint40 gracePeriodUntil); /** * @dev Emitted when the liquidation grace period is disabled. * @param asset The address of the underlying asset of the reserve */ event LiquidationGracePeriodDisabled(address indexed asset); /** * @dev Emitted when the unbacked mint cap of a reserve is updated. * @param asset The address of the underlying asset of the reserve * @param oldUnbackedMintCap The old unbacked mint cap * @param newUnbackedMintCap The new unbacked mint cap */ event UnbackedMintCapChanged( address indexed asset, uint256 oldUnbackedMintCap, uint256 newUnbackedMintCap ); /** * @dev Emitted when an collateral configuration of an asset in an eMode is changed. * @param asset The address of the underlying asset of the reserve * @param categoryId The eMode category * @param collateral True if the asset is enabled as collateral in the eMode, false otherwise. */ event AssetCollateralInEModeChanged(address indexed asset, uint8 categoryId, bool collateral); /** * @dev Emitted when the borrowable configuration of an asset in an eMode changed. * @param asset The address of the underlying asset of the reserve * @param categoryId The eMode category * @param borrowable True if the asset is enabled as borrowable in the eMode, false otherwise. */ event AssetBorrowableInEModeChanged(address indexed asset, uint8 categoryId, bool borrowable); /** * @dev Emitted when a new eMode category is added or an existing category is altered. * @param categoryId The new eMode category id * @param ltv The ltv for the asset category in eMode * @param liquidationThreshold The liquidationThreshold for the asset category in eMode * @param liquidationBonus The liquidationBonus for the asset category in eMode * @param oracle DEPRECATED in v3.2.0 * @param label A human readable identifier for the category */ event EModeCategoryAdded( uint8 indexed categoryId, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, address oracle, string label ); /** * @dev Emitted when a reserve interest strategy contract is updated. * @param asset The address of the underlying asset of the reserve * @param oldStrategy The address of the old interest strategy contract * @param newStrategy The address of the new interest strategy contract */ event ReserveInterestRateStrategyChanged( address indexed asset, address oldStrategy, address newStrategy ); /** * @dev Emitted when the data of a reserve interest strategy contract is updated. * @param asset The address of the underlying asset of the reserve * @param data abi encoded data */ event ReserveInterestRateDataChanged(address indexed asset, address indexed strategy, bytes data); /** * @dev Emitted when an aToken implementation is upgraded. * @param asset The address of the underlying asset of the reserve * @param proxy The aToken proxy address * @param implementation The new aToken implementation */ event ATokenUpgraded( address indexed asset, address indexed proxy, address indexed implementation ); /** * @dev Emitted when the implementation of a variable debt token is upgraded. * @param asset The address of the underlying asset of the reserve * @param proxy The variable debt token proxy address * @param implementation The new aToken implementation */ event VariableDebtTokenUpgraded( address indexed asset, address indexed proxy, address indexed implementation ); /** * @dev Emitted when the debt ceiling of an asset is set. * @param asset The address of the underlying asset of the reserve * @param oldDebtCeiling The old debt ceiling * @param newDebtCeiling The new debt ceiling */ event DebtCeilingChanged(address indexed asset, uint256 oldDebtCeiling, uint256 newDebtCeiling); /** * @dev Emitted when the the siloed borrowing state for an asset is changed. * @param asset The address of the underlying asset of the reserve * @param oldState The old siloed borrowing state * @param newState The new siloed borrowing state */ event SiloedBorrowingChanged(address indexed asset, bool oldState, bool newState); /** * @dev Emitted when the bridge protocol fee is updated. * @param oldBridgeProtocolFee The old protocol fee, expressed in bps * @param newBridgeProtocolFee The new protocol fee, expressed in bps */ event BridgeProtocolFeeUpdated(uint256 oldBridgeProtocolFee, uint256 newBridgeProtocolFee); /** * @dev Emitted when the total premium on flashloans is updated. * @param oldFlashloanPremiumTotal The old premium, expressed in bps * @param newFlashloanPremiumTotal The new premium, expressed in bps */ event FlashloanPremiumTotalUpdated( uint128 oldFlashloanPremiumTotal, uint128 newFlashloanPremiumTotal ); /** * @dev Emitted when the part of the premium that goes to protocol is updated. * @param oldFlashloanPremiumToProtocol The old premium, expressed in bps * @param newFlashloanPremiumToProtocol The new premium, expressed in bps */ event FlashloanPremiumToProtocolUpdated( uint128 oldFlashloanPremiumToProtocol, uint128 newFlashloanPremiumToProtocol ); /** * @dev Emitted when the reserve is set as borrowable/non borrowable in isolation mode. * @param asset The address of the underlying asset of the reserve * @param borrowable True if the reserve is borrowable in isolation, false otherwise */ event BorrowableInIsolationChanged(address asset, bool borrowable); /** * @notice Initializes multiple reserves. * @dev param useVirtualBalance of the input struct should be true for all normal assets and should be false * only in special cases (ex. GHO) where an asset is minted instead of supplied. * @param input The array of initialization parameters */ function initReserves(ConfiguratorInputTypes.InitReserveInput[] calldata input) external; /** * @dev Updates the aToken implementation for the reserve. * @param input The aToken update parameters */ function updateAToken(ConfiguratorInputTypes.UpdateATokenInput calldata input) external; /** * @notice Updates the variable debt token implementation for the asset. * @param input The variableDebtToken update parameters */ function updateVariableDebtToken( ConfiguratorInputTypes.UpdateDebtTokenInput calldata input ) external; /** * @notice Configures borrowing on a reserve. * @param asset The address of the underlying asset of the reserve * @param enabled True if borrowing needs to be enabled, false otherwise */ function setReserveBorrowing(address asset, bool enabled) external; /** * @notice Configures the reserve collateralization parameters. * @dev All the values are expressed in bps. A value of 10000, results in 100.00% * @dev The `liquidationBonus` is always above 100%. A value of 105% means the liquidator will receive a 5% bonus * @param asset The address of the underlying asset of the reserve * @param ltv The loan to value of the asset when used as collateral * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized * @param liquidationBonus The bonus liquidators receive to liquidate this asset */ function configureReserveAsCollateral( address asset, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus ) external; /** * @notice Enable or disable flashloans on a reserve * @param asset The address of the underlying asset of the reserve * @param enabled True if flashloans need to be enabled, false otherwise */ function setReserveFlashLoaning(address asset, bool enabled) external; /** * @notice Activate or deactivate a reserve * @param asset The address of the underlying asset of the reserve * @param active True if the reserve needs to be active, false otherwise */ function setReserveActive(address asset, bool active) external; /** * @notice Freeze or unfreeze a reserve. A frozen reserve doesn't allow any new supply, borrow * or rate swap but allows repayments, liquidations, rate rebalances and withdrawals. * @param asset The address of the underlying asset of the reserve * @param freeze True if the reserve needs to be frozen, false otherwise */ function setReserveFreeze(address asset, bool freeze) external; /** * @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 (e.g. USD stablecoins) should be borrowable in isolation mode to keep * consistency in the debt ceiling calculations * @param asset The address of the underlying asset of the reserve * @param borrowable True if the asset should be borrowable in isolation, false otherwise */ function setBorrowableInIsolation(address asset, bool borrowable) external; /** * @notice Pauses a reserve. A paused reserve does not allow any interaction (supply, borrow, repay, * swap interest rate, liquidate, atoken transfers). * @param asset The address of the underlying asset of the reserve * @param paused True if pausing the reserve, false if unpausing * @param gracePeriod Count of seconds after unpause during which liquidations will not be available * - Only applicable whenever unpausing (`paused` as false) * - Passing 0 means no grace period * - Capped to maximum MAX_GRACE_PERIOD */ function setReservePause(address asset, bool paused, uint40 gracePeriod) external; /** * @notice Pauses a reserve. A paused reserve does not allow any interaction (supply, borrow, repay, * swap interest rate, liquidate, atoken transfers). * @dev Version with no grace period * @param asset The address of the underlying asset of the reserve * @param paused True if pausing the reserve, false if unpausing */ function setReservePause(address asset, bool paused) external; /** * @notice Disables liquidation grace period for the asset. The liquidation grace period is set in the past * so that liquidations are allowed for the asset. * @param asset The address of the underlying asset of the reserve */ function disableLiquidationGracePeriod(address asset) external; /** * @notice Updates the reserve factor of a reserve. * @param asset The address of the underlying asset of the reserve * @param newReserveFactor The new reserve factor of the reserve */ function setReserveFactor(address asset, uint256 newReserveFactor) external; /** * @notice Sets the interest rate strategy of a reserve. * @param asset The address of the underlying asset of the reserve * @param newRateStrategyAddress The address of the new interest strategy contract * @param rateData bytes-encoded rate data. In this format in order to allow the rate strategy contract * to de-structure custom data */ function setReserveInterestRateStrategyAddress( address asset, address newRateStrategyAddress, bytes calldata rateData ) external; /** * @notice Sets interest rate data for a reserve * @param asset The address of the underlying asset of the reserve * @param rateData bytes-encoded rate data. In this format in order to allow the rate strategy contract * to de-structure custom data */ function setReserveInterestRateData(address asset, bytes calldata rateData) external; /** * @notice Pauses or unpauses all the protocol reserves. In the paused state all the protocol interactions * are suspended. * @param paused True if protocol needs to be paused, false otherwise * @param gracePeriod Count of seconds after unpause during which liquidations will not be available * - Only applicable whenever unpausing (`paused` as false) * - Passing 0 means no grace period * - Capped to maximum MAX_GRACE_PERIOD */ function setPoolPause(bool paused, uint40 gracePeriod) external; /** * @notice Pauses or unpauses all the protocol reserves. In the paused state all the protocol interactions * are suspended. * @dev Version with no grace period * @param paused True if protocol needs to be paused, false otherwise */ function setPoolPause(bool paused) external; /** * @notice Updates the borrow cap of a reserve. * @param asset The address of the underlying asset of the reserve * @param newBorrowCap The new borrow cap of the reserve */ function setBorrowCap(address asset, uint256 newBorrowCap) external; /** * @notice Updates the supply cap of a reserve. * @param asset The address of the underlying asset of the reserve * @param newSupplyCap The new supply cap of the reserve */ function setSupplyCap(address asset, uint256 newSupplyCap) external; /** * @notice Updates the liquidation protocol fee of reserve. * @param asset The address of the underlying asset of the reserve * @param newFee The new liquidation protocol fee of the reserve, expressed in bps */ function setLiquidationProtocolFee(address asset, uint256 newFee) external; /** * @notice Updates the unbacked mint cap of reserve. * @param asset The address of the underlying asset of the reserve * @param newUnbackedMintCap The new unbacked mint cap of the reserve */ function setUnbackedMintCap(address asset, uint256 newUnbackedMintCap) external; /** * @notice Enables/disables an asset to be borrowable in a selected eMode. * - eMode.borrowable always has less priority then reserve.borrowable * @param asset The address of the underlying asset of the reserve * @param categoryId The eMode categoryId * @param borrowable True if the asset should be borrowable in the given eMode category, false otherwise. */ function setAssetBorrowableInEMode(address asset, uint8 categoryId, bool borrowable) external; /** * @notice Enables/disables an asset to be collateral in a selected eMode. * @param asset The address of the underlying asset of the reserve * @param categoryId The eMode categoryId * @param collateral True if the asset should be collateral in the given eMode category, false otherwise. */ function setAssetCollateralInEMode(address asset, uint8 categoryId, bool collateral) external; /** * @notice Adds a new efficiency mode (eMode) category or alters a existing one. * @param categoryId The id of the category to be configured * @param ltv The ltv associated with the category * @param liquidationThreshold The liquidation threshold associated with the category * @param liquidationBonus The liquidation bonus associated with the category * @param label A label identifying the category */ function setEModeCategory( uint8 categoryId, uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus, string calldata label ) external; /** * @notice Drops a reserve entirely. * @param asset The address of the reserve to drop */ function dropReserve(address asset) external; /** * @notice Updates the bridge fee collected by the protocol reserves. * @param newBridgeProtocolFee The part of the fee sent to the protocol treasury, expressed in bps */ function updateBridgeProtocolFee(uint256 newBridgeProtocolFee) external; /** * @notice Updates the total flash loan premium. * Total flash loan premium consists of two parts: * - A part is sent to aToken holders as extra balance * - A part is collected by the protocol reserves * @dev Expressed in bps * @dev The premium is calculated on the total amount borrowed * @param newFlashloanPremiumTotal The total flashloan premium */ function updateFlashloanPremiumTotal(uint128 newFlashloanPremiumTotal) external; /** * @notice Updates the flash loan premium collected by protocol reserves * @dev Expressed in bps * @dev The premium to protocol is calculated on the total flashloan premium * @param newFlashloanPremiumToProtocol The part of the flashloan premium sent to the protocol treasury */ function updateFlashloanPremiumToProtocol(uint128 newFlashloanPremiumToProtocol) external; /** * @notice Sets the debt ceiling for an asset. * @param newDebtCeiling The new debt ceiling */ function setDebtCeiling(address asset, uint256 newDebtCeiling) external; /** * @notice Sets siloed borrowing for an asset * @param siloed The new siloed borrowing state */ function setSiloedBorrowing(address asset, bool siloed) external; /** * @notice Gets pending ltv value * @param asset The new siloed borrowing state */ function getPendingLtv(address asset) external view returns (uint256); /** * @notice Gets the address of the external ConfiguratorLogic */ function getConfiguratorLogic() external view returns (address); /** * @notice Gets the maximum liquidations grace period allowed, in seconds */ function MAX_GRACE_PERIOD() external view returns (uint40); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPriceOracleGetter} from './IPriceOracleGetter.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IAaveOracle * @author Aave * @notice Defines the basic interface for the Aave Oracle */ interface IAaveOracle is IPriceOracleGetter { /** * @dev Emitted after the base currency is set * @param baseCurrency The base currency of used for price quotes * @param baseCurrencyUnit The unit of the base currency */ event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit); /** * @dev Emitted after the price source of an asset is updated * @param asset The address of the asset * @param source The price source of the asset */ event AssetSourceUpdated(address indexed asset, address indexed source); /** * @dev Emitted after the address of fallback oracle is updated * @param fallbackOracle The address of the fallback oracle */ event FallbackOracleUpdated(address indexed fallbackOracle); /** * @notice Returns the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Sets or replaces price sources of assets * @param assets The addresses of the assets * @param sources The addresses of the price sources */ function setAssetSources(address[] calldata assets, address[] calldata sources) external; /** * @notice Sets the fallback oracle * @param fallbackOracle The address of the fallback oracle */ function setFallbackOracle(address fallbackOracle) external; /** * @notice Returns a list of prices from a list of assets addresses * @param assets The list of assets addresses * @return The prices of the given assets */ function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory); /** * @notice Returns the address of the source for an asset address * @param asset The address of the asset * @return The address of the source */ function getSourceOfAsset(address asset) external view returns (address); /** * @notice Returns the address of the fallback oracle * @return The address of the fallback oracle */ function getFallbackOracle() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableAToken} from './IInitializableAToken.sol'; /** * @title IAToken * @author Aave * @notice Defines the basic interface for an AToken. */ interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken { /** * @dev Emitted during the transfer action * @param from The user whose tokens are being transferred * @param to The recipient * @param value The scaled amount being transferred * @param index The next liquidity index of the reserve */ event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); /** * @notice Mints `amount` aTokens to `user` * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted aTokens * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve * @return `true` if the the previous balance of the user was 0 */ function mint( address caller, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool); /** * @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` * @dev In some instances, the mint event could be emitted from a burn transaction * if the amount to burn is less than the interest that the user accrued * @param from The address from which the aTokens will be burned * @param receiverOfUnderlying The address that will receive the underlying * @param amount The amount being burned * @param index The next liquidity index of the reserve */ function burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external; /** * @notice Mints aTokens to the reserve treasury * @param amount The amount of tokens getting minted * @param index The next liquidity index of the reserve */ function mintToTreasury(uint256 amount, uint256 index) external; /** * @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * @param from The address getting liquidated, current owner of the aTokens * @param to The recipient * @param value The amount of tokens getting transferred */ function transferOnLiquidation(address from, address to, uint256 value) external; /** * @notice Transfers the underlying asset to `target`. * @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan() * @param target The recipient of the underlying * @param amount The amount getting transferred */ function transferUnderlyingTo(address target, uint256 amount) external; /** * @notice Handles the underlying received by the aToken after the transfer has been completed. * @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the * transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying * to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset. * @param user The user executing the repayment * @param onBehalfOf The address of the user who will get his debt reduced/removed * @param amount The amount getting repaid */ function handleRepayment(address user, address onBehalfOf, uint256 amount) external; /** * @notice Allow passing a signed message to approve spending * @dev implements the permit function as for * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md * @param owner The owner of the funds * @param spender The spender * @param value The amount * @param deadline The deadline timestamp, type(uint256).max for max deadline * @param v Signature param * @param s Signature param * @param r Signature param */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) * @return The address of the underlying asset */ function UNDERLYING_ASSET_ADDRESS() external view returns (address); /** * @notice Returns the address of the Aave treasury, receiving the fees on this aToken. * @return Address of the Aave treasury */ function RESERVE_TREASURY_ADDRESS() external view returns (address); /** * @notice Get the domain separator for the token * @dev Return cached value if chainId matches cache, otherwise recomputes separator * @return The domain separator of the token at current chain */ function DOMAIN_SEPARATOR() external view returns (bytes32); /** * @notice Returns the nonce for owner. * @param owner The address of the owner * @return The nonce of the owner */ function nonces(address owner) external view returns (uint256); /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; /** * @title IVariableDebtToken * @author Aave * @notice Defines the basic interface for a variable debt token. */ interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken { /** * @notice Mints debt token to the `onBehalfOf` address * @param user The address receiving the borrowed underlying, being the delegatee in case * of credit delegate, or same as `onBehalfOf` otherwise * @param onBehalfOf The address receiving the debt tokens * @param amount The amount of debt being minted * @param index The variable debt index of the reserve * @return True if the previous balance of the user is 0, false otherwise * @return The scaled total debt of the reserve */ function mint( address user, address onBehalfOf, uint256 amount, uint256 index ) external returns (bool, uint256); /** * @notice Burns user variable debt * @dev In some instances, a burn transaction will emit a mint event * if the amount to burn is less than the interest that the user accrued * @param from The address from which the debt will be burned * @param amount The amount getting burned * @param index The variable debt index of the reserve * @return The scaled total debt of the reserve */ function burn(address from, uint256 amount, uint256 index) external returns (uint256); /** * @notice Returns the address of the underlying asset of this debtToken (E.g. WETH for variableDebtWETH) * @return The address of the underlying asset */ function UNDERLYING_ASSET_ADDRESS() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IACLManager * @author Aave * @notice Defines the basic interface for the ACL Manager */ interface IACLManager { /** * @notice Returns the contract address of the PoolAddressesProvider * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the identifier of the PoolAdmin role * @return The id of the PoolAdmin role */ function POOL_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the EmergencyAdmin role * @return The id of the EmergencyAdmin role */ function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the RiskAdmin role * @return The id of the RiskAdmin role */ function RISK_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the FlashBorrower role * @return The id of the FlashBorrower role */ function FLASH_BORROWER_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the Bridge role * @return The id of the Bridge role */ function BRIDGE_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the AssetListingAdmin role * @return The id of the AssetListingAdmin role */ function ASSET_LISTING_ADMIN_ROLE() external view returns (bytes32); /** * @notice Set the role as admin of a specific role. * @dev By default the admin role for all roles is `DEFAULT_ADMIN_ROLE`. * @param role The role to be managed by the admin role * @param adminRole The admin role */ function setRoleAdmin(bytes32 role, bytes32 adminRole) external; /** * @notice Adds a new admin as PoolAdmin * @param admin The address of the new admin */ function addPoolAdmin(address admin) external; /** * @notice Removes an admin as PoolAdmin * @param admin The address of the admin to remove */ function removePoolAdmin(address admin) external; /** * @notice Returns true if the address is PoolAdmin, false otherwise * @param admin The address to check * @return True if the given address is PoolAdmin, false otherwise */ function isPoolAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as EmergencyAdmin * @param admin The address of the new admin */ function addEmergencyAdmin(address admin) external; /** * @notice Removes an admin as EmergencyAdmin * @param admin The address of the admin to remove */ function removeEmergencyAdmin(address admin) external; /** * @notice Returns true if the address is EmergencyAdmin, false otherwise * @param admin The address to check * @return True if the given address is EmergencyAdmin, false otherwise */ function isEmergencyAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as RiskAdmin * @param admin The address of the new admin */ function addRiskAdmin(address admin) external; /** * @notice Removes an admin as RiskAdmin * @param admin The address of the admin to remove */ function removeRiskAdmin(address admin) external; /** * @notice Returns true if the address is RiskAdmin, false otherwise * @param admin The address to check * @return True if the given address is RiskAdmin, false otherwise */ function isRiskAdmin(address admin) external view returns (bool); /** * @notice Adds a new address as FlashBorrower * @param borrower The address of the new FlashBorrower */ function addFlashBorrower(address borrower) external; /** * @notice Removes an address as FlashBorrower * @param borrower The address of the FlashBorrower to remove */ function removeFlashBorrower(address borrower) external; /** * @notice Returns true if the address is FlashBorrower, false otherwise * @param borrower The address to check * @return True if the given address is FlashBorrower, false otherwise */ function isFlashBorrower(address borrower) external view returns (bool); /** * @notice Adds a new address as Bridge * @param bridge The address of the new Bridge */ function addBridge(address bridge) external; /** * @notice Removes an address as Bridge * @param bridge The address of the bridge to remove */ function removeBridge(address bridge) external; /** * @notice Returns true if the address is Bridge, false otherwise * @param bridge The address to check * @return True if the given address is Bridge, false otherwise */ function isBridge(address bridge) external view returns (bool); /** * @notice Adds a new admin as AssetListingAdmin * @param admin The address of the new admin */ function addAssetListingAdmin(address admin) external; /** * @notice Removes an admin as AssetListingAdmin * @param admin The address of the admin to remove */ function removeAssetListingAdmin(address admin) external; /** * @notice Returns true if the address is AssetListingAdmin, false otherwise * @param admin The address to check * @return True if the given address is AssetListingAdmin, false otherwise */ function isAssetListingAdmin(address admin) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IReserveInterestRateStrategy} from './IReserveInterestRateStrategy.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IDefaultInterestRateStrategyV2 * @author BGD Labs * @notice Interface of the default interest rate strategy used by the Aave protocol */ interface IDefaultInterestRateStrategyV2 is IReserveInterestRateStrategy { /** * @notice Holds the interest rate data for a given reserve * * @dev Since values are in bps, they are multiplied by 1e23 in order to become rays with 27 decimals. This * in turn means that the maximum supported interest rate is 4294967295 (2**32-1) bps or 42949672.95%. * * @param optimalUsageRatio The optimal usage ratio, in bps * @param baseVariableBorrowRate The base variable borrow rate, in bps * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps */ struct InterestRateData { uint16 optimalUsageRatio; uint32 baseVariableBorrowRate; uint32 variableRateSlope1; uint32 variableRateSlope2; } /** * @notice The interest rate data, where all values are in ray (fixed-point 27 decimal numbers) for a given reserve, * used in in-memory calculations. * * @param optimalUsageRatio The optimal usage ratio * @param baseVariableBorrowRate The base variable borrow rate * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio */ struct InterestRateDataRay { uint256 optimalUsageRatio; uint256 baseVariableBorrowRate; uint256 variableRateSlope1; uint256 variableRateSlope2; } /** * @notice emitted when new interest rate data is set in a reserve * * @param reserve address of the reserve that has new interest rate data set * @param optimalUsageRatio The optimal usage ratio, in bps * @param baseVariableBorrowRate The base variable borrow rate, in bps * @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal ratio, in bps * @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal ratio, in bps */ event RateDataUpdate( address indexed reserve, uint256 optimalUsageRatio, uint256 baseVariableBorrowRate, uint256 variableRateSlope1, uint256 variableRateSlope2 ); /** * @notice Returns the address of the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the maximum value achievable for variable borrow rate, in bps * @return The maximum rate */ function MAX_BORROW_RATE() external view returns (uint256); /** * @notice Returns the minimum optimal point, in bps * @return The optimal point */ function MIN_OPTIMAL_POINT() external view returns (uint256); /** * @notice Returns the maximum optimal point, in bps * @return The optimal point */ function MAX_OPTIMAL_POINT() external view returns (uint256); /** * notice Returns the full InterestRateData object for the given reserve, in ray * * @param reserve The reserve to get the data of * * @return The InterestRateDataRay object for the given reserve */ function getInterestRateData(address reserve) external view returns (InterestRateDataRay memory); /** * notice Returns the full InterestRateDataRay object for the given reserve, in bps * * @param reserve The reserve to get the data of * * @return The InterestRateData object for the given reserve */ function getInterestRateDataBps(address reserve) external view returns (InterestRateData memory); /** * @notice Returns the optimal usage rate for the given reserve in ray * * @param reserve The reserve to get the optimal usage rate of * * @return The optimal usage rate is the level of borrow / collateral at which the borrow rate */ function getOptimalUsageRatio(address reserve) external view returns (uint256); /** * @notice Returns the variable rate slope below optimal usage ratio in ray * @dev It's the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO * * @param reserve The reserve to get the variable rate slope 1 of * * @return The variable rate slope */ function getVariableRateSlope1(address reserve) external view returns (uint256); /** * @notice Returns the variable rate slope above optimal usage ratio in ray * @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO * * @param reserve The reserve to get the variable rate slope 2 of * * @return The variable rate slope */ function getVariableRateSlope2(address reserve) external view returns (uint256); /** * @notice Returns the base variable borrow rate, in ray * * @param reserve The reserve to get the base variable borrow rate of * * @return The base variable borrow rate */ function getBaseVariableBorrowRate(address reserve) external view returns (uint256); /** * @notice Returns the maximum variable borrow rate, in ray * * @param reserve The reserve to get the maximum variable borrow rate of * * @return The maximum variable borrow rate */ function getMaxVariableBorrowRate(address reserve) external view returns (uint256); /** * @notice Sets interest rate data for an Aave rate strategy * @param reserve The reserve to update * @param rateData The reserve interest rate data to apply to the given reserve * Being specific to this custom implementation, with custom struct type, * overloading the function on the generic interface */ function setInterestRateParams(address reserve, InterestRateData calldata rateData) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IPoolDataProvider} from '../interfaces/IPoolDataProvider.sol'; /** * @title AaveProtocolDataProvider * @author Aave * @notice Peripheral contract to collect and pre-process information from the Pool. */ contract AaveProtocolDataProvider is IPoolDataProvider { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using UserConfiguration for DataTypes.UserConfigurationMap; using WadRayMath for uint256; address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /// @inheritdoc IPoolDataProvider IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; /** * @notice Constructor * @param addressesProvider The address of the PoolAddressesProvider contract */ constructor(IPoolAddressesProvider addressesProvider) { ADDRESSES_PROVIDER = addressesProvider; } /// @inheritdoc IPoolDataProvider function getAllReservesTokens() external view override returns (TokenData[] memory) { IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); address[] memory reserves = pool.getReservesList(); TokenData[] memory reservesTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { if (reserves[i] == MKR) { reservesTokens[i] = TokenData({symbol: 'MKR', tokenAddress: reserves[i]}); continue; } if (reserves[i] == ETH) { reservesTokens[i] = TokenData({symbol: 'ETH', tokenAddress: reserves[i]}); continue; } reservesTokens[i] = TokenData({ symbol: IERC20Detailed(reserves[i]).symbol(), tokenAddress: reserves[i] }); } return reservesTokens; } /// @inheritdoc IPoolDataProvider function getAllATokens() external view override returns (TokenData[] memory) { IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { DataTypes.ReserveDataLegacy memory reserveData = pool.getReserveData(reserves[i]); aTokens[i] = TokenData({ symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(), tokenAddress: reserveData.aTokenAddress }); } return aTokens; } /// @inheritdoc IPoolDataProvider function getReserveConfigurationData( address asset ) external view override returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration .getParams(); (isActive, isFrozen, borrowingEnabled, ) = configuration.getFlags(); // @notice all stable debt related parameters deprecated in v3.2.0 stableBorrowRateEnabled = false; usageAsCollateralEnabled = liquidationThreshold != 0; } /// @inheritdoc IPoolDataProvider function getReserveCaps( address asset ) external view override returns (uint256 borrowCap, uint256 supplyCap) { (borrowCap, supplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps(); } /// @inheritdoc IPoolDataProvider function getPaused(address asset) external view override returns (bool isPaused) { (, , , isPaused) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getFlags(); } /// @inheritdoc IPoolDataProvider function getSiloedBorrowing(address asset) external view override returns (bool) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getSiloedBorrowing(); } /// @inheritdoc IPoolDataProvider function getLiquidationProtocolFee(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getLiquidationProtocolFee(); } /// @inheritdoc IPoolDataProvider function getUnbackedMintCap(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getUnbackedMintCap(); } /// @inheritdoc IPoolDataProvider function getDebtCeiling(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getDebtCeiling(); } /// @inheritdoc IPoolDataProvider function getDebtCeilingDecimals() external pure override returns (uint256) { return ReserveConfiguration.DEBT_CEILING_DECIMALS; } /// @inheritdoc IPoolDataProvider function getReserveData( address asset ) external view override returns ( uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256, uint256, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); // @notice all stable debt related parameters deprecated in v3.2.0 return ( reserve.unbacked, reserve.accruedToTreasury, IERC20Detailed(reserve.aTokenAddress).totalSupply(), 0, IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(), reserve.currentLiquidityRate, reserve.currentVariableBorrowRate, 0, 0, reserve.liquidityIndex, reserve.variableBorrowIndex, reserve.lastUpdateTimestamp ); } /// @inheritdoc IPoolDataProvider function getATokenTotalSupply(address asset) external view override returns (uint256) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); return IERC20Detailed(reserve.aTokenAddress).totalSupply(); } /// @inheritdoc IPoolDataProvider function getTotalDebt(address asset) external view override returns (uint256) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); return IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(); } /// @inheritdoc IPoolDataProvider function getUserReserveData( address asset, address user ) external view override returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); DataTypes.UserConfigurationMap memory userConfig = IPool(ADDRESSES_PROVIDER.getPool()) .getUserConfiguration(user); currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user); // @notice all stable debt related parameters deprecated in v3.2.0 currentStableDebt = principalStableDebt = stableBorrowRate = stableRateLastUpdated = 0; scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); liquidityRate = reserve.currentLiquidityRate; usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id); } /// @inheritdoc IPoolDataProvider function getReserveTokensAddresses( address asset ) external view override returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); // @notice all stable debt related parameters deprecated in v3.2.0 return (reserve.aTokenAddress, address(0), reserve.variableDebtTokenAddress); } /// @inheritdoc IPoolDataProvider function getInterestRateStrategyAddress( address asset ) external view override returns (address irStrategyAddress) { DataTypes.ReserveDataLegacy memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( asset ); return (reserve.interestRateStrategyAddress); } /// @inheritdoc IPoolDataProvider function getFlashLoanEnabled(address asset) external view override returns (bool) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); return configuration.getFlashLoanEnabled(); } /// @inheritdoc IPoolDataProvider function getIsVirtualAccActive(address asset) external view override returns (bool) { DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) .getConfiguration(asset); return configuration.getIsVirtualAccActive(); } /// @inheritdoc IPoolDataProvider function getVirtualUnderlyingBalance(address asset) external view override returns (uint256) { return IPool(ADDRESSES_PROVIDER.getPool()).getVirtualUnderlyingBalance(asset); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IAaveOracle} from '../interfaces/IAaveOracle.sol'; import {IAToken} from '../interfaces/IAToken.sol'; import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol'; import {AaveProtocolDataProvider} from './AaveProtocolDataProvider.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.sol'; import {IERC20DetailedBytes} from './interfaces/IERC20DetailedBytes.sol'; import {IUiPoolDataProviderV3} from './interfaces/IUiPoolDataProviderV3.sol'; contract UiPoolDataProviderV3 is IUiPoolDataProviderV3 { using WadRayMath for uint256; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using UserConfiguration for DataTypes.UserConfigurationMap; IEACAggregatorProxy public immutable networkBaseTokenPriceInUsdProxyAggregator; IEACAggregatorProxy public immutable marketReferenceCurrencyPriceInUsdProxyAggregator; uint256 public constant ETH_CURRENCY_UNIT = 1 ether; address public constant MKR_ADDRESS = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; constructor( IEACAggregatorProxy _networkBaseTokenPriceInUsdProxyAggregator, IEACAggregatorProxy _marketReferenceCurrencyPriceInUsdProxyAggregator ) { networkBaseTokenPriceInUsdProxyAggregator = _networkBaseTokenPriceInUsdProxyAggregator; marketReferenceCurrencyPriceInUsdProxyAggregator = _marketReferenceCurrencyPriceInUsdProxyAggregator; } function getReservesList( IPoolAddressesProvider provider ) external view override returns (address[] memory) { IPool pool = IPool(provider.getPool()); return pool.getReservesList(); } function getReservesData( IPoolAddressesProvider provider ) external view override returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory) { IAaveOracle oracle = IAaveOracle(provider.getPriceOracle()); IPool pool = IPool(provider.getPool()); AaveProtocolDataProvider poolDataProvider = AaveProtocolDataProvider( provider.getPoolDataProvider() ); address[] memory reserves = pool.getReservesList(); AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { AggregatedReserveData memory reserveData = reservesData[i]; reserveData.underlyingAsset = reserves[i]; // reserve current state DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData( reserveData.underlyingAsset ); //the liquidity index. Expressed in ray reserveData.liquidityIndex = baseData.liquidityIndex; //variable borrow index. Expressed in ray reserveData.variableBorrowIndex = baseData.variableBorrowIndex; //the current supply rate. Expressed in ray reserveData.liquidityRate = baseData.currentLiquidityRate; //the current variable borrow rate. Expressed in ray reserveData.variableBorrowRate = baseData.currentVariableBorrowRate; reserveData.lastUpdateTimestamp = baseData.lastUpdateTimestamp; reserveData.aTokenAddress = baseData.aTokenAddress; reserveData.variableDebtTokenAddress = baseData.variableDebtTokenAddress; //address of the interest rate strategy reserveData.interestRateStrategyAddress = baseData.interestRateStrategyAddress; reserveData.priceInMarketReferenceCurrency = oracle.getAssetPrice( reserveData.underlyingAsset ); reserveData.priceOracle = oracle.getSourceOfAsset(reserveData.underlyingAsset); reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf( reserveData.aTokenAddress ); reserveData.totalScaledVariableDebt = IVariableDebtToken(reserveData.variableDebtTokenAddress) .scaledTotalSupply(); // Due we take the symbol from underlying token we need a special case for $MKR as symbol() returns bytes32 if (address(reserveData.underlyingAsset) == address(MKR_ADDRESS)) { bytes32 symbol = IERC20DetailedBytes(reserveData.underlyingAsset).symbol(); bytes32 name = IERC20DetailedBytes(reserveData.underlyingAsset).name(); reserveData.symbol = bytes32ToString(symbol); reserveData.name = bytes32ToString(name); } else { reserveData.symbol = IERC20Detailed(reserveData.underlyingAsset).symbol(); reserveData.name = IERC20Detailed(reserveData.underlyingAsset).name(); } //stores the reserve configuration DataTypes.ReserveConfigurationMap memory reserveConfigurationMap = baseData.configuration; ( reserveData.baseLTVasCollateral, reserveData.reserveLiquidationThreshold, reserveData.reserveLiquidationBonus, reserveData.decimals, reserveData.reserveFactor ) = reserveConfigurationMap.getParams(); reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0; ( reserveData.isActive, reserveData.isFrozen, reserveData.borrowingEnabled, reserveData.isPaused ) = reserveConfigurationMap.getFlags(); // interest rates try IDefaultInterestRateStrategyV2(reserveData.interestRateStrategyAddress).getInterestRateData( reserveData.underlyingAsset ) returns (IDefaultInterestRateStrategyV2.InterestRateDataRay memory res) { reserveData.baseVariableBorrowRate = res.baseVariableBorrowRate; reserveData.variableRateSlope1 = res.variableRateSlope1; reserveData.variableRateSlope2 = res.variableRateSlope2; reserveData.optimalUsageRatio = res.optimalUsageRatio; } catch {} // v3 only reserveData.debtCeiling = reserveConfigurationMap.getDebtCeiling(); reserveData.debtCeilingDecimals = poolDataProvider.getDebtCeilingDecimals(); (reserveData.borrowCap, reserveData.supplyCap) = reserveConfigurationMap.getCaps(); try poolDataProvider.getFlashLoanEnabled(reserveData.underlyingAsset) returns ( bool flashLoanEnabled ) { reserveData.flashLoanEnabled = flashLoanEnabled; } catch (bytes memory) { reserveData.flashLoanEnabled = true; } reserveData.isSiloedBorrowing = reserveConfigurationMap.getSiloedBorrowing(); reserveData.unbacked = baseData.unbacked; reserveData.isolationModeTotalDebt = baseData.isolationModeTotalDebt; reserveData.accruedToTreasury = baseData.accruedToTreasury; reserveData.borrowableInIsolation = reserveConfigurationMap.getBorrowableInIsolation(); try poolDataProvider.getIsVirtualAccActive(reserveData.underlyingAsset) returns ( bool virtualAccActive ) { reserveData.virtualAccActive = virtualAccActive; } catch (bytes memory) { reserveData.virtualAccActive = false; } try pool.getVirtualUnderlyingBalance(reserveData.underlyingAsset) returns ( uint128 virtualUnderlyingBalance ) { reserveData.virtualUnderlyingBalance = virtualUnderlyingBalance; } catch (bytes memory) { reserveData.virtualUnderlyingBalance = 0; } } BaseCurrencyInfo memory baseCurrencyInfo; baseCurrencyInfo.networkBaseTokenPriceInUsd = networkBaseTokenPriceInUsdProxyAggregator .latestAnswer(); baseCurrencyInfo.networkBaseTokenPriceDecimals = networkBaseTokenPriceInUsdProxyAggregator .decimals(); try oracle.BASE_CURRENCY_UNIT() returns (uint256 baseCurrencyUnit) { baseCurrencyInfo.marketReferenceCurrencyUnit = baseCurrencyUnit; baseCurrencyInfo.marketReferenceCurrencyPriceInUsd = int256(baseCurrencyUnit); } catch (bytes memory /*lowLevelData*/) { baseCurrencyInfo.marketReferenceCurrencyUnit = ETH_CURRENCY_UNIT; baseCurrencyInfo .marketReferenceCurrencyPriceInUsd = marketReferenceCurrencyPriceInUsdProxyAggregator .latestAnswer(); } return (reservesData, baseCurrencyInfo); } /// @inheritdoc IUiPoolDataProviderV3 function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory) { IPool pool = IPool(provider.getPool()); Emode[] memory tempCategories = new Emode[](256); uint8 eModesFound = 0; uint8 missCounter = 0; for (uint8 i = 1; i < 256; i++) { DataTypes.CollateralConfig memory cfg = pool.getEModeCategoryCollateralConfig(i); if (cfg.liquidationThreshold != 0) { tempCategories[eModesFound] = Emode({ eMode: DataTypes.EModeCategory({ ltv: cfg.ltv, liquidationThreshold: cfg.liquidationThreshold, liquidationBonus: cfg.liquidationBonus, label: pool.getEModeCategoryLabel(i), collateralBitmap: pool.getEModeCategoryCollateralBitmap(i), borrowableBitmap: pool.getEModeCategoryBorrowableBitmap(i) }), id: i }); ++eModesFound; missCounter = 0; } else { ++missCounter; } // assumes there will never be a gap > 2 when setting eModes if (missCounter > 2) break; } Emode[] memory categories = new Emode[](eModesFound); for (uint8 i = 0; i < eModesFound; i++) { categories[i] = tempCategories[i]; } return categories; } function getUserReservesData( IPoolAddressesProvider provider, address user ) external view override returns (UserReserveData[] memory, uint8) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); DataTypes.UserConfigurationMap memory userConfig = pool.getUserConfiguration(user); uint8 userEmodeCategoryId = uint8(pool.getUserEMode(user)); UserReserveData[] memory userReservesData = new UserReserveData[]( user != address(0) ? reserves.length : 0 ); for (uint256 i = 0; i < reserves.length; i++) { DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // user reserve data userReservesData[i].underlyingAsset = reserves[i]; userReservesData[i].scaledATokenBalance = IAToken(baseData.aTokenAddress).scaledBalanceOf( user ); userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i); if (userConfig.isBorrowing(i)) { userReservesData[i].scaledVariableDebt = IVariableDebtToken( baseData.variableDebtTokenAddress ).scaledBalanceOf(user); } } return (userReservesData, userEmodeCategoryId); } function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) { uint8 i = 0; while (i < 32 && _bytes32[i] != 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 32 && _bytes32[i] != 0; i++) { bytesArray[i] = _bytes32[i]; } return string(bytesArray); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {IncentivizedERC20} from '../protocol/tokenization/base/IncentivizedERC20.sol'; import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IRewardsController} from '../rewards/interfaces/IRewardsController.sol'; import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.sol'; import {IUiIncentiveDataProviderV3} from './interfaces/IUiIncentiveDataProviderV3.sol'; contract UiIncentiveDataProviderV3 is IUiIncentiveDataProviderV3 { using UserConfiguration for DataTypes.UserConfigurationMap; function getFullReservesIncentiveData( IPoolAddressesProvider provider, address user ) external view override returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory) { return (_getReservesIncentivesData(provider), _getUserReservesIncentivesData(provider, user)); } function getReservesIncentivesData( IPoolAddressesProvider provider ) external view override returns (AggregatedReserveIncentiveData[] memory) { return _getReservesIncentivesData(provider); } function _getReservesIncentivesData( IPoolAddressesProvider provider ) private view returns (AggregatedReserveIncentiveData[] memory) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); AggregatedReserveIncentiveData[] memory reservesIncentiveData = new AggregatedReserveIncentiveData[](reserves.length); // Iterate through the reserves to get all the information from the (a/s/v) Tokens for (uint256 i = 0; i < reserves.length; i++) { AggregatedReserveIncentiveData memory reserveIncentiveData = reservesIncentiveData[i]; reserveIncentiveData.underlyingAsset = reserves[i]; DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // Get aTokens rewards information IRewardsController aTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.aTokenAddress).getIncentivesController()) ); RewardInfo[] memory aRewardsInformation; if (address(aTokenIncentiveController) != address(0)) { address[] memory aTokenRewardAddresses = aTokenIncentiveController.getRewardsByAsset( baseData.aTokenAddress ); aRewardsInformation = new RewardInfo[](aTokenRewardAddresses.length); for (uint256 j = 0; j < aTokenRewardAddresses.length; ++j) { RewardInfo memory rewardInformation; rewardInformation.rewardTokenAddress = aTokenRewardAddresses[j]; ( rewardInformation.tokenIncentivesIndex, rewardInformation.emissionPerSecond, rewardInformation.incentivesLastUpdateTimestamp, rewardInformation.emissionEndTimestamp ) = aTokenIncentiveController.getRewardsData( baseData.aTokenAddress, rewardInformation.rewardTokenAddress ); rewardInformation.precision = aTokenIncentiveController.getAssetDecimals( baseData.aTokenAddress ); rewardInformation.rewardTokenDecimals = IERC20Detailed( rewardInformation.rewardTokenAddress ).decimals(); rewardInformation.rewardTokenSymbol = IERC20Detailed(rewardInformation.rewardTokenAddress) .symbol(); // Get price of reward token from Chainlink Proxy Oracle rewardInformation.rewardOracleAddress = aTokenIncentiveController.getRewardOracle( rewardInformation.rewardTokenAddress ); rewardInformation.priceFeedDecimals = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).latestAnswer(); aRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.aIncentiveData = IncentiveData( baseData.aTokenAddress, address(aTokenIncentiveController), aRewardsInformation ); // Get vTokens rewards information IRewardsController vTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.variableDebtTokenAddress).getIncentivesController()) ); RewardInfo[] memory vRewardsInformation; if (address(vTokenIncentiveController) != address(0)) { address[] memory vTokenRewardAddresses = vTokenIncentiveController.getRewardsByAsset( baseData.variableDebtTokenAddress ); vRewardsInformation = new RewardInfo[](vTokenRewardAddresses.length); for (uint256 j = 0; j < vTokenRewardAddresses.length; ++j) { RewardInfo memory rewardInformation; rewardInformation.rewardTokenAddress = vTokenRewardAddresses[j]; ( rewardInformation.tokenIncentivesIndex, rewardInformation.emissionPerSecond, rewardInformation.incentivesLastUpdateTimestamp, rewardInformation.emissionEndTimestamp ) = vTokenIncentiveController.getRewardsData( baseData.variableDebtTokenAddress, rewardInformation.rewardTokenAddress ); rewardInformation.precision = vTokenIncentiveController.getAssetDecimals( baseData.variableDebtTokenAddress ); rewardInformation.rewardTokenDecimals = IERC20Detailed( rewardInformation.rewardTokenAddress ).decimals(); rewardInformation.rewardTokenSymbol = IERC20Detailed(rewardInformation.rewardTokenAddress) .symbol(); // Get price of reward token from Chainlink Proxy Oracle rewardInformation.rewardOracleAddress = vTokenIncentiveController.getRewardOracle( rewardInformation.rewardTokenAddress ); rewardInformation.priceFeedDecimals = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).decimals(); rewardInformation.rewardPriceFeed = IEACAggregatorProxy( rewardInformation.rewardOracleAddress ).latestAnswer(); vRewardsInformation[j] = rewardInformation; } } reserveIncentiveData.vIncentiveData = IncentiveData( baseData.variableDebtTokenAddress, address(vTokenIncentiveController), vRewardsInformation ); } return (reservesIncentiveData); } function getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) external view override returns (UserReserveIncentiveData[] memory) { return _getUserReservesIncentivesData(provider, user); } function _getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) private view returns (UserReserveIncentiveData[] memory) { IPool pool = IPool(provider.getPool()); address[] memory reserves = pool.getReservesList(); UserReserveIncentiveData[] memory userReservesIncentivesData = new UserReserveIncentiveData[]( user != address(0) ? reserves.length : 0 ); for (uint256 i = 0; i < reserves.length; i++) { DataTypes.ReserveDataLegacy memory baseData = pool.getReserveData(reserves[i]); // user reserve data userReservesIncentivesData[i].underlyingAsset = reserves[i]; IRewardsController aTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.aTokenAddress).getIncentivesController()) ); if (address(aTokenIncentiveController) != address(0)) { // get all rewards information from the asset address[] memory aTokenRewardAddresses = aTokenIncentiveController.getRewardsByAsset( baseData.aTokenAddress ); UserRewardInfo[] memory aUserRewardsInformation = new UserRewardInfo[]( aTokenRewardAddresses.length ); for (uint256 j = 0; j < aTokenRewardAddresses.length; ++j) { UserRewardInfo memory userRewardInformation; userRewardInformation.rewardTokenAddress = aTokenRewardAddresses[j]; userRewardInformation.tokenIncentivesUserIndex = aTokenIncentiveController .getUserAssetIndex( user, baseData.aTokenAddress, userRewardInformation.rewardTokenAddress ); userRewardInformation.userUnclaimedRewards = aTokenIncentiveController .getUserAccruedRewards(user, userRewardInformation.rewardTokenAddress); userRewardInformation.rewardTokenDecimals = IERC20Detailed( userRewardInformation.rewardTokenAddress ).decimals(); userRewardInformation.rewardTokenSymbol = IERC20Detailed( userRewardInformation.rewardTokenAddress ).symbol(); // Get price of reward token from Chainlink Proxy Oracle userRewardInformation.rewardOracleAddress = aTokenIncentiveController.getRewardOracle( userRewardInformation.rewardTokenAddress ); userRewardInformation.priceFeedDecimals = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).latestAnswer(); aUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].aTokenIncentivesUserData = UserIncentiveData( baseData.aTokenAddress, address(aTokenIncentiveController), aUserRewardsInformation ); } // variable debt token IRewardsController vTokenIncentiveController = IRewardsController( address(IncentivizedERC20(baseData.variableDebtTokenAddress).getIncentivesController()) ); if (address(vTokenIncentiveController) != address(0)) { // get all rewards information from the asset address[] memory vTokenRewardAddresses = vTokenIncentiveController.getRewardsByAsset( baseData.variableDebtTokenAddress ); UserRewardInfo[] memory vUserRewardsInformation = new UserRewardInfo[]( vTokenRewardAddresses.length ); for (uint256 j = 0; j < vTokenRewardAddresses.length; ++j) { UserRewardInfo memory userRewardInformation; userRewardInformation.rewardTokenAddress = vTokenRewardAddresses[j]; userRewardInformation.tokenIncentivesUserIndex = vTokenIncentiveController .getUserAssetIndex( user, baseData.variableDebtTokenAddress, userRewardInformation.rewardTokenAddress ); userRewardInformation.userUnclaimedRewards = vTokenIncentiveController .getUserAccruedRewards(user, userRewardInformation.rewardTokenAddress); userRewardInformation.rewardTokenDecimals = IERC20Detailed( userRewardInformation.rewardTokenAddress ).decimals(); userRewardInformation.rewardTokenSymbol = IERC20Detailed( userRewardInformation.rewardTokenAddress ).symbol(); // Get price of reward token from Chainlink Proxy Oracle userRewardInformation.rewardOracleAddress = vTokenIncentiveController.getRewardOracle( userRewardInformation.rewardTokenAddress ); userRewardInformation.priceFeedDecimals = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).decimals(); userRewardInformation.rewardPriceFeed = IEACAggregatorProxy( userRewardInformation.rewardOracleAddress ).latestAnswer(); vUserRewardsInformation[j] = userRewardInformation; } userReservesIncentivesData[i].vTokenIncentivesUserData = UserIncentiveData( baseData.variableDebtTokenAddress, address(aTokenIncentiveController), vUserRewardsInformation ); } } return (userReservesIncentivesData); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; import {RewardsDataTypes} from '../libraries/RewardsDataTypes.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; import {IRewardsController} from './IRewardsController.sol'; /** * @title IEmissionManager * @author Aave * @notice Defines the basic interface for the Emission Manager */ interface IEmissionManager { /** * @dev Emitted when the admin of a reward emission is updated. * @param reward The address of the rewarding token * @param oldAdmin The address of the old emission admin * @param newAdmin The address of the new emission admin */ event EmissionAdminUpdated( address indexed reward, address indexed oldAdmin, address indexed newAdmin ); /** * @dev Configure assets to incentivize with an emission of rewards per second until the end of distribution. * @dev Only callable by the emission admin of the given rewards * @param config The assets configuration input, the list of structs contains the following fields: * uint104 emissionPerSecond: The emission per second following rewards unit decimals. * uint256 totalSupply: The total supply of the asset to incentivize * uint40 distributionEnd: The end of the distribution of the incentives for an asset * address asset: The asset address to incentivize * address reward: The reward token address * ITransferStrategy transferStrategy: The TransferStrategy address with the install hook and claim logic. * IEACAggregatorProxy rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend. * Must follow Chainlink Aggregator IEACAggregatorProxy interface to be compatible. */ function configureAssets(RewardsDataTypes.RewardsConfigInput[] memory config) external; /** * @dev Sets a TransferStrategy logic contract that determines the logic of the rewards transfer * @dev Only callable by the emission admin of the given reward * @param reward The address of the reward token * @param transferStrategy The address of the TransferStrategy logic contract */ function setTransferStrategy(address reward, ITransferStrategyBase transferStrategy) external; /** * @dev Sets an Aave Oracle contract to enforce rewards with a source of value. * @dev Only callable by the emission admin of the given reward * @notice At the moment of reward configuration, the Incentives Controller performs * a check to see if the reward asset oracle is compatible with IEACAggregator proxy. * This check is enforced for integrators to be able to show incentives at * the current Aave UI without the need to setup an external price registry * @param reward The address of the reward to set the price aggregator * @param rewardOracle The address of price aggregator that follows IEACAggregatorProxy interface */ function setRewardOracle(address reward, IEACAggregatorProxy rewardOracle) external; /** * @dev Sets the end date for the distribution * @dev Only callable by the emission admin of the given reward * @param asset The asset to incentivize * @param reward The reward token that incentives the asset * @param newDistributionEnd The end date of the incentivization, in unix time format **/ function setDistributionEnd(address asset, address reward, uint32 newDistributionEnd) external; /** * @dev Sets the emission per second of a set of reward distributions * @param asset The asset is being incentivized * @param rewards List of reward addresses are being distributed * @param newEmissionsPerSecond List of new reward emissions per second */ function setEmissionPerSecond( address asset, address[] calldata rewards, uint88[] calldata newEmissionsPerSecond ) external; /** * @dev Whitelists an address to claim the rewards on behalf of another address * @dev Only callable by the owner of the EmissionManager * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Updates the admin of the reward emission * @dev Only callable by the owner of the EmissionManager * @param reward The address of the reward token * @param admin The address of the new admin of the emission */ function setEmissionAdmin(address reward, address admin) external; /** * @dev Updates the address of the rewards controller * @dev Only callable by the owner of the EmissionManager * @param controller the address of the RewardsController contract */ function setRewardsController(address controller) external; /** * @dev Returns the rewards controller address * @return The address of the RewardsController contract */ function getRewardsController() external view returns (IRewardsController); /** * @dev Returns the admin of the given reward emission * @param reward The address of the reward token * @return The address of the emission admin */ function getEmissionAdmin(address reward) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IRewardsDistributor} from './IRewardsDistributor.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; import {RewardsDataTypes} from '../libraries/RewardsDataTypes.sol'; /** * @title IRewardsController * @author Aave * @notice Defines the basic interface for a Rewards Controller. */ interface IRewardsController is IRewardsDistributor { /** * @dev Emitted when a new address is whitelisted as claimer of rewards on behalf of a user * @param user The address of the user * @param claimer The address of the claimer */ event ClaimerSet(address indexed user, address indexed claimer); /** * @dev Emitted when rewards are claimed * @param user The address of the user rewards has been claimed on behalf of * @param reward The address of the token reward is claimed * @param to The address of the receiver of the rewards * @param claimer The address of the claimer * @param amount The amount of rewards claimed */ event RewardsClaimed( address indexed user, address indexed reward, address indexed to, address claimer, uint256 amount ); /** * @dev Emitted when a transfer strategy is installed for the reward distribution * @param reward The address of the token reward * @param transferStrategy The address of TransferStrategy contract */ event TransferStrategyInstalled(address indexed reward, address indexed transferStrategy); /** * @dev Emitted when the reward oracle is updated * @param reward The address of the token reward * @param rewardOracle The address of oracle */ event RewardOracleUpdated(address indexed reward, address indexed rewardOracle); /** * @dev Whitelists an address to claim the rewards on behalf of another address * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Sets a TransferStrategy logic contract that determines the logic of the rewards transfer * @param reward The address of the reward token * @param transferStrategy The address of the TransferStrategy logic contract */ function setTransferStrategy(address reward, ITransferStrategyBase transferStrategy) external; /** * @dev Sets an Aave Oracle contract to enforce rewards with a source of value. * @notice At the moment of reward configuration, the Incentives Controller performs * a check to see if the reward asset oracle is compatible with IEACAggregator proxy. * This check is enforced for integrators to be able to show incentives at * the current Aave UI without the need to setup an external price registry * @param reward The address of the reward to set the price aggregator * @param rewardOracle The address of price aggregator that follows IEACAggregatorProxy interface */ function setRewardOracle(address reward, IEACAggregatorProxy rewardOracle) external; /** * @dev Get the price aggregator oracle address * @param reward The address of the reward * @return The price oracle of the reward */ function getRewardOracle(address reward) external view returns (address); /** * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) * @param user The address of the user * @return The claimer address */ function getClaimer(address user) external view returns (address); /** * @dev Returns the Transfer Strategy implementation contract address being used for a reward address * @param reward The address of the reward * @return The address of the TransferStrategy contract */ function getTransferStrategy(address reward) external view returns (address); /** * @dev Configure assets to incentivize with an emission of rewards per second until the end of distribution. * @param config The assets configuration input, the list of structs contains the following fields: * uint104 emissionPerSecond: The emission per second following rewards unit decimals. * uint256 totalSupply: The total supply of the asset to incentivize * uint40 distributionEnd: The end of the distribution of the incentives for an asset * address asset: The asset address to incentivize * address reward: The reward token address * ITransferStrategy transferStrategy: The TransferStrategy address with the install hook and claim logic. * IEACAggregatorProxy rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend. * Must follow Chainlink Aggregator IEACAggregatorProxy interface to be compatible. */ function configureAssets(RewardsDataTypes.RewardsConfigInput[] memory config) external; /** * @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution. * @dev The units of `totalSupply` and `userBalance` should be the same. * @param user The address of the user whose asset balance has changed * @param totalSupply The total supply of the asset prior to user balance change * @param userBalance The previous user balance prior to balance change **/ function handleAction(address user, uint256 totalSupply, uint256 userBalance) external; /** * @dev Claims reward for a user to the desired address, on all the assets of the pool, accumulating the pending rewards * @param assets List of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param to The address that will be receiving the rewards * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to, address reward ) external returns (uint256); /** * @dev Claims reward for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The * caller must be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param assets The list of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param user The address to check and claim rewards * @param to The address that will be receiving the rewards * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to, address reward ) external returns (uint256); /** * @dev Claims reward for msg.sender, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @param amount The amount of rewards to claim * @param reward The address of the reward token * @return The amount of rewards claimed **/ function claimRewardsToSelf( address[] calldata assets, uint256 amount, address reward ) external returns (uint256); /** * @dev Claims all rewards for a user to the desired address, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @param to The address that will be receiving the rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardList" **/ function claimAllRewards( address[] calldata assets, address to ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); /** * @dev Claims all rewards for a user on behalf, on all the assets of the pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param assets The list of assets to check eligible distributions before claiming rewards * @param user The address to check and claim rewards * @param to The address that will be receiving the rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList" **/ function claimAllRewardsOnBehalf( address[] calldata assets, address user, address to ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); /** * @dev Claims all reward for msg.sender, on all the assets of the pool, accumulating the pending rewards * @param assets The list of assets to check eligible distributions before claiming rewards * @return rewardsList List of addresses of the reward tokens * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList" **/ function claimAllRewardsToSelf( address[] calldata assets ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {Address} from '../dependencies/openzeppelin/contracts/Address.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../interfaces/IPool.sol'; import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title WalletBalanceProvider contract * @author Aave, influenced by https://github.com/wbobeirne/eth-balance-checker/blob/master/contracts/BalanceChecker.sol * @notice Implements a logic of getting multiple tokens balance for one user address * @dev NOTE: THIS CONTRACT IS NOT USED WITHIN THE AAVE PROTOCOL. It's an accessory contract used to reduce the number of calls * towards the blockchain from the Aave backend. **/ contract WalletBalanceProvider { using Address for address payable; using Address for address; using GPv2SafeERC20 for IERC20; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /** @dev Fallback function, don't accept any ETH **/ receive() external payable { //only contracts can send ETH to the core require(msg.sender.isContract(), '22'); } /** @dev Check the token balance of a wallet in a token contract Returns the balance of the token for user. Avoids possible errors: - return 0 on non-contract address **/ function balanceOf(address user, address token) public view returns (uint256) { if (token == MOCK_ETH_ADDRESS) { return user.balance; // ETH balance // check if token is actually a contract } else if (token.isContract()) { return IERC20(token).balanceOf(user); } revert('INVALID_TOKEN'); } /** * @notice Fetches, for a list of _users and _tokens (ETH included with mock address), the balances * @param users The list of users * @param tokens The list of tokens * @return And array with the concatenation of, for each user, his/her balances **/ function batchBalanceOf( address[] calldata users, address[] calldata tokens ) external view returns (uint256[] memory) { uint256[] memory balances = new uint256[](users.length * tokens.length); for (uint256 i = 0; i < users.length; i++) { for (uint256 j = 0; j < tokens.length; j++) { balances[i * tokens.length + j] = balanceOf(users[i], tokens[j]); } } return balances; } /** @dev provides balances of user wallet for all reserves available on the pool */ function getUserWalletBalances( address provider, address user ) external view returns (address[] memory, uint256[] memory) { IPool pool = IPool(IPoolAddressesProvider(provider).getPool()); address[] memory reserves = pool.getReservesList(); address[] memory reservesWithEth = new address[](reserves.length + 1); for (uint256 i = 0; i < reserves.length; i++) { reservesWithEth[i] = reserves[i]; } reservesWithEth[reserves.length] = MOCK_ETH_ADDRESS; uint256[] memory balances = new uint256[](reservesWithEth.length); for (uint256 j = 0; j < reserves.length; j++) { DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration( reservesWithEth[j] ); (bool isActive, , , ) = configuration.getFlags(); if (!isActive) { balances[j] = 0; continue; } balances[j] = balanceOf(user, reservesWithEth[j]); } balances[reserves.length] = balanceOf(user, MOCK_ETH_ADDRESS); return (reservesWithEth, balances); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol'; /** * @title ParaSwapLiquiditySwapAdapter * @notice Adapter to swap liquidity using ParaSwap. * @author Jason Raymond Bell */ contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20Detailed; constructor( IPoolAddressesProvider addressesProvider, IParaSwapAugustusRegistry augustusRegistry, address owner ) BaseParaSwapSellAdapter(addressesProvider, augustusRegistry) { transferOwnership(owner); } /** * @dev Swaps the received reserve amount from the flash loan into the asset specified in the params. * The received funds from the swap are then deposited into the protocol on behalf of the user. * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and repay the flash loan. * @param asset The address of the flash-borrowed asset * @param amount The amount of the flash-borrowed asset * @param premium The fee of the flash-borrowed asset * @param initiator The address of the flashloan initiator * @param params The byte-encoded params passed when initiating the flashloan * @return True if the execution of the operation succeeds, false otherwise * address assetToSwapTo Address of the underlying asset to be swapped to and deposited * uint256 minAmountToReceive Min amount to be received from the swap * uint256 swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0 * bytes swapCalldata Calldata for ParaSwap's AugustusSwapper contract * address augustus Address of ParaSwap's AugustusSwapper contract * PermitSignature permitParams Struct containing the permit signatures, set to all zeroes if not used */ function executeOperation( address asset, uint256 amount, uint256 premium, address initiator, bytes calldata params ) external override nonReentrant returns (bool) { require(msg.sender == address(POOL), 'CALLER_MUST_BE_POOL'); uint256 flashLoanAmount = amount; uint256 premiumLocal = premium; address initiatorLocal = initiator; IERC20Detailed assetToSwapFrom = IERC20Detailed(asset); ( IERC20Detailed assetToSwapTo, uint256 minAmountToReceive, uint256 swapAllBalanceOffset, bytes memory swapCalldata, IParaSwapAugustus augustus, PermitSignature memory permitParams ) = abi.decode( params, (IERC20Detailed, uint256, uint256, bytes, IParaSwapAugustus, PermitSignature) ); _swapLiquidity( swapAllBalanceOffset, swapCalldata, augustus, permitParams, flashLoanAmount, premiumLocal, initiatorLocal, assetToSwapFrom, assetToSwapTo, minAmountToReceive ); return true; } /** * @dev Swaps an amount of an asset to another and deposits the new asset amount on behalf of the user without using a flash loan. * This method can be used when the temporary transfer of the collateral asset to this contract does not affect the user position. * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and perform the swap. * @param assetToSwapFrom Address of the underlying asset to be swapped from * @param assetToSwapTo Address of the underlying asset to be swapped to and deposited * @param amountToSwap Amount to be swapped, or maximum amount when swapping all balance * @param minAmountToReceive Minimum amount to be received from the swap * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0 * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract * @param augustus Address of ParaSwap's AugustusSwapper contract * @param permitParams Struct containing the permit signatures, set to all zeroes if not used */ function swapAndDeposit( IERC20Detailed assetToSwapFrom, IERC20Detailed assetToSwapTo, uint256 amountToSwap, uint256 minAmountToReceive, uint256 swapAllBalanceOffset, bytes calldata swapCalldata, IParaSwapAugustus augustus, PermitSignature calldata permitParams ) external nonReentrant { IERC20WithPermit aToken = IERC20WithPermit( _getReserveData(address(assetToSwapFrom)).aTokenAddress ); if (swapAllBalanceOffset != 0) { uint256 balance = aToken.balanceOf(msg.sender); require(balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP'); amountToSwap = balance; } _pullATokenAndWithdraw( address(assetToSwapFrom), aToken, msg.sender, amountToSwap, permitParams ); uint256 amountReceived = _sellOnParaSwap( swapAllBalanceOffset, swapCalldata, augustus, assetToSwapFrom, assetToSwapTo, amountToSwap, minAmountToReceive ); assetToSwapTo.safeApprove(address(POOL), 0); assetToSwapTo.safeApprove(address(POOL), amountReceived); POOL.deposit(address(assetToSwapTo), amountReceived, msg.sender, 0); } /** * @dev Swaps an amount of an asset to another and deposits the funds on behalf of the initiator. * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0 * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract * @param augustus Address of ParaSwap's AugustusSwapper contract * @param permitParams Struct containing the permit signatures, set to all zeroes if not used * @param flashLoanAmount Amount of the flash loan i.e. maximum amount to swap * @param premium Fee of the flash loan * @param initiator Account that initiated the flash loan * @param assetToSwapFrom Address of the underyling asset to be swapped from * @param assetToSwapTo Address of the underlying asset to be swapped to and deposited * @param minAmountToReceive Min amount to be received from the swap */ function _swapLiquidity( uint256 swapAllBalanceOffset, bytes memory swapCalldata, IParaSwapAugustus augustus, PermitSignature memory permitParams, uint256 flashLoanAmount, uint256 premium, address initiator, IERC20Detailed assetToSwapFrom, IERC20Detailed assetToSwapTo, uint256 minAmountToReceive ) internal { IERC20WithPermit aToken = IERC20WithPermit( _getReserveData(address(assetToSwapFrom)).aTokenAddress ); uint256 amountToSwap = flashLoanAmount; uint256 balance = aToken.balanceOf(initiator); if (swapAllBalanceOffset != 0) { uint256 balanceToSwap = balance.sub(premium); require(balanceToSwap <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP'); amountToSwap = balanceToSwap; } else { require(balance >= amountToSwap.add(premium), 'INSUFFICIENT_ATOKEN_BALANCE'); } uint256 amountReceived = _sellOnParaSwap( swapAllBalanceOffset, swapCalldata, augustus, assetToSwapFrom, assetToSwapTo, amountToSwap, minAmountToReceive ); assetToSwapTo.safeApprove(address(POOL), 0); assetToSwapTo.safeApprove(address(POOL), amountReceived); POOL.deposit(address(assetToSwapTo), amountReceived, initiator, 0); _pullATokenAndWithdraw( address(assetToSwapFrom), aToken, initiator, amountToSwap.add(premium), permitParams ); // Repay flash loan assetToSwapFrom.safeApprove(address(POOL), 0); assetToSwapFrom.safeApprove(address(POOL), flashLoanAmount.add(premium)); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {BaseParaSwapBuyAdapter} from './BaseParaSwapBuyAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol'; /** * @title ParaSwapRepayAdapter * @notice ParaSwap Adapter to perform a repay of a debt with collateral. * @author Aave **/ contract ParaSwapRepayAdapter is BaseParaSwapBuyAdapter, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; struct RepayParams { address collateralAsset; uint256 collateralAmount; uint256 rateMode; PermitSignature permitSignature; bool useEthPath; } constructor( IPoolAddressesProvider addressesProvider, IParaSwapAugustusRegistry augustusRegistry, address owner ) BaseParaSwapBuyAdapter(addressesProvider, augustusRegistry) { transferOwnership(owner); } /** * @dev Uses the received funds from the flash loan to repay a debt on the protocol on behalf of the user. Then pulls * the collateral from the user and swaps it to the debt asset to repay the flash loan. * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset, swap it * and repay the flash loan. * Supports only one asset on the flash loan. * @param asset The address of the flash-borrowed asset * @param amount The amount of the flash-borrowed asset * @param premium The fee of the flash-borrowed asset * @param initiator The address of the flashloan initiator * @param params The byte-encoded params passed when initiating the flashloan * @return True if the execution of the operation succeeds, false otherwise * IERC20Detailed debtAsset Address of the debt asset * uint256 debtAmount Amount of debt to be repaid * uint256 rateMode Rate modes of the debt to be repaid * uint256 deadline Deadline for the permit signature * uint256 debtRateMode Rate mode of the debt to be repaid * bytes paraswapData Paraswap Data * * bytes buyCallData Call data for augustus * * IParaSwapAugustus augustus Address of Augustus Swapper * PermitSignature permitParams Struct containing the permit signatures, set to all zeroes if not used */ function executeOperation( address asset, uint256 amount, uint256 premium, address initiator, bytes calldata params ) external override nonReentrant returns (bool) { require(msg.sender == address(POOL), 'CALLER_MUST_BE_POOL'); uint256 collateralAmount = amount; address initiatorLocal = initiator; IERC20Detailed collateralAsset = IERC20Detailed(asset); _swapAndRepay(params, premium, initiatorLocal, collateralAsset, collateralAmount); return true; } /** * @dev Swaps the user collateral for the debt asset and then repay the debt on the protocol on behalf of the user * without using flash loans. This method can be used when the temporary transfer of the collateral asset to this * contract does not affect the user position. * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset * @param collateralAsset Address of asset to be swapped * @param debtAsset Address of debt asset * @param collateralAmount max Amount of the collateral to be swapped * @param debtRepayAmount Amount of the debt to be repaid, or maximum amount when repaying entire debt * @param debtRateMode Rate mode of the debt to be repaid * @param buyAllBalanceOffset Set to offset of toAmount in Augustus calldata if wanting to pay entire debt, otherwise 0 * @param paraswapData Data for Paraswap Adapter * @param permitSignature struct containing the permit signature */ function swapAndRepay( IERC20Detailed collateralAsset, IERC20Detailed debtAsset, uint256 collateralAmount, uint256 debtRepayAmount, uint256 debtRateMode, uint256 buyAllBalanceOffset, bytes calldata paraswapData, PermitSignature calldata permitSignature ) external nonReentrant { debtRepayAmount = getDebtRepayAmount( debtAsset, debtRateMode, buyAllBalanceOffset, debtRepayAmount, msg.sender ); // Pull aTokens from user _pullATokenAndWithdraw(address(collateralAsset), msg.sender, collateralAmount, permitSignature); //buy debt asset using collateral asset (uint256 amountSold, uint256 amountBought) = _buyOnParaSwap( buyAllBalanceOffset, paraswapData, collateralAsset, debtAsset, collateralAmount, debtRepayAmount ); uint256 collateralBalanceLeft = collateralAmount - amountSold; //deposit collateral back in the pool, if left after the swap(buy) if (collateralBalanceLeft > 0) { IERC20(collateralAsset).safeApprove(address(POOL), collateralBalanceLeft); POOL.deposit(address(collateralAsset), collateralBalanceLeft, msg.sender, 0); IERC20(collateralAsset).safeApprove(address(POOL), 0); } // Repay debt. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount); POOL.repay(address(debtAsset), debtRepayAmount, debtRateMode, msg.sender); IERC20(debtAsset).safeApprove(address(POOL), 0); { //transfer excess of debtAsset back to the user, if any uint256 debtAssetExcess = amountBought - debtRepayAmount; if (debtAssetExcess > 0) { IERC20(debtAsset).safeTransfer(msg.sender, debtAssetExcess); } } } /** * @dev Perform the repay of the debt, pulls the initiator collateral and swaps to repay the flash loan * @param premium Fee of the flash loan * @param initiator Address of the user * @param collateralAsset Address of token to be swapped * @param collateralAmount Amount of the reserve to be swapped(flash loan amount) */ function _swapAndRepay( bytes calldata params, uint256 premium, address initiator, IERC20Detailed collateralAsset, uint256 collateralAmount ) private { ( IERC20Detailed debtAsset, uint256 debtRepayAmount, uint256 buyAllBalanceOffset, uint256 rateMode, bytes memory paraswapData, PermitSignature memory permitSignature ) = abi.decode(params, (IERC20Detailed, uint256, uint256, uint256, bytes, PermitSignature)); debtRepayAmount = getDebtRepayAmount( debtAsset, rateMode, buyAllBalanceOffset, debtRepayAmount, initiator ); (uint256 amountSold, uint256 amountBought) = _buyOnParaSwap( buyAllBalanceOffset, paraswapData, collateralAsset, debtAsset, collateralAmount, debtRepayAmount ); // Repay debt. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix. IERC20(debtAsset).safeApprove(address(POOL), debtRepayAmount); POOL.repay(address(debtAsset), debtRepayAmount, rateMode, initiator); IERC20(debtAsset).safeApprove(address(POOL), 0); uint256 neededForFlashLoanRepay = amountSold.add(premium); // Pull aTokens from user _pullATokenAndWithdraw( address(collateralAsset), initiator, neededForFlashLoanRepay, permitSignature ); { //transfer excess of debtAsset back to the user, if any uint256 debtAssetExcess = amountBought - debtRepayAmount; if (debtAssetExcess > 0) { IERC20(debtAsset).safeTransfer(initiator, debtAssetExcess); } } // Repay flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix. IERC20(collateralAsset).safeApprove(address(POOL), 0); IERC20(collateralAsset).safeApprove(address(POOL), collateralAmount.add(premium)); } function getDebtRepayAmount( IERC20Detailed debtAsset, uint256 rateMode, uint256 buyAllBalanceOffset, uint256 debtRepayAmount, address initiator ) private view returns (uint256) { require( DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE, 'INVALID_RATE_MODE' ); DataTypes.ReserveDataLegacy memory debtReserveData = _getReserveData(address(debtAsset)); uint256 currentDebt = IERC20(debtReserveData.variableDebtTokenAddress).balanceOf(initiator); if (buyAllBalanceOffset != 0) { require(currentDebt <= debtRepayAmount, 'INSUFFICIENT_AMOUNT_TO_REPAY'); debtRepayAmount = currentDebt; } else { require(debtRepayAmount <= currentDebt, 'INVALID_DEBT_REPAY_AMOUNT'); } return debtRepayAmount; } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol'; contract ParaSwapWithdrawSwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuard { using SafeERC20 for IERC20Detailed; constructor( IPoolAddressesProvider addressesProvider, IParaSwapAugustusRegistry augustusRegistry, address owner ) BaseParaSwapSellAdapter(addressesProvider, augustusRegistry) { transferOwnership(owner); } function executeOperation( address, uint256, uint256, address, bytes calldata ) external override nonReentrant returns (bool) { revert('NOT_SUPPORTED'); } /** * @dev Swaps an amount of an asset to another after a withdraw and transfers the new asset to the user. * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and perform the swap. * @param assetToSwapFrom Address of the underlying asset to be swapped from * @param assetToSwapTo Address of the underlying asset to be swapped to * @param amountToSwap Amount to be swapped, or maximum amount when swapping all balance * @param minAmountToReceive Minimum amount to be received from the swap * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0 * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract * @param augustus Address of ParaSwap's AugustusSwapper contract * @param permitParams Struct containing the permit signatures, set to all zeroes if not used */ function withdrawAndSwap( IERC20Detailed assetToSwapFrom, IERC20Detailed assetToSwapTo, uint256 amountToSwap, uint256 minAmountToReceive, uint256 swapAllBalanceOffset, bytes calldata swapCalldata, IParaSwapAugustus augustus, PermitSignature calldata permitParams ) external nonReentrant { IERC20WithPermit aToken = IERC20WithPermit( _getReserveData(address(assetToSwapFrom)).aTokenAddress ); if (swapAllBalanceOffset != 0) { uint256 balance = aToken.balanceOf(msg.sender); require(balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP'); amountToSwap = balance; } _pullATokenAndWithdraw( address(assetToSwapFrom), aToken, msg.sender, amountToSwap, permitParams ); uint256 amountReceived = _sellOnParaSwap( swapAllBalanceOffset, swapCalldata, augustus, assetToSwapFrom, assetToSwapTo, amountToSwap, minAmountToReceive ); assetToSwapTo.safeTransfer(msg.sender, amountReceived); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IWrappedTokenGatewayV3 { function depositETH(address pool, address onBehalfOf, uint16 referralCode) external payable; function withdrawETH(address pool, uint256 amount, address onBehalfOf) external; function repayETH(address pool, uint256 amount, address onBehalfOf) external payable; function borrowETH(address pool, uint256 amount, uint16 referralCode) external; function withdrawETHWithPermit( address pool, uint256 amount, address to, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {SafeCast} from '../dependencies/openzeppelin/contracts/SafeCast.sol'; import {IPool} from '../interfaces/IPool.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title L2Encoder * @author Aave * @notice Helper contract to encode calldata, used to optimize calldata size in L2Pool for transaction cost reduction * only indented to help generate calldata for uses/frontends. */ contract L2Encoder { using SafeCast for uint256; IPool public immutable POOL; /** * @dev Constructor. * @param pool The address of the Pool contract */ constructor(IPool pool) { POOL = pool; } /** * @notice Encodes supply parameters from standard input to compact representation of 1 bytes32 * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param referralCode 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 * @return compact representation of supply parameters */ function encodeSupplyParams( address asset, uint256 amount, uint16 referralCode ) external view returns (bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount.toUint128(); bytes32 res; assembly { res := add(assetId, add(shl(16, shortenedAmount), shl(144, referralCode))) } return res; } /** * @notice Encodes supplyWithPermit parameters from standard input to compact representation of 3 bytes32 * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param referralCode 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 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 compact representation of supplyWithPermit parameters * @return The R parameter of ERC712 permit sig * @return The S parameter of ERC712 permit sig */ function encodeSupplyWithPermitParams( address asset, uint256 amount, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external view returns (bytes32, bytes32, bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount.toUint128(); uint32 shortenedDeadline = deadline.toUint32(); bytes32 res; assembly { res := add( assetId, add( shl(16, shortenedAmount), add(shl(144, referralCode), add(shl(160, shortenedDeadline), shl(192, permitV))) ) ) } return (res, permitR, permitS); } /** * @notice Encodes withdraw parameters from standard input to compact representation of 1 bytes32 * @dev Without a to parameter as the compact calls to L2Pool will use msg.sender as to * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * @return compact representation of withdraw parameters */ function encodeWithdrawParams(address asset, uint256 amount) external view returns (bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); bytes32 res; assembly { res := add(assetId, shl(16, shortenedAmount)) } return res; } /** * @notice Encodes borrow parameters from standard input to compact representation of 1 bytes32 * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 2 for Variable, 1 is deprecated (changed 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 * @return compact representation of withdraw parameters */ function encodeBorrowParams( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode ) external view returns (bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount.toUint128(); uint8 shortenedInterestRateMode = interestRateMode.toUint8(); bytes32 res; assembly { res := add( assetId, add( shl(16, shortenedAmount), add(shl(144, shortenedInterestRateMode), shl(152, referralCode)) ) ) } return res; } /** * @notice Encodes repay parameters from standard input to compact representation of 1 bytes32 * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf * @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 `interestRateMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @return compact representation of repay parameters */ function encodeRepayParams( address asset, uint256 amount, uint256 interestRateMode ) public view returns (bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); uint8 shortenedInterestRateMode = interestRateMode.toUint8(); bytes32 res; assembly { res := add(assetId, add(shl(16, shortenedAmount), shl(144, shortenedInterestRateMode))) } return res; } /** * @notice Encodes repayWithPermit parameters from standard input to compact representation of 3 bytes32 * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @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 compact representation of repayWithPermit parameters * @return The R parameter of ERC712 permit sig * @return The S parameter of ERC712 permit sig */ function encodeRepayWithPermitParams( address asset, uint256 amount, uint256 interestRateMode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external view returns (bytes32, bytes32, bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); uint8 shortenedInterestRateMode = interestRateMode.toUint8(); uint32 shortenedDeadline = deadline.toUint32(); bytes32 res; assembly { res := add( assetId, add( shl(16, shortenedAmount), add( shl(144, shortenedInterestRateMode), add(shl(152, shortenedDeadline), shl(184, permitV)) ) ) ) } return (res, permitR, permitS); } /** * @notice Encodes repay with aToken parameters from standard input to compact representation of 1 bytes32 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 2 for Variable, 1 is deprecated (changed on v3.2.0) * @return compact representation of repay with aToken parameters */ function encodeRepayWithATokensParams( address asset, uint256 amount, uint256 interestRateMode ) external view returns (bytes32) { return encodeRepayParams(asset, amount, interestRateMode); } /** * @notice Encodes set user use reserve as collateral parameters from standard input to compact representation of 1 bytes32 * @param asset The address of the underlying asset borrowed * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise * @return compact representation of set user use reserve as collateral parameters */ function encodeSetUserUseReserveAsCollateral( address asset, bool useAsCollateral ) external view returns (bytes32) { DataTypes.ReserveDataLegacy memory data = POOL.getReserveData(asset); uint16 assetId = data.id; bytes32 res; assembly { res := add(assetId, shl(16, useAsCollateral)) } return res; } /** * @notice Encodes liquidation call parameters from standard input to compact representation of 2 bytes32 * @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 * @return First half ot compact representation of liquidation call parameters * @return Second half ot compact representation of liquidation call parameters */ function encodeLiquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external view returns (bytes32, bytes32) { DataTypes.ReserveDataLegacy memory collateralData = POOL.getReserveData(collateralAsset); uint16 collateralAssetId = collateralData.id; DataTypes.ReserveDataLegacy memory debtData = POOL.getReserveData(debtAsset); uint16 debtAssetId = debtData.id; uint128 shortenedDebtToCover = debtToCover == type(uint256).max ? type(uint128).max : debtToCover.toUint128(); bytes32 res1; bytes32 res2; assembly { res1 := add(add(collateralAssetId, shl(16, debtAssetId)), shl(32, user)) res2 := add(shortenedDebtToCover, shl(128, receiveAToken)) } return (res1, res2); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; interface ICollector { struct Stream { uint256 deposit; uint256 ratePerSecond; uint256 remainingBalance; uint256 startTime; uint256 stopTime; address recipient; address sender; address tokenAddress; bool isEntity; } /** @notice Emitted when the funds admin changes * @param fundsAdmin The new funds admin. **/ event NewFundsAdmin(address indexed fundsAdmin); /** @notice Emitted when the new stream is created * @param streamId The identifier of the stream. * @param sender The address of the collector. * @param recipient The address towards which the money is streamed. * @param deposit The amount of money to be streamed. * @param tokenAddress The ERC20 token to use as streaming currency. * @param startTime The unix timestamp for when the stream starts. * @param stopTime The unix timestamp for when the stream stops. **/ event CreateStream( uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime ); /** * @notice Emmitted when withdraw happens from the contract to the recipient's account. * @param streamId The id of the stream to withdraw tokens from. * @param recipient The address towards which the money is streamed. * @param amount The amount of tokens to withdraw. */ event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount); /** * @notice Emmitted when the stream is canceled. * @param streamId The id of the stream to withdraw tokens from. * @param sender The address of the collector. * @param recipient The address towards which the money is streamed. * @param senderBalance The sender's balance at the moment of cancelling. * @param recipientBalance The recipient's balance at the moment of cancelling. */ event CancelStream( uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 senderBalance, uint256 recipientBalance ); /** @notice Returns the mock ETH reference address * @return address The address **/ function ETH_MOCK_ADDRESS() external pure returns (address); /** @notice Initializes the contracts * @param fundsAdmin Funds admin address * @param nextStreamId StreamId to set, applied if greater than 0 **/ function initialize(address fundsAdmin, uint256 nextStreamId) external; /** * @notice Return the funds admin, only entity to be able to interact with this contract (controller of reserve) * @return address The address of the funds admin **/ function getFundsAdmin() external view returns (address); /** * @notice Returns the available funds for the given stream id and address. * @param streamId The id of the stream for which to query the balance. * @param who The address for which to query the balance. * @notice Returns the total funds allocated to `who` as uint256. */ function balanceOf(uint256 streamId, address who) external view returns (uint256 balance); /** * @dev Function for the funds admin to give ERC20 allowance to other parties * @param token The address of the token to give allowance from * @param recipient Allowance's recipient * @param amount Allowance to approve **/ function approve(IERC20 token, address recipient, uint256 amount) external; /** * @notice Function for the funds admin to transfer ERC20 tokens to other parties * @param token The address of the token to transfer * @param recipient Transfer's recipient * @param amount Amount to transfer **/ function transfer(IERC20 token, address recipient, uint256 amount) external; /** * @dev Transfer the ownership of the funds administrator role. This function should only be callable by the current funds administrator. * @param admin The address of the new funds administrator */ function setFundsAdmin(address admin) external; /** * @notice Creates a new stream funded by this contracts itself and paid towards `recipient`. * @param recipient The address towards which the money is streamed. * @param deposit The amount of money to be streamed. * @param tokenAddress The ERC20 token to use as streaming currency. * @param startTime The unix timestamp for when the stream starts. * @param stopTime The unix timestamp for when the stream stops. * @return streamId the uint256 id of the newly created stream. */ function createStream( address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime ) external returns (uint256 streamId); /** * @notice Returns the stream with all its properties. * @dev Throws if the id does not point to a valid stream. * @param streamId The id of the stream to query. * @notice Returns the stream object. */ function getStream( uint256 streamId ) external view returns ( address sender, address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime, uint256 remainingBalance, uint256 ratePerSecond ); /** * @notice Withdraws from the contract to the recipient's account. * @param streamId The id of the stream to withdraw tokens from. * @param amount The amount of tokens to withdraw. * @return bool Returns true if successful. */ function withdrawFromStream(uint256 streamId, uint256 amount) external returns (bool); /** * @notice Cancels the stream and transfers the tokens back on a pro rata basis. * @param streamId The id of the stream to cancel. * @return bool Returns true if successful. */ function cancelStream(uint256 streamId) external returns (bool); /** * @notice Returns the next available stream id * @return nextStreamId Returns the stream id. */ function getNextStreamId() external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/ProxyAdmin.sol) pragma solidity ^0.8.20; import {ITransparentUpgradeableProxy} from './TransparentUpgradeableProxy.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; /** * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. */ contract ProxyAdmin is Ownable { /** * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgrade(address)` * and `upgradeAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called, * while `upgradeAndCall` will invoke the `receive` function if the second argument is the empty byte string. * If the getter returns `"5.0.0"`, only `upgradeAndCall(address,bytes)` is present, and the second argument must * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function * during an upgrade. */ string public constant UPGRADE_INTERFACE_VERSION = '5.0.0'; /** * @dev Sets the initial owner who can perform upgrades. */ constructor(address initialOwner) Ownable(initialOwner) {} /** * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. * See {TransparentUpgradeableProxy-_dispatchUpgradeToAndCall}. * * Requirements: * * - This contract must be the admin of `proxy`. * - If `data` is empty, `msg.value` must be zero. */ function upgradeAndCall( ITransparentUpgradeableProxy proxy, address implementation, bytes memory data ) public payable virtual onlyOwner { proxy.upgradeToAndCall{value: msg.value}(implementation, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Errors library * @author Aave * @notice Defines the error messages emitted by the different contracts of the Aave protocol */ library Errors { string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin' string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin' string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin' string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin' string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin' string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge' string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered' string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider' string public constant NOT_CONTRACT = '9'; // 'Address is not a contract' string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator' string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken' string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid' string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function' string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list' string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached' string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets' string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset' string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0' string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium' string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve' string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category' string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee' string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool' string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint' string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn' string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0' string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve' string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen' string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused' string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled' string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance' string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected' string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0' string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold' string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow' string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed' string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type' string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed' string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve' string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0' string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met' string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold' string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated' string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency' string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters' string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded' string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded' string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded' string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded' string public constant UNDERLYING_CLAIMABLE_RIGHTS_NOT_ZERO = '54'; // 'Claimable rights over underlying not zero (aToken supply or accruedToTreasury)' string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero' string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed' string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category' string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed' string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode' string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized' string public constant USER_IN_ISOLATION_MODE_OR_LTV_ZERO = '62'; // 'User is in isolation mode or ltv is zero' string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve' string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve' string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve' string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve' string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve' string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve' string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve' string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve' string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve' string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve' string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index' string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address' string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not' string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid' string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration' string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature' string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported' string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero' string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed' string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio' string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued' string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list' string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match' string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one' string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0 string public constant FLASHLOAN_DISABLED = '91'; // FlashLoaning for this asset is disabled string public constant INVALID_MAX_RATE = '92'; // The expect maximum borrow rate is invalid string public constant WITHDRAW_TO_ATOKEN = '93'; // Withdrawing to the aToken is not allowed string public constant SUPPLY_TO_ATOKEN = '94'; // Supplying to the aToken is not allowed string public constant SLOPE_2_MUST_BE_GTE_SLOPE_1 = '95'; // Variable interest rate slope 2 can not be lower than slope 1 string public constant CALLER_NOT_RISK_OR_POOL_OR_EMERGENCY_ADMIN = '96'; // 'The caller of the function is not a risk, pool or emergency admin' string public constant LIQUIDATION_GRACE_SENTINEL_CHECK_FAILED = '97'; // 'Liquidation grace sentinel validation failed' string public constant INVALID_GRACE_PERIOD = '98'; // Grace period above a valid range string public constant INVALID_FREEZE_STATE = '99'; // Reserve is already in the passed freeze state string public constant NOT_BORROWABLE_IN_EMODE = '100'; // Asset not borrowable in eMode }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IPriceOracleSentinel * @author Aave * @notice Defines the basic interface for the PriceOracleSentinel */ interface IPriceOracleSentinel { /** * @dev Emitted after the sequencer oracle is updated * @param newSequencerOracle The new sequencer oracle */ event SequencerOracleUpdated(address newSequencerOracle); /** * @dev Emitted after the grace period is updated * @param newGracePeriod The new grace period value */ event GracePeriodUpdated(uint256 newGracePeriod); /** * @notice Returns the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns true if the `borrow` operation is allowed. * @dev Operation not allowed when PriceOracle is down or grace period not passed. * @return True if the `borrow` operation is allowed, false otherwise. */ function isBorrowAllowed() external view returns (bool); /** * @notice Returns true if the `liquidation` operation is allowed. * @dev Operation not allowed when PriceOracle is down or grace period not passed. * @return True if the `liquidation` operation is allowed, false otherwise. */ function isLiquidationAllowed() external view returns (bool); /** * @notice Updates the address of the sequencer oracle * @param newSequencerOracle The address of the new Sequencer Oracle to use */ function setSequencerOracle(address newSequencerOracle) external; /** * @notice Updates the duration of the grace period * @param newGracePeriod The value of the new grace period duration */ function setGracePeriod(uint256 newGracePeriod) external; /** * @notice Returns the SequencerOracle * @return The address of the sequencer oracle contract */ function getSequencerOracle() external view returns (address); /** * @notice Returns the grace period * @return The duration of the grace period */ function getGracePeriod() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ISequencerOracle * @author Aave * @notice Defines the basic interface for a Sequencer oracle. */ interface ISequencerOracle { /** * @notice Returns the health status of the sequencer. * @return roundId The round ID from the aggregator for which the data was retrieved combined with a phase to ensure * that round IDs get larger as time moves forward. * @return answer The answer for the latest round: 0 if the sequencer is up, 1 if it is down. * @return startedAt The timestamp when the round was started. * @return updatedAt The timestamp of the block in which the answer was updated on L1. * @return answeredInRound The round ID of the round in which the answer was computed. */ function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: 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; /** * @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: MIT pragma solidity ^0.8.0; library DataTypes { /** * This exists specifically to maintain the `getReserveData()` interface, since the new, internal * `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`. */ struct ReserveDataLegacy { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; // DEPRECATED on v3.2.0 uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; // DEPRECATED on v3.2.0 uint128 __deprecatedStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed uint40 liquidationGracePeriodUntil; //aToken address address aTokenAddress; // DEPRECATED on v3.2.0 address __deprecatedStableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; //the amount of underlying accounted for by the protocol uint128 virtualUnderlyingBalance; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: DEPRECATED: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167: liquidation protocol fee //bit 168-175: DEPRECATED: eMode category //bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252: virtual accounting is enabled for the reserve //bit 253-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } // DEPRECATED: kept for backwards compatibility, might be removed in a future version struct EModeCategoryLegacy { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // DEPRECATED address priceSource; string label; } struct CollateralConfig { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; } struct EModeCategoryBaseConfiguration { uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; string label; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; uint128 collateralBitmap; string label; uint128 borrowableBitmap; } enum InterestRateMode { NONE, __DEPRECATED, VARIABLE } struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 reservesCount; address addressesProvider; address pool; uint8 userEModeCategory; bool isAuthorizedFlashBorrower; } struct FlashloanSimpleParams { address receiverAddress; address asset; uint256 amount; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; } struct FlashLoanRepaymentParams { uint256 amount; uint256 totalPremium; uint256 flashLoanPremiumToProtocol; address asset; address receiverAddress; uint16 referralCode; } struct CalculateUserAccountDataParams { UserConfigurationMap userConfig; uint256 reservesCount; address user; address oracle; uint8 userEModeCategory; } struct ValidateBorrowParams { ReserveCache reserveCache; UserConfigurationMap userConfig; address asset; address userAddress; uint256 amount; InterestRateMode interestRateMode; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalDebt; uint256 reserveFactor; address reserve; bool usingVirtualBalance; uint256 virtualUnderlyingBalance; } struct InitReserveParams { address asset; address aTokenAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IReserveInterestRateStrategy * @author BGD Labs * @notice Basic interface for any rate strategy used by the Aave protocol */ interface IReserveInterestRateStrategy { /** * @notice Sets interest rate data for an Aave rate strategy * @param reserve The reserve to update * @param rateData The abi encoded reserve interest rate data to apply to the given reserve * Abstracted this way as rate strategies can be custom */ function setInterestRateParams(address reserve, bytes calldata rateData) external; /** * @notice Calculates the interest rates depending on the reserve's state and configurations * @param params The parameters needed to calculate interest rates * @return liquidityRate The liquidity rate expressed in ray * @return variableBorrowRate The variable borrow rate expressed in ray */ function calculateInterestRates( DataTypes.CalculateInterestRatesParams memory params ) external view returns (uint256, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library ConfiguratorInputTypes { struct InitReserveInput { address aTokenImpl; address variableDebtTokenImpl; bool useVirtualBalance; address interestRateStrategyAddress; address underlyingAsset; address treasury; address incentivesController; string aTokenName; string aTokenSymbol; string variableDebtTokenName; string variableDebtTokenSymbol; bytes params; bytes interestRateData; } struct UpdateATokenInput { address asset; address treasury; address incentivesController; string name; string symbol; address implementation; bytes params; } struct UpdateDebtTokenInput { address asset; address incentivesController; string name; string symbol; address implementation; bytes params; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IPriceOracleGetter * @author Aave * @notice Interface for the Aave price oracle. */ interface IPriceOracleGetter { /** * @notice Returns the base currency address * @dev Address 0x0 is reserved for USD as base currency. * @return Returns the base currency address. */ function BASE_CURRENCY() external view returns (address); /** * @notice Returns the base currency unit * @dev 1 ether for ETH, 1e8 for USD. * @return Returns the base currency unit. */ function BASE_CURRENCY_UNIT() external view returns (uint256); /** * @notice Returns the asset price in the base currency * @param asset The address of the asset * @return The price of the asset */ function getAssetPrice(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IScaledBalanceToken * @author Aave * @notice Defines the basic interface for a scaled-balance token. */ interface IScaledBalanceToken { /** * @dev Emitted after the mint action * @param caller The address performing the mint * @param onBehalfOf The address of the user that will receive the minted tokens * @param value The scaled-up amount being minted (based on user entered amount and balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'onBehalfOf' * @param index The next liquidity index of the reserve */ event Mint( address indexed caller, address indexed onBehalfOf, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @dev Emitted after the burn action * @dev If the burn function does not involve a transfer of the underlying asset, the target defaults to zero address * @param from The address from which the tokens will be burned * @param target The address that will receive the underlying, if any * @param value The scaled-up amount being burned (user entered amount - balance increase from interest) * @param balanceIncrease The increase in scaled-up balance since the last action of 'from' * @param index The next liquidity index of the reserve */ event Burn( address indexed from, address indexed target, uint256 value, uint256 balanceIncrease, uint256 index ); /** * @notice Returns the scaled balance of the user. * @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index * at the moment of the update * @param user The user whose balance is calculated * @return The scaled balance of the user */ function scaledBalanceOf(address user) external view returns (uint256); /** * @notice Returns the scaled balance of the user and the scaled total supply. * @param user The address of the user * @return The scaled balance of the user * @return The scaled total supply */ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); /** * @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index) * @return The scaled total supply */ function scaledTotalSupply() external view returns (uint256); /** * @notice Returns last index interest was accrued to the user's balance * @param user The address of the user * @return The last index interest was accrued to the user's balance, expressed in ray */ function getPreviousIndex(address user) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; import {IPool} from './IPool.sol'; /** * @title IInitializableAToken * @author Aave * @notice Interface for the initialize function on AToken */ interface IInitializableAToken { /** * @dev Emitted when an aToken is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated pool * @param treasury The address of the treasury * @param incentivesController The address of the incentives controller for this aToken * @param aTokenDecimals The decimals of the underlying * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ event Initialized( address indexed underlyingAsset, address indexed pool, address treasury, address incentivesController, uint8 aTokenDecimals, string aTokenName, string aTokenSymbol, bytes params ); /** * @notice Initializes the aToken * @param pool The pool contract that is initializing this contract * @param treasury The address of the Aave treasury, receiving the fees on this aToken * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's * @param aTokenName The name of the aToken * @param aTokenSymbol The symbol of the aToken * @param params A set of encoded parameters for additional initialization */ function initialize( IPool pool, address treasury, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 aTokenDecimals, string calldata aTokenName, string calldata aTokenSymbol, bytes calldata params ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; import {IPool} from './IPool.sol'; /** * @title IInitializableDebtToken * @author Aave * @notice Interface for the initialize function common between debt tokens */ interface IInitializableDebtToken { /** * @dev Emitted when a debt token is initialized * @param underlyingAsset The address of the underlying asset * @param pool The address of the associated pool * @param incentivesController The address of the incentives controller for this aToken * @param debtTokenDecimals The decimals of the debt token * @param debtTokenName The name of the debt token * @param debtTokenSymbol The symbol of the debt token * @param params A set of encoded parameters for additional initialization */ event Initialized( address indexed underlyingAsset, address indexed pool, address incentivesController, uint8 debtTokenDecimals, string debtTokenName, string debtTokenSymbol, bytes params ); /** * @notice Initializes the debt token. * @param pool The pool contract that is initializing this contract * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) * @param incentivesController The smart contract managing potential incentives distribution * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's * @param debtTokenName The name of the token * @param debtTokenSymbol The symbol of the token * @param params A set of encoded parameters for additional initialization */ function initialize( IPool pool, address underlyingAsset, IAaveIncentivesController incentivesController, uint8 debtTokenDecimals, string memory debtTokenName, string memory debtTokenSymbol, bytes calldata params ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20} from './IERC20.sol'; interface IERC20Detailed is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Errors} from '../helpers/Errors.sol'; import {DataTypes} from '../types/DataTypes.sol'; /** * @title ReserveConfiguration library * @author Aave * @notice Implements the bitmap logic to handle the reserve configuration */ library ReserveConfiguration { uint256 internal constant LTV_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000; // prettier-ignore uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF; // prettier-ignore uint256 internal constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF; // prettier-ignore uint256 internal constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF; // prettier-ignore uint256 internal constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore // @notice there is an unoccupied hole of 1 bit at position 59 from pre 3.2 stableBorrowRateEnabled uint256 internal constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant SILOED_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant FLASHLOAN_ENABLED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore // @notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory uint256 internal constant UNBACKED_MINT_CAP_MASK = 0xFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant DEBT_CEILING_MASK = 0xF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 internal constant VIRTUAL_ACC_ACTIVE_MASK = 0xEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore /// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16; uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32; uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48; uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56; uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57; uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58; uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60; uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61; uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62; uint256 internal constant FLASHLOAN_ENABLED_START_BIT_POSITION = 63; uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64; uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80; uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116; uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152; //@notice there is an unoccupied hole of 8 bits from 168 to 176 left from pre 3.2 eModeCategory uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176; uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212; uint256 internal constant VIRTUAL_ACC_START_BIT_POSITION = 252; uint256 internal constant MAX_VALID_LTV = 65535; uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535; uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535; uint256 internal constant MAX_VALID_DECIMALS = 255; uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535; uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735; uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735; uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535; uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735; uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775; uint256 public constant DEBT_CEILING_DECIMALS = 2; uint16 public constant MAX_RESERVES_COUNT = 128; /** * @notice Sets the Loan to Value of the reserve * @param self The reserve configuration * @param ltv The new ltv */ function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure { require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV); self.data = (self.data & LTV_MASK) | ltv; } /** * @notice Gets the Loan to Value of the reserve * @param self The reserve configuration * @return The loan to value */ function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) { return self.data & ~LTV_MASK; } /** * @notice Sets the liquidation threshold of the reserve * @param self The reserve configuration * @param threshold The new liquidation threshold */ function setLiquidationThreshold( DataTypes.ReserveConfigurationMap memory self, uint256 threshold ) internal pure { require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD); self.data = (self.data & LIQUIDATION_THRESHOLD_MASK) | (threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION); } /** * @notice Gets the liquidation threshold of the reserve * @param self The reserve configuration * @return The liquidation threshold */ function getLiquidationThreshold( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION; } /** * @notice Sets the liquidation bonus of the reserve * @param self The reserve configuration * @param bonus The new liquidation bonus */ function setLiquidationBonus( DataTypes.ReserveConfigurationMap memory self, uint256 bonus ) internal pure { require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS); self.data = (self.data & LIQUIDATION_BONUS_MASK) | (bonus << LIQUIDATION_BONUS_START_BIT_POSITION); } /** * @notice Gets the liquidation bonus of the reserve * @param self The reserve configuration * @return The liquidation bonus */ function getLiquidationBonus( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION; } /** * @notice Sets the decimals of the underlying asset of the reserve * @param self The reserve configuration * @param decimals The decimals */ function setDecimals( DataTypes.ReserveConfigurationMap memory self, uint256 decimals ) internal pure { require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS); self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); } /** * @notice Gets the decimals of the underlying asset of the reserve * @param self The reserve configuration * @return The decimals of the asset */ function getDecimals( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; } /** * @notice Sets the active state of the reserve * @param self The reserve configuration * @param active The active state */ function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure { self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); } /** * @notice Gets the active state of the reserve * @param self The reserve configuration * @return The active state */ function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & ~ACTIVE_MASK) != 0; } /** * @notice Sets the frozen state of the reserve * @param self The reserve configuration * @param frozen The frozen state */ function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure { self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); } /** * @notice Gets the frozen state of the reserve * @param self The reserve configuration * @return The frozen state */ function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & ~FROZEN_MASK) != 0; } /** * @notice Sets the paused state of the reserve * @param self The reserve configuration * @param paused The paused state */ function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure { self.data = (self.data & PAUSED_MASK) | (uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION); } /** * @notice Gets the paused state of the reserve * @param self The reserve configuration * @return The paused state */ function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { return (self.data & ~PAUSED_MASK) != 0; } /** * @notice Sets the borrowable in isolation flag for the reserve. * @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed * amount will be accumulated in the isolated collateral's total debt exposure. * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep * consistency in the debt ceiling calculations. * @param self The reserve configuration * @param borrowable True if the asset is borrowable */ function setBorrowableInIsolation( DataTypes.ReserveConfigurationMap memory self, bool borrowable ) internal pure { self.data = (self.data & BORROWABLE_IN_ISOLATION_MASK) | (uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION); } /** * @notice Gets the borrowable in isolation flag for the reserve. * @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with * isolated collateral is accounted for in the isolated collateral's total debt exposure. * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep * consistency in the debt ceiling calculations. * @param self The reserve configuration * @return The borrowable in isolation flag */ function getBorrowableInIsolation( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } /** * @notice Sets the siloed borrowing flag for the reserve. * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. * @param self The reserve configuration * @param siloed True if the asset is siloed */ function setSiloedBorrowing( DataTypes.ReserveConfigurationMap memory self, bool siloed ) internal pure { self.data = (self.data & SILOED_BORROWING_MASK) | (uint256(siloed ? 1 : 0) << SILOED_BORROWING_START_BIT_POSITION); } /** * @notice Gets the siloed borrowing flag for the reserve. * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. * @param self The reserve configuration * @return The siloed borrowing flag */ function getSiloedBorrowing( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~SILOED_BORROWING_MASK) != 0; } /** * @notice Enables or disables borrowing on the reserve * @param self The reserve configuration * @param enabled True if the borrowing needs to be enabled, false otherwise */ function setBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self, bool enabled ) internal pure { self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); } /** * @notice Gets the borrowing state of the reserve * @param self The reserve configuration * @return The borrowing state */ function getBorrowingEnabled( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~BORROWING_MASK) != 0; } /** * @notice Sets the reserve factor of the reserve * @param self The reserve configuration * @param reserveFactor The reserve factor */ function setReserveFactor( DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor ) internal pure { require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR); self.data = (self.data & RESERVE_FACTOR_MASK) | (reserveFactor << RESERVE_FACTOR_START_BIT_POSITION); } /** * @notice Gets the reserve factor of the reserve * @param self The reserve configuration * @return The reserve factor */ function getReserveFactor( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; } /** * @notice Sets the borrow cap of the reserve * @param self The reserve configuration * @param borrowCap The borrow cap */ function setBorrowCap( DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap ) internal pure { require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.INVALID_BORROW_CAP); self.data = (self.data & BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION); } /** * @notice Gets the borrow cap of the reserve * @param self The reserve configuration * @return The borrow cap */ function getBorrowCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION; } /** * @notice Sets the supply cap of the reserve * @param self The reserve configuration * @param supplyCap The supply cap */ function setSupplyCap( DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap ) internal pure { require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.INVALID_SUPPLY_CAP); self.data = (self.data & SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION); } /** * @notice Gets the supply cap of the reserve * @param self The reserve configuration * @return The supply cap */ function getSupplyCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION; } /** * @notice Sets the debt ceiling in isolation mode for the asset * @param self The reserve configuration * @param ceiling The maximum debt ceiling for the asset */ function setDebtCeiling( DataTypes.ReserveConfigurationMap memory self, uint256 ceiling ) internal pure { require(ceiling <= MAX_VALID_DEBT_CEILING, Errors.INVALID_DEBT_CEILING); self.data = (self.data & DEBT_CEILING_MASK) | (ceiling << DEBT_CEILING_START_BIT_POSITION); } /** * @notice Gets the debt ceiling for the asset if the asset is in isolation mode * @param self The reserve configuration * @return The debt ceiling (0 = isolation mode disabled) */ function getDebtCeiling( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~DEBT_CEILING_MASK) >> DEBT_CEILING_START_BIT_POSITION; } /** * @notice Sets the liquidation protocol fee of the reserve * @param self The reserve configuration * @param liquidationProtocolFee The liquidation protocol fee */ function setLiquidationProtocolFee( DataTypes.ReserveConfigurationMap memory self, uint256 liquidationProtocolFee ) internal pure { require( liquidationProtocolFee <= MAX_VALID_LIQUIDATION_PROTOCOL_FEE, Errors.INVALID_LIQUIDATION_PROTOCOL_FEE ); self.data = (self.data & LIQUIDATION_PROTOCOL_FEE_MASK) | (liquidationProtocolFee << LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION); } /** * @dev Gets the liquidation protocol fee * @param self The reserve configuration * @return The liquidation protocol fee */ function getLiquidationProtocolFee( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~LIQUIDATION_PROTOCOL_FEE_MASK) >> LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION; } /** * @notice Sets the unbacked mint cap of the reserve * @param self The reserve configuration * @param unbackedMintCap The unbacked mint cap */ function setUnbackedMintCap( DataTypes.ReserveConfigurationMap memory self, uint256 unbackedMintCap ) internal pure { require(unbackedMintCap <= MAX_VALID_UNBACKED_MINT_CAP, Errors.INVALID_UNBACKED_MINT_CAP); self.data = (self.data & UNBACKED_MINT_CAP_MASK) | (unbackedMintCap << UNBACKED_MINT_CAP_START_BIT_POSITION); } /** * @dev Gets the unbacked mint cap of the reserve * @param self The reserve configuration * @return The unbacked mint cap */ function getUnbackedMintCap( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256) { return (self.data & ~UNBACKED_MINT_CAP_MASK) >> UNBACKED_MINT_CAP_START_BIT_POSITION; } /** * @notice Sets the flashloanable flag for the reserve * @param self The reserve configuration * @param flashLoanEnabled True if the asset is flashloanable, false otherwise */ function setFlashLoanEnabled( DataTypes.ReserveConfigurationMap memory self, bool flashLoanEnabled ) internal pure { self.data = (self.data & FLASHLOAN_ENABLED_MASK) | (uint256(flashLoanEnabled ? 1 : 0) << FLASHLOAN_ENABLED_START_BIT_POSITION); } /** * @notice Gets the flashloanable flag for the reserve * @param self The reserve configuration * @return The flashloanable flag */ function getFlashLoanEnabled( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~FLASHLOAN_ENABLED_MASK) != 0; } /** * @notice Sets the virtual account active/not state of the reserve * @param self The reserve configuration * @param active The active state */ function setVirtualAccActive( DataTypes.ReserveConfigurationMap memory self, bool active ) internal pure { self.data = (self.data & VIRTUAL_ACC_ACTIVE_MASK) | (uint256(active ? 1 : 0) << VIRTUAL_ACC_START_BIT_POSITION); } /** * @notice Gets the virtual account active/not state of the reserve * @dev The state should be true for all normal assets and should be false * only in special cases (ex. GHO) where an asset is minted instead of supplied. * @param self The reserve configuration * @return The active state */ function getIsVirtualAccActive( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool) { return (self.data & ~VIRTUAL_ACC_ACTIVE_MASK) != 0; } /** * @notice Gets the configuration flags of the reserve * @param self The reserve configuration * @return The state flag representing active * @return The state flag representing frozen * @return The state flag representing borrowing enabled * @return The state flag representing paused */ function getFlags( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (bool, bool, bool, bool) { uint256 dataLocal = self.data; return ( (dataLocal & ~ACTIVE_MASK) != 0, (dataLocal & ~FROZEN_MASK) != 0, (dataLocal & ~BORROWING_MASK) != 0, (dataLocal & ~PAUSED_MASK) != 0 ); } /** * @notice Gets the configuration parameters of the reserve from storage * @param self The reserve configuration * @return The state param representing ltv * @return The state param representing liquidation threshold * @return The state param representing liquidation bonus * @return The state param representing reserve decimals * @return The state param representing reserve factor */ function getParams( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256, uint256, uint256, uint256, uint256) { uint256 dataLocal = self.data; return ( dataLocal & ~LTV_MASK, (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION ); } /** * @notice Gets the caps parameters of the reserve from storage * @param self The reserve configuration * @return The state param representing borrow cap * @return The state param representing supply cap. */ function getCaps( DataTypes.ReserveConfigurationMap memory self ) internal pure returns (uint256, uint256) { uint256 dataLocal = self.data; return ( (dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION, (dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Errors} from '../helpers/Errors.sol'; import {DataTypes} from '../types/DataTypes.sol'; import {ReserveConfiguration} from './ReserveConfiguration.sol'; /** * @title UserConfiguration library * @author Aave * @notice Implements the bitmap logic to handle the user configuration */ library UserConfiguration { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; uint256 internal constant BORROWING_MASK = 0x5555555555555555555555555555555555555555555555555555555555555555; uint256 internal constant COLLATERAL_MASK = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; /** * @notice Sets if the user is borrowing the reserve identified by reserveIndex * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @param borrowing True if the user is borrowing the reserve, false otherwise */ function setBorrowing( DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool borrowing ) internal { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); uint256 bit = 1 << (reserveIndex << 1); if (borrowing) { self.data |= bit; } else { self.data &= ~bit; } } } /** * @notice Sets if the user is using as collateral the reserve identified by reserveIndex * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @param usingAsCollateral True if the user is using the reserve as collateral, false otherwise */ function setUsingAsCollateral( DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool usingAsCollateral ) internal { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); uint256 bit = 1 << ((reserveIndex << 1) + 1); if (usingAsCollateral) { self.data |= bit; } else { self.data &= ~bit; } } } /** * @notice Returns if a user has been using the reserve for borrowing or as collateral * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve for borrowing or as collateral, false otherwise */ function isUsingAsCollateralOrBorrowing( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> (reserveIndex << 1)) & 3 != 0; } } /** * @notice Validate a user has been using the reserve for borrowing * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve for borrowing, false otherwise */ function isBorrowing( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> (reserveIndex << 1)) & 1 != 0; } } /** * @notice Validate a user has been using the reserve as collateral * @param self The configuration object * @param reserveIndex The index of the reserve in the bitmap * @return True if the user has been using a reserve as collateral, false otherwise */ function isUsingAsCollateral( DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { unchecked { require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); return (self.data >> ((reserveIndex << 1) + 1)) & 1 != 0; } } /** * @notice Checks if a user has been supplying only one reserve as collateral * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 * @param self The configuration object * @return True if the user has been supplying as collateral one reserve, false otherwise */ function isUsingAsCollateralOne( DataTypes.UserConfigurationMap memory self ) internal pure returns (bool) { uint256 collateralData = self.data & COLLATERAL_MASK; return collateralData != 0 && (collateralData & (collateralData - 1) == 0); } /** * @notice Checks if a user has been supplying any reserve as collateral * @param self The configuration object * @return True if the user has been supplying as collateral any reserve, false otherwise */ function isUsingAsCollateralAny( DataTypes.UserConfigurationMap memory self ) internal pure returns (bool) { return self.data & COLLATERAL_MASK != 0; } /** * @notice Checks if a user has been borrowing only one asset * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 * @param self The configuration object * @return True if the user has been supplying as collateral one reserve, false otherwise */ function isBorrowingOne(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { uint256 borrowingData = self.data & BORROWING_MASK; return borrowingData != 0 && (borrowingData & (borrowingData - 1) == 0); } /** * @notice Checks if a user has been borrowing from any reserve * @param self The configuration object * @return True if the user has been borrowing any reserve, false otherwise */ function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data & BORROWING_MASK != 0; } /** * @notice Checks if a user has not been using any reserve for borrowing or supply * @param self The configuration object * @return True if the user has not been borrowing or supplying any reserve, false otherwise */ function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data == 0; } /** * @notice Returns the Isolation Mode state of the user * @param self The configuration object * @param reservesData The state of all the reserves * @param reservesList The addresses of all the active reserves * @return True if the user is in isolation mode, false otherwise * @return The address of the only asset used as collateral * @return The debt ceiling of the reserve */ function getIsolationModeState( DataTypes.UserConfigurationMap memory self, mapping(address => DataTypes.ReserveData) storage reservesData, mapping(uint256 => address) storage reservesList ) internal view returns (bool, address, uint256) { if (isUsingAsCollateralOne(self)) { uint256 assetId = _getFirstAssetIdByMask(self, COLLATERAL_MASK); address assetAddress = reservesList[assetId]; uint256 ceiling = reservesData[assetAddress].configuration.getDebtCeiling(); if (ceiling != 0) { return (true, assetAddress, ceiling); } } return (false, address(0), 0); } /** * @notice Returns the siloed borrowing state for the user * @param self The configuration object * @param reservesData The data of all the reserves * @param reservesList The reserve list * @return True if the user has borrowed a siloed asset, false otherwise * @return The address of the only borrowed asset */ function getSiloedBorrowingState( DataTypes.UserConfigurationMap memory self, mapping(address => DataTypes.ReserveData) storage reservesData, mapping(uint256 => address) storage reservesList ) internal view returns (bool, address) { if (isBorrowingOne(self)) { uint256 assetId = _getFirstAssetIdByMask(self, BORROWING_MASK); address assetAddress = reservesList[assetId]; if (reservesData[assetAddress].configuration.getSiloedBorrowing()) { return (true, assetAddress); } } return (false, address(0)); } /** * @notice Returns the address of the first asset flagged in the bitmap given the corresponding bitmask * @param self The configuration object * @return The index of the first asset flagged in the bitmap once the corresponding mask is applied */ function _getFirstAssetIdByMask( DataTypes.UserConfigurationMap memory self, uint256 mask ) internal pure returns (uint256) { unchecked { uint256 bitmapData = self.data & mask; uint256 firstAssetPosition = bitmapData & ~(bitmapData - 1); uint256 id; while ((firstAssetPosition >>= 2) != 0) { id += 1; } return id; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IPoolDataProvider * @author Aave * @notice Defines the basic interface of a PoolDataProvider */ interface IPoolDataProvider { struct TokenData { string symbol; address tokenAddress; } /** * @notice Returns the address for the PoolAddressesProvider contract. * @return The address for the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the list of the existing reserves in the pool. * @dev Handling MKR and ETH in a different way since they do not have standard `symbol` functions. * @return The list of reserves, pairs of symbols and addresses */ function getAllReservesTokens() external view returns (TokenData[] memory); /** * @notice Returns the list of the existing ATokens in the pool. * @return The list of ATokens, pairs of symbols and addresses */ function getAllATokens() external view returns (TokenData[] memory); /** * @notice Returns the configuration data of the reserve * @dev Not returning borrow and supply caps for compatibility, nor pause flag * @param asset The address of the underlying asset of the reserve * @return decimals The number of decimals of the reserve * @return ltv The ltv of the reserve * @return liquidationThreshold The liquidationThreshold of the reserve * @return liquidationBonus The liquidationBonus of the reserve * @return reserveFactor The reserveFactor of the reserve * @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise * @return borrowingEnabled True if borrowing is enabled, false otherwise * @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise * @return isActive True if it is active, false otherwise * @return isFrozen True if it is frozen, false otherwise */ function getReserveConfigurationData( address asset ) external view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); /** * @notice Returns the caps parameters of the reserve * @param asset The address of the underlying asset of the reserve * @return borrowCap The borrow cap of the reserve * @return supplyCap The supply cap of the reserve */ function getReserveCaps( address asset ) external view returns (uint256 borrowCap, uint256 supplyCap); /** * @notice Returns if the pool is paused * @param asset The address of the underlying asset of the reserve * @return isPaused True if the pool is paused, false otherwise */ function getPaused(address asset) external view returns (bool isPaused); /** * @notice Returns the siloed borrowing flag * @param asset The address of the underlying asset of the reserve * @return True if the asset is siloed for borrowing */ function getSiloedBorrowing(address asset) external view returns (bool); /** * @notice Returns the protocol fee on the liquidation bonus * @param asset The address of the underlying asset of the reserve * @return The protocol fee on liquidation */ function getLiquidationProtocolFee(address asset) external view returns (uint256); /** * @notice Returns the unbacked mint cap of the reserve * @param asset The address of the underlying asset of the reserve * @return The unbacked mint cap of the reserve */ function getUnbackedMintCap(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling of the reserve * @param asset The address of the underlying asset of the reserve * @return The debt ceiling of the reserve */ function getDebtCeiling(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling decimals * @return The debt ceiling decimals */ function getDebtCeilingDecimals() external pure returns (uint256); /** * @notice Returns the reserve data * @param asset The address of the underlying asset of the reserve * @return unbacked The amount of unbacked tokens * @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted * @return totalAToken The total supply of the aToken * @return totalStableDebt The total stable debt of the reserve * @return totalVariableDebt The total variable debt of the reserve * @return liquidityRate The liquidity rate of the reserve * @return variableBorrowRate The variable borrow rate of the reserve * @return stableBorrowRate The stable borrow rate of the reserve * @return averageStableBorrowRate The average stable borrow rate of the reserve * @return liquidityIndex The liquidity index of the reserve * @return variableBorrowIndex The variable borrow index of the reserve * @return lastUpdateTimestamp The timestamp of the last update of the reserve */ function getReserveData( address asset ) external view returns ( uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); /** * @notice Returns the total supply of aTokens for a given asset * @param asset The address of the underlying asset of the reserve * @return The total supply of the aToken */ function getATokenTotalSupply(address asset) external view returns (uint256); /** * @notice Returns the total debt for a given asset * @param asset The address of the underlying asset of the reserve * @return The total debt for asset */ function getTotalDebt(address asset) external view returns (uint256); /** * @notice Returns the user data in a reserve * @param asset The address of the underlying asset of the reserve * @param user The address of the user * @return currentATokenBalance The current AToken balance of the user * @return currentStableDebt The current stable debt of the user * @return currentVariableDebt The current variable debt of the user * @return principalStableDebt The principal stable debt of the user * @return scaledVariableDebt The scaled variable debt of the user * @return stableBorrowRate The stable borrow rate of the user * @return liquidityRate The liquidity rate of the reserve * @return stableRateLastUpdated The timestamp of the last update of the user stable rate * @return usageAsCollateralEnabled True if the user is using the asset as collateral, false * otherwise */ function getUserReserveData( address asset, address user ) external view returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); /** * @notice Returns the token addresses of the reserve * @param asset The address of the underlying asset of the reserve * @return aTokenAddress The AToken address of the reserve * @return stableDebtTokenAddress DEPRECATED in v3.2.0 * @return variableDebtTokenAddress The VariableDebtToken address of the reserve */ function getReserveTokensAddresses( address asset ) external view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); /** * @notice Returns the address of the Interest Rate strategy * @param asset The address of the underlying asset of the reserve * @return irStrategyAddress The address of the Interest Rate strategy */ function getInterestRateStrategyAddress( address asset ) external view returns (address irStrategyAddress); /** * @notice Returns whether the reserve has FlashLoans enabled or disabled * @param asset The address of the underlying asset of the reserve * @return True if FlashLoans are enabled, false otherwise */ function getFlashLoanEnabled(address asset) external view returns (bool); /** * @notice Returns whether virtual accounting is enabled/not for a reserve * @param asset The address of the underlying asset of the reserve * @return True if active, false otherwise */ function getIsVirtualAccActive(address asset) external view returns (bool); /** * @notice Returns the virtual underlying balance of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve virtual underlying balance */ function getVirtualUnderlyingBalance(address asset) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IEACAggregatorProxy { function decimals() external view returns (uint8); function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); function latestRound() external view returns (uint256); function getAnswer(uint256 roundId) external view returns (int256); function getTimestamp(uint256 roundId) external view returns (uint256); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp); event NewRound(uint256 indexed roundId, address indexed startedBy); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; interface IERC20DetailedBytes is IERC20 { function name() external view returns (bytes32); function symbol() external view returns (bytes32); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; interface IUiPoolDataProviderV3 { struct AggregatedReserveData { address underlyingAsset; string name; string symbol; uint256 decimals; uint256 baseLTVasCollateral; uint256 reserveLiquidationThreshold; uint256 reserveLiquidationBonus; uint256 reserveFactor; bool usageAsCollateralEnabled; bool borrowingEnabled; bool isActive; bool isFrozen; // base data uint128 liquidityIndex; uint128 variableBorrowIndex; uint128 liquidityRate; uint128 variableBorrowRate; uint40 lastUpdateTimestamp; address aTokenAddress; address variableDebtTokenAddress; address interestRateStrategyAddress; // uint256 availableLiquidity; uint256 totalScaledVariableDebt; uint256 priceInMarketReferenceCurrency; address priceOracle; uint256 variableRateSlope1; uint256 variableRateSlope2; uint256 baseVariableBorrowRate; uint256 optimalUsageRatio; // v3 only bool isPaused; bool isSiloedBorrowing; uint128 accruedToTreasury; uint128 unbacked; uint128 isolationModeTotalDebt; bool flashLoanEnabled; // uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 borrowCap; uint256 supplyCap; bool borrowableInIsolation; // v3.1 bool virtualAccActive; uint128 virtualUnderlyingBalance; } struct UserReserveData { address underlyingAsset; uint256 scaledATokenBalance; bool usageAsCollateralEnabledOnUser; uint256 scaledVariableDebt; } struct BaseCurrencyInfo { uint256 marketReferenceCurrencyUnit; int256 marketReferenceCurrencyPriceInUsd; int256 networkBaseTokenPriceInUsd; uint8 networkBaseTokenPriceDecimals; } struct Emode { uint8 id; DataTypes.EModeCategory eMode; } function getReservesList( IPoolAddressesProvider provider ) external view returns (address[] memory); function getReservesData( IPoolAddressesProvider provider ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); function getUserReservesData( IPoolAddressesProvider provider, address user ) external view returns (UserReserveData[] memory, uint8); /** * @dev Iterates the eModes mapping and returns all eModes found * @notice The method assumes for id gaps <= 2 within the eMode definitions * @return an array of eModes that were found in the eMode mapping */ function getEModes(IPoolAddressesProvider provider) external view returns (Emode[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol'; import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20Detailed} from '../../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; import {WadRayMath} from '../../libraries/math/WadRayMath.sol'; import {Errors} from '../../libraries/helpers/Errors.sol'; import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../../../interfaces/IPool.sol'; import {IACLManager} from '../../../interfaces/IACLManager.sol'; /** * @title IncentivizedERC20 * @author Aave, inspired by the Openzeppelin ERC20 implementation * @notice Basic ERC20 implementation */ abstract contract IncentivizedERC20 is Context, IERC20Detailed { using WadRayMath for uint256; using SafeCast for uint256; /** * @dev Only pool admin can call functions marked by this modifier. */ modifier onlyPoolAdmin() { IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); _; } /** * @dev Only pool can call functions marked by this modifier. */ modifier onlyPool() { require(_msgSender() == address(POOL), Errors.CALLER_MUST_BE_POOL); _; } /** * @dev UserState - additionalData is a flexible field. * ATokens and VariableDebtTokens use this field store the index of the * user's last supply/withdrawal/borrow/repayment. */ struct UserState { uint128 balance; uint128 additionalData; } // Map of users address and their state data (userAddress => userStateData) mapping(address => UserState) internal _userState; // Map of allowances (delegator => delegatee => allowanceAmount) mapping(address => mapping(address => uint256)) private _allowances; uint256 internal _totalSupply; string private _name; string private _symbol; uint8 private _decimals; IAaveIncentivesController internal _incentivesController; IPoolAddressesProvider internal immutable _addressesProvider; IPool public immutable POOL; /** * @dev Constructor. * @param pool The reference to the main Pool contract * @param name_ The name of the token * @param symbol_ The symbol of the token * @param decimals_ The number of decimals of the token */ constructor(IPool pool, string memory name_, string memory symbol_, uint8 decimals_) { _addressesProvider = pool.ADDRESSES_PROVIDER(); _name = name_; _symbol = symbol_; _decimals = decimals_; POOL = pool; } /// @inheritdoc IERC20Detailed function name() public view override returns (string memory) { return _name; } /// @inheritdoc IERC20Detailed function symbol() external view override returns (string memory) { return _symbol; } /// @inheritdoc IERC20Detailed function decimals() external view override returns (uint8) { return _decimals; } /// @inheritdoc IERC20 function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /// @inheritdoc IERC20 function balanceOf(address account) public view virtual override returns (uint256) { return _userState[account].balance; } /** * @notice Returns the address of the Incentives Controller contract * @return The address of the Incentives Controller */ function getIncentivesController() external view virtual returns (IAaveIncentivesController) { return _incentivesController; } /** * @notice Sets a new Incentives Controller * @param controller the new Incentives controller */ function setIncentivesController(IAaveIncentivesController controller) external onlyPoolAdmin { _incentivesController = controller; } /// @inheritdoc IERC20 function transfer(address recipient, uint256 amount) external virtual override returns (bool) { uint128 castAmount = amount.toUint128(); _transfer(_msgSender(), recipient, castAmount); return true; } /// @inheritdoc IERC20 function allowance( address owner, address spender ) external view virtual override returns (uint256) { return _allowances[owner][spender]; } /// @inheritdoc IERC20 function approve(address spender, uint256 amount) external virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /// @inheritdoc IERC20 function transferFrom( address sender, address recipient, uint256 amount ) external virtual override returns (bool) { uint128 castAmount = amount.toUint128(); _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - castAmount); _transfer(sender, recipient, castAmount); return true; } /** * @notice Increases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param addedValue The amount being added to the allowance * @return `true` */ function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @notice Decreases the allowance of spender to spend _msgSender() tokens * @param spender The user allowed to spend on behalf of _msgSender() * @param subtractedValue The amount being subtracted to the allowance * @return `true` */ function decreaseAllowance( address spender, uint256 subtractedValue ) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue); return true; } /** * @notice Transfers tokens between two users and apply incentives if defined. * @param sender The source address * @param recipient The destination address * @param amount The amount getting transferred */ function _transfer(address sender, address recipient, uint128 amount) internal virtual { uint128 oldSenderBalance = _userState[sender].balance; _userState[sender].balance = oldSenderBalance - amount; uint128 oldRecipientBalance = _userState[recipient].balance; _userState[recipient].balance = oldRecipientBalance + amount; IAaveIncentivesController incentivesControllerLocal = _incentivesController; if (address(incentivesControllerLocal) != address(0)) { uint256 currentTotalSupply = _totalSupply; incentivesControllerLocal.handleAction(sender, currentTotalSupply, oldSenderBalance); if (sender != recipient) { incentivesControllerLocal.handleAction(recipient, currentTotalSupply, oldRecipientBalance); } } } /** * @notice Approve `spender` to use `amount` of `owner`s balance * @param owner The address owning the tokens * @param spender The address approved for spending * @param amount The amount of tokens to approve spending of */ function _approve(address owner, address spender, uint256 amount) internal virtual { _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @notice Update the name of the token * @param newName The new name for the token */ function _setName(string memory newName) internal { _name = newName; } /** * @notice Update the symbol for the token * @param newSymbol The new symbol for the token */ function _setSymbol(string memory newSymbol) internal { _symbol = newSymbol; } /** * @notice Update the number of decimals for the token * @param newDecimals The new number of decimals for the token */ function _setDecimals(uint8 newDecimals) internal { _decimals = newDecimals; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; interface IUiIncentiveDataProviderV3 { struct AggregatedReserveIncentiveData { address underlyingAsset; IncentiveData aIncentiveData; IncentiveData vIncentiveData; } struct IncentiveData { address tokenAddress; address incentiveControllerAddress; RewardInfo[] rewardsTokenInformation; } struct RewardInfo { string rewardTokenSymbol; address rewardTokenAddress; address rewardOracleAddress; uint256 emissionPerSecond; uint256 incentivesLastUpdateTimestamp; uint256 tokenIncentivesIndex; uint256 emissionEndTimestamp; int256 rewardPriceFeed; uint8 rewardTokenDecimals; uint8 precision; uint8 priceFeedDecimals; } struct UserReserveIncentiveData { address underlyingAsset; UserIncentiveData aTokenIncentivesUserData; UserIncentiveData vTokenIncentivesUserData; } struct UserIncentiveData { address tokenAddress; address incentiveControllerAddress; UserRewardInfo[] userRewardsInformation; } struct UserRewardInfo { string rewardTokenSymbol; address rewardOracleAddress; address rewardTokenAddress; uint256 userUnclaimedRewards; uint256 tokenIncentivesUserIndex; int256 rewardPriceFeed; uint8 priceFeedDecimals; uint8 rewardTokenDecimals; } function getReservesIncentivesData( IPoolAddressesProvider provider ) external view returns (AggregatedReserveIncentiveData[] memory); function getUserReservesIncentivesData( IPoolAddressesProvider provider, address user ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data function getFullReservesIncentiveData( IPoolAddressesProvider provider, address user ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; library RewardsDataTypes { struct RewardsConfigInput { uint88 emissionPerSecond; uint256 totalSupply; uint32 distributionEnd; address asset; address reward; ITransferStrategyBase transferStrategy; IEACAggregatorProxy rewardOracle; } struct UserAssetBalance { address asset; uint256 userBalance; uint256 totalSupply; } struct UserData { // Liquidity index of the reward distribution for the user uint104 index; // Amount of accrued rewards for the user since last user index update uint128 accrued; } struct RewardData { // Liquidity index of the reward distribution uint104 index; // Amount of reward tokens distributed per second uint88 emissionPerSecond; // Timestamp of the last reward index update uint32 lastUpdateTimestamp; // The end of the distribution of rewards (in seconds) uint32 distributionEnd; // Map of user addresses and their rewards data (userAddress => userData) mapping(address => UserData) usersData; } struct AssetData { // Map of reward token addresses and their data (rewardTokenAddress => rewardData) mapping(address => RewardData) rewards; // List of reward token addresses for the asset mapping(uint128 => address) availableRewards; // Count of reward tokens for the asset uint128 availableRewardsCount; // Number of decimals of the asset uint8 decimals; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface ITransferStrategyBase { event EmergencyWithdrawal( address indexed caller, address indexed token, address indexed to, uint256 amount ); /** * @dev Perform custom transfer logic via delegate call from source contract to a TransferStrategy implementation * @param to Account to transfer rewards * @param reward Address of the reward token * @param amount Amount to transfer to the "to" address parameter * @return Returns true bool if transfer logic succeeds */ function performTransfer(address to, address reward, uint256 amount) external returns (bool); /** * @return Returns the address of the Incentives Controller */ function getIncentivesController() external view returns (address); /** * @return Returns the address of the Rewards admin */ function getRewardsAdmin() external view returns (address); /** * @dev Perform an emergency token withdrawal only callable by the Rewards admin * @param token Address of the token to withdraw funds from this contract * @param to Address of the recipient of the withdrawal * @param amount Amount of the withdrawal */ function emergencyWithdrawal(address token, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /** * @title IRewardsDistributor * @author Aave * @notice Defines the basic interface for a Rewards Distributor. */ interface IRewardsDistributor { /** * @dev Emitted when the configuration of the rewards of an asset is updated. * @param asset The address of the incentivized asset * @param reward The address of the reward token * @param oldEmission The old emissions per second value of the reward distribution * @param newEmission The new emissions per second value of the reward distribution * @param oldDistributionEnd The old end timestamp of the reward distribution * @param newDistributionEnd The new end timestamp of the reward distribution * @param assetIndex The index of the asset distribution */ event AssetConfigUpdated( address indexed asset, address indexed reward, uint256 oldEmission, uint256 newEmission, uint256 oldDistributionEnd, uint256 newDistributionEnd, uint256 assetIndex ); /** * @dev Emitted when rewards of an asset are accrued on behalf of a user. * @param asset The address of the incentivized asset * @param reward The address of the reward token * @param user The address of the user that rewards are accrued on behalf of * @param assetIndex The index of the asset distribution * @param userIndex The index of the asset distribution on behalf of the user * @param rewardsAccrued The amount of rewards accrued */ event Accrued( address indexed asset, address indexed reward, address indexed user, uint256 assetIndex, uint256 userIndex, uint256 rewardsAccrued ); /** * @dev Sets the end date for the distribution * @param asset The asset to incentivize * @param reward The reward token that incentives the asset * @param newDistributionEnd The end date of the incentivization, in unix time format **/ function setDistributionEnd(address asset, address reward, uint32 newDistributionEnd) external; /** * @dev Sets the emission per second of a set of reward distributions * @param asset The asset is being incentivized * @param rewards List of reward addresses are being distributed * @param newEmissionsPerSecond List of new reward emissions per second */ function setEmissionPerSecond( address asset, address[] calldata rewards, uint88[] calldata newEmissionsPerSecond ) external; /** * @dev Gets the end date for the distribution * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The timestamp with the end of the distribution, in unix time format **/ function getDistributionEnd(address asset, address reward) external view returns (uint256); /** * @dev Returns the index of a user on a reward distribution * @param user Address of the user * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The current user asset index, not including new distributions **/ function getUserAssetIndex( address user, address asset, address reward ) external view returns (uint256); /** * @dev Returns the configuration of the distribution reward for a certain asset * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The index of the asset distribution * @return The emission per second of the reward distribution * @return The timestamp of the last update of the index * @return The timestamp of the distribution end **/ function getRewardsData( address asset, address reward ) external view returns (uint256, uint256, uint256, uint256); /** * @dev Calculates the next value of an specific distribution index, with validations. * @param asset The incentivized asset * @param reward The reward token of the incentivized asset * @return The old index of the asset distribution * @return The new index of the asset distribution **/ function getAssetIndex(address asset, address reward) external view returns (uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset * @param asset The incentivized asset * @return List of rewards addresses of the input asset **/ function getRewardsByAsset(address asset) external view returns (address[] memory); /** * @dev Returns the list of available reward addresses * @return List of rewards supported in this contract **/ function getRewardsList() external view returns (address[] memory); /** * @dev Returns the accrued rewards balance of a user, not including virtually accrued rewards since last distribution. * @param user The address of the user * @param reward The address of the reward token * @return Unclaimed rewards, not including new distributions **/ function getUserAccruedRewards(address user, address reward) external view returns (uint256); /** * @dev Returns a single rewards balance of a user, including virtually accrued and unrealized claimable rewards. * @param assets List of incentivized assets to check eligible distributions * @param user The address of the user * @param reward The address of the reward token * @return The rewards amount **/ function getUserRewards( address[] calldata assets, address user, address reward ) external view returns (uint256); /** * @dev Returns a list all rewards of a user, including already accrued and unrealized claimable rewards * @param assets List of incentivized assets to check eligible distributions * @param user The address of the user * @return The list of reward addresses * @return The list of unclaimed amount of rewards **/ function getAllUserRewards( address[] calldata assets, address user ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta * @param asset The address to retrieve decimals * @return The decimals of an underlying asset */ function getAssetDecimals(address asset) external view returns (uint8); /** * @dev Returns the address of the emission manager * @return The address of the EmissionManager */ function EMISSION_MANAGER() external view returns (address); /** * @dev Returns the address of the emission manager. * Deprecated: This getter is maintained for compatibility purposes. Use the `EMISSION_MANAGER()` function instead. * @return The address of the EmissionManager */ function getEmissionManager() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, 'Address: low-level delegate call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8.10; import {IERC20} from '../../openzeppelin/contracts/IERC20.sol'; /// @title Gnosis Protocol v2 Safe ERC20 Transfer Library /// @author Gnosis Developers /// @dev Gas-efficient version of Openzeppelin's SafeERC20 contract. library GPv2SafeERC20 { /// @dev Wrapper around a call to the ERC20 function `transfer` that reverts /// also when the token returns `false`. function safeTransfer(IERC20 token, address to, uint256 value) internal { bytes4 selector_ = token.transfer.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transfer'); } /// @dev Wrapper around a call to the ERC20 function `transferFrom` that /// reverts also when the token returns `false`. function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { bytes4 selector_ = token.transferFrom.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 68), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transferFrom'); } /// @dev Verifies that the last return was a successful `transfer*` call. /// This is done by checking that the return data is either empty, or /// is a valid ABI encoded boolean. function getLastTransferResult(IERC20 token) private view returns (bool success) { // NOTE: Inspecting previous return data requires assembly. Note that // we write the return data to memory 0 in the case where the return // data size is 32, this is OK since the first 64 bytes of memory are // reserved by Solidy as a scratch space that can be used within // assembly blocks. // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html> // solhint-disable-next-line no-inline-assembly assembly { /// @dev Revert with an ABI encoded Solidity error with a message /// that fits into 32-bytes. /// /// An ABI encoded Solidity error has the following memory layout: /// /// ------------+---------------------------------- /// byte range | value /// ------------+---------------------------------- /// 0x00..0x04 | selector("Error(string)") /// 0x04..0x24 | string offset (always 0x20) /// 0x24..0x44 | string length /// 0x44..0x64 | string value, padded to 32-bytes function revertWithMessage(length, message) { mstore(0x00, '\x08\xc3\x79\xa0') mstore(0x04, 0x20) mstore(0x24, length) mstore(0x44, message) revert(0x00, 0x64) } switch returndatasize() // Non-standard ERC20 transfer without return. case 0 { // NOTE: When the return data size is 0, verify that there // is code at the address. This is done in order to maintain // compatibility with Solidity calling conventions. // <https://docs.soliditylang.org/en/v0.7.6/control-structures.html#external-function-calls> if iszero(extcodesize(token)) { revertWithMessage(20, 'GPv2: not a contract') } success := 1 } // Standard ERC20 transfer returning boolean success value. case 32 { returndatacopy(0, 0, returndatasize()) // NOTE: For ABI encoding v1, any non-zero value is accepted // as `true` for a boolean. In order to stay compatible with // OpenZeppelin's `SafeERC20` library which is known to work // with the existing ERC20 implementation we care about, // make sure we return success for any non-zero return value // from the `transfer*` call. success := iszero(iszero(mload(0))) } default { revertWithMessage(31, 'GPv2: malformed transfer result') } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title IERC20WithPermit * @author Aave * @notice Interface for the permit function (EIP-2612) */ interface IERC20WithPermit is IERC20 { /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import './IERC20.sol'; import './Address.sol'; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), 'SafeERC20: approve from non-zero to non-zero allowance' ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, 'SafeERC20: decreased allowance below zero'); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, 'SafeERC20: low-level call failed'); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed'); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /// @title Optimized overflow and underflow safe math operations /// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost library SafeMath { /// @notice Returns x + y, reverts if sum overflows uint256 /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add(uint256 x, uint256 y) internal pure returns (uint256 z) { unchecked { require((z = x + y) >= x); } } /// @notice Returns x - y, reverts if underflows /// @param x The minuend /// @param y The subtrahend /// @return z The difference of x and y function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { unchecked { require((z = x - y) <= x); } } /// @notice Returns x - y, reverts if underflows /// @param x The minuend /// @param y The subtrahend /// @param message The error msg /// @return z The difference of x and y function sub(uint256 x, uint256 y, string memory message) internal pure returns (uint256 z) { unchecked { require((z = x - y) <= x, message); } } /// @notice Returns x * y, reverts if overflows /// @param x The multiplicand /// @param y The multiplier /// @return z The product of x and y function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { unchecked { require(x == 0 || (z = x * y) / x == y); } } /// @notice Returns x / y, reverts if overflows - no specific check, solidity reverts on division by 0 /// @param x The numerator /// @param y The denominator /// @return z The product of x and y function div(uint256 x, uint256 y) internal pure returns (uint256 z) { return x / y; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol'; /** * @title BaseParaSwapSellAdapter * @notice Implements the logic for selling tokens on ParaSwap * @author Jason Raymond Bell */ abstract contract BaseParaSwapSellAdapter is BaseParaSwapAdapter { using PercentageMath for uint256; using SafeMath for uint256; using SafeERC20 for IERC20Detailed; IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY; constructor( IPoolAddressesProvider addressesProvider, IParaSwapAugustusRegistry augustusRegistry ) BaseParaSwapAdapter(addressesProvider) { // Do something on Augustus registry to check the right contract was passed require(!augustusRegistry.isValidAugustus(address(0))); AUGUSTUS_REGISTRY = augustusRegistry; } /** * @dev Swaps a token for another using ParaSwap * @param fromAmountOffset Offset of fromAmount in Augustus calldata if it should be overwritten, otherwise 0 * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract * @param augustus Address of ParaSwap's AugustusSwapper contract * @param assetToSwapFrom Address of the asset to be swapped from * @param assetToSwapTo Address of the asset to be swapped to * @param amountToSwap Amount to be swapped * @param minAmountToReceive Minimum amount to be received from the swap * @return amountReceived The amount received from the swap */ function _sellOnParaSwap( uint256 fromAmountOffset, bytes memory swapCalldata, IParaSwapAugustus augustus, IERC20Detailed assetToSwapFrom, IERC20Detailed assetToSwapTo, uint256 amountToSwap, uint256 minAmountToReceive ) internal returns (uint256 amountReceived) { require(AUGUSTUS_REGISTRY.isValidAugustus(address(augustus)), 'INVALID_AUGUSTUS'); { uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 toAssetDecimals = _getDecimals(assetToSwapTo); uint256 fromAssetPrice = _getPrice(address(assetToSwapFrom)); uint256 toAssetPrice = _getPrice(address(assetToSwapTo)); uint256 expectedMinAmountOut = amountToSwap .mul(fromAssetPrice.mul(10 ** toAssetDecimals)) .div(toAssetPrice.mul(10 ** fromAssetDecimals)) .percentMul(PercentageMath.PERCENTAGE_FACTOR - MAX_SLIPPAGE_PERCENT); require(expectedMinAmountOut <= minAmountToReceive, 'MIN_AMOUNT_EXCEEDS_MAX_SLIPPAGE'); } uint256 balanceBeforeAssetFrom = assetToSwapFrom.balanceOf(address(this)); require(balanceBeforeAssetFrom >= amountToSwap, 'INSUFFICIENT_BALANCE_BEFORE_SWAP'); uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this)); address tokenTransferProxy = augustus.getTokenTransferProxy(); assetToSwapFrom.safeApprove(tokenTransferProxy, 0); assetToSwapFrom.safeApprove(tokenTransferProxy, amountToSwap); if (fromAmountOffset != 0) { // Ensure 256 bit (32 bytes) fromAmount value is within bounds of the // calldata, not overlapping with the first 4 bytes (function selector). require( fromAmountOffset >= 4 && fromAmountOffset <= swapCalldata.length.sub(32), 'FROM_AMOUNT_OFFSET_OUT_OF_RANGE' ); // Overwrite the fromAmount with the correct amount for the swap. // In memory, swapCalldata consists of a 256 bit length field, followed by // the actual bytes data, that is why 32 is added to the byte offset. assembly { mstore(add(swapCalldata, add(fromAmountOffset, 32)), amountToSwap) } } (bool success, ) = address(augustus).call(swapCalldata); if (!success) { // Copy revert reason from call assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require( assetToSwapFrom.balanceOf(address(this)) == balanceBeforeAssetFrom - amountToSwap, 'WRONG_BALANCE_AFTER_SWAP' ); amountReceived = assetToSwapTo.balanceOf(address(this)).sub(balanceBeforeAssetTo); require(amountReceived >= minAmountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED'); emit Swapped(address(assetToSwapFrom), address(assetToSwapTo), amountToSwap, amountReceived); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IParaSwapAugustusRegistry { function isValidAugustus(address augustus) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IParaSwapAugustus { function getTokenTransferProxy() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, 'ReentrancyGuard: reentrant call'); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev As we use the guard with the proxy we need to init it with the empty value */ function _initGuard() internal { _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol'; /** * @title BaseParaSwapBuyAdapter * @notice Implements the logic for buying tokens on ParaSwap */ abstract contract BaseParaSwapBuyAdapter is BaseParaSwapAdapter { using PercentageMath for uint256; using SafeMath for uint256; using SafeERC20 for IERC20Detailed; IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY; constructor( IPoolAddressesProvider addressesProvider, IParaSwapAugustusRegistry augustusRegistry ) BaseParaSwapAdapter(addressesProvider) { // Do something on Augustus registry to check the right contract was passed require(!augustusRegistry.isValidAugustus(address(0)), 'Not a valid Augustus address'); AUGUSTUS_REGISTRY = augustusRegistry; } /** * @dev Swaps a token for another using ParaSwap * @param toAmountOffset Offset of toAmount in Augustus calldata if it should be overwritten, otherwise 0 * @param paraswapData Data for Paraswap Adapter * @param assetToSwapFrom Address of the asset to be swapped from * @param assetToSwapTo Address of the asset to be swapped to * @param maxAmountToSwap Max amount to be swapped * @param amountToReceive Amount to be received from the swap * @return amountSold The amount sold during the swap * @return amountBought The amount bought during the swap */ function _buyOnParaSwap( uint256 toAmountOffset, bytes memory paraswapData, IERC20Detailed assetToSwapFrom, IERC20Detailed assetToSwapTo, uint256 maxAmountToSwap, uint256 amountToReceive ) internal returns (uint256 amountSold, uint256 amountBought) { (bytes memory buyCalldata, IParaSwapAugustus augustus) = abi.decode( paraswapData, (bytes, IParaSwapAugustus) ); require(AUGUSTUS_REGISTRY.isValidAugustus(address(augustus)), 'INVALID_AUGUSTUS'); { uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 toAssetDecimals = _getDecimals(assetToSwapTo); uint256 fromAssetPrice = _getPrice(address(assetToSwapFrom)); uint256 toAssetPrice = _getPrice(address(assetToSwapTo)); uint256 expectedMaxAmountToSwap = amountToReceive .mul(toAssetPrice.mul(10 ** fromAssetDecimals)) .div(fromAssetPrice.mul(10 ** toAssetDecimals)) .percentMul(PercentageMath.PERCENTAGE_FACTOR.add(MAX_SLIPPAGE_PERCENT)); require(maxAmountToSwap <= expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage'); } uint256 balanceBeforeAssetFrom = assetToSwapFrom.balanceOf(address(this)); require(balanceBeforeAssetFrom >= maxAmountToSwap, 'INSUFFICIENT_BALANCE_BEFORE_SWAP'); uint256 balanceBeforeAssetTo = assetToSwapTo.balanceOf(address(this)); address tokenTransferProxy = augustus.getTokenTransferProxy(); assetToSwapFrom.safeApprove(tokenTransferProxy, maxAmountToSwap); if (toAmountOffset != 0) { // Ensure 256 bit (32 bytes) toAmountOffset value is within bounds of the // calldata, not overlapping with the first 4 bytes (function selector). require( toAmountOffset >= 4 && toAmountOffset <= buyCalldata.length.sub(32), 'TO_AMOUNT_OFFSET_OUT_OF_RANGE' ); // Overwrite the toAmount with the correct amount for the buy. // In memory, buyCalldata consists of a 256 bit length field, followed by // the actual bytes data, that is why 32 is added to the byte offset. assembly { mstore(add(buyCalldata, add(toAmountOffset, 32)), amountToReceive) } } (bool success, ) = address(augustus).call(buyCalldata); if (!success) { // Copy revert reason from call assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } // Reset allowance assetToSwapFrom.safeApprove(tokenTransferProxy, 0); uint256 balanceAfterAssetFrom = assetToSwapFrom.balanceOf(address(this)); amountSold = balanceBeforeAssetFrom - balanceAfterAssetFrom; require(amountSold <= maxAmountToSwap, 'WRONG_BALANCE_AFTER_SWAP'); amountBought = assetToSwapTo.balanceOf(address(this)).sub(balanceBeforeAssetTo); require(amountBought >= amountToReceive, 'INSUFFICIENT_AMOUNT_RECEIVED'); emit Bought(address(assetToSwapFrom), address(assetToSwapTo), amountSold, amountBought); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) pragma solidity ^0.8.10; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, 'SafeCast: value must be positive'); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require( value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits" ); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require( value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits" ); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require( value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits" ); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require( value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits" ); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require( value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits" ); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/TransparentUpgradeableProxy.sol) /** * Adaptation of OpenZeppelin's TransparentUpgradeableProxy contract by BGD Labs. * The original contract creates a new proxy admin per contract. * In the context of AAVE this is suboptimal, as it is more efficient to have a single proxy admin for all proxies. * This way, if an executor is ever migrated to a new address only the ownership of that single proxy admin has to ever change. */ pragma solidity ^0.8.20; import {ERC1967Utils} from 'openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol'; import {ERC1967Proxy} from 'openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol'; import {IERC1967} from 'openzeppelin-contracts/contracts/interfaces/IERC1967.sol'; import {ProxyAdmin} from './ProxyAdmin.sol'; /** * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} * does not implement this interface directly, and its upgradeability mechanism is implemented by an internal dispatch * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not * include them in the ABI so this interface must be used to interact with it. */ interface ITransparentUpgradeableProxy is IERC1967 { function upgradeToAndCall(address, bytes calldata) external payable; } /** * @dev This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself. * 2. If the admin calls the proxy, it can call the `upgradeToAndCall` function but any other call won't be forwarded to * the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating * the proxy admin cannot fallback to the target implementation. * * These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a * dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to * call a function from the proxy implementation. You should think of the `ProxyAdmin` instance as the administrative * interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership. * * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not * inherit from that interface, and instead `upgradeToAndCall` is implicitly implemented using a custom dispatch * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the * implementation. * * NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a * meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract. * * IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an * immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be * overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an * undesirable state where the admin slot is different from the actual admin. * * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the * compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new * function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This * could render the `upgradeToAndCall` function inaccessible, preventing upgradeability and compromising transparency. */ contract TransparentUpgradeableProxy is ERC1967Proxy { // An immutable address for the admin to avoid unnecessary SLOADs before each call // at the expense of removing the ability to change the admin once it's set. // This is acceptable if the admin is always a ProxyAdmin instance or similar contract // with its own ability to transfer the permissions to another account. address private immutable _admin; /** * @dev The proxy caller is the current admin, and can't fallback to the proxy target. */ error ProxyDeniedAdminAccess(); /** * @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`, * backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in * {ERC1967Proxy-constructor}. */ constructor( address _logic, ProxyAdmin initialOwner, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { _admin = address(initialOwner); // Set the storage value and emit an event for ERC-1967 compatibility ERC1967Utils.changeAdmin(_proxyAdmin()); } /** * @dev Returns the admin of this proxy. */ function _proxyAdmin() internal virtual returns (address) { return _admin; } /** * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior. */ function _fallback() internal virtual override { if (msg.sender == _proxyAdmin()) { if (msg.sig != ITransparentUpgradeableProxy.upgradeToAndCall.selector) { revert ProxyDeniedAdminAccess(); } else { _dispatchUpgradeToAndCall(); } } else { super._fallback(); } } /** * @dev Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}. * * Requirements: * * - If `data` is empty, `msg.value` must be zero. */ function _dispatchUpgradeToAndCall() private { (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes)); ERC1967Utils.upgradeToAndCall(newImplementation, data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IAaveIncentivesController * @author Aave * @notice Defines the basic interface for an Aave Incentives Controller. * @dev It only contains one single function, needed as a hook on aToken and debtToken transfers. */ interface IAaveIncentivesController { /** * @dev Called by the corresponding asset on transfer hook in order to update the rewards distribution. * @dev The units of `totalSupply` and `userBalance` should be the same. * @param user The address of the user whose asset balance has changed * @param totalSupply The total supply of the asset prior to user balance change * @param userBalance The previous user balance prior to balance change */ function handleAction(address user, uint256 totalSupply, uint256 userBalance) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return payable(msg.sender); } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; import {FlashLoanSimpleReceiverBase} from '../../misc/flashloan/base/FlashLoanSimpleReceiverBase.sol'; import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; /** * @title BaseParaSwapAdapter * @notice Utility functions for adapters using ParaSwap * @author Jason Raymond Bell */ abstract contract BaseParaSwapAdapter is FlashLoanSimpleReceiverBase, Ownable { using SafeMath for uint256; using GPv2SafeERC20 for IERC20; using GPv2SafeERC20 for IERC20Detailed; using GPv2SafeERC20 for IERC20WithPermit; struct PermitSignature { uint256 amount; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } // Max slippage percent allowed uint256 public constant MAX_SLIPPAGE_PERCENT = 3000; // 30% IPriceOracleGetter public immutable ORACLE; event Swapped( address indexed fromAsset, address indexed toAsset, uint256 fromAmount, uint256 receivedAmount ); event Bought( address indexed fromAsset, address indexed toAsset, uint256 amountSold, uint256 receivedAmount ); constructor( IPoolAddressesProvider addressesProvider ) FlashLoanSimpleReceiverBase(addressesProvider) { ORACLE = IPriceOracleGetter(addressesProvider.getPriceOracle()); } /** * @dev Get the price of the asset from the oracle denominated in eth * @param asset address * @return eth price for the asset */ function _getPrice(address asset) internal view returns (uint256) { return ORACLE.getAssetPrice(asset); } /** * @dev Get the decimals of an asset * @return number of decimals of the asset */ function _getDecimals(IERC20Detailed asset) internal view returns (uint8) { uint8 decimals = asset.decimals(); // Ensure 10**decimals won't overflow a uint256 require(decimals <= 77, 'TOO_MANY_DECIMALS_ON_TOKEN'); return decimals; } /** * @dev Get the aToken associated to the asset * @return address of the aToken */ function _getReserveData( address asset ) internal view returns (DataTypes.ReserveDataLegacy memory) { return POOL.getReserveData(asset); } function _pullATokenAndWithdraw( address reserve, address user, uint256 amount, PermitSignature memory permitSignature ) internal { IERC20WithPermit reserveAToken = IERC20WithPermit( _getReserveData(address(reserve)).aTokenAddress ); _pullATokenAndWithdraw(reserve, reserveAToken, user, amount, permitSignature); } /** * @dev Pull the ATokens from the user * @param reserve address of the asset * @param reserveAToken address of the aToken of the reserve * @param user address * @param amount of tokens to be transferred to the contract * @param permitSignature struct containing the permit signature */ function _pullATokenAndWithdraw( address reserve, IERC20WithPermit reserveAToken, address user, uint256 amount, PermitSignature memory permitSignature ) internal { // If deadline is set to zero, assume there is no signature for permit if (permitSignature.deadline != 0) { reserveAToken.permit( user, address(this), permitSignature.amount, permitSignature.deadline, permitSignature.v, permitSignature.r, permitSignature.s ); } // transfer from user to adapter reserveAToken.safeTransferFrom(user, address(this), amount); // withdraw reserve require(POOL.withdraw(reserve, amount, address(this)) == amount, 'UNEXPECTED_AMOUNT_WITHDRAWN'); } /** * @dev Emergency rescue for token stucked on this contract, as failsafe mechanism * - Funds should never remain in this contract more time than during transactions * - Only callable by the owner */ function rescueTokens(IERC20 token) external onlyOwner { token.safeTransfer(owner(), token.balanceOf(address(this))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Utils.sol) pragma solidity ^0.8.21; import {IBeacon} from "../beacon/IBeacon.sol"; import {IERC1967} from "../../interfaces/IERC1967.sol"; import {Address} from "../../utils/Address.sol"; import {StorageSlot} from "../../utils/StorageSlot.sol"; /** * @dev This library provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots. */ library ERC1967Utils { /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev The `implementation` of the proxy is invalid. */ error ERC1967InvalidImplementation(address implementation); /** * @dev The `admin` of the proxy is invalid. */ error ERC1967InvalidAdmin(address admin); /** * @dev The `beacon` of the proxy is invalid. */ error ERC1967InvalidBeacon(address beacon); /** * @dev An upgrade function sees `msg.value > 0` that may be lost. */ error ERC1967NonPayable(); /** * @dev Returns the current implementation address. */ function getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the ERC-1967 implementation slot. */ function _setImplementation(address newImplementation) private { if (newImplementation.code.length == 0) { revert ERC1967InvalidImplementation(newImplementation); } StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Performs implementation upgrade with additional setup call if data is nonempty. * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected * to avoid stuck value in the contract. * * Emits an {IERC1967-Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) internal { _setImplementation(newImplementation); emit IERC1967.Upgraded(newImplementation); if (data.length > 0) { Address.functionDelegateCall(newImplementation, data); } else { _checkNonPayable(); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(ADMIN_SLOT).value; } /** * @dev Stores a new address in the ERC-1967 admin slot. */ function _setAdmin(address newAdmin) private { if (newAdmin == address(0)) { revert ERC1967InvalidAdmin(address(0)); } StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {IERC1967-AdminChanged} event. */ function changeAdmin(address newAdmin) internal { emit IERC1967.AdminChanged(getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1. */ // solhint-disable-next-line private-vars-leading-underscore bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(BEACON_SLOT).value; } /** * @dev Stores a new beacon in the ERC-1967 beacon slot. */ function _setBeacon(address newBeacon) private { if (newBeacon.code.length == 0) { revert ERC1967InvalidBeacon(newBeacon); } StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon; address beaconImplementation = IBeacon(newBeacon).implementation(); if (beaconImplementation.code.length == 0) { revert ERC1967InvalidImplementation(beaconImplementation); } } /** * @dev Change the beacon and trigger a setup call if data is nonempty. * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected * to avoid stuck value in the contract. * * Emits an {IERC1967-BeaconUpgraded} event. * * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for * efficiency. */ function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal { _setBeacon(newBeacon); emit IERC1967.BeaconUpgraded(newBeacon); if (data.length > 0) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } else { _checkNonPayable(); } } /** * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract * if an upgrade doesn't perform an initialization call. */ function _checkNonPayable() private { if (msg.value > 0) { revert ERC1967NonPayable(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.20; import {Proxy} from "../Proxy.sol"; import {ERC1967Utils} from "./ERC1967Utils.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`. * * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor. * * Requirements: * * - If `data` is empty, `msg.value` must be zero. */ constructor(address implementation, bytes memory _data) payable { ERC1967Utils.upgradeToAndCall(implementation, _data); } /** * @dev Returns the current implementation address. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function _implementation() internal view virtual override returns (address) { return ERC1967Utils.getImplementation(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.20; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IFlashLoanSimpleReceiver} from '../interfaces/IFlashLoanSimpleReceiver.sol'; import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../../../interfaces/IPool.sol'; /** * @title FlashLoanSimpleReceiverBase * @author Aave * @notice Base contract to develop a flashloan-receiver contract. */ abstract contract FlashLoanSimpleReceiverBase is IFlashLoanSimpleReceiver { IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; IPool public immutable override POOL; constructor(IPoolAddressesProvider provider) { ADDRESSES_PROVIDER = provider; POOL = IPool(provider.getPool()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import './Context.sol'; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'Ownable: new owner is the zero address'); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.20; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {UpgradeableBeacon} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC-1967 implementation slot: * ```solidity * contract ERC1967 { * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * TIP: Consider using this library along with {SlotDerivation}. */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct Int256Slot { int256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Int256Slot` with member `value` located at `slot`. */ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } /** * @dev Returns a `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol) pragma solidity ^0.8.20; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback * function and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; import {IPool} from '../../../interfaces/IPool.sol'; /** * @title IFlashLoanSimpleReceiver * @author Aave * @notice Defines the basic interface of a flashloan-receiver contract. * @dev Implement this interface to develop a flashloan-compatible flashLoanReceiver contract */ interface IFlashLoanSimpleReceiver { /** * @notice Executes an operation after receiving the flash-borrowed asset * @dev Ensure that the contract can return the debt + premium, e.g., has * enough funds to repay and has approved the Pool to pull the total amount * @param asset The address of the flash-borrowed asset * @param amount The amount of the flash-borrowed asset * @param premium The fee of the flash-borrowed asset * @param initiator The address of the flashloan initiator * @param params The byte-encoded params passed when initiating the flashloan * @return True if the execution of the operation succeeds, false otherwise */ function executeOperation( address asset, uint256 amount, uint256 premium, address initiator, bytes calldata params ) external returns (bool); function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); function POOL() external view returns (IPool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
{ "remappings": [ "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "@pythnetwork/=lib/pyth-sdk-solidity/", "@money-market/=contracts/moneyMarket/src/", "@money-market-scripts/=contracts/moneyMarket/scripts/", "@money-market-tests/=contracts/moneyMarket/tests/", "@contracts/=contracts/", "solidity-utils/=lib/solidity-utils/src/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "ds-test/=lib/solmate/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/", "pyth-sdk-solidity/=lib/pyth-sdk-solidity/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": { "contracts/moneyMarket/src/contracts/protocol/libraries/logic/BorrowLogic.sol": { "BorrowLogic": "0x8d2517e8eb3a288813F3d86Acf72583c93137cC7" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/BridgeLogic.sol": { "BridgeLogic": "0x4Fa0B79Cd0382b8bf9F90755Ae2dB1004b67Ba12" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol": { "ConfiguratorLogic": "0x616a5cAab4973a741E18Ba95B8Dfa766de34Fb71" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/EModeLogic.sol": { "EModeLogic": "0xfC1E2b81f2b20D829E05BcEa902a9959CE083F0A" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/FlashLoanLogic.sol": { "FlashLoanLogic": "0xEa33385DD1De5790b49752449B8C4f88e5013ac3" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/LiquidationLogic.sol": { "LiquidationLogic": "0x634E2130c0B8EbF1a3eF111A0337f23cFF28d19A" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/PoolLogic.sol": { "PoolLogic": "0xedeae456C72c464E917C690DE562eC02a7b426B4" }, "contracts/moneyMarket/src/contracts/protocol/libraries/logic/SupplyLogic.sol": { "SupplyLogic": "0x16D26622643973B3ea574280998572F220Ede139" } } }
Contract ABI
API[{"inputs":[{"internalType":"bool","name":"l2Flag","type":"bool"},{"internalType":"address","name":"poolAddressesProvider","type":"address"},{"internalType":"address","name":"sequencerUptimeOracle","type":"address"},{"internalType":"uint256","name":"gracePeriod","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"L2MustBeDisabled","type":"error"},{"inputs":[],"name":"L2MustBeEnabled","type":"error"},{"inputs":[],"name":"ProviderNotFound","type":"error"},{"inputs":[],"name":"ProxyAdminNotFound","type":"error"},{"inputs":[],"name":"getMiscReport","outputs":[{"components":[{"internalType":"address","name":"priceOracleSentinel","type":"address"},{"internalType":"address","name":"defaultInterestRateStrategy","type":"address"}],"internalType":"struct MiscReport","name":"","type":"tuple"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561000f575f5ffd5b50604051611af4380380611af483398101604081905261002e916101ac565b5f61003b85858585610078565b80515f80546001600160a01b03199081166001600160a01b0393841617909155602090920151600180549093169116179055506101fa9350505050565b604080518082019091525f80825260208201526001600160a01b0384166100b25760405163b1cd090360e01b815260040160405180910390fd5b8480156100c757506001600160a01b03831615155b80156100d257508115155b1561012a578383836040516100e690610177565b6001600160a01b0393841681529290911660208301526040820152606001604051809103905ff08015801561011d573d5f5f3e3d5ffd5b506001600160a01b031681525b8360405161013790610184565b6001600160a01b039091168152602001604051809103905ff080158015610160573d5f5f3e3d5ffd5b506001600160a01b03166020820152949350505050565b610771806102b883390190565b6110cb80610a2983390190565b80516001600160a01b03811681146101a7575f5ffd5b919050565b5f5f5f5f608085870312156101bf575f5ffd5b845180151581146101ce575f5ffd5b93506101dc60208601610191565b92506101ea60408601610191565b6060959095015193969295505050565b60b2806102065f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063edffa84714602a575b5f5ffd5b6040805180820182525f80825260209182018190528251808401845290546001600160a01b03908116808352600154821692840192835284519081529151169181019190915281519081900390910190f3fea2646970667358221220017a720ed55695ccf843dde9f6e2e3c80d34422ddb4af8dbf12745887d1e3b8664736f6c634300081c003360a060405234801561000f575f5ffd5b5060405161077138038061077183398101604081905261002e91610073565b6001600160a01b039283166080525f80546001600160a01b03191692909316919091179091556001556100b3565b6001600160a01b0381168114610070575f5ffd5b50565b5f5f5f60608486031215610085575f5ffd5b83516100908161005c565b60208501519093506100a18161005c565b80925050604084015190509250925092565b6080516106996100d85f395f818160830152818161013401526102b501526106995ff3fe608060405234801561000f575f5ffd5b506004361061007a575f3560e01c80637a5d20ea116100585780637a5d20ea146100d2578063dbd18388146100ea578063f0aef31c146100fb578063f2f6596014610110575f5ffd5b80630542975c1461007e57806312168dc2146100c257806349aa2e81146100d2575b5f5ffd5b6100a57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b5f546001600160a01b03166100a5565b6100da610123565b60405190151581526020016100b9565b6001546040519081526020016100b9565b61010e61010936600461052a565b610131565b005b61010e61011e36600461054c565b6102b2565b5f61012c610476565b905090565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663707cd7166040518163ffffffff1660e01b8152600401602060405180830381865afa15801561018e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101b29190610563565b604051637be53ca160e01b81523360048201529091506001600160a01b03821690637be53ca190602401602060405180830381865afa1580156101f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061021b919061057e565b604051806040016040528060018152602001603160f81b8152509061025c5760405162461bcd60e51b8152600401610253919061059d565b60405180910390fd5b505f80546001600160a01b0319166001600160a01b0384169081179091556040519081527f95cbf1d8f44ec81ff345ed9cf2fe53b6a6473e072bf046ee412f198c54dba449906020015b60405180910390a15050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663707cd7166040518163ffffffff1660e01b8152600401602060405180830381865afa15801561030f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103339190610563565b60405163674b5e4d60e01b81523360048201529091506001600160a01b0382169063674b5e4d90602401602060405180830381865afa158015610378573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061039c919061057e565b806104085750604051637be53ca160e01b81523360048201526001600160a01b03821690637be53ca190602401602060405180830381865afa1580156103e4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610408919061057e565b604051806040016040528060018152602001600d60fa1b815250906104405760405162461bcd60e51b8152600401610253919061059d565b5060018290556040518281527f33d1191f5a3abfe19d468d51bb5ece97489f1277a912a5b5c65992fc279ad3d4906020016102a6565b5f5f5f5f5f9054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156104c8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ec91906105f0565b50509250925050815f14801561050c575060015461050a824261063e565b115b9250505090565b6001600160a01b0381168114610527575f5ffd5b50565b5f6020828403121561053a575f5ffd5b813561054581610513565b9392505050565b5f6020828403121561055c575f5ffd5b5035919050565b5f60208284031215610573575f5ffd5b815161054581610513565b5f6020828403121561058e575f5ffd5b81518015158114610545575f5ffd5b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b805169ffffffffffffffffffff811681146105eb575f5ffd5b919050565b5f5f5f5f5f60a08688031215610604575f5ffd5b61060d866105d2565b60208701516040880151606089015192975090955093509150610632608087016105d2565b90509295509295909350565b8181038181111561065d57634e487b7160e01b5f52601160045260245ffd5b9291505056fea26469706673582212203a67faa04675fcbf1c5e28669b50e44520615a4c0795ce2f1a47c4e4fad3f63064736f6c634300081c003360a060405234801561000f575f5ffd5b506040516110cb3803806110cb83398101604081905261002e91610089565b604080518082019091526002815261189960f11b60208201526001600160a01b0382166100775760405162461bcd60e51b815260040161006e91906100b6565b60405180910390fd5b506001600160a01b03166080526100eb565b5f60208284031215610099575f5ffd5b81516001600160a01b03811681146100af575f5ffd5b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b608051610fbb6101105f395f818160ee0152818161047201526108030152610fbb5ff3fe608060405234801561000f575f5ffd5b50600436106100e5575f3560e01c8063a8d9e56f11610088578063c79ce42e11610063578063c79ce42e1461021d578063cca22ea1146102fa578063f7e0fe671461030d578063fd81bb1214610315575f5ffd5b8063a8d9e56f146101cd578063aa33f063146101e2578063b90db31b146101f5575f5ffd5b80636a00178e116100c35780636a00178e146101945780637a0c5ebf146101a75780637a24bd7e146101b15780638f4b0d5d146101ba575f5ffd5b80630542975c146100e9578063131e889c1461012d5780635b651bae14610173575b5f5ffd5b6101107f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61014061013b366004610c7c565b610328565b60405161012491908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b610186610181366004610c7c565b6103ba565b604051908152602001610124565b6101866101a2366004610c7c565b6103e8565b610186620186a081565b6101866126ac81565b6101866101c8366004610c7c565b610442565b6101e06101db366004610c9e565b610470565b005b6101866101f0366004610c7c565b610561565b610208610203366004610d68565b610586565b60408051928352602083019190915201610124565b6102ad61022b366004610c7c565b604080516080810182525f808252602082018190529181018290526060810191909152506001600160a01b03165f90815260208181526040918290208251608081018452905461ffff8116825263ffffffff620100008204811693830193909352600160301b8104831693820193909352600160501b90920416606082015290565b60405161012491905f60808201905061ffff835116825263ffffffff602084015116602083015263ffffffff604084015116604083015263ffffffff606084015116606083015292915050565b610186610308366004610c7c565b6107d4565b610186606481565b6101e0610323366004610de6565b610801565b61034f60405180608001604052805f81526020015f81526020015f81526020015f81525090565b6001600160a01b0382165f90815260208181526040918290208251608081018452905461ffff8116825263ffffffff620100008204811693830193909352600160301b8104831693820193909352600160501b9092041660608201526103b4906108e6565b92915050565b6001600160a01b0381165f908152602081905260408120546103b490600160301b900463ffffffff16610978565b6001600160a01b0381165f908152602081905260408120546103b49063ffffffff600160501b820481169161042d91600160301b820481169162010000900416610e38565b6104379190610e38565b63ffffffff16610978565b6001600160a01b0381165f908152602081905260408120546103b490600160501b900463ffffffff16610978565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663631adfca6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104cc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104f09190610e54565b6001600160a01b0316336001600160a01b03161460405180604001604052806002815260200161031360f41b815250906105465760405162461bcd60e51b815260040161053d9190610e6f565b60405180910390fd5b5061055c8361055783850185610eb7565b61098d565b505050565b6001600160a01b0381165f908152602081905260408120546103b49061ffff16610978565b60a08101516001600160a01b03165f908152602081815260408083208151608081018352905461ffff8116825263ffffffff620100008204811694830194909452600160301b8104841692820192909252600160501b9091049091166060820152819081906105f4906108e6565b90508360c0015161060d57602001515f94909350915050565b6106406040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f6040820152602080830151908201526060850151156106d157846040015185602001518660e001516106739190610f48565b61067d9190610f5b565b808252606086015161068e91610f48565b60a0820181905260608601516106a391610bc2565b6060820152845160a08201516106c7916106bc91610f48565b606087015190610bc2565b60808201526106e0565b602001515f9590945092505050565b81516060820151111561075e5781515f906107229061070b906b033b2e3c9fd0803ce8000000610f5b565b8451606085015161071c9190610f5b565b90610bc2565b60608401519091506107349082610bff565b83604001516107439190610f48565b826020018181516107549190610f48565b90525061078e9050565b815160608201516040840151610779929161071c9190610bff565b8160200181815161078a9190610f48565b9052505b6107bc85608001516127106107a39190610f5b565b608083015160208401516107b691610bff565b90610c41565b60408201819052602090910151909590945092505050565b6001600160a01b0381165f908152602081905260408120546103b49062010000900463ffffffff16610978565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663631adfca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561085d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108819190610e54565b6001600160a01b0316336001600160a01b03161460405180604001604052806002815260200161031360f41b815250906108ce5760405162461bcd60e51b815260040161053d9190610e6f565b506108e28261055736849003840184610eb7565b5050565b61090d60405180608001604052805f81526020015f81526020015f81526020015f81525090565b6040518060800160405280610928845f015161ffff16610978565b8152602001610940846020015163ffffffff16610978565b8152602001610958846040015163ffffffff16610978565b8152602001610970846060015163ffffffff16610978565b905292915050565b5f6103b48269152d02c7e14af6800000610f6e565b604080518082019091526002815261373760f01b60208201526001600160a01b0383166109cd5760405162461bcd60e51b815260040161053d9190610e6f565b506126ac815f015161ffff16111580156109ef57506064815f015161ffff1610155b60405180604001604052806002815260200161383360f01b81525090610a285760405162461bcd60e51b815260040161053d9190610e6f565b50806060015163ffffffff16816040015163ffffffff16111560405180604001604052806002815260200161393560f01b81525090610a7a5760405162461bcd60e51b815260040161053d9190610e6f565b50620186a0816060015163ffffffff16826040015163ffffffff16836020015163ffffffff16610aaa9190610f48565b610ab49190610f48565b1115604051806040016040528060028152602001611c9960f11b81525090610aef5760405162461bcd60e51b815260040161053d9190610e6f565b506001600160a01b0382165f81815260208181526040918290208451815486840151878601516060808a015161ffff90951665ffffffffffff1990941684176201000063ffffffff948516908102919091176dffffffffffffffff0000000000001916600160301b93851693840263ffffffff60501b191617600160501b9490961693840295909517909555865192835294820192909252938401929092528201527f5d123bea2036a4052274206f59d99350b9741e17da56ffae335d809b25ee09429060800160405180910390a25050565b5f81156b033b2e3c9fd0803ce800000060028404190484111715610be4575f5ffd5b506b033b2e3c9fd0803ce80000009190910260028204010490565b5f81156b019d971e4fe8401e740000001983900484111517610c1f575f5ffd5b506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b5f81156113881983900484111517610c57575f5ffd5b506127109102611388010490565b6001600160a01b0381168114610c79575f5ffd5b50565b5f60208284031215610c8c575f5ffd5b8135610c9781610c65565b9392505050565b5f5f5f60408486031215610cb0575f5ffd5b8335610cbb81610c65565b9250602084013567ffffffffffffffff811115610cd6575f5ffd5b8401601f81018613610ce6575f5ffd5b803567ffffffffffffffff811115610cfc575f5ffd5b866020828401011115610d0d575f5ffd5b939660209190910195509293505050565b604051610100810167ffffffffffffffff81118282101715610d4e57634e487b7160e01b5f52604160045260245ffd5b60405290565b80358015158114610d63575f5ffd5b919050565b5f610100828403128015610d7a575f5ffd5b50610d83610d1e565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0830135610dbd81610c65565b60a0820152610dce60c08401610d54565b60c082015260e0928301359281019290925250919050565b5f5f82840360a0811215610df8575f5ffd5b8335610e0381610c65565b92506080601f1982011215610e16575f5ffd5b506020830190509250929050565b634e487b7160e01b5f52601160045260245ffd5b63ffffffff81811683821601908111156103b4576103b4610e24565b5f60208284031215610e64575f5ffd5b8151610c9781610c65565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b803563ffffffff81168114610d63575f5ffd5b5f6080828403128015610ec8575f5ffd5b506040516080810167ffffffffffffffff81118282101715610ef857634e487b7160e01b5f52604160045260245ffd5b604052823561ffff81168114610f0c575f5ffd5b8152610f1a60208401610ea4565b6020820152610f2b60408401610ea4565b6040820152610f3c60608401610ea4565b60608201529392505050565b808201808211156103b4576103b4610e24565b818103818111156103b4576103b4610e24565b80820281158282048414176103b4576103b4610e2456fea2646970667358221220fa3ec8dc6ca195a15b2c5024dd462d3b003dc7cb64a744e9b80c1633d5174f0064736f6c634300081c0033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b3f588578bf89b1d2af7283762e3375f0340da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063edffa84714602a575b5f5ffd5b6040805180820182525f80825260209182018190528251808401845290546001600160a01b03908116808352600154821692840192835284519081529151169181019190915281519081900390910190f3fea2646970667358221220017a720ed55695ccf843dde9f6e2e3c80d34422ddb4af8dbf12745887d1e3b8664736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b3f588578bf89b1d2af7283762e3375f0340da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : l2Flag (bool): False
Arg [1] : poolAddressesProvider (address): 0x04b3f588578BF89B1D2af7283762E3375f0340dA
Arg [2] : sequencerUptimeOracle (address): 0x0000000000000000000000000000000000000000
Arg [3] : gracePeriod (uint256): 0
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000004b3f588578bf89b1d2af7283762e3375f0340da
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.