Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
SparkEthereum_20250320
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.25; import { IERC20 } from 'forge-std/interfaces/IERC20.sol'; import { Ethereum } from 'spark-address-registry/Ethereum.sol'; import { ICapAutomator } from "sparklend-cap-automator/interfaces/ICapAutomator.sol"; import { IMetaMorpho, MarketParams } from 'metamorpho/interfaces/IMetaMorpho.sol'; import { IAaveV3ConfigEngine as IEngine } from '../../interfaces/IAaveV3ConfigEngine.sol'; import { SparkPayloadEthereum, Rates, EngineFlags } from "../../SparkPayloadEthereum.sol"; /** * @title March 20, 2025 Spark Ethereum Proposal * @notice SparkLend: Onboard LBTC, tBTC, ezETH, rsETH, create new BTC emode with LBTC and cbBTC * Update DAI/USDS IRMs to 50bps spread (No poll required) * Morpho: Onboard May eUSDe PT, July USDe PT * @author Phoenix Labs * Forum: https://forum.sky.money/t/march-6-2025-proposed-changes-to-spark-for-upcoming-spell/26036 * https://forum.sky.money/t/march-20-2025-proposed-changes-to-spark-for-upcoming-spell/26113 * https://forum.sky.money/t/mar-20-2025-stability-scope-parameter-changes-24/26129 * Vote: https://vote.makerdao.com/polling/QmfM4SBB * https://vote.makerdao.com/polling/QmbDzZ3F * https://vote.makerdao.com/polling/QmTj3BSu * https://vote.makerdao.com/polling/QmPkA2GP */ contract SparkEthereum_20250320 is SparkPayloadEthereum { address internal constant AGGOR_BTCUSD_ORACLE = 0x4219aA1A99f3fe90C2ACB97fCbc1204f6485B537; address internal constant EZETH_ORACLE = 0x52E85eB49e07dF74c8A9466D2164b4C4cA60014A; address internal constant RSETH_ORACLE = 0x70942D6b580741CF50A7906f4100063EE037b8eb; address internal constant PT_EUSDE_29MAY2025 = 0x50D2C7992b802Eef16c04FeADAB310f31866a545; address internal constant PT_EUSDE_29MAY2025_PRICE_FEED = 0x39a695Eb6d0C01F6977521E5E79EA8bc232b506a; address internal constant PT_USDE_31JUL2025 = 0x917459337CaAC939D41d7493B3999f571D20D667; address internal constant PT_USDE_31JUL2025_PRICE_FEED = 0xFCaE69BEF9B6c96D89D58664d8aeA84BddCe2E5c; address internal constant DAI_IRM = 0x5a7E7a32331189a794ac33Fec76C0A1dD3dDCF9c; address internal constant USDS_IRM = 0xD94BA511284d2c56F59a687C3338441d33304E07; constructor() { PAYLOAD_BASE = 0x356f19Cb575CF40c7ff33A5117F9a9264C23f6e8; PAYLOAD_ARBITRUM = 0x1d54A093b8FDdFcc6fBB411d9Af31D96e034B3D5; } function _preExecute() internal override { LISTING_ENGINE.POOL_CONFIGURATOR().setEModeCategory({ categoryId: 3, ltv: 85_00, liquidationThreshold: 90_00, liquidationBonus: 102_00, oracle: address(0), // No oracle override label: 'BTC' }); } function newListings() public pure override returns (IEngine.Listing[] memory) { IEngine.Listing[] memory listings = new IEngine.Listing[](4); listings[0] = IEngine.Listing({ asset: Ethereum.LBTC, assetSymbol: 'LBTC', priceFeed: AGGOR_BTCUSD_ORACLE, rateStrategyParams: Rates.RateStrategyParams({ optimalUsageRatio: _bpsToRay(45_00), baseVariableBorrowRate: _bpsToRay(5_00), variableRateSlope1: _bpsToRay(15_00), variableRateSlope2: _bpsToRay(300_00), stableRateSlope1: 0, stableRateSlope2: 0, baseStableRateOffset: 0, stableRateExcessOffset: 0, optimalStableToTotalDebtRatio: 0 }), enabledToBorrow: EngineFlags.DISABLED, stableRateModeEnabled: EngineFlags.DISABLED, borrowableInIsolation: EngineFlags.DISABLED, withSiloedBorrowing: EngineFlags.DISABLED, flashloanable: EngineFlags.DISABLED, ltv: 65_00, liqThreshold: 70_00, liqBonus: 8_00, reserveFactor: 15_00, supplyCap: 250, borrowCap: 0, debtCeiling: 0, liqProtocolFee: 10_00, eModeCategory: 3 }); listings[1] = IEngine.Listing({ asset: Ethereum.TBTC, assetSymbol: 'tBTC', priceFeed: AGGOR_BTCUSD_ORACLE, rateStrategyParams: Rates.RateStrategyParams({ optimalUsageRatio: _bpsToRay(60_00), baseVariableBorrowRate: 0, variableRateSlope1: _bpsToRay(4_00), variableRateSlope2: _bpsToRay(300_00), stableRateSlope1: 0, stableRateSlope2: 0, baseStableRateOffset: 0, stableRateExcessOffset: 0, optimalStableToTotalDebtRatio: 0 }), enabledToBorrow: EngineFlags.ENABLED, stableRateModeEnabled: EngineFlags.DISABLED, borrowableInIsolation: EngineFlags.DISABLED, withSiloedBorrowing: EngineFlags.DISABLED, flashloanable: EngineFlags.ENABLED, ltv: 65_00, liqThreshold: 70_00, liqBonus: 8_00, reserveFactor: 20_00, supplyCap: 125, borrowCap: 25, debtCeiling: 0, liqProtocolFee: 10_00, eModeCategory: 0 }); listings[2] = IEngine.Listing({ asset: Ethereum.EZETH, assetSymbol: 'ezETH', priceFeed: EZETH_ORACLE, rateStrategyParams: Rates.RateStrategyParams({ optimalUsageRatio: _bpsToRay(45_00), baseVariableBorrowRate: _bpsToRay(5_00), variableRateSlope1: _bpsToRay(15_00), variableRateSlope2: _bpsToRay(300_00), stableRateSlope1: 0, stableRateSlope2: 0, baseStableRateOffset: 0, stableRateExcessOffset: 0, optimalStableToTotalDebtRatio: 0 }), enabledToBorrow: EngineFlags.DISABLED, stableRateModeEnabled: EngineFlags.DISABLED, borrowableInIsolation: EngineFlags.DISABLED, withSiloedBorrowing: EngineFlags.DISABLED, flashloanable: EngineFlags.DISABLED, ltv: 72_00, liqThreshold: 73_00, liqBonus: 10_00, reserveFactor: 15_00, supplyCap: 2_000, borrowCap: 0, debtCeiling: 0, liqProtocolFee: 10_00, eModeCategory: 0 }); listings[3] = IEngine.Listing({ asset: Ethereum.RSETH, assetSymbol: 'rsETH', priceFeed: RSETH_ORACLE, rateStrategyParams: Rates.RateStrategyParams({ optimalUsageRatio: _bpsToRay(45_00), baseVariableBorrowRate: _bpsToRay(5_00), variableRateSlope1: _bpsToRay(15_00), variableRateSlope2: _bpsToRay(300_00), stableRateSlope1: 0, stableRateSlope2: 0, baseStableRateOffset: 0, stableRateExcessOffset: 0, optimalStableToTotalDebtRatio: 0 }), enabledToBorrow: EngineFlags.DISABLED, stableRateModeEnabled: EngineFlags.DISABLED, borrowableInIsolation: EngineFlags.DISABLED, withSiloedBorrowing: EngineFlags.DISABLED, flashloanable: EngineFlags.DISABLED, ltv: 72_00, liqThreshold: 73_00, liqBonus: 10_00, reserveFactor: 15_00, supplyCap: 2_000, borrowCap: 0, debtCeiling: 0, liqProtocolFee: 10_00, eModeCategory: 0 }); return listings; } function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory collateralUpdates) { collateralUpdates = new IEngine.CollateralUpdate[](1); collateralUpdates[0] = IEngine.CollateralUpdate({ asset: Ethereum.CBBTC, ltv: EngineFlags.KEEP_CURRENT, liqThreshold: EngineFlags.KEEP_CURRENT, liqBonus: EngineFlags.KEEP_CURRENT, debtCeiling: EngineFlags.KEEP_CURRENT, liqProtocolFee: EngineFlags.KEEP_CURRENT, eModeCategory: 3 }); } function _postExecute() internal override { // Seed the new LBTC pool IERC20(Ethereum.LBTC).approve(address(LISTING_ENGINE.POOL()), 0.0001e8); LISTING_ENGINE.POOL().supply(Ethereum.LBTC, 0.0001e8, address(this), 0); // Seed the new tBTC pool IERC20(Ethereum.TBTC).approve(address(LISTING_ENGINE.POOL()), 0.0001e18); LISTING_ENGINE.POOL().supply(Ethereum.TBTC, 0.0001e18, address(this), 0); // Seed the new ezETH pool IERC20(Ethereum.EZETH).approve(address(LISTING_ENGINE.POOL()), 0.0001e18); LISTING_ENGINE.POOL().supply(Ethereum.EZETH, 0.0001e18, address(this), 0); // Seed the new rsETH pool IERC20(Ethereum.RSETH).approve(address(LISTING_ENGINE.POOL()), 0.0001e18); LISTING_ENGINE.POOL().supply(Ethereum.RSETH, 0.0001e18, address(this), 0); ICapAutomator capAutomator = ICapAutomator(Ethereum.CAP_AUTOMATOR); capAutomator.setSupplyCapConfig({ asset: Ethereum.LBTC, max: 2500, gap: 250, increaseCooldown: 12 hours }); capAutomator.setSupplyCapConfig({ asset: Ethereum.TBTC, max: 500, gap: 125, increaseCooldown: 12 hours }); capAutomator.setBorrowCapConfig({ asset: Ethereum.TBTC, max: 250, gap: 25, increaseCooldown: 12 hours }); capAutomator.setSupplyCapConfig({ asset: Ethereum.EZETH, max: 20_000, gap: 2_000, increaseCooldown: 12 hours }); capAutomator.setSupplyCapConfig({ asset: Ethereum.RSETH, max: 20_000, gap: 2_000, increaseCooldown: 12 hours }); // Onboard PT-eUSDE-29MAY2025/DAI IMetaMorpho(Ethereum.MORPHO_VAULT_DAI_1).submitCap( MarketParams({ loanToken: Ethereum.DAI, collateralToken: PT_EUSDE_29MAY2025, oracle: PT_EUSDE_29MAY2025_PRICE_FEED, irm: Ethereum.MORPHO_DEFAULT_IRM, lltv: 0.915e18 }), 300_000_000e18 ); // Onboard PT-USDe-31JUL2025/DAI IMetaMorpho(Ethereum.MORPHO_VAULT_DAI_1).submitCap( MarketParams({ loanToken: Ethereum.DAI, collateralToken: PT_USDE_31JUL2025, oracle: PT_USDE_31JUL2025_PRICE_FEED, irm: Ethereum.MORPHO_DEFAULT_IRM, lltv: 0.915e18 }), 200_000_000e18 ); // Update DAI/USDS IRMs to 50bps spread LISTING_ENGINE.POOL_CONFIGURATOR().setReserveInterestRateStrategyAddress( Ethereum.DAI, DAI_IRM ); LISTING_ENGINE.POOL_CONFIGURATOR().setReserveInterestRateStrategyAddress( Ethereum.USDS, USDS_IRM ); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2; /// @dev Interface of the ERC20 standard as defined in the EIP. /// @dev This includes the optional name, symbol, and decimals metadata. interface IERC20 { /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). event Transfer(address indexed from, address indexed to, uint256 value); /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` /// is the new allowance. event Approval(address indexed owner, address indexed spender, uint256 value); /// @notice Returns the amount of tokens in existence. function totalSupply() external view returns (uint256); /// @notice Returns the amount of tokens owned by `account`. function balanceOf(address account) external view returns (uint256); /// @notice Moves `amount` tokens from the caller's account to `to`. function transfer(address to, uint256 amount) external returns (bool); /// @notice Returns the remaining number of tokens that `spender` is allowed /// to spend on behalf of `owner` function allowance(address owner, address spender) external view returns (uint256); /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 function approve(address spender, uint256 amount) external returns (bool); /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. /// `amount` is then deducted from the caller's allowance. function transferFrom(address from, address to, uint256 amount) external returns (bool); /// @notice Returns the name of the token. function name() external view returns (string memory); /// @notice Returns the symbol of the token. function symbol() external view returns (string memory); /// @notice Returns the decimals places of the token. function decimals() external view returns (uint8); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; library Ethereum { /******************************************************************************************************************/ /*** Token Addresses ***/ /******************************************************************************************************************/ address internal constant CBBTC = 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf; address internal constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address internal constant EZETH = 0xbf5495Efe5DB9ce00f80364C8B423567e58d2110; address internal constant GNO = 0x6810e776880C02933D47DB1b9fc05908e5386b96; address internal constant LBTC = 0x8236a87084f8B84306f72007F36F2618A5634494; address internal constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; address internal constant RETH = 0xae78736Cd615f374D3085123A210448E74Fc6393; address internal constant RSETH = 0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7; address internal constant SDAI = 0x83F20F44975D03b1b09e64809B757c47f942BEeA; address internal constant SUSDC = 0xBc65ad17c5C0a2A4D159fa5a503f4992c7B545FE; address internal constant SUSDE = 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; address internal constant SUSDS = 0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD; address internal constant TBTC = 0x18084fbA666a33d37592fA2633fD49a74DD93a88; address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address internal constant USDE = 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3; address internal constant USDS = 0xdC035D45d973E3EC169d2276DDab16f1e407384F; address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address internal constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address internal constant WEETH = 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee; address internal constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address internal constant WSTETH = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; /******************************************************************************************************************/ /*** MakerDAO Addresses ***/ /******************************************************************************************************************/ address internal constant CHIEF = 0x0a3f6849f78076aefaDf113F5BED87720274dDC0; address internal constant DAI_USDS = 0x3225737a9Bbb6473CB4a45b7244ACa2BeFdB276A; address internal constant PAUSE_PROXY = 0xBE8E3e3618f7474F8cB1d074A26afFef007E98FB; address internal constant POT = 0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7; address internal constant PSM = 0xf6e72Db5454dd049d0788e411b06CfAF16853042; // Lite PSM address internal constant VAT = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B; /******************************************************************************************************************/ /*** SparkDAO Addresses ***/ /******************************************************************************************************************/ address internal constant SPARK_PROXY = 0x3300f198988e4C9C63F75dF86De36421f06af8c4; address internal constant SPARK_REWARDS = 0xbaf21A27622Db71041Bd336a573DDEdC8eB65122; /******************************************************************************************************************/ /*** Allocation System Addresses ***/ /******************************************************************************************************************/ address internal constant ALLOCATOR_BUFFER = 0xc395D150e71378B47A1b8E9de0c1a83b75a08324; address internal constant ALLOCATOR_ORACLE = 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7; address internal constant ALLOCATOR_REGISTRY = 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B; address internal constant ALLOCATOR_ROLES = 0x9A865A710399cea85dbD9144b7a09C889e94E803; address internal constant ALLOCATOR_VAULT = 0x691a6c29e9e96dd897718305427Ad5D534db16BA; /******************************************************************************************************************/ /*** Spark Liquidity Layer Addresses ***/ /******************************************************************************************************************/ address internal constant ALM_CONTROLLER = 0x5cf73FDb7057E436A6eEaDFAd27E45E7ab6E431e; address internal constant ALM_PROXY = 0x1601843c5E9bC251A3272907010AFa41Fa18347E; address internal constant ALM_RATE_LIMITS = 0x7A5FD5cf045e010e62147F065cEAe59e5344b188; address internal constant ALM_FREEZER = 0x90D8c80C028B4C09C0d8dcAab9bbB057F0513431; address internal constant ALM_RELAYER = 0x8a25A24EDE9482C4Fc0738F99611BE58F1c839AB; /******************************************************************************************************************/ /*** Ethena Addresses ***/ /******************************************************************************************************************/ address internal constant ETHENA_MINTER = 0xe3490297a08d6fC8Da46Edb7B6142E4F461b62D3; /******************************************************************************************************************/ /*** Aave Addresses ***/ /******************************************************************************************************************/ address internal constant ATOKEN_CORE_USDS = 0x32a6268f9Ba3642Dda7892aDd74f1D34469A4259; address internal constant ATOKEN_CORE_USDC = 0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c; /******************************************************************************************************************/ /*** Blackrock BUIDL Addresses ***/ /******************************************************************************************************************/ address internal constant BUIDL_REDEEM = 0x31D3F59Ad4aAC0eeE2247c65EBE8Bf6E9E470a53; /******************************************************************************************************************/ /*** Fluid Addresses ***/ /******************************************************************************************************************/ address internal constant FLUID_SUSDS = 0x2BBE31d63E6813E3AC858C04dae43FB2a72B0D11; /******************************************************************************************************************/ /*** Morpho Addresses ***/ /******************************************************************************************************************/ address internal constant MORPHO = 0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb; address internal constant MORPHO_DEFAULT_IRM = 0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC; address internal constant MORPHO_SUSDE_ORACLE = 0x5D916980D5Ae1737a8330Bf24dF812b2911Aae25; address internal constant MORPHO_USDE_ORACLE = 0xaE4750d0813B5E37A51f7629beedd72AF1f9cA35; address internal constant MORPHO_VAULT_DAI_1 = 0x73e65DBD630f90604062f6E02fAb9138e713edD9; /******************************************************************************************************************/ /*** SparkLend - Core Protocol Addresses ***/ /******************************************************************************************************************/ address internal constant AAVE_ORACLE = 0x8105f69D9C41644c6A0803fDA7D03Aa70996cFD9; address internal constant ACL_MANAGER = 0xdA135Cd78A086025BcdC87B038a1C462032b510C; address internal constant DAI_TREASURY = 0x856900aa78e856a5df1a2665eE3a66b2487cD68f; address internal constant EMISSION_MANAGER = 0xf09e48dd4CA8e76F63a57ADd428bB06fee7932a4; address internal constant INCENTIVES = 0x4370D3b6C9588E02ce9D22e684387859c7Ff5b34; address internal constant POOL = 0xC13e21B648A5Ee794902342038FF3aDAB66BE987; address internal constant POOL_ADDRESSES_PROVIDER = 0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE; address internal constant POOL_ADDRESSES_PROVIDER_REGISTRY = 0x03cFa0C4622FF84E50E75062683F44c9587e6Cc1; address internal constant POOL_CONFIGURATOR = 0x542DBa469bdE58FAeE189ffB60C6b49CE60E0738; address internal constant TREASURY = 0xb137E7d16564c81ae2b0C8ee6B55De81dd46ECe5; address internal constant TREASURY_CONTROLLER = 0x92eF091C5a1E01b3CE1ba0D0150C84412d818F7a; address internal constant WETH_GATEWAY = 0xBD7D6a9ad7865463DE44B05F04559f65e3B11704; /******************************************************************************************************************/ /*** SparkLend - Reserve Token Addresses ***/ /******************************************************************************************************************/ address internal constant CBBTC_ATOKEN = 0xb3973D459df38ae57797811F2A1fd061DA1BC123; address internal constant CBBTC_STABLE_DEBT_TOKEN = 0x26a76E2fa1EaDbe7C30f0c333059Bcc3642c28d2; address internal constant CBBTC_DEBT_TOKEN = 0x661fE667D2103eb52d3632a3eB2cAbd123F27938; address internal constant DAI_ATOKEN = 0x4DEDf26112B3Ec8eC46e7E31EA5e123490B05B8B; address internal constant DAI_STABLE_DEBT_TOKEN = 0xfe2B7a7F4cC0Fb76f7Fc1C6518D586F1e4559176; address internal constant DAI_DEBT_TOKEN = 0xf705d2B7e92B3F38e6ae7afaDAA2fEE110fE5914; address internal constant GNO_ATOKEN = 0x7b481aCC9fDADDc9af2cBEA1Ff2342CB1733E50F; address internal constant GNO_STABLE_DEBT_TOKEN = 0xbf13910620722D4D4F8A03962894EB3335Bf4FaE; address internal constant GNO_DEBT_TOKEN = 0x57a2957651DA467fCD4104D749f2F3684784c25a; address internal constant RETH_ATOKEN = 0x9985dF20D7e9103ECBCeb16a84956434B6f06ae8; address internal constant RETH_STABLE_DEBT_TOKEN = 0xa9a4037295Ea3a168DC3F65fE69FdA524d52b3e1; address internal constant RETH_DEBT_TOKEN = 0xBa2C8F2eA5B56690bFb8b709438F049e5Dd76B96; address internal constant SDAI_ATOKEN = 0x78f897F0fE2d3B5690EbAe7f19862DEacedF10a7; address internal constant SDAI_STABLE_DEBT_TOKEN = 0xEc6C6aBEd4DC03299EFf82Ac8A0A83643d3cB335; address internal constant SDAI_DEBT_TOKEN = 0xaBc57081C04D921388240393ec4088Aa47c6832B; address internal constant USDC_ATOKEN = 0x377C3bd93f2a2984E1E7bE6A5C22c525eD4A4815; address internal constant USDC_STABLE_DEBT_TOKEN = 0x887Ac022983Ff083AEb623923789052A955C6798; address internal constant USDC_DEBT_TOKEN = 0x7B70D04099CB9cfb1Db7B6820baDAfB4C5C70A67; address internal constant USDT_ATOKEN = 0xe7dF13b8e3d6740fe17CBE928C7334243d86c92f; address internal constant USDT_STABLE_DEBT_TOKEN = 0x0Dae62F953Ceb2E969fB4dE85f3F9074fa920776; address internal constant USDT_DEBT_TOKEN = 0x529b6158d1D2992E3129F7C69E81a7c677dc3B12; address internal constant WBTC_ATOKEN = 0x4197ba364AE6698015AE5c1468f54087602715b2; address internal constant WBTC_STABLE_DEBT_TOKEN = 0x4b29e6cBeE62935CfC92efcB3839eD2c2F35C1d9; address internal constant WBTC_DEBT_TOKEN = 0xf6fEe3A8aC8040C3d6d81d9A4a168516Ec9B51D2; address internal constant WEETH_ATOKEN = 0x3CFd5C0D4acAA8Faee335842e4f31159fc76B008; address internal constant WEETH_STABLE_DEBT_TOKEN = 0x5B1F8aF3E6C0BF4d20e8e5220a4e4A3A8fA6Dc0A; address internal constant WEETH_DEBT_TOKEN = 0xc2bD6d2fEe70A0A73a33795BdbeE0368AeF5c766; address internal constant WETH_ATOKEN = 0x59cD1C87501baa753d0B5B5Ab5D8416A45cD71DB; address internal constant WETH_STABLE_DEBT_TOKEN = 0x3c6b93D38ffA15ea995D1BC950d5D0Fa6b22bD05; address internal constant WETH_DEBT_TOKEN = 0x2e7576042566f8D6990e07A1B61Ad1efd86Ae70d; address internal constant WSTETH_ATOKEN = 0x12B54025C112Aa61fAce2CDB7118740875A566E9; address internal constant WSTETH_STABLE_DEBT_TOKEN = 0x9832D969a0c8662D98fFf334A4ba7FeE62b109C2; address internal constant WSTETH_DEBT_TOKEN = 0xd5c3E3B566a42A6110513Ac7670C1a86D76E13E6; /******************************************************************************************************************/ /*** SparkLend - Auxiliary Protocol Addresses ***/ /******************************************************************************************************************/ address internal constant CAP_AUTOMATOR = 0x2276f52afba7Cf2525fd0a050DF464AC8532d0ef; address internal constant FREEZER_MOM = 0x237e3985dD7E373F2ec878EC1Ac48A228Cf2e7a3; address internal constant KILL_SWITCH_ORACLE = 0x909A86f78e1cdEd68F9c2Fe2c9CD922c401abe82; /******************************************************************************************************************/ /*** SparkLend - Emergency Spells ***/ /******************************************************************************************************************/ address internal constant SPELL_FREEZE_ALL = 0x9e2890BF7f8D5568Cc9e5092E67Ba00C8dA3E97f; address internal constant SPELL_FREEZE_DAI = 0xa2039bef2c5803d66E4e68F9E23a942E350b938c; address internal constant SPELL_PAUSE_ALL = 0x425b0de240b4c2DC45979DB782A355D090Dc4d37; address internal constant SPELL_PAUSE_DAI = 0xCacB88e39112B56278db25b423441248cfF94241; address internal constant SPELL_REMOVE_MULTISIG = 0xE47AB4919F6F5459Dcbbfbe4264BD4630c0169A9; /******************************************************************************************************************/ /*** SparkLend - Implementation Addresses ***/ /******************************************************************************************************************/ address internal constant A_TOKEN_IMPL = 0x6175ddEc3B9b38c88157C10A01ed4A3fa8639cC6; address internal constant DAI_TREASURY_IMPL = 0xF1E57711Eb5F897b415de1aEFCB64d9BAe58D312; address internal constant INCENTIVES_IMPL = 0x0ee554F6A1f7a4Cb4f82D4C124DdC2AD3E37fde1; address internal constant POOL_CONFIGURATOR_IMPL = 0xF7b656C95420194b79687fc86D965FB51DA4799F; address internal constant POOL_IMPL = 0x5aE329203E00f76891094DcfedD5Aca082a50e1b; address internal constant STABLE_DEBT_TOKEN_IMPL = 0x026a5B6114431d8F3eF2fA0E1B2EDdDccA9c540E; address internal constant TREASURY_IMPL = 0xF1E57711Eb5F897b415de1aEFCB64d9BAe58D312; address internal constant VARIABLE_DEBT_TOKEN_IMPL = 0x86C71796CcDB31c3997F8Ec5C2E3dB3e9e40b985; /******************************************************************************************************************/ /*** SparkLend - Config Engine Addresses ***/ /******************************************************************************************************************/ address internal constant CONFIG_ENGINE = 0x3254F7cd0565aA67eEdC86c2fB608BE48d5cCd78; address internal constant PROXY_ADMIN = 0x883A82BDd3d07ae6ACfD151020faD350df25087e; address internal constant RATES_FACTORY = 0xfE57e187EF6285e90d7049e6a21571aa47cF11a2; address internal constant TRANSPARENT_PROXY_FACTORY = 0x777803CbDD89D5D5Bc1DdD2151B51b0B07F6bf37; /******************************************************************************************************************/ /*** SparkLend - Data Provider Addresses ***/ /******************************************************************************************************************/ address internal constant PROTOCOL_DATA_PROVIDER = 0xFc21d6d146E6086B8359705C8b28512a983db0cb; address internal constant UI_INCENTIVE_DATA_PROVIDER = 0xA7F8A757C4f7696c015B595F51B2901AC0121B18; address internal constant UI_POOL_DATA_PROVIDER = 0xF028c2F4b19898718fD0F77b9b881CbfdAa5e8Bb; address internal constant WALLET_BALANCE_PROVIDER = 0xd2AeF86F51F92E8e49F42454c287AE4879D1BeDc; /******************************************************************************************************************/ /*** SparkLend - Library Addresses ***/ /******************************************************************************************************************/ address internal constant BORROW_LOGIC = 0x4662C88C542F0954F8CccCDE4542eEc32d7E7e9a; address internal constant BRIDGE_LOGIC = 0x2C54924711E479E639032704146b865E12f0C6D1; address internal constant EMODE_LOGIC = 0x2Ad00613A66D71Ff2B0607fB3C4632C47a50DADe; address internal constant FLASH_LOAN_LOGIC = 0x7f44e1c1dE70059D7cc483378BEFeE2a030CE247; address internal constant LIQUIDATION_LOGIC = 0x6aEa92693C527bC2c7B3171C6f2598d67d619088; address internal constant POOL_LOGIC = 0x1761a0f74032963B6Ad0774C5EBF4586c0bD7604; address internal constant SUPPLY_LOGIC = 0x46256841e36b7557BB8e4c706beD38b17A9EB2c1; /******************************************************************************************************************/ /*** Cross-Domain Addresses ***/ /******************************************************************************************************************/ address internal constant CCTP_TOKEN_MESSENGER = 0xBd3fa81B58Ba92a82136038B25aDec7066af3155; address internal constant OPTIMISM_DSR_FORWARDER = 0x4042127DecC0cF7cc0966791abebf7F76294DeF3; address internal constant WORLD_CHAIN_DSR_FORWARDER = 0xA34437dAAE56A7CC6DC757048933D7777b3e547B; /******************************************************************************************************************/ /*** Arbitrum Addresses ***/ /******************************************************************************************************************/ address internal constant ARBITRUM_DSR_FORWARDER = 0x7F36E7F562Ee3f320644F6031e03E12a02B85799; address internal constant ARBITRUM_SSR_FORWARDER = 0x1A229AdbAC83A948226783F2A3257B52006247D5; address internal constant ARBITRUM_ESCROW = 0xA10c7CE4b876998858b1a9E12b10092229539400; address internal constant ARBITRUM_SKY_GOV_RELAY = 0x9ba25c289e351779E0D481Ba37489317c34A899d; address internal constant ARBITRUM_TOKEN_BRIDGE = 0x84b9700E28B23F873b82c1BEb23d86C091b6079E; /******************************************************************************************************************/ /*** Base Addresses ***/ /******************************************************************************************************************/ address internal constant BASE_DSR_FORWARDER = 0x8Ed551D485701fe489c215E13E42F6fc59563e0e; address internal constant BASE_SSR_FORWARDER = 0xB2833392527f41262eB0E3C7b47AFbe030ef188E; address internal constant BASE_ESCROW = 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3; address internal constant BASE_SKY_GOV_RELAY = 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b; address internal constant BASE_TOKEN_BRIDGE = 0xA5874756416Fa632257eEA380CAbd2E87cED352A; /******************************************************************************************************************/ /*** Multisigs ***/ /******************************************************************************************************************/ address internal constant FREEZER_MULTISIG = 0x44efFc473e81632B12486866AA1678edbb7BEeC3; address internal constant SPARKLEND_REWARDS_MULTISIG = 0x8076807464DaC94Ac8Aa1f7aF31b58F73bD88A27; address internal constant SPARK_REWARDS_MULTISIG = 0xF649956f43825d4d7295a50EDdBe1EDC814A3a83; /******************************************************************************************************************/ /*** User Action Addresses ***/ /******************************************************************************************************************/ address internal constant USER_ACTIONS_PSM_VARIANT1 = 0x52d298Ff9e77E71C2EB1992260520E7b15257d99; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.13; import { IPool } from "aave-v3-core/contracts/interfaces/IPool.sol"; import { IPoolConfigurator } from "aave-v3-core/contracts/interfaces/IPoolConfigurator.sol"; interface ICapAutomator { /**********************************************************************************************/ /*** Events ***/ /**********************************************************************************************/ /** * @dev Event to log the setting of a new supply cap config. * @param asset The address of the asset for which the config was set. * @param max Maximum allowed supply cap. * @param gap A gap between the supply and the supply cap that is being maintained. * @param increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. */ event SetSupplyCapConfig(address indexed asset, uint256 max, uint256 gap, uint256 increaseCooldown); /** * @dev Event to log the setting of a new borrow cap config. * @param asset The address of the asset for which the config was set. * @param max Maximum allowed borrow cap. * @param gap A gap between the borrows and the borrow cap that is being maintained. * @param increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. */ event SetBorrowCapConfig(address indexed asset, uint256 max, uint256 gap, uint256 increaseCooldown); /** * @dev Event to log the removing of a supply cap config. * @param asset The address of the asset for which supply config was removed. */ event RemoveSupplyCapConfig(address indexed asset); /** * @dev Event to log the removing of a borrow cap config. * @param asset The address of the asset for which borrow config was removed. */ event RemoveBorrowCapConfig(address indexed asset); /** * @dev Event to log the update of the supply cap. * @param asset The address of the asset which supply cap was updated. * @param oldSupplyCap The old supply cap. * @param newSupplyCap The newly set supply cap. */ event UpdateSupplyCap(address indexed asset, uint256 oldSupplyCap, uint256 newSupplyCap); /** * @dev Event to log the update of the borrow cap. * @param asset The address of the asset which borrow cap was updated. * @param oldBorrowCap The old borrow cap. * @param newBorrowCap The newly set borrow cap. */ event UpdateBorrowCap(address indexed asset, uint256 oldBorrowCap, uint256 newBorrowCap); /**********************************************************************************************/ /*** Storage Variables ***/ /**********************************************************************************************/ /** * @dev Returns the address of the pool configurator. * @return poolConfigurator The address of the pool configurator. */ function poolConfigurator() external view returns (IPoolConfigurator poolConfigurator); /** * @dev Returns the address of the data provider. * @return pool The address of the data provider. */ function pool() external view returns (IPool pool); /** * @dev Returns current configuration for automatic supply cap management. * @param asset The address of the asset which config is going to be returned. * @return max Maximum allowed supply cap. * @return gap A gap between the supply and the supply cap that is being maintained. * @return increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. * @return lastUpdateBlock The block of the last cap update. * @return lastIncreaseTime The timestamp of the last cap increase. */ function supplyCapConfigs(address asset) external view returns ( uint48 max, uint48 gap, uint48 increaseCooldown, uint48 lastUpdateBlock, uint48 lastIncreaseTime ); /** * @dev Returns current configuration for automatic borrow cap management. * @param asset The address of the asset which config is going to be returned. * @return max Maximum allowed borrow cap. * @return gap A gap between the borrows and the borrow cap that is being maintained. * @return increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. * @return lastUpdateBlock The block of the last cap update. * @return lastIncreaseTime The timestamp of the last cap increase. */ function borrowCapConfigs(address asset) external view returns ( uint48 max, uint48 gap, uint48 increaseCooldown, uint48 lastUpdateBlock, uint48 lastIncreaseTime ); /**********************************************************************************************/ /*** Owner Functions ***/ /**********************************************************************************************/ /** * @dev Function creating (or re-setting) a configuration for automatic supply cap management. * @param asset The address of the asset that is going to be managed. * @param max Maximum allowed supply cap. * @param gap A gap between the supply and the supply cap that is being maintained. * @param increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. */ function setSupplyCapConfig( address asset, uint256 max, uint256 gap, uint256 increaseCooldown ) external; /** * @dev Function creating (or re-setting) a configuration for automatic borrow cap management. * @param asset The address of the asset that is going to be managed. * @param max Maximum allowed borrow cap. * @param gap A gap between the borrows and the borrow cap that is being maintained. * @param increaseCooldown A minimum period of time that needs to elapse between consequent cap increases. */ function setBorrowCapConfig( address asset, uint256 max, uint256 gap, uint256 increaseCooldown ) external; /** * @dev Function removing a configuration for automatic supply cap management. * @param asset The address of the asset for which the configuration is going to be removed. */ function removeSupplyCapConfig(address asset) external; /** * @dev Function removing a configuration for automatic borrow cap management. * @param asset The address of the asset for which the configuration is going to be removed. */ function removeBorrowCapConfig(address asset) external; /**********************************************************************************************/ /*** Public Functions ***/ /**********************************************************************************************/ /** * @dev A public function that updates supply cap on market of a given asset. * The supply cap is going to be set to the value equal * to the sum of current supply and the supply cap gap. * The cap is only going to be increased if the required cooldown time has passed. * Calling this function more than once per block will not have any additional effect. * @param asset The address of the asset which cap is going to be updated. * @return newSupplyCap A newly set supply cap, or the old one if it was not updated. */ function execSupply(address asset) external returns (uint256 newSupplyCap); /** * @dev A public function that updates borrow cap on market of a given asset. * The borrow cap is going to be set to the values equal * to the sum of current borrows and the borrow cap gap. * The caps is only going to be increased if the required cooldown time has passed. * Calling this function more than once per block will not have any additional effect. * @param asset The address of the asset which cap is going to be updated. * @return newBorrowCap A newly set borrow cap, or the old one if it was not updated. */ function execBorrow(address asset) external returns (uint256 newBorrowCap); /** * @dev A public function that updates supply and borrow caps on market of a given asset. * The supply and borrow caps are going to be set to, respectively, the values equal * to the sum of current supply and the supply cap gap and the sum of current borrows and the borrow cap gap. * The caps are only going to be increased if the required cooldown time has passed. * Calling this function more than once per block will not have any additional effect. * @param asset The address of the asset which caps are going to be updated. * @return newSupplyCap A newly set supply cap, or the old one if it was not updated. * @return newBorrowCap A newly set borrow cap, or the old one if it was not updated. */ function exec(address asset) external returns (uint256 newSupplyCap, uint256 newBorrowCap); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol"; import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol"; import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol"; import {MarketConfig, PendingUint192, PendingAddress} from "../libraries/PendingLib.sol"; struct MarketAllocation { /// @notice The market to allocate. MarketParams marketParams; /// @notice The amount of assets to allocate. uint256 assets; } interface IMulticall { function multicall(bytes[] calldata) external returns (bytes[] memory); } interface IOwnable { function owner() external view returns (address); function transferOwnership(address) external; function renounceOwnership() external; function acceptOwnership() external; function pendingOwner() external view returns (address); } /// @dev This interface is used for factorizing IMetaMorphoStaticTyping and IMetaMorpho. /// @dev Consider using the IMetaMorpho interface instead of this one. interface IMetaMorphoBase { /// @notice The address of the Morpho contract. function MORPHO() external view returns (IMorpho); function DECIMALS_OFFSET() external view returns (uint8); /// @notice The address of the curator. function curator() external view returns (address); /// @notice Stores whether an address is an allocator or not. function isAllocator(address target) external view returns (bool); /// @notice The current guardian. Can be set even without the timelock set. function guardian() external view returns (address); /// @notice The current fee. function fee() external view returns (uint96); /// @notice The fee recipient. function feeRecipient() external view returns (address); /// @notice The skim recipient. function skimRecipient() external view returns (address); /// @notice The current timelock. function timelock() external view returns (uint256); /// @dev Stores the order of markets on which liquidity is supplied upon deposit. /// @dev Can contain any market. A market is skipped as soon as its supply cap is reached. function supplyQueue(uint256) external view returns (Id); /// @notice Returns the length of the supply queue. function supplyQueueLength() external view returns (uint256); /// @dev Stores the order of markets from which liquidity is withdrawn upon withdrawal. /// @dev Always contain all non-zero cap markets as well as all markets on which the vault supplies liquidity, /// without duplicate. function withdrawQueue(uint256) external view returns (Id); /// @notice Returns the length of the withdraw queue. function withdrawQueueLength() external view returns (uint256); /// @notice Stores the total assets managed by this vault when the fee was last accrued. /// @dev May be greater than `totalAssets()` due to removal of markets with non-zero supply or socialized bad debt. /// This difference will decrease the fee accrued until one of the functions updating `lastTotalAssets` is /// triggered (deposit/mint/withdraw/redeem/setFee/setFeeRecipient). function lastTotalAssets() external view returns (uint256); /// @notice Submits a `newTimelock`. /// @dev Warning: Reverts if a timelock is already pending. Revoke the pending timelock to overwrite it. /// @dev In case the new timelock is higher than the current one, the timelock is set immediately. function submitTimelock(uint256 newTimelock) external; /// @notice Accepts the pending timelock. function acceptTimelock() external; /// @notice Revokes the pending timelock. /// @dev Does not revert if there is no pending timelock. function revokePendingTimelock() external; /// @notice Submits a `newSupplyCap` for the market defined by `marketParams`. /// @dev Warning: Reverts if a cap is already pending. Revoke the pending cap to overwrite it. /// @dev Warning: Reverts if a market removal is pending. /// @dev In case the new cap is lower than the current one, the cap is set immediately. function submitCap(MarketParams memory marketParams, uint256 newSupplyCap) external; /// @notice Accepts the pending cap of the market defined by `marketParams`. function acceptCap(MarketParams memory marketParams) external; /// @notice Revokes the pending cap of the market defined by `id`. /// @dev Does not revert if there is no pending cap. function revokePendingCap(Id id) external; /// @notice Submits a forced market removal from the vault, eventually losing all funds supplied to the market. /// @notice Funds can be recovered by enabling this market again and withdrawing from it (using `reallocate`), /// but funds will be distributed pro-rata to the shares at the time of withdrawal, not at the time of removal. /// @notice This forced removal is expected to be used as an emergency process in case a market constantly reverts. /// To softly remove a sane market, the curator role is expected to bundle a reallocation that empties the market /// first (using `reallocate`), followed by the removal of the market (using `updateWithdrawQueue`). /// @dev Warning: Removing a market with non-zero supply will instantly impact the vault's price per share. /// @dev Warning: Reverts for non-zero cap or if there is a pending cap. Successfully submitting a zero cap will /// prevent such reverts. function submitMarketRemoval(MarketParams memory marketParams) external; /// @notice Revokes the pending removal of the market defined by `id`. /// @dev Does not revert if there is no pending market removal. function revokePendingMarketRemoval(Id id) external; /// @notice Submits a `newGuardian`. /// @notice Warning: a malicious guardian could disrupt the vault's operation, and would have the power to revoke /// any pending guardian. /// @dev In case there is no guardian, the gardian is set immediately. /// @dev Warning: Submitting a gardian will overwrite the current pending gardian. function submitGuardian(address newGuardian) external; /// @notice Accepts the pending guardian. function acceptGuardian() external; /// @notice Revokes the pending guardian. function revokePendingGuardian() external; /// @notice Skims the vault `token` balance to `skimRecipient`. function skim(address) external; /// @notice Sets `newAllocator` as an allocator or not (`newIsAllocator`). function setIsAllocator(address newAllocator, bool newIsAllocator) external; /// @notice Sets `curator` to `newCurator`. function setCurator(address newCurator) external; /// @notice Sets the `fee` to `newFee`. function setFee(uint256 newFee) external; /// @notice Sets `feeRecipient` to `newFeeRecipient`. function setFeeRecipient(address newFeeRecipient) external; /// @notice Sets `skimRecipient` to `newSkimRecipient`. function setSkimRecipient(address newSkimRecipient) external; /// @notice Sets `supplyQueue` to `newSupplyQueue`. /// @param newSupplyQueue is an array of enabled markets, and can contain duplicate markets, but it would only /// increase the cost of depositing to the vault. function setSupplyQueue(Id[] calldata newSupplyQueue) external; /// @notice Updates the withdraw queue. Some markets can be removed, but no market can be added. /// @notice Removing a market requires the vault to have 0 supply on it, or to have previously submitted a removal /// for this market (with the function `submitMarketRemoval`). /// @notice Warning: Anyone can supply on behalf of the vault so the call to `updateWithdrawQueue` that expects a /// market to be empty can be griefed by a front-run. To circumvent this, the allocator can simply bundle a /// reallocation that withdraws max from this market with a call to `updateWithdrawQueue`. /// @dev Warning: Removing a market with supply will decrease the fee accrued until one of the functions updating /// `lastTotalAssets` is triggered (deposit/mint/withdraw/redeem/setFee/setFeeRecipient). /// @dev Warning: `updateWithdrawQueue` is not idempotent. Submitting twice the same tx will change the queue twice. /// @param indexes The indexes of each market in the previous withdraw queue, in the new withdraw queue's order. function updateWithdrawQueue(uint256[] calldata indexes) external; /// @notice Reallocates the vault's liquidity so as to reach a given allocation of assets on each given market. /// @notice The allocator can withdraw from any market, even if it's not in the withdraw queue, as long as the loan /// token of the market is the same as the vault's asset. /// @dev The behavior of the reallocation can be altered by state changes, including: /// - Deposits on the vault that supplies to markets that are expected to be supplied to during reallocation. /// - Withdrawals from the vault that withdraws from markets that are expected to be withdrawn from during /// reallocation. /// - Donations to the vault on markets that are expected to be supplied to during reallocation. /// - Withdrawals from markets that are expected to be withdrawn from during reallocation. /// @dev Sender is expected to pass `assets = type(uint256).max` with the last MarketAllocation of `allocations` to /// supply all the remaining withdrawn liquidity, which would ensure that `totalWithdrawn` = `totalSupplied`. function reallocate(MarketAllocation[] calldata allocations) external; } /// @dev This interface is inherited by MetaMorpho so that function signatures are checked by the compiler. /// @dev Consider using the IMetaMorpho interface instead of this one. interface IMetaMorphoStaticTyping is IMetaMorphoBase { /// @notice Returns the current configuration of each market. function config(Id) external view returns (uint184 cap, bool enabled, uint64 removableAt); /// @notice Returns the pending guardian. function pendingGuardian() external view returns (address guardian, uint64 validAt); /// @notice Returns the pending cap for each market. function pendingCap(Id) external view returns (uint192 value, uint64 validAt); /// @notice Returns the pending timelock. function pendingTimelock() external view returns (uint192 value, uint64 validAt); } /// @title IMetaMorpho /// @author Morpho Labs /// @custom:contact [email protected] /// @dev Use this interface for MetaMorpho to have access to all the functions with the appropriate function signatures. interface IMetaMorpho is IMetaMorphoBase, IERC4626, IERC20Permit, IOwnable, IMulticall { /// @notice Returns the current configuration of each market. function config(Id) external view returns (MarketConfig memory); /// @notice Returns the pending guardian. function pendingGuardian() external view returns (PendingAddress memory); /// @notice Returns the pending cap for each market. function pendingCap(Id) external view returns (PendingUint192 memory); /// @notice Returns the pending timelock. function pendingTimelock() external view returns (PendingUint192 memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IPool} from 'sparklend-v1-core/contracts/interfaces/IPool.sol'; import {IPoolConfigurator} from 'sparklend-v1-core/contracts/interfaces/IPoolConfigurator.sol'; import {IAaveOracle} from 'sparklend-v1-core/contracts/interfaces/IAaveOracle.sol'; import {IV3RateStrategyFactory} from './IV3RateStrategyFactory.sol'; /// @dev Examples here assume the usage of the `AaveV3PayloadBase` base contracts /// contained in this same repository interface IAaveV3ConfigEngine { /** * @dev Required for naming of a/v/s tokens * Example (mock): * PoolContext({ * networkName: 'Polygon', * networkAbbreviation: 'Pol' * }) */ struct PoolContext { string networkName; string networkAbbreviation; } /** * @dev Example (mock): * Listing({ * asset: 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9, * assetSymbol: 'AAVE', * priceFeed: 0x547a514d5e3769680Ce22B2361c10Ea13619e8a9, * rateStrategyParams: Rates.RateStrategyParams({ * optimalUsageRatio: _bpsToRay(80_00), * baseVariableBorrowRate: _bpsToRay(25), // 0.25% * variableRateSlope1: _bpsToRay(3_00), * variableRateSlope2: _bpsToRay(75_00), * stableRateSlope1: _bpsToRay(3_00), * stableRateSlope2: _bpsToRay(75_00), * baseStableRateOffset: _bpsToRay(2_00), * stableRateExcessOffset: _bpsToRay(3_00), * optimalStableToTotalDebtRatio: _bpsToRay(30_00) * }), * enabledToBorrow: EngineFlags.ENABLED, * flashloanable: EngineFlags.ENABLED, * stableRateModeEnabled: EngineFlags.DISABLED, * borrowableInIsolation: EngineFlags.ENABLED, * withSiloedBorrowing:, EngineFlags.DISABLED, * ltv: 70_50, // 70.5% * liqThreshold: 76_00, // 76% * liqBonus: 5_00, // 5% * reserveFactor: 10_00, // 10% * supplyCap: 100_000, // 100k AAVE * borrowCap: 60_000, // 60k AAVE * debtCeiling: 100_000, // 100k USD * liqProtocolFee: 10_00, // 10% * eModeCategory: 0, // No category * } */ struct Listing { address asset; string assetSymbol; address priceFeed; IV3RateStrategyFactory.RateStrategyParams rateStrategyParams; // Mandatory, no matter if enabled for borrowing or not uint256 enabledToBorrow; uint256 stableRateModeEnabled; // Only considered is enabledToBorrow == EngineFlags.ENABLED (true) uint256 borrowableInIsolation; // Only considered is enabledToBorrow == EngineFlags.ENABLED (true) uint256 withSiloedBorrowing; // Only considered if enabledToBorrow == EngineFlags.ENABLED (true) uint256 flashloanable; // Independent from enabled to borrow: an asset can be flashloanble and not enabled to borrow uint256 ltv; // Only considered if liqThreshold > 0 uint256 liqThreshold; // If `0`, the asset will not be enabled as collateral uint256 liqBonus; // Only considered if liqThreshold > 0 uint256 reserveFactor; // Only considered if enabledToBorrow == EngineFlags.ENABLED (true) uint256 supplyCap; // If passing any value distinct to EngineFlags.KEEP_CURRENT, always configured uint256 borrowCap; // If passing any value distinct to EngineFlags.KEEP_CURRENT, always configured uint256 debtCeiling; // Only considered if liqThreshold > 0 uint256 liqProtocolFee; // Only considered if liqThreshold > 0 uint8 eModeCategory; // If `O`, no eMode category will be set } struct TokenImplementations { address aToken; address vToken; address sToken; } struct ListingWithCustomImpl { Listing base; TokenImplementations implementations; } /** * @dev Example (mock): * CapsUpdate({ * asset: AaveV3EthereumAssets.AAVE_UNDERLYING, * supplyCap: 1_000_000, * borrowCap: EngineFlags.KEEP_CURRENT * } */ struct CapsUpdate { address asset; uint256 supplyCap; // Pass any value, of EngineFlags.KEEP_CURRENT to keep it as it is uint256 borrowCap; // Pass any value, of EngineFlags.KEEP_CURRENT to keep it as it is } /** * @dev Example (mock): * PriceFeedUpdate({ * asset: AaveV3EthereumAssets.AAVE_UNDERLYING, * priceFeed: 0x547a514d5e3769680Ce22B2361c10Ea13619e8a9 * }) */ struct PriceFeedUpdate { address asset; address priceFeed; } /** * @dev Example (mock): * CollateralUpdate({ * asset: AaveV3EthereumAssets.AAVE_UNDERLYING, * ltv: 60_00, * liqThreshold: 70_00, * liqBonus: EngineFlags.KEEP_CURRENT, * debtCeiling: EngineFlags.KEEP_CURRENT, * liqProtocolFee: 7_00, * eModeCategory: EngineFlags.KEEP_CURRENT * }) */ struct CollateralUpdate { address asset; uint256 ltv; uint256 liqThreshold; uint256 liqBonus; uint256 debtCeiling; uint256 liqProtocolFee; uint256 eModeCategory; } /** * @dev Example (mock): * BorrowUpdate({ * asset: AaveV3EthereumAssets.AAVE_UNDERLYING, * enabledToBorrow: EngineFlags.ENABLED, * flashloanable: EngineFlags.KEEP_CURRENT, * stableRateModeEnabled: EngineFlags.KEEP_CURRENT, * borrowableInIsolation: EngineFlags.KEEP_CURRENT, * withSiloedBorrowing: EngineFlags.KEEP_CURRENT, * reserveFactor: 15_00, // 15% * }) */ struct BorrowUpdate { address asset; uint256 enabledToBorrow; uint256 flashloanable; uint256 stableRateModeEnabled; uint256 borrowableInIsolation; uint256 withSiloedBorrowing; uint256 reserveFactor; } /** * @dev Example (mock): * RateStrategyUpdate({ * asset: AaveV3OptimismAssets.USDT_UNDERLYING, * params: Rates.RateStrategyParams({ * optimalUsageRatio: _bpsToRay(80_00), * baseVariableBorrowRate: EngineFlags.KEEP_CURRENT, * variableRateSlope1: EngineFlags.KEEP_CURRENT, * variableRateSlope2: _bpsToRay(75_00), * stableRateSlope1: EngineFlags.KEEP_CURRENT, * stableRateSlope2: _bpsToRay(75_00), * baseStableRateOffset: EngineFlags.KEEP_CURRENT, * stableRateExcessOffset: EngineFlags.KEEP_CURRENT, * optimalStableToTotalDebtRatio: EngineFlags.KEEP_CURRENT * }) * }) */ struct RateStrategyUpdate { address asset; IV3RateStrategyFactory.RateStrategyParams params; } /** * @notice Performs full listing of the assets, in the Aave pool configured in this engine instance * @param context `PoolContext` struct, effectively meta-data for naming of a/v/s tokens. * More information on the documentation of the struct. * @param listings `Listing[]` list of declarative configs for every aspect of the asset listings. * More information on the documentation of the struct. */ function listAssets(PoolContext memory context, Listing[] memory listings) external; /** * @notice Performs full listings of assets, in the Aave pool configured in this engine instance * @dev This function allows more customization, especifically enables to set custom implementations * for a/v/s tokens. * IMPORTANT. Use it only if understanding the internals of the Aave v3 protocol * @param context `PoolContext` struct, effectively meta-data for naming of a/v/s tokens. * More information on the documentation of the struct. * @param listings `ListingWithCustomImpl[]` list of declarative configs for every aspect of the asset listings. */ function listAssetsCustom( PoolContext memory context, ListingWithCustomImpl[] memory listings ) external; /** * @notice Performs an update of the caps (supply, borrow) of the assets, in the Aave pool configured in this engine instance * @param updates `CapsUpdate[]` list of declarative updates containing the new caps * More information on the documentation of the struct. */ function updateCaps(CapsUpdate[] memory updates) external; /** * @notice Performs an update on the rate strategy params of the assets, in the Aave pool configured in this engine instance * @dev The engine itself manages if a new rate strategy needs to be deployed or if an existing one can be re-used * @param updates `RateStrategyUpdate[]` list of declarative updates containing the new rate strategy params * More information on the documentation of the struct. */ function updateRateStrategies(RateStrategyUpdate[] memory updates) external; /** * @notice Performs an update of the collateral-related params of the assets, in the Aave pool configured in this engine instance * @param updates `CollateralUpdate[]` list of declarative updates containing the new parameters * More information on the documentation of the struct. */ function updateCollateralSide(CollateralUpdate[] memory updates) external; /** * @notice Performs an update of the price feed of the assets, in the Aave pool configured in this engine instance * @param updates `PriceFeedUpdate[]` list of declarative updates containing the new parameters * More information on the documentation of the struct. */ function updatePriceFeeds(PriceFeedUpdate[] memory updates) external; /** * @notice Performs an update of the borrow-related params of the assets, in the Aave pool configured in this engine instance * @param updates `BorrowUpdate[]` list of declarative updates containing the new parameters * More information on the documentation of the struct. */ function updateBorrowSide(BorrowUpdate[] memory updates) external; function RATE_STRATEGIES_FACTORY() external view returns (IV3RateStrategyFactory); function POOL() external view returns (IPool); function POOL_CONFIGURATOR() external view returns (IPoolConfigurator); function ORACLE() external view returns (IAaveOracle); function ATOKEN_IMPL() external view returns (address); function VTOKEN_IMPL() external view returns (address); function STOKEN_IMPL() external view returns (address); function REWARDS_CONTROLLER() external view returns (address); function COLLECTOR() external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import './AaveV3PayloadBase.sol'; import { Arbitrum } from 'spark-address-registry/Arbitrum.sol'; import { Base } from 'spark-address-registry/Base.sol'; import { Ethereum } from 'spark-address-registry/Ethereum.sol'; import { Gnosis } from 'spark-address-registry/Gnosis.sol'; import { IExecutor } from 'spark-gov-relay/src/interfaces/IExecutor.sol'; import { AMBForwarder } from "xchain-helpers/forwarders/AMBForwarder.sol"; import { ArbitrumForwarder } from "xchain-helpers/forwarders/ArbitrumForwarder.sol"; import { OptimismForwarder } from "xchain-helpers/forwarders/OptimismForwarder.sol"; import { SparkLiquidityLayerHelpers } from './libraries/SparkLiquidityLayerHelpers.sol'; /** * @dev Base smart contract for Ethereum. * @author Phoenix Labs */ abstract contract SparkPayloadEthereum is AaveV3PayloadBase(IEngine(Ethereum.CONFIG_ENGINE)) { // These need to be immutable (delegatecall) and can only be set in constructor address public immutable PAYLOAD_ARBITRUM; address public immutable PAYLOAD_BASE; address public immutable PAYLOAD_GNOSIS; function execute() public override { super.execute(); if (PAYLOAD_ARBITRUM != address(0)) { ArbitrumForwarder.sendMessageL1toL2({ l1CrossDomain: ArbitrumForwarder.L1_CROSS_DOMAIN_ARBITRUM_ONE, target: Arbitrum.SPARK_RECEIVER, message: _encodePayloadQueue(PAYLOAD_ARBITRUM), gasLimit: 1_000_000, maxFeePerGas: 50e9, baseFee: block.basefee }); } if (PAYLOAD_BASE != address(0)) { OptimismForwarder.sendMessageL1toL2({ l1CrossDomain: OptimismForwarder.L1_CROSS_DOMAIN_BASE, target: Base.SPARK_RECEIVER, message: _encodePayloadQueue(PAYLOAD_BASE), gasLimit: 1_000_000 }); } if (PAYLOAD_GNOSIS != address(0)) { AMBForwarder.sendMessageEthereumToGnosisChain({ target: Gnosis.AMB_EXECUTOR, message: _encodePayloadQueue(PAYLOAD_GNOSIS), gasLimit: 1_000_000 }); } } function getPoolContext() public pure override returns (IEngine.PoolContext memory) { return IEngine.PoolContext({networkName: 'Ethereum', networkAbbreviation: 'Eth'}); } function _encodePayloadQueue(address _payload) internal pure returns (bytes memory) { address[] memory targets = new address[](1); uint256[] memory values = new uint256[](1); string[] memory signatures = new string[](1); bytes[] memory calldatas = new bytes[](1); bool[] memory withDelegatecalls = new bool[](1); targets[0] = _payload; values[0] = 0; signatures[0] = 'execute()'; calldatas[0] = ''; withDelegatecalls[0] = true; return abi.encodeCall(IExecutor.queue, ( targets, values, signatures, calldatas, withDelegatecalls )); } function _onboardAaveToken(address token, uint256 depositMax, uint256 depositSlope) internal { SparkLiquidityLayerHelpers.onboardAaveToken( Ethereum.ALM_RATE_LIMITS, token, depositMax, depositSlope ); } function _onboardERC4626Vault(address vault, uint256 depositMax, uint256 depositSlope) internal { SparkLiquidityLayerHelpers.onboardERC4626Vault( Ethereum.ALM_RATE_LIMITS, vault, depositMax, depositSlope ); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ event SwapBorrowRateMode( address indexed reserve, address indexed user, DataTypes.InterestRateMode interestRateMode ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed */ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa * @param asset The address of the underlying asset borrowed * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ function swapBorrowRateMode(address asset, uint256 interestRateMode) external; /** * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too * much has been borrowed at a stable rate and suppliers are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced */ function rebalanceStableBorrowRate(address asset, address user) external; /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve */ function getConfiguration( address asset ) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @notice Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user */ function getUserConfiguration( address user ) external view returns (DataTypes.UserConfigurationMap memory); /** * @notice Returns the normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct * @param id The id of the reserve as stored in the DataTypes.ReserveData struct * @return The address of the reserve associated with id */ function getReserveAddressById(uint16 id) external view returns (address); /** * @notice Returns the PoolAddressesProvider connected to this contract * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Updates the protocol fee on the bridging * @param bridgeProtocolFee The part of the premium sent to the protocol treasury */ function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; /** * @notice Updates flash loan premiums. Flash loan premium consists of two parts: * - A part is sent to aToken holders as extra, one time accumulated interest * - A part is collected by the protocol treasury * @dev The total premium is calculated on the total borrowed amount * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` * @dev Only callable by the PoolConfigurator contract * @param flashLoanPremiumTotal The total premium, expressed in bps * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps */ function updateFlashloanPremiums( uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol ) external; /** * @notice Configures a new category for the eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external; /** * @notice Returns the data of an eMode category * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate * @return The percentage of available liquidity to borrow, expressed in bps */ function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {ConfiguratorInputTypes} from '../protocol/libraries/types/ConfiguratorInputTypes.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 The address of the associated stable rate debt token * @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 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 stable rate borrowing is enabled or disabled on a reserve * @param asset The address of the underlying asset of the reserve * @param enabled True if stable rate borrowing is enabled, false otherwise */ event ReserveStableRateBorrowing(address indexed asset, bool enabled); /** * @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 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 the category of an asset in eMode is changed. * @param asset The address of the underlying asset of the reserve * @param oldCategoryId The old eMode asset category * @param newCategoryId The new eMode asset category */ event EModeAssetCategoryChanged(address indexed asset, uint8 oldCategoryId, uint8 newCategoryId); /** * @dev Emitted when a new eMode category is added. * @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 The optional address of the price oracle specific for this category * @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 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 stable debt token is upgraded. * @param asset The address of the underlying asset of the reserve * @param proxy The stable debt token proxy address * @param implementation The new aToken implementation */ event StableDebtTokenUpgraded( 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. * @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 stable debt token implementation for the reserve. * @param input The stableDebtToken update parameters */ function updateStableDebtToken( ConfiguratorInputTypes.UpdateDebtTokenInput 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. * @dev Can only be disabled (set to false) if stable borrowing is disabled * @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 stable rate borrowing on a reserve. * @dev Can only be enabled (set to true) if borrowing is enabled * @param asset The address of the underlying asset of the reserve * @param enabled True if stable rate borrowing needs to be enabled, false otherwise */ function setReserveStableRateBorrowing(address asset, bool enabled) 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 */ function setReservePause(address asset, bool paused) 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 */ function setReserveInterestRateStrategyAddress( address asset, address newRateStrategyAddress ) 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 */ 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 Assign an efficiency mode (eMode) category to asset. * @param asset The address of the underlying asset of the reserve * @param newCategoryId The new category id of the asset */ function setAssetEModeCategory(address asset, uint8 newCategoryId) external; /** * @notice Adds a new efficiency mode (eMode) category. * @dev If zero is provided as oracle address, the default asset oracles will be used to compute the overall debt and * overcollateralization of the users using this category. * @dev The new ltv and liquidation threshold must be greater than the base * ltvs and liquidation thresholds of all assets within the eMode category * @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 oracle The oracle associated with the category * @param label A label identifying the category */ function setEModeCategory( uint8 categoryId, uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus, address oracle, 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; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; type Id is bytes32; struct MarketParams { address loanToken; address collateralToken; address oracle; address irm; uint256 lltv; } /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest /// accrual. struct Position { uint256 supplyShares; uint128 borrowShares; uint128 collateral; } /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last /// interest accrual. struct Market { uint128 totalSupplyAssets; uint128 totalSupplyShares; uint128 totalBorrowAssets; uint128 totalBorrowShares; uint128 lastUpdate; uint128 fee; } struct Authorization { address authorizer; address authorized; bool isAuthorized; uint256 nonce; uint256 deadline; } struct Signature { uint8 v; bytes32 r; bytes32 s; } /// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho. /// @dev Consider using the IMorpho interface instead of this one. interface IMorphoBase { /// @notice The EIP-712 domain separator. /// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on another chain sharing /// the same chain id because the domain separator would be the same. function DOMAIN_SEPARATOR() external view returns (bytes32); /// @notice The owner of the contract. /// @dev It has the power to change the owner. /// @dev It has the power to set fees on markets and set the fee recipient. /// @dev It has the power to enable but not disable IRMs and LLTVs. function owner() external view returns (address); /// @notice The fee recipient of all markets. /// @dev The recipient receives the fees of a given market through a supply position on that market. function feeRecipient() external view returns (address); /// @notice Whether the `irm` is enabled. function isIrmEnabled(address irm) external view returns (bool); /// @notice Whether the `lltv` is enabled. function isLltvEnabled(uint256 lltv) external view returns (bool); /// @notice Whether `authorized` is authorized to modify `authorizer`'s position on all markets. /// @dev Anyone is authorized to modify their own positions, regardless of this variable. function isAuthorized(address authorizer, address authorized) external view returns (bool); /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures. function nonce(address authorizer) external view returns (uint256); /// @notice Sets `newOwner` as `owner` of the contract. /// @dev Warning: No two-step transfer ownership. /// @dev Warning: The owner can be set to the zero address. function setOwner(address newOwner) external; /// @notice Enables `irm` as a possible IRM for market creation. /// @dev Warning: It is not possible to disable an IRM. function enableIrm(address irm) external; /// @notice Enables `lltv` as a possible LLTV for market creation. /// @dev Warning: It is not possible to disable a LLTV. function enableLltv(uint256 lltv) external; /// @notice Sets the `newFee` for the given market `marketParams`. /// @param newFee The new fee, scaled by WAD. /// @dev Warning: The recipient can be the zero address. function setFee(MarketParams memory marketParams, uint256 newFee) external; /// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee. /// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost. /// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To /// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes. function setFeeRecipient(address newFeeRecipient) external; /// @notice Creates the market `marketParams`. /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees /// Morpho behaves as expected: /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`. /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with /// burn functions are not supported. /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`. /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported. /// - The IRM should not re-enter Morpho. /// - The oracle should return a price with the correct scaling. /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties /// (funds could get stuck): /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue. /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and /// `toSharesDown` overflow. /// - The IRM can revert on `borrowRate`. /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest` /// overflow. /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and /// `liquidate` from being used under certain market conditions. /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or /// the computation of `assetsRepaid` in `liquidate` overflow. /// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to /// the point where `totalBorrowShares` is very large and borrowing overflows. function createMarket(MarketParams memory marketParams) external; /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's /// `onMorphoSupply` function with the given `data`. /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the /// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific /// amount of shares is given for full compatibility and precision. /// @dev Supplying a large amount can revert for overflow. /// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage. /// Consider using the `assets` parameter to avoid this. /// @param marketParams The market to supply assets to. /// @param assets The amount of assets to supply. /// @param shares The amount of shares to mint. /// @param onBehalf The address that will own the increased supply position. /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. /// @return assetsSupplied The amount of assets supplied. /// @return sharesSupplied The amount of shares minted. function supply( MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, bytes memory data ) external returns (uint256 assetsSupplied, uint256 sharesSupplied); /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`. /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`. /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow. /// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to /// conversion roundings between shares and assets. /// @param marketParams The market to withdraw assets from. /// @param assets The amount of assets to withdraw. /// @param shares The amount of shares to burn. /// @param onBehalf The address of the owner of the supply position. /// @param receiver The address that will receive the withdrawn assets. /// @return assetsWithdrawn The amount of assets withdrawn. /// @return sharesWithdrawn The amount of shares burned. function withdraw( MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn); /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`. /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the /// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is /// given for full compatibility and precision. /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. /// @dev Borrowing a large amount can revert for overflow. /// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage. /// Consider using the `assets` parameter to avoid this. /// @param marketParams The market to borrow assets from. /// @param assets The amount of assets to borrow. /// @param shares The amount of shares to mint. /// @param onBehalf The address that will own the increased borrow position. /// @param receiver The address that will receive the borrowed assets. /// @return assetsBorrowed The amount of assets borrowed. /// @return sharesBorrowed The amount of shares minted. function borrow( MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed); /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's /// `onMorphoReplay` function with the given `data`. /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`. /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow. /// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion /// roundings between shares and assets. /// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow. /// @param marketParams The market to repay assets to. /// @param assets The amount of assets to repay. /// @param shares The amount of shares to burn. /// @param onBehalf The address of the owner of the debt position. /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed. /// @return assetsRepaid The amount of assets repaid. /// @return sharesRepaid The amount of shares burned. function repay( MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, bytes memory data ) external returns (uint256 assetsRepaid, uint256 sharesRepaid); /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's /// `onMorphoSupplyCollateral` function with the given `data`. /// @dev Interest are not accrued since it's not required and it saves gas. /// @dev Supplying a large amount can revert for overflow. /// @param marketParams The market to supply collateral to. /// @param assets The amount of collateral to supply. /// @param onBehalf The address that will own the increased collateral position. /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed. function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data) external; /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` and sends the assets to `receiver`. /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow. /// @param marketParams The market to withdraw collateral from. /// @param assets The amount of collateral to withdraw. /// @param onBehalf The address of the owner of the collateral position. /// @param receiver The address that will receive the collateral assets. function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver) external; /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's /// `onMorphoLiquidate` function with the given `data`. /// @dev Either `seizedAssets` or `repaidShares` should be zero. /// @dev Seizing more than the collateral balance will underflow and revert without any error message. /// @dev Repaying more than the borrow balance will underflow and revert without any error message. /// @dev An attacker can front-run a liquidation with a small repay making the transaction revert for underflow. /// @param marketParams The market of the position. /// @param borrower The owner of the position. /// @param seizedAssets The amount of collateral to seize. /// @param repaidShares The amount of shares to repay. /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed. /// @return The amount of assets seized. /// @return The amount of assets repaid. function liquidate( MarketParams memory marketParams, address borrower, uint256 seizedAssets, uint256 repaidShares, bytes memory data ) external returns (uint256, uint256); /// @notice Executes a flash loan. /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all /// markets combined, plus donations). /// @dev Warning: Not ERC-3156 compliant but compatibility is easily reached: /// - `flashFee` is zero. /// - `maxFlashLoan` is the token's balance of this contract. /// - The receiver of `assets` is the caller. /// @param token The token to flash loan. /// @param assets The amount of assets to flash loan. /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback. function flashLoan(address token, uint256 assets, bytes calldata data) external; /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions. /// @param authorized The authorized address. /// @param newIsAuthorized The new authorization status. function setAuthorization(address authorized, bool newIsAuthorized) external; /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions. /// @dev Warning: Reverts if the signature has already been submitted. /// @dev The signature is malleable, but it has no impact on the security here. /// @dev The nonce is passed as argument to be able to revert with a different error message. /// @param authorization The `Authorization` struct. /// @param signature The signature. function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external; /// @notice Accrues interest for the given market `marketParams`. function accrueInterest(MarketParams memory marketParams) external; /// @notice Returns the data stored on the different `slots`. function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory); } /// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler. /// @dev Consider using the IMorpho interface instead of this one. interface IMorphoStaticTyping is IMorphoBase { /// @notice The state of the position of `user` on the market corresponding to `id`. /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest /// accrual. function position(Id id, address user) external view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral); /// @notice The state of the market corresponding to `id`. /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest /// accrual. function market(Id id) external view returns ( uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee ); /// @notice The market params corresponding to `id`. /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`. function idToMarketParams(Id id) external view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv); } /// @title IMorpho /// @author Morpho Labs /// @custom:contact [email protected] /// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures. interface IMorpho is IMorphoBase { /// @notice The state of the position of `user` on the market corresponding to `id`. /// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest /// accrual. function position(Id id, address user) external view returns (Position memory p); /// @notice The state of the market corresponding to `id`. /// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual. /// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last /// interest accrual. function market(Id id) external view returns (Market memory m); /// @notice The market params corresponding to `id`. /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`. function idToMarketParams(Id id) external view returns (MarketParams memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; struct MarketConfig { /// @notice The maximum amount of assets that can be allocated to the market. uint184 cap; /// @notice Whether the market is in the withdraw queue. bool enabled; /// @notice The timestamp at which the market can be instantly removed from the withdraw queue. uint64 removableAt; } struct PendingUint192 { /// @notice The pending value to set. uint192 value; /// @notice The timestamp at which the pending value becomes valid. uint64 validAt; } struct PendingAddress { /// @notice The pending value to set. address value; /// @notice The timestamp at which the pending value becomes valid. uint64 validAt; } /// @title PendingLib /// @author Morpho Labs /// @custom:contact [email protected] /// @notice Library to manage pending values and their validity timestamp. library PendingLib { /// @dev Updates `pending`'s value to `newValue` and its corresponding `validAt` timestamp. /// @dev Assumes `timelock` <= `MAX_TIMELOCK`. function update(PendingUint192 storage pending, uint184 newValue, uint256 timelock) internal { pending.value = newValue; // Safe "unchecked" cast because timelock <= MAX_TIMELOCK. pending.validAt = uint64(block.timestamp + timelock); } /// @dev Updates `pending`'s value to `newValue` and its corresponding `validAt` timestamp. /// @dev Assumes `timelock` <= `MAX_TIMELOCK`. function update(PendingAddress storage pending, address newValue, uint256 timelock) internal { pending.value = newValue; // Safe "unchecked" cast because timelock <= MAX_TIMELOCK. pending.validAt = uint64(block.timestamp + timelock); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ event SwapBorrowRateMode( address indexed reserve, address indexed user, DataTypes.InterestRateMode interestRateMode ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed */ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa * @param asset The address of the underlying asset borrowed * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ function swapBorrowRateMode(address asset, uint256 interestRateMode) external; /** * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too * much has been borrowed at a stable rate and suppliers are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced */ function rebalanceStableBorrowRate(address asset, address user) external; /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve */ function getConfiguration( address asset ) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @notice Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user */ function getUserConfiguration( address user ) external view returns (DataTypes.UserConfigurationMap memory); /** * @notice Returns the normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the 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 category for the eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external; /** * @notice Returns the data of an eMode category * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate * @return The percentage of available liquidity to borrow, expressed in bps */ function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {ConfiguratorInputTypes} from '../protocol/libraries/types/ConfiguratorInputTypes.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 The address of the associated stable rate debt token * @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 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 stable rate borrowing is enabled or disabled on a reserve * @param asset The address of the underlying asset of the reserve * @param enabled True if stable rate borrowing is enabled, false otherwise */ event ReserveStableRateBorrowing(address indexed asset, bool enabled); /** * @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 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 the category of an asset in eMode is changed. * @param asset The address of the underlying asset of the reserve * @param oldCategoryId The old eMode asset category * @param newCategoryId The new eMode asset category */ event EModeAssetCategoryChanged(address indexed asset, uint8 oldCategoryId, uint8 newCategoryId); /** * @dev Emitted when a new eMode category is added. * @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 The optional address of the price oracle specific for this category * @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 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 stable debt token is upgraded. * @param asset The address of the underlying asset of the reserve * @param proxy The stable debt token proxy address * @param implementation The new aToken implementation */ event StableDebtTokenUpgraded( 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. * @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 stable debt token implementation for the reserve. * @param input The stableDebtToken update parameters */ function updateStableDebtToken( ConfiguratorInputTypes.UpdateDebtTokenInput 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. * @dev Can only be disabled (set to false) if stable borrowing is disabled * @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 stable rate borrowing on a reserve. * @dev Can only be enabled (set to true) if borrowing is enabled * @param asset The address of the underlying asset of the reserve * @param enabled True if stable rate borrowing needs to be enabled, false otherwise */ function setReserveStableRateBorrowing(address asset, bool enabled) 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 */ function setReservePause(address asset, bool paused) 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 */ function setReserveInterestRateStrategyAddress( address asset, address newRateStrategyAddress ) 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 */ 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 Assign an efficiency mode (eMode) category to asset. * @param asset The address of the underlying asset of the reserve * @param newCategoryId The new category id of the asset */ function setAssetEModeCategory(address asset, uint8 newCategoryId) external; /** * @notice Adds a new efficiency mode (eMode) category. * @dev If zero is provided as oracle address, the default asset oracles will be used to compute the overall debt and * overcollateralization of the users using this category. * @dev The new ltv and liquidation threshold must be greater than the base * ltvs and liquidation thresholds of all assets within the eMode category * @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 oracle The oracle associated with the category * @param label A label identifying the category */ function setEModeCategory( uint8 categoryId, uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus, address oracle, 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; }
// SPDX-License-Identifier: AGPL-3.0 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 {IPoolAddressesProvider} from 'sparklend-v1-core/contracts/interfaces/IPoolAddressesProvider.sol'; import {IDefaultInterestRateStrategy} from 'sparklend-v1-core/contracts/interfaces/IDefaultInterestRateStrategy.sol'; interface IV3RateStrategyFactory { event RateStrategyCreated( address indexed strategy, bytes32 indexed hashedParam, RateStrategyParams params ); /// @dev same parameters and the ones received on the constructor of DefaultReserveInterestRateStrategy /// in practise defining the strategy itself struct RateStrategyParams { uint256 optimalUsageRatio; uint256 baseVariableBorrowRate; uint256 variableRateSlope1; uint256 variableRateSlope2; uint256 stableRateSlope1; uint256 stableRateSlope2; uint256 baseStableRateOffset; uint256 stableRateExcessOffset; uint256 optimalStableToTotalDebtRatio; } /** * @notice Create new rate strategies from a list of parameters * @dev If a strategy with exactly the same `RateStrategyParams` already exists, no creation happens but * its address is returned * @param params `RateStrategyParams[]` list of parameters for multiple strategies * @return address[] list of strategies */ function createStrategies(RateStrategyParams[] memory params) external returns (address[] memory); /** * @notice Returns the identifier of a rate strategy from its parameters * @param params `RateStrategyParams` the parameters of the rate strategy * @return bytes32 the keccak256 hash generated from the `RateStrategyParams` parameters * to be used as identifier of the rate strategy on the factory */ function strategyHashFromParams(RateStrategyParams memory params) external pure returns (bytes32); /** * @notice Returns all the strategies registered in the factory * @return address[] list of strategies */ function getAllStrategies() external view returns (address[] memory); /** * @notice Returns the a strategy added, given its parameters. * @dev Only if the strategy is registered in the factory. * @param params `RateStrategyParams` the parameters of the rate strategy * @return address the address of the strategy */ function getStrategyByParams(RateStrategyParams memory params) external view returns (address); /** * @notice From an asset in the Aave v3 pool, returns exclusively its parameters * @param asset The address of the asset * @return RateStrategyParams The parameters or the strategy, or empty RateStrategyParams struct */ function getStrategyDataOfAsset(address asset) external view returns (RateStrategyParams memory); /** * @notice From a rate strategy address, returns its parameters * @param strategy The address of the rate strategy * @return RateStrategyParams Struct with the parameters of the strategy */ function getStrategyData( IDefaultInterestRateStrategy strategy ) external view returns (RateStrategyParams memory); function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Address} from './libraries/Address.sol'; import {IAaveV3ConfigEngine as IEngine} from './interfaces/IAaveV3ConfigEngine.sol'; import {IV3RateStrategyFactory as Rates} from './interfaces/IV3RateStrategyFactory.sol'; library EngineFlags { /// @dev magic value to be used as flag to keep unchanged any current configuration /// Strongly assumes that the value `type(uint256).max - 42` will never be used, which seems reasonable uint256 internal constant KEEP_CURRENT = type(uint256).max - 42; /// @dev value to be used as flag for bool value true uint256 internal constant ENABLED = 1; /// @dev value to be used as flag for bool value false uint256 internal constant DISABLED = 0; /// @dev converts flag ENABLED DISABLED to bool function toBool(uint256 flag) internal pure returns (bool) { require(flag == 0 || flag == 1, 'INVALID_CONVERSION_TO_BOOL'); return flag == 1; } /// @dev converts bool to ENABLED DISABLED flags function fromBool(bool isTrue) internal pure returns (uint256) { return isTrue ? ENABLED : DISABLED; } } /** * @dev Base smart contract for an Aave v3.0.1 configs update. * - Assumes this contract has the right permissions * - Connected to a IAaveV3ConfigEngine engine contact, which abstract the complexities of * interaction with the Aave protocol. * - At the moment covering: * - Listings of new assets on the pool. * - Updates of caps (supply cap, borrow cap). * - Updates of price feeds * - Updates of interest rate strategies. * - Updates of borrow parameters (flashloanable, stableRateModeEnabled, borrowableInIsolation, withSiloedBorrowing, reserveFactor) * - Updates of collateral parameters (ltv, liq threshold, liq bonus, liq protocol fee, debt ceiling) * @author BGD Labs */ abstract contract AaveV3PayloadBase { using Address for address; IEngine public immutable LISTING_ENGINE; constructor(IEngine engine) { LISTING_ENGINE = engine; } /// @dev to be overriden on the child if any extra logic is needed pre-listing function _preExecute() internal virtual {} /// @dev to be overriden on the child if any extra logic is needed post-listing function _postExecute() internal virtual {} function execute() public virtual { _preExecute(); IEngine.Listing[] memory listings = newListings(); IEngine.ListingWithCustomImpl[] memory listingsCustom = newListingsCustom(); IEngine.CapsUpdate[] memory caps = capsUpdates(); IEngine.CollateralUpdate[] memory collaterals = collateralsUpdates(); IEngine.BorrowUpdate[] memory borrows = borrowsUpdates(); IEngine.PriceFeedUpdate[] memory priceFeeds = priceFeedsUpdates(); IEngine.RateStrategyUpdate[] memory rates = rateStrategiesUpdates(); if (listings.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.listAssets.selector, getPoolContext(), listings) ); } if (listingsCustom.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector( LISTING_ENGINE.listAssetsCustom.selector, getPoolContext(), listingsCustom ) ); } if (borrows.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.updateBorrowSide.selector, borrows) ); } if (collaterals.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.updateCollateralSide.selector, collaterals) ); } if (rates.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.updateRateStrategies.selector, rates) ); } if (priceFeeds.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.updatePriceFeeds.selector, priceFeeds) ); } if (caps.length != 0) { address(LISTING_ENGINE).functionDelegateCall( abi.encodeWithSelector(LISTING_ENGINE.updateCaps.selector, caps) ); } _postExecute(); } /** @dev Converts basis points to RAY units * e.g. 10_00 (10.00%) will return 100000000000000000000000000 */ function _bpsToRay(uint256 amount) internal pure returns (uint256) { return (amount * 1e27) / 10_000; } /// @dev to be defined in the child with a list of new assets to list function newListings() public view virtual returns (IEngine.Listing[] memory) {} /// @dev to be defined in the child with a list of new assets to list (with custom a/v/s tokens implementations) function newListingsCustom() public view virtual returns (IEngine.ListingWithCustomImpl[] memory) {} /// @dev to be defined in the child with a list of caps to update function capsUpdates() public view virtual returns (IEngine.CapsUpdate[] memory) {} /// @dev to be defined in the child with a list of collaterals' params to update function collateralsUpdates() public view virtual returns (IEngine.CollateralUpdate[] memory) {} /// @dev to be defined in the child with a list of borrows' params to update function borrowsUpdates() public view virtual returns (IEngine.BorrowUpdate[] memory) {} /// @dev to be defined in the child with a list of priceFeeds to update function priceFeedsUpdates() public view virtual returns (IEngine.PriceFeedUpdate[] memory) {} /// @dev to be defined in the child with a list of set of parameters of rate strategies function rateStrategiesUpdates() public view virtual returns (IEngine.RateStrategyUpdate[] memory) {} /// @dev the lack of support for immutable strings kinds of forces for this /// Besides that, it can actually be useful being able to change the naming, but remote function getPoolContext() public view virtual returns (IEngine.PoolContext memory); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; library Arbitrum { /******************************************************************************************************************/ /*** Token Addresses ***/ /******************************************************************************************************************/ address internal constant SUSDC = 0x940098b108fB7D0a7E374f6eDED7760787464609; address internal constant SUSDS = 0xdDb46999F8891663a8F2828d25298f70416d7610; address internal constant USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831; address internal constant USDS = 0x6491c05A82219b8D1479057361ff1654749b876b; /******************************************************************************************************************/ /*** Bridging Addresses ***/ /******************************************************************************************************************/ address internal constant CCTP_TOKEN_MESSENGER = 0x19330d10D9Cc8751218eaf51E8885D058642E08A; address internal constant SKY_GOV_RELAY = 0x10E6593CDda8c58a1d0f14C5164B376352a55f2F; address internal constant TOKEN_BRIDGE = 0x13F7F24CA959359a4D710D32c715D4bce273C793; /******************************************************************************************************************/ /*** PSM Addresses ***/ /******************************************************************************************************************/ address internal constant PSM3 = 0x2B05F8e1cACC6974fD79A673a341Fe1f58d27266; /******************************************************************************************************************/ /*** Spark Liquidity Layer Addresses ***/ /******************************************************************************************************************/ address internal constant ALM_CONTROLLER = 0x77e11453a99a7770b04f7921FfccD3eE9761ba6c; address internal constant ALM_PROXY = 0x92afd6F2385a90e44da3a8B60fe36f6cBe1D8709; address internal constant ALM_RATE_LIMITS = 0x19D08879851FB54C2dCc4bb32b5a1EA5E9Ad6838; address internal constant ALM_FREEZER = 0x90D8c80C028B4C09C0d8dcAab9bbB057F0513431; address internal constant ALM_RELAYER = 0x8a25A24EDE9482C4Fc0738F99611BE58F1c839AB; /******************************************************************************************************************/ /*** Aave Addresses ***/ /******************************************************************************************************************/ address internal constant ATOKEN_USDC = 0x724dc807b04555b71ed48a6896b6F41593b8C637; /******************************************************************************************************************/ /*** Governance Relay Addresses ***/ /******************************************************************************************************************/ address internal constant SPARK_EXECUTOR = 0x65d946e533748A998B1f0E430803e39A6388f7a1; address internal constant SPARK_RECEIVER = 0x212871A1C235892F86cAB30E937e18c94AEd8474; /******************************************************************************************************************/ /*** SSR Oracle Addresses ***/ /******************************************************************************************************************/ address internal constant SSR_AUTH_ORACLE = 0xEE2816c1E1eed14d444552654Ed3027abC033A36; address internal constant SSR_BALANCER_RATE_PROVIDER = 0xc0737f29b964e6fC8025F16B30f2eA4C2e2d6f22; address internal constant SSR_CHAINLINK_RATE_PROVIDER = 0x84AB0c8C158A1cD0d215BE2746cCa668B79cc287; address internal constant SSR_RECEIVER = 0x567214Dc57a2385Abc4a756f523ddF0275305Cbc; /******************************************************************************************************************/ /*** DSR Oracle Addresses ***/ /******************************************************************************************************************/ address internal constant DSR_AUTH_ORACLE = 0xE206AEbca7B28e3E8d6787df00B010D4a77c32F3; address internal constant DSR_RECEIVER = 0xcA61540eC2AC74E6954FA558B4aF836d95eCb91b; address internal constant DSR_BALANCER_RATE_PROVIDER = 0x73750DbD85753074e452B2C27fB9e3B0E75Ff3B8; /******************************************************************************************************************/ /*** Multisigs ***/ /******************************************************************************************************************/ address internal constant SPARK_REWARDS_MULTISIG = 0xF649956f43825d4d7295a50EDdBe1EDC814A3a83; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; library Base { /******************************************************************************************************************/ /*** Token Addresses ***/ /******************************************************************************************************************/ address internal constant CBBTC = 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf; address internal constant SKY = 0x60e3c701e65DEE30c23c9Fb78c3866479cc0944a; address internal constant SUSDC = 0x3128a0F7f0ea68E7B7c9B00AFa7E41045828e858; address internal constant SUSDS = 0x5875eEE11Cf8398102FdAd704C9E96607675467a; address internal constant USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913; address internal constant USDS = 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc; /******************************************************************************************************************/ /*** Bridging Addresses ***/ /******************************************************************************************************************/ address internal constant CCTP_TOKEN_MESSENGER = 0x1682Ae6375C4E4A97e4B583BC394c861A46D8962; address internal constant SKY_GOV_RELAY = 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255; address internal constant TOKEN_BRIDGE = 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7; /******************************************************************************************************************/ /*** PSM Addresses ***/ /******************************************************************************************************************/ address internal constant PSM3 = 0x1601843c5E9bC251A3272907010AFa41Fa18347E; /******************************************************************************************************************/ /*** Spark Liquidity Layer Addresses ***/ /******************************************************************************************************************/ address internal constant ALM_CONTROLLER = 0x5F032555353f3A1D16aA6A4ADE0B35b369da0440; address internal constant ALM_PROXY = 0x2917956eFF0B5eaF030abDB4EF4296DF775009cA; address internal constant ALM_RATE_LIMITS = 0x983eC82E45C61a42FDDA7B3c43B8C767004c8A74; address internal constant ALM_FREEZER = 0x90D8c80C028B4C09C0d8dcAab9bbB057F0513431; address internal constant ALM_RELAYER = 0x8a25A24EDE9482C4Fc0738F99611BE58F1c839AB; /******************************************************************************************************************/ /*** Aave Addresses ***/ /******************************************************************************************************************/ address internal constant ATOKEN_USDC = 0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB; /******************************************************************************************************************/ /*** Fluid Addresses ***/ /******************************************************************************************************************/ address internal constant FLUID_SUSDS = 0xf62e339f21d8018940f188F6987Bcdf02A849619; /******************************************************************************************************************/ /*** Morpho Addresses ***/ /******************************************************************************************************************/ address internal constant MORPHO = 0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb; address internal constant MORPHO_DEFAULT_IRM = 0x46415998764C29aB2a25CbeA6254146D50D22687; address internal constant MORPHO_VAULT_SUSDC = 0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A; /******************************************************************************************************************/ /*** Governance Relay Addresses ***/ /******************************************************************************************************************/ address internal constant SPARK_EXECUTOR = 0xF93B7122450A50AF3e5A76E1d546e95Ac1d0F579; address internal constant SPARK_RECEIVER = 0xfda082e00EF89185d9DB7E5DcD8c5505070F5A3B; /******************************************************************************************************************/ /*** SSR Oracle Addresses ***/ /******************************************************************************************************************/ address internal constant SSR_AUTH_ORACLE = 0x65d946e533748A998B1f0E430803e39A6388f7a1; address internal constant SSR_BALANCER_RATE_PROVIDER = 0x49aF4eE75Ae62C2229bb2486a59Aa1a999f050f0; address internal constant SSR_CHAINLINK_RATE_PROVIDER = 0x026a5B6114431d8F3eF2fA0E1B2EDdDccA9c540E; address internal constant SSR_RECEIVER = 0x212871A1C235892F86cAB30E937e18c94AEd8474; /******************************************************************************************************************/ /*** DSR Oracle Addresses (Legacy) ***/ /******************************************************************************************************************/ address internal constant DSR_AUTH_ORACLE = 0x2Dd2a2Fe346B5704380EfbF6Bd522042eC3E8FAe; address internal constant DSR_RECEIVER = 0xaDEAf02Ddb5Bed574045050B8096307bE66E0676; address internal constant DSR_BALANCER_RATE_PROVIDER = 0xeC0C14Ea7fF20F104496d960FDEBF5a0a0cC14D0; /******************************************************************************************************************/ /*** Multisigs ***/ /******************************************************************************************************************/ address internal constant SPARK_REWARDS_MULTISIG = 0xF649956f43825d4d7295a50EDdBe1EDC814A3a83; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; library Gnosis { /******************************************************************************************************************/ /*** Token Addresses ***/ /******************************************************************************************************************/ address internal constant GNO = 0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb; address internal constant WETH = 0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1; address internal constant WSTETH = 0x6C76971f98945AE98dD7d4DFcA8711ebea946eA6; address internal constant WXDAI = 0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d; address internal constant SXDAI = 0xaf204776c7245bF4147c2612BF6e5972Ee483701; address internal constant USDC = 0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83; address internal constant USDCE = 0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0; address internal constant USDT = 0x4ECaBa5870353805a9F068101A40E0f32ed605C6; address internal constant EURE = 0xcB444e90D8198415266c6a2724b7900fb12FC56E; /******************************************************************************************************************/ /*** SparkLend - Core Protocol Addresses ***/ /******************************************************************************************************************/ address internal constant AAVE_ORACLE = 0x8105f69D9C41644c6A0803fDA7D03Aa70996cFD9; address internal constant ACL_MANAGER = 0x86C71796CcDB31c3997F8Ec5C2E3dB3e9e40b985; address internal constant EMISSION_MANAGER = 0x4d988568b5f0462B08d1F40bA1F5f17ad2D24F76; address internal constant INCENTIVES = 0x98e6BcBA7d5daFbfa4a92dAF08d3d7512820c30C; address internal constant POOL = 0x2Dae5307c5E3FD1CF5A72Cb6F698f915860607e0; address internal constant POOL_ADDRESSES_PROVIDER = 0xA98DaCB3fC964A6A0d2ce3B77294241585EAbA6d; address internal constant POOL_ADDRESSES_PROVIDER_REGISTRY = 0x49d24798d3b84965F0d1fc8684EF6565115e70c1; address internal constant POOL_CONFIGURATOR = 0x2Fc8823E1b967D474b47Ae0aD041c2ED562ab588; address internal constant TREASURY = 0xb9E6DBFa4De19CCed908BcbFe1d015190678AB5f; address internal constant TREASURY_CONTROLLER = 0x8220096398c3Dc2644026E8864f5D80Ef613B437; address internal constant WETH_GATEWAY = 0xBD7D6a9ad7865463DE44B05F04559f65e3B11704; /******************************************************************************************************************/ /*** SparkLend - Reserve Token Addresses ***/ /******************************************************************************************************************/ address internal constant GNO_ATOKEN = 0x5671b0B8aC13DC7813D36B99C21c53F6cd376a14; address internal constant GNO_STABLE_DEBT_TOKEN = 0x2f589BADbE2024a94f144ef24344aF91dE21a33c; address internal constant GNO_DEBT_TOKEN = 0xd4bAbF714964E399f95A7bb94B3DeaF22d9F575d; address internal constant WETH_ATOKEN = 0x629D562E92fED431122e865Cc650Bc6bdE6B96b0; address internal constant WETH_STABLE_DEBT_TOKEN = 0xe21Bf3FB5A2b5Bf7BAE8c6F1696c4B097F5D2f93; address internal constant WETH_DEBT_TOKEN = 0x0aD6cCf9a2e81d4d48aB7db791e9da492967eb84; address internal constant WSTETH_ATOKEN = 0x9Ee4271E17E3a427678344fd2eE64663Cb78B4be; address internal constant WSTETH_STABLE_DEBT_TOKEN = 0x0F0e336Ab69D9516A9acF448bC59eA0CE79E4a42; address internal constant WSTETH_DEBT_TOKEN = 0x3294dA2E28b29D1c08D556e2B86879d221256d31; address internal constant WXDAI_ATOKEN = 0xC9Fe2D32E96Bb364c7d29f3663ed3b27E30767bB; address internal constant WXDAI_STABLE_DEBT_TOKEN = 0xab1B62A1346Acf534b581684940E2FD781F2EA22; address internal constant WXDAI_DEBT_TOKEN = 0x868ADfDf12A86422524EaB6978beAE08A0008F37; address internal constant SXDAI_ATOKEN = 0xE877b96caf9f180916bF2B5Ce7Ea8069e0123182; address internal constant SXDAI_STABLE_DEBT_TOKEN = 0x2cF710377b3576287Be7cf352FF75D4472902789; address internal constant SXDAI_DEBT_TOKEN = 0x1022E390E2457A78E18AEEE0bBf0E96E482EeE19; address internal constant USDC_ATOKEN = 0x5850D127a04ed0B4F1FCDFb051b3409FB9Fe6B90; address internal constant USDC_STABLE_DEBT_TOKEN = 0x40BF0Bf6AECeE50eCE10C74E81a52C654A467ae4; address internal constant USDC_DEBT_TOKEN = 0xBC4f20DAf4E05c17E93676D2CeC39769506b8219; address internal constant USDCE_ATOKEN = 0xA34DB0ee8F84C4B90ed268dF5aBbe7Dcd3c277ec; address internal constant USDCE_STABLE_DEBT_TOKEN = 0xC5dfde524371F9424c81F453260B2CCd24936c15; address internal constant USDCE_DEBT_TOKEN = 0x397b97b572281d0b3e3513BD4A7B38050a75962b; address internal constant USDT_ATOKEN = 0x08B0cAebE352c3613302774Cd9B82D08afd7bDC4; address internal constant USDT_STABLE_DEBT_TOKEN = 0x4cB3F681B5e393947BD1e5cAE84764f5892923C2; address internal constant USDT_DEBT_TOKEN = 0x3A98aBC6F46CA2Fc6c7d06eD02184D63C55e19B2; address internal constant EURE_ATOKEN = 0x6dc304337BF3EB397241d1889cAE7da638e6e782; address internal constant EURE_STABLE_DEBT_TOKEN = 0x80F87B8F9c1199e468923D8EE87cEE311690FDA6; address internal constant EURE_DEBT_TOKEN = 0x0b33480d3FbD1E2dBE88c82aAbe191D7473759D5; /******************************************************************************************************************/ /*** SparkLend - Implementation Addresses ***/ /******************************************************************************************************************/ address internal constant A_TOKEN_IMPL = 0x856900aa78e856a5df1a2665eE3a66b2487cD68f; address internal constant INCENTIVES_IMPL = 0x764b4AB9bCA18eB633d92368F725765Ebb8f047C; address internal constant POOL_CONFIGURATOR_IMPL = 0x6175ddEc3B9b38c88157C10A01ed4A3fa8639cC6; address internal constant POOL_IMPL = 0xCF86A65779e88bedfF0319FE13aE2B47358EB1bF; address internal constant STABLE_DEBT_TOKEN_IMPL = 0x4370D3b6C9588E02ce9D22e684387859c7Ff5b34; address internal constant TREASURY_IMPL = 0x571501be53711c372cE69De51865dD34B87698D5; address internal constant VARIABLE_DEBT_TOKEN_IMPL = 0x0ee554F6A1f7a4Cb4f82D4C124DdC2AD3E37fde1; /******************************************************************************************************************/ /*** SparkLend - Config Engine Addresses ***/ /******************************************************************************************************************/ address internal constant PROXY_ADMIN = 0xf76B8262dfd60fb7432C6b55E91f42b6da953647; address internal constant CONFIG_ENGINE = 0x36eddc380C7f370e5f05Da5Bd7F970a27f063e39; address internal constant RATES_FACTORY = 0xe04ba71E46fCd7DBB9334D8FBa13d476f38EB0f8; address internal constant TRANSPARENT_PROXY_FACTORY = 0x91277b74a9d1Cc30fA0ff4927C287fe55E307D78; /******************************************************************************************************************/ /*** SparkLend - Data Provider Addresses ***/ /******************************************************************************************************************/ address internal constant PROTOCOL_DATA_PROVIDER = 0x2a002054A06546bB5a264D57A81347e23Af91D18; address internal constant UI_INCENTIVE_DATA_PROVIDER = 0xA7F8A757C4f7696c015B595F51B2901AC0121B18; address internal constant UI_POOL_DATA_PROVIDER = 0xF028c2F4b19898718fD0F77b9b881CbfdAa5e8Bb; address internal constant WALLET_BALANCE_PROVIDER = 0xd2AeF86F51F92E8e49F42454c287AE4879D1BeDc; /******************************************************************************************************************/ /*** Governance Addresses ***/ /******************************************************************************************************************/ address constant AMB_EXECUTOR = 0xc4218C1127cB24a0D6c1e7D25dc34e10f2625f5A; /******************************************************************************************************************/ /*** Multisigs ***/ /******************************************************************************************************************/ address internal constant SPARK_REWARDS_MULTISIG = 0xF649956f43825d4d7295a50EDdBe1EDC814A3a83; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity >=0.8.0; import { IAccessControl } from 'openzeppelin-contracts/contracts/access/IAccessControl.sol'; /** * @title IExecutor * @author Aave * @notice Defines the interface for the Executor */ interface IExecutor is IAccessControl { /******************************************************************************************************************/ /*** Errors ***/ /******************************************************************************************************************/ error GracePeriodTooShort(); error OnlyQueuedActions(); error TimelockNotFinished(); error InvalidActionsSetId(); error EmptyTargets(); error InconsistentParamsLength(); error InsufficientBalance(); /******************************************************************************************************************/ /*** Enums ***/ /******************************************************************************************************************/ /** * @notice This enum contains all possible actions set states */ enum ActionsSetState { Queued, Executed, Canceled, Expired } /******************************************************************************************************************/ /*** Events ***/ /******************************************************************************************************************/ /** * @notice This struct contains the data needed to execute a specified set of actions. * @param targets Array of targets to call. * @param values Array of values to pass in each call. * @param signatures Array of function signatures to encode in each call by the actions which can be empty strings. * @param calldatas Array of calldatas to pass in each call, appended to the signature at the same array index if not empty. * @param withDelegateCalls Array of whether to delegatecall for each call. * @param executionTime Timestamp starting from which the actions set can be executed. * @param executed True if the actions set has been executed, false otherwise. * @param canceled True if the actions set has been canceled, false otherwise. */ struct ActionsSet { address[] targets; uint256[] values; string[] signatures; bytes[] calldatas; bool[] withDelegatecalls; uint256 executionTime; bool executed; bool canceled; } /** * @dev Emitted when an ActionsSet is queued. * @param id Id of the ActionsSet. * @param targets Array of targets to be called by the actions set. * @param values Array of values to pass in each call by the actions set. * @param signatures Array of function signatures to encode in each call by the actions set. * @param calldatas Array of calldata to pass in each call by the actions set. * @param withDelegatecalls Array of whether to delegatecall for each call of the actions set. * @param executionTime The timestamp at which this actions set can be executed. **/ event ActionsSetQueued( uint256 indexed id, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, bool[] withDelegatecalls, uint256 executionTime ); /** * @dev Emitted when an ActionsSet is successfully executed. * @param id Id of the ActionsSet. * @param initiatorExecution The address that triggered the ActionsSet execution. * @param returnedData The returned data from the ActionsSet execution. **/ event ActionsSetExecuted( uint256 indexed id, address indexed initiatorExecution, bytes[] returnedData ); /** * @dev Emitted when an ActionsSet is cancelled by the guardian. * @param id Id of the ActionsSet. **/ event ActionsSetCanceled(uint256 indexed id); /** * @dev Emitted when the delay (between queueing and execution) is updated. * @param oldDelay The value of the old delay. * @param newDelay The value of the new delay. **/ event DelayUpdate(uint256 oldDelay, uint256 newDelay); /** * @dev Emitted when the grace period (between executionTime and expiration) is updated. * @param oldGracePeriod The value of the old grace period. * @param newGracePeriod The value of the new grace period. **/ event GracePeriodUpdate(uint256 oldGracePeriod, uint256 newGracePeriod); /******************************************************************************************************************/ /*** State variables ***/ /******************************************************************************************************************/ /** * @notice The role that allows submission of a queued action. **/ function SUBMISSION_ROLE() external view returns (bytes32); /** * @notice The role that allows a guardian to cancel a pending action. **/ function GUARDIAN_ROLE() external view returns (bytes32); /** * @notice Returns the minimum grace period that can be set, 10 minutes. */ function MINIMUM_GRACE_PERIOD() external view returns (uint256); /** * @notice Returns the total number of actions sets of the executor. * @return The number of actions sets. **/ function actionsSetCount() external view returns (uint256); /** * @notice Returns the delay (between queuing and execution) * @return The value of the delay (in seconds) **/ function delay() external view returns (uint256); /** * @notice Time after the execution time during which the actions set can be executed. * @return The value of the grace period (in seconds) **/ function gracePeriod() external view returns (uint256); /******************************************************************************************************************/ /*** ActionSet functions ***/ /******************************************************************************************************************/ /** * @notice Queue an ActionsSet. * @dev If a signature is empty, calldata is used for the execution, calldata is appended to signature otherwise. * @param targets Array of targets to be called by the actions set. * @param values Array of values to pass in each call by the actions set. * @param signatures Array of function signatures to encode in each call by the actions which can be empty strings. * @param calldatas Array of calldata to pass in each call by the actions set. * @param withDelegatecalls Array of whether to delegatecall for each call of the actions set. **/ function queue( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, bool[] memory withDelegatecalls ) external; /** * @notice Execute the ActionsSet * @param actionsSetId The id of the ActionsSet to execute **/ function execute(uint256 actionsSetId) external payable; /** * @notice Cancel the ActionsSet. * @param actionsSetId The id of the ActionsSet to cancel. **/ function cancel(uint256 actionsSetId) external; /******************************************************************************************************************/ /*** Admin functions ***/ /******************************************************************************************************************/ /** * @notice Update the delay, time between queueing and execution of ActionsSet. * @dev It does not affect to actions set that are already queued. * @param delay The value of the delay (in seconds). **/ function updateDelay(uint256 delay) external; /** * @notice Update the grace period, the period after the execution time during which an actions set can be executed * @param gracePeriod The value of the grace period (in seconds). **/ function updateGracePeriod(uint256 gracePeriod) external; /******************************************************************************************************************/ /*** Misc functions ***/ /******************************************************************************************************************/ /** * @notice Allows to delegatecall a given target with an specific amount of value. * @dev This function is external so it allows to specify a defined msg.value for the delegate call, reducing * the risk that a delegatecall gets executed with more value than intended. * @return The bytes returned by the delegate call. **/ function executeDelegateCall(address target, bytes calldata data) external payable returns (bytes memory); /** * @notice Allows to receive funds into the executor. * @dev Useful for actionsSet that needs funds to gets executed. */ function receiveFunds() external payable; /******************************************************************************************************************/ /*** View functions ***/ /******************************************************************************************************************/ /** * @notice Returns the data of an actions set. * @param actionsSetId The id of the ActionsSet. * @return The data of the ActionsSet. **/ function getActionsSetById(uint256 actionsSetId) external view returns (ActionsSet memory); /** * @notice Returns the current state of an actions set. * @param actionsSetId The id of the ActionsSet. * @return The current state of theI ActionsSet. **/ function getCurrentState(uint256 actionsSetId) external view returns (ActionsSetState); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; interface IArbitraryMessagingBridge { function requireToPassMessage(address _contract, bytes memory _data, uint256 _gas) external returns (bytes32); } library AMBForwarder { address constant internal GNOSIS_AMB_ETHEREUM = 0x4C36d2919e407f0Cc2Ee3c993ccF8ac26d9CE64e; address constant internal GNOSIS_AMB_GNOSIS_CHAIN = 0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59; function sendMessage( address amb, address target, bytes memory message, uint256 gasLimit ) internal { IArbitraryMessagingBridge(amb).requireToPassMessage( target, message, gasLimit ); } function sendMessageEthereumToGnosisChain( address target, bytes memory message, uint256 gasLimit ) internal { sendMessage( GNOSIS_AMB_ETHEREUM, target, message, gasLimit ); } function sendMessageGnosisChainToEthereum( address target, bytes memory message, uint256 gasLimit ) internal { sendMessage( GNOSIS_AMB_GNOSIS_CHAIN, target, message, gasLimit ); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; interface ICrossDomainArbitrum { function createRetryableTicket( address to, uint256 l2CallValue, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes calldata data ) external payable returns (uint256); function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee) external view returns (uint256); } interface IArbSys { function sendTxToL1(address target, bytes calldata message) external; } library ArbitrumForwarder { address constant internal L1_CROSS_DOMAIN_ARBITRUM_ONE = 0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f; address constant internal L1_CROSS_DOMAIN_ARBITRUM_NOVA = 0xc4448b71118c9071Bcb9734A0EAc55D18A153949; address constant internal L2_CROSS_DOMAIN = 0x0000000000000000000000000000000000000064; function sendMessageL1toL2( address l1CrossDomain, address target, bytes memory message, uint256 gasLimit, uint256 maxFeePerGas, uint256 baseFee ) internal { uint256 maxSubmission = ICrossDomainArbitrum(l1CrossDomain).calculateRetryableSubmissionFee(message.length, baseFee); uint256 maxRedemption = gasLimit * maxFeePerGas; ICrossDomainArbitrum(l1CrossDomain).createRetryableTicket{value: maxSubmission + maxRedemption}( target, 0, // we always assume that l2CallValue = 0 maxSubmission, address(0), // burn the excess gas address(0), // burn the excess gas gasLimit, maxFeePerGas, message ); } function sendMessageL2toL1( address target, bytes memory message ) internal { IArbSys(L2_CROSS_DOMAIN).sendTxToL1( target, message ); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; interface ICrossDomainOptimism { function sendMessage(address _target, bytes calldata _message, uint32 _gasLimit) external; } library OptimismForwarder { address constant internal L1_CROSS_DOMAIN_OPTIMISM = 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1; address constant internal L1_CROSS_DOMAIN_BASE = 0x866E82a600A1414e583f7F13623F1aC5d58b0Afa; address constant internal L1_CROSS_DOMAIN_WORLD_CHAIN = 0xf931a81D18B1766d15695ffc7c1920a62b7e710a; address constant internal L2_CROSS_DOMAIN = 0x4200000000000000000000000000000000000007; function sendMessageL1toL2( address l1CrossDomain, address target, bytes memory message, uint32 gasLimit ) internal { ICrossDomainOptimism(l1CrossDomain).sendMessage( target, message, gasLimit ); } function sendMessageL2toL1( address target, bytes memory message, uint32 gasLimit ) internal { ICrossDomainOptimism(L2_CROSS_DOMAIN).sendMessage( target, message, gasLimit ); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import { IERC20 } from 'forge-std/interfaces/IERC20.sol'; import { IERC4626 } from 'forge-std/interfaces/IERC4626.sol'; import { IAToken } from "aave-v3-origin/src/core/contracts/interfaces/IAToken.sol"; import { IMetaMorpho, Id } from "metamorpho/interfaces/IMetaMorpho.sol"; import { MarketParams } from "morpho-blue/src/interfaces/IMorpho.sol"; import { MarketParamsLib } from "morpho-blue/src/libraries/MarketParamsLib.sol"; import { RateLimitHelpers, RateLimitData } from "spark-alm-controller/src/RateLimitHelpers.sol"; /** * @notice Helper functions for Spark Liquidity Layer */ library SparkLiquidityLayerHelpers { // This is the same on all chains address private constant MORPHO = 0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb; bytes32 private constant LIMIT_4626_DEPOSIT = keccak256("LIMIT_4626_DEPOSIT"); bytes32 private constant LIMIT_4626_WITHDRAW = keccak256("LIMIT_4626_WITHDRAW"); bytes32 private constant LIMIT_AAVE_DEPOSIT = keccak256("LIMIT_AAVE_DEPOSIT"); bytes32 private constant LIMIT_AAVE_WITHDRAW = keccak256("LIMIT_AAVE_WITHDRAW"); bytes32 private constant LIMIT_USDS_MINT = keccak256("LIMIT_USDS_MINT"); bytes32 private constant LIMIT_USDS_TO_USDC = keccak256("LIMIT_USDS_TO_USDC"); bytes32 private constant LIMIT_USDC_TO_CCTP = keccak256("LIMIT_USDC_TO_CCTP"); bytes32 private constant LIMIT_USDC_TO_DOMAIN = keccak256("LIMIT_USDC_TO_DOMAIN"); bytes32 private constant LIMIT_PSM_DEPOSIT = keccak256("LIMIT_PSM_DEPOSIT"); bytes32 private constant LIMIT_PSM_WITHDRAW = keccak256("LIMIT_PSM_WITHDRAW"); /** * @notice Activate the bare minimum for Spark Liquidity Layer * @dev Sets PSM and CCTP rate limits. */ function activateSparkLiquidityLayer( address rateLimits, address usdc, address usds, address susds, RateLimitData memory usdcDeposit, RateLimitData memory usdcWithdraw, RateLimitData memory cctpEthereumDeposit ) internal { // PSM USDC RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_DEPOSIT, usdc ), rateLimits, usdcDeposit, "psmUsdcDepositLimit", 6 ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_WITHDRAW, usdc ), rateLimits, usdcWithdraw, "psmUsdcWithdrawLimit", 6 ); // PSM USDS RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_DEPOSIT, usds ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "psmUsdsDepositLimit", 18 ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_WITHDRAW, usds ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "psmUsdsWithdrawLimit", 18 ); // PSM sUSDS RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_DEPOSIT, susds ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "psmSusdsDepositLimit", 18 ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_PSM_WITHDRAW, susds ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "psmSusdsWithdrawLimit", 18 ); // CCTP RateLimitHelpers.setRateLimitData( LIMIT_USDC_TO_CCTP, rateLimits, RateLimitHelpers.unlimitedRateLimit(), "usdcToCctpLimit", 6 ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeDomainKey( LIMIT_USDC_TO_DOMAIN, 0 // Ethereum domain id (https://developers.circle.com/stablecoins/evm-smart-contracts) ), rateLimits, cctpEthereumDeposit, "usdcToCctpEthereumLimit", 6 ); } /** * @notice Onboard an Aave token * @dev This will set the deposit to the given numbers with * the withdraw limit set to unlimited. */ function onboardAaveToken( address rateLimits, address token, uint256 depositMax, uint256 depositSlope ) internal { IERC20 underlying = IERC20(IAToken(token).UNDERLYING_ASSET_ADDRESS()); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_AAVE_DEPOSIT, token ), rateLimits, RateLimitData({ maxAmount : depositMax, slope : depositSlope }), "atokenDepositLimit", underlying.decimals() ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_AAVE_WITHDRAW, token ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "atokenWithdrawLimit", underlying.decimals() ); } /** * @notice Onboard an ERC4626 vault * @dev This will set the deposit to the given numbers with * the withdraw limit set to unlimited. */ function onboardERC4626Vault( address rateLimits, address vault, uint256 depositMax, uint256 depositSlope ) internal { IERC20 asset = IERC20(IERC4626(vault).asset()); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_4626_DEPOSIT, vault ), rateLimits, RateLimitData({ maxAmount : depositMax, slope : depositSlope }), "vaultDepositLimit", asset.decimals() ); RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeAssetKey( LIMIT_4626_WITHDRAW, vault ), rateLimits, RateLimitHelpers.unlimitedRateLimit(), "vaultWithdrawLimit", asset.decimals() ); } function morphoIdleMarket( address asset ) internal pure returns (MarketParams memory) { return MarketParams({ loanToken: asset, collateralToken: address(0), oracle: address(0), irm: address(0), lltv: 0 }); } /** * @notice Activate a Morpho Vault * @dev This will do the following: * - Add the relayer as an allocator * - Add the idle market for the underlying asset with unlimited size * - Set the supply queue to the idle market */ function activateMorphoVault( address vault, address relayer ) internal { IERC20 asset = IERC20(IERC4626(vault).asset()); MarketParams memory idleMarket = morphoIdleMarket(address(asset)); IMetaMorpho(vault).setIsAllocator( relayer, true ); IMetaMorpho(vault).submitCap( idleMarket, type(uint184).max ); IMetaMorpho(vault).acceptCap( idleMarket ); Id[] memory supplyQueue = new Id[](1); supplyQueue[0] = MarketParamsLib.id(idleMarket); IMetaMorpho(vault).setSupplyQueue(supplyQueue); } function setUSDSMintRateLimit( address rateLimits, uint256 maxAmount, uint256 slope ) internal { RateLimitHelpers.setRateLimitData( LIMIT_USDS_MINT, rateLimits, RateLimitData({ maxAmount : maxAmount, slope : slope }), "USDS mint limit", 18 ); } function setUSDSToUSDCRateLimit( address rateLimits, uint256 maxUsdcAmount, uint256 slope ) internal { RateLimitHelpers.setRateLimitData( LIMIT_USDS_TO_USDC, rateLimits, RateLimitData({ maxAmount : maxUsdcAmount, slope : slope }), "Swap USDS to USDC limit", 6 ); } function setUSDCToCCTPRateLimit( address rateLimits, uint256 maxUsdcAmount, uint256 slope ) internal { RateLimitHelpers.setRateLimitData( LIMIT_USDC_TO_CCTP, rateLimits, RateLimitData({ maxAmount : maxUsdcAmount, slope : slope }), "Send USDC to CCTP general limit", 6 ); } function setUSDCToDomainRateLimit( address rateLimits, uint32 destinationDomain, uint256 maxUsdcAmount, uint256 slope ) internal { RateLimitHelpers.setRateLimitData( RateLimitHelpers.makeDomainKey(LIMIT_USDC_TO_DOMAIN, destinationDomain), rateLimits, RateLimitData({ maxAmount : maxUsdcAmount, slope : slope }), "Send USDC via CCTP to a specific domain limit", 6 ); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library DataTypes { struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; //stableDebtToken address address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167 liquidation protocol fee //bit 168-175 eMode category //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles address priceSource; string label; } enum InterestRateMode {NONE, STABLE, VARIABLE} struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currPrincipalStableDebt; uint256 currAvgStableBorrowRate; uint256 currTotalStableDebt; uint256 nextAvgStableBorrowRate; uint256 nextTotalStableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; uint40 stableDebtLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address addressesProvider; uint8 userEModeCategory; bool isAuthorizedFlashBorrower; } struct FlashloanSimpleParams { address receiverAddress; address asset; uint256 amount; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; } struct FlashLoanRepaymentParams { uint256 amount; uint256 totalPremium; uint256 flashLoanPremiumToProtocol; address asset; address receiverAddress; uint16 referralCode; } struct CalculateUserAccountDataParams { UserConfigurationMap userConfig; uint256 reservesCount; address user; address oracle; uint8 userEModeCategory; } struct ValidateBorrowParams { ReserveCache reserveCache; UserConfigurationMap userConfig; address asset; address userAddress; uint256 amount; InterestRateMode interestRateMode; uint256 maxStableLoanPercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalStableDebt; uint256 totalVariableDebt; uint256 averageStableBorrowRate; uint256 reserveFactor; address reserve; address aToken; } struct InitReserveParams { address asset; address aTokenAddress; address stableDebtAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library ConfiguratorInputTypes { struct InitReserveInput { address aTokenImpl; address stableDebtTokenImpl; address variableDebtTokenImpl; uint8 underlyingAssetDecimals; address interestRateStrategyAddress; address underlyingAsset; address treasury; address incentivesController; string aTokenName; string aTokenSymbol; string variableDebtTokenName; string variableDebtTokenSymbol; string stableDebtTokenName; string stableDebtTokenSymbol; bytes params; } struct UpdateATokenInput { address asset; address treasury; address incentivesController; string name; string symbol; address implementation; bytes params; } struct UpdateDebtTokenInput { address asset; address incentivesController; string name; string symbol; address implementation; bytes params; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library DataTypes { struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; //stableDebtToken address address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167 liquidation protocol fee //bit 168-175 eMode category //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles address priceSource; string label; } enum InterestRateMode {NONE, STABLE, VARIABLE} struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currPrincipalStableDebt; uint256 currAvgStableBorrowRate; uint256 currTotalStableDebt; uint256 nextAvgStableBorrowRate; uint256 nextTotalStableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; uint40 stableDebtLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address addressesProvider; 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 maxStableLoanPercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalStableDebt; uint256 totalVariableDebt; uint256 averageStableBorrowRate; uint256 reserveFactor; address reserve; address aToken; } struct InitReserveParams { address asset; address aTokenAddress; address stableDebtAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library ConfiguratorInputTypes { struct InitReserveInput { address aTokenImpl; address stableDebtTokenImpl; address variableDebtTokenImpl; uint8 underlyingAssetDecimals; address interestRateStrategyAddress; address underlyingAsset; address treasury; address incentivesController; string aTokenName; string aTokenSymbol; string variableDebtTokenName; string variableDebtTokenSymbol; string stableDebtTokenName; string stableDebtTokenSymbol; bytes params; } struct UpdateATokenInput { address asset; address treasury; address incentivesController; string name; string symbol; address implementation; bytes params; } struct UpdateDebtTokenInput { address asset; address incentivesController; string name; string symbol; address implementation; bytes params; } }
// SPDX-License-Identifier: AGPL-3.0 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: AGPL-3.0 pragma solidity ^0.8.0; import {IReserveInterestRateStrategy} from './IReserveInterestRateStrategy.sol'; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IDefaultInterestRateStrategy * @author Aave * @notice Defines the basic interface of the DefaultReserveInterestRateStrategy */ interface IDefaultInterestRateStrategy is IReserveInterestRateStrategy { /** * @notice Returns the usage ratio at which the pool aims to obtain most competitive borrow rates. * @return The optimal usage ratio, expressed in ray. */ function OPTIMAL_USAGE_RATIO() external view returns (uint256); /** * @notice Returns the optimal stable to total debt ratio of the reserve. * @return The optimal stable to total debt ratio, expressed in ray. */ function OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO() external view returns (uint256); /** * @notice Returns the excess usage ratio above the optimal. * @dev It's always equal to 1-optimal usage ratio (added as constant for gas optimizations) * @return The max excess usage ratio, expressed in ray. */ function MAX_EXCESS_USAGE_RATIO() external view returns (uint256); /** * @notice Returns the excess stable debt ratio above the optimal. * @dev It's always equal to 1-optimal stable to total debt ratio (added as constant for gas optimizations) * @return The max excess stable to total debt ratio, expressed in ray. */ function MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO() external view returns (uint256); /** * @notice Returns the address of the PoolAddressesProvider * @return The address of the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the variable rate slope below optimal usage ratio * @dev It's the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO * @return The variable rate slope, expressed in ray */ function getVariableRateSlope1() external view returns (uint256); /** * @notice Returns the variable rate slope above optimal usage ratio * @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO * @return The variable rate slope, expressed in ray */ function getVariableRateSlope2() external view returns (uint256); /** * @notice Returns the stable rate slope below optimal usage ratio * @dev It's the stable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO * @return The stable rate slope, expressed in ray */ function getStableRateSlope1() external view returns (uint256); /** * @notice Returns the stable rate slope above optimal usage ratio * @dev It's the variable rate when usage ratio > OPTIMAL_USAGE_RATIO * @return The stable rate slope, expressed in ray */ function getStableRateSlope2() external view returns (uint256); /** * @notice Returns the stable rate excess offset * @dev It's an additional premium applied to the stable when stable debt > OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO * @return The stable rate excess offset, expressed in ray */ function getStableRateExcessOffset() external view returns (uint256); /** * @notice Returns the base stable borrow rate * @return The base stable borrow rate, expressed in ray */ function getBaseStableBorrowRate() external view returns (uint256); /** * @notice Returns the base variable borrow rate * @return The base variable borrow rate, expressed in ray */ function getBaseVariableBorrowRate() external view returns (uint256); /** * @notice Returns the maximum variable borrow rate * @return The maximum variable borrow rate, expressed in ray */ function getMaxVariableBorrowRate() external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) // From commit https://github.com/OpenZeppelin/openzeppelin-contracts/commit/8b778fa20d6d76340c5fac1ed66c80273f05b95a pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, 'Address: low-level delegate call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), 'Address: call to non-contract'); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2; import "./IERC20.sol"; /// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in /// https://eips.ethereum.org/EIPS/eip-4626 interface IERC4626 is IERC20 { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. /// @dev /// - MUST be an ERC-20 token contract. /// - MUST NOT revert. function asset() external view returns (address assetTokenAddress); /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. /// @dev /// - SHOULD include any compounding that occurs from yield. /// - MUST be inclusive of any fees that are charged against assets in the Vault. /// - MUST NOT revert. function totalAssets() external view returns (uint256 totalManagedAssets); /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal /// scenario where all the conditions are met. /// @dev /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. /// - MUST NOT show any variations depending on the caller. /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. /// - MUST NOT revert. /// /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and /// from. function convertToShares(uint256 assets) external view returns (uint256 shares); /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal /// scenario where all the conditions are met. /// @dev /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. /// - MUST NOT show any variations depending on the caller. /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. /// - MUST NOT revert. /// /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and /// from. function convertToAssets(uint256 shares) external view returns (uint256 assets); /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, /// through a deposit call. /// @dev /// - MUST return a limited value if receiver is subject to some deposit limit. /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. /// - MUST NOT revert. function maxDeposit(address receiver) external view returns (uint256 maxAssets); /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given /// current on-chain conditions. /// @dev /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called /// in the same transaction. /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the /// deposit would be accepted, regardless if the user has enough tokens approved, etc. /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. /// - MUST NOT revert. /// /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in /// share price or some other type of condition, meaning the depositor will lose assets by depositing. function previewDeposit(uint256 assets) external view returns (uint256 shares); /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. /// @dev /// - MUST emit the Deposit event. /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the /// deposit execution, and are accounted for during deposit. /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not /// approving enough underlying tokens to the Vault contract, etc). /// /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. function deposit(uint256 assets, address receiver) external returns (uint256 shares); /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. /// @dev /// - MUST return a limited value if receiver is subject to some mint limit. /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. /// - MUST NOT revert. function maxMint(address receiver) external view returns (uint256 maxShares); /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given /// current on-chain conditions. /// @dev /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the /// same transaction. /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint /// would be accepted, regardless if the user has enough tokens approved, etc. /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. /// - MUST NOT revert. /// /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in /// share price or some other type of condition, meaning the depositor will lose assets by minting. function previewMint(uint256 shares) external view returns (uint256 assets); /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. /// @dev /// - MUST emit the Deposit event. /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint /// execution, and are accounted for during mint. /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not /// approving enough underlying tokens to the Vault contract, etc). /// /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. function mint(uint256 shares, address receiver) external returns (uint256 assets); /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the /// Vault, through a withdrawal call. /// @dev /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. /// - MUST NOT revert. function maxWithdraw(address owner) external view returns (uint256 maxAssets); /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, /// given current on-chain conditions. /// @dev /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if /// called /// in the same transaction. /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though /// the withdrawal would be accepted, regardless if the user has enough shares, etc. /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. /// - MUST NOT revert. /// /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in /// share price or some other type of condition, meaning the depositor will lose assets by depositing. function previewWithdraw(uint256 assets) external view returns (uint256 shares); /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. /// @dev /// - MUST emit the Withdraw event. /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the /// withdraw execution, and are accounted for during withdrawal. /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner /// not having enough shares, etc). /// /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. /// Those methods should be performed separately. function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, /// through a redeem call. /// @dev /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. /// - MUST NOT revert. function maxRedeem(address owner) external view returns (uint256 maxShares); /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, /// given current on-chain conditions. /// @dev /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the /// same transaction. /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the /// redemption would be accepted, regardless if the user has enough shares, etc. /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. /// - MUST NOT revert. /// /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. function previewRedeem(uint256 shares) external view returns (uint256 assets); /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. /// @dev /// - MUST emit the Withdraw event. /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the /// redeem execution, and are accounted for during redeem. /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner /// not having enough shares, etc). /// /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. /// Those methods should be performed separately. function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// 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: GPL-2.0-or-later pragma solidity ^0.8.0; import {Id, MarketParams} from "../interfaces/IMorpho.sol"; /// @title MarketParamsLib /// @author Morpho Labs /// @custom:contact [email protected] /// @notice Library to convert a market to its id. library MarketParamsLib { /// @notice The length of the data used to compute the id of a market. /// @dev The length is 5 * 32 because `MarketParams` has 5 variables of 32 bytes each. uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32; /// @notice Returns the id of the market `marketParams`. function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) { assembly ("memory-safe") { marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH) } } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.21; import { IRateLimits } from "../src/interfaces/IRateLimits.sol"; struct RateLimitData { uint256 maxAmount; uint256 slope; } library RateLimitHelpers { function makeAssetKey(bytes32 key, address asset) internal pure returns (bytes32) { return keccak256(abi.encode(key, asset)); } function makeDomainKey(bytes32 key, uint32 domain) internal pure returns (bytes32) { return keccak256(abi.encode(key, domain)); } function unlimitedRateLimit() internal pure returns (RateLimitData memory) { return RateLimitData({ maxAmount : type(uint256).max, slope : 0 }); } function setRateLimitData( bytes32 key, address rateLimits, RateLimitData memory data, string memory name, uint256 decimals ) internal { // Handle setting an unlimited rate limit if (data.maxAmount == type(uint256).max) { require( data.slope == 0, string(abi.encodePacked("RateLimitHelpers/invalid-rate-limit-", name)) ); } else { require( data.maxAmount <= 1e12 * (10 ** decimals), string(abi.encodePacked("RateLimitHelpers/invalid-max-amount-precision-", name)) ); require( data.slope <= 1e12 * (10 ** decimals) / 1 hours, string(abi.encodePacked("RateLimitHelpers/invalid-slope-precision-", name)) ); } IRateLimits(rateLimits).setRateLimitData(key, data.maxAmount, data.slope); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IReserveInterestRateStrategy * @author Aave * @notice Interface for the calculation of the interest rates */ interface IReserveInterestRateStrategy { /** * @notice Calculates the interest rates depending on the reserve's state and configurations * @param params The parameters needed to calculate interest rates * @return liquidityRate The liquidity rate expressed in rays * @return stableBorrowRate The stable borrow rate expressed in rays * @return variableBorrowRate The variable borrow rate expressed in rays */ function calculateInterestRates( DataTypes.CalculateInterestRatesParams memory params ) external view returns (uint256, uint256, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title 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: AGPL-3.0-or-later pragma solidity >=0.8.0; import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol"; interface IRateLimits is IAccessControl { /**********************************************************************************************/ /*** Structs ***/ /**********************************************************************************************/ /** * @dev Struct representing a rate limit. * The current rate limit is calculated using the formula: * `currentRateLimit = min(slope * (block.timestamp - lastUpdated) + lastAmount, maxAmount)`. * @param maxAmount Maximum allowed amount at any time. * @param slope The slope of the rate limit, used to calculate the new * limit based on time passed. [tokens / second] * @param lastAmount The amount left available at the last update. * @param lastUpdated The timestamp when the rate limit was last updated. */ struct RateLimitData { uint256 maxAmount; uint256 slope; uint256 lastAmount; uint256 lastUpdated; } /**********************************************************************************************/ /*** Events ***/ /**********************************************************************************************/ /** * @dev Emitted when the rate limit data is set. * @param key The identifier for the rate limit. * @param maxAmount The maximum allowed amount for the rate limit. * @param slope The slope value used in the rate limit calculation. * @param lastAmount The amount left available at the last update. * @param lastUpdated The timestamp when the rate limit was last updated. */ event RateLimitDataSet( bytes32 indexed key, uint256 maxAmount, uint256 slope, uint256 lastAmount, uint256 lastUpdated ); /** * @dev Emitted when a rate limit decrease is triggered. * @param key The identifier for the rate limit. * @param amountToDecrease The amount to decrease from the current rate limit. * @param oldRateLimit The previous rate limit value before triggering. * @param newRateLimit The new rate limit value after triggering. */ event RateLimitDecreaseTriggered( bytes32 indexed key, uint256 amountToDecrease, uint256 oldRateLimit, uint256 newRateLimit ); /** * @dev Emitted when a rate limit increase is triggered. * @param key The identifier for the rate limit. * @param amountToIncrease The amount to increase from the current rate limit. * @param oldRateLimit The previous rate limit value before triggering. * @param newRateLimit The new rate limit value after triggering. */ event RateLimitIncreaseTriggered( bytes32 indexed key, uint256 amountToIncrease, uint256 oldRateLimit, uint256 newRateLimit ); /**********************************************************************************************/ /*** State variables ***/ /**********************************************************************************************/ /** * @dev Returns the controller identifier as a bytes32 value. * @return The controller identifier. */ function CONTROLLER() external view returns (bytes32); /**********************************************************************************************/ /*** Admin functions ***/ /**********************************************************************************************/ /** * @dev Sets rate limit data for a specific key. * @param key The identifier for the rate limit. * @param maxAmount The maximum allowed amount for the rate limit. * @param slope The slope value used in the rate limit calculation. * @param lastAmount The amount left available at the last update. * @param lastUpdated The timestamp when the rate limit was last updated. */ function setRateLimitData( bytes32 key, uint256 maxAmount, uint256 slope, uint256 lastAmount, uint256 lastUpdated ) external; /** * @dev Sets rate limit data for a specific key with * `lastAmount == maxAmount` and `lastUpdated == block.timestamp`. * @param key The identifier for the rate limit. * @param maxAmount The maximum allowed amount for the rate limit. * @param slope The slope value used in the rate limit calculation. */ function setRateLimitData(bytes32 key, uint256 maxAmount, uint256 slope) external; /** * @dev Sets an unlimited rate limit. * @param key The identifier for the rate limit. */ function setUnlimitedRateLimitData(bytes32 key) external; /**********************************************************************************************/ /*** Getter Functions ***/ /**********************************************************************************************/ /** * @dev Retrieves the RateLimitData struct associated with a specific key. * @param key The identifier for the rate limit. * @return The data associated with the rate limit. */ function getRateLimitData(bytes32 key) external view returns (RateLimitData memory); /** * @dev Retrieves the current rate limit for a specific key. * @param key The identifier for the rate limit. * @return The current rate limit value for the given key. */ function getCurrentRateLimit(bytes32 key) external view returns (uint256); /**********************************************************************************************/ /*** Controller functions ***/ /**********************************************************************************************/ /** * @dev Triggers the rate limit for a specific key and reduces the available * amount by the provided value. * @param key The identifier for the rate limit. * @param amountToDecrease The amount to decrease from the current rate limit. * @return newLimit The updated rate limit after the deduction. */ function triggerRateLimitDecrease(bytes32 key, uint256 amountToDecrease) external returns (uint256 newLimit); /** * @dev Increases the rate limit for a given key up to the maxAmount. Does not revert if * the new rate limit exceeds the maxAmount. * @param key The identifier for the rate limit. * @param amountToIncrease The amount to increase from the current rate limit. * @return newLimit The updated rate limit after the addition. */ function triggerRateLimitIncrease(bytes32 key, uint256 amountToIncrease) external returns (uint256 newLimit); }
// 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.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ event SwapBorrowRateMode( address indexed reserve, address indexed user, DataTypes.InterestRateMode interestRateMode ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed */ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa * @param asset The address of the underlying asset borrowed * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ function swapBorrowRateMode(address asset, uint256 interestRateMode) external; /** * @notice Permissionless method which allows anyone to swap a users stable debt to variable debt * @dev Introduced in favor of stable rate deprecation * @param asset The address of the underlying asset borrowed * @param user The address of the user whose debt will be swapped from stable to variable */ function swapToVariable(address asset, address user) external; /** * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too * much has been borrowed at a stable rate and suppliers are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced */ function rebalanceStableBorrowRate(address asset, address user) external; /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice 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 * @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 category for the eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external; /** * @notice Returns the data of an eMode category * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice 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 percentage of available liquidity that can be borrowed at once at stable rate * @return The percentage of available liquidity to borrow, expressed in bps */ function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Gets the address of the external FlashLoanLogic */ function getFlashLoanLogic() external returns (address); /** * @notice Gets the address of the external BorrowLogic */ function getBorrowLogic() external returns (address); /** * @notice Gets the address of the external BridgeLogic */ function getBridgeLogic() external returns (address); /** * @notice Gets the address of the external EModeLogic */ function getEModeLogic() external returns (address); /** * @notice Gets the address of the external LiquidationLogic */ function getLiquidationLogic() external returns (address); /** * @notice Gets the address of the external PoolLogic */ function getPoolLogic() external returns (address); /** * @notice Gets the address of the external SupplyLogic */ function getSupplyLogic() external returns (address); }
// 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; 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; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; //stableDebtToken address address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed uint40 liquidationGracePeriodUntil; //aToken address address aTokenAddress; //stableDebtToken address address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; //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: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167: liquidation protocol fee //bit 168-175: eMode category //bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252: 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; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles address priceSource; string label; } enum InterestRateMode { NONE, STABLE, VARIABLE } struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currPrincipalStableDebt; uint256 currAvgStableBorrowRate; uint256 currTotalStableDebt; uint256 nextAvgStableBorrowRate; uint256 nextTotalStableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; uint40 stableDebtLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address addressesProvider; 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 maxStableLoanPercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalStableDebt; uint256 totalVariableDebt; uint256 averageStableBorrowRate; uint256 reserveFactor; address reserve; bool usingVirtualBalance; uint256 virtualUnderlyingBalance; } struct InitReserveParams { address asset; address aTokenAddress; address stableDebtAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
{ "remappings": [ "@openzeppelin/contracts-upgradeable/=lib/spark-alm-controller/lib/sdai/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/metamorpho/lib/openzeppelin-contracts/contracts/", "aave-v3-core/=lib/sparklend-kill-switch/lib/aave-v3-core/", "aave-v3-origin/=lib/spark-alm-controller/lib/aave-v3-origin/", "aave-v3-periphery/=lib/aave-v3-periphery/contracts/", "ds-test/=lib/metamorpho/lib/forge-std/lib/ds-test/src/", "dss-allocator/=lib/spark-alm-controller/lib/dss-allocator/", "dss-interfaces/=lib/spark-alm-controller/lib/dss-test/lib/dss-interfaces/src/", "dss-test/=lib/spark-alm-controller/lib/dss-test/src/", "erc20-helpers/=lib/erc20-helpers/src/", "erc4626-tests/=lib/metamorpho/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "metamorpho/=lib/metamorpho/src/", "morpho-blue/=lib/metamorpho/lib/morpho-blue/", "murky/=lib/metamorpho/lib/universal-rewards-distributor/lib/murky/src/", "openzeppelin-contracts-upgradeable/=lib/spark-alm-controller/lib/sdai/lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/metamorpho/lib/openzeppelin-contracts/", "openzeppelin-foundry-upgrades/=lib/spark-alm-controller/lib/sdai/lib/openzeppelin-foundry-upgrades/src/", "openzeppelin/=lib/metamorpho/lib/universal-rewards-distributor/lib/openzeppelin-contracts/contracts/", "sdai/=lib/spark-alm-controller/lib/sdai/", "solidity-stringutils/=lib/spark-alm-controller/lib/sdai/lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/", "solidity-utils/=lib/spark-alm-controller/lib/aave-v3-origin/lib/solidity-utils/", "spark-address-registry/=lib/spark-address-registry/src/", "spark-alm-controller/=lib/spark-alm-controller/", "spark-gov-relay/=lib/spark-gov-relay/", "spark-psm/=lib/spark-alm-controller/lib/spark-psm/", "sparklend-address-registry/=lib/spark-alm-controller/lib/spark-psm/lib/xchain-ssr-oracle/lib/sparklend-address-registry/", "sparklend-cap-automator/=lib/sparklend-cap-automator/src/", "sparklend-freezer/=lib/sparklend-freezer/src/", "sparklend-kill-switch/=lib/sparklend-kill-switch/src/", "sparklend-v1-core/=lib/sparklend-v1-core/", "token-tests/=lib/spark-alm-controller/lib/sdai/lib/token-tests/src/", "universal-rewards-distributor/=lib/metamorpho/lib/universal-rewards-distributor/src/", "usds/=lib/spark-alm-controller/lib/usds/", "xchain-helpers/=lib/xchain-helpers/src/", "xchain-ssr-oracle/=lib/spark-alm-controller/lib/spark-psm/lib/xchain-ssr-oracle/" ], "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": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"LISTING_ENGINE","outputs":[{"internalType":"contract IAaveV3ConfigEngine","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYLOAD_ARBITRUM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYLOAD_BASE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYLOAD_GNOSIS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrowsUpdates","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"enabledToBorrow","type":"uint256"},{"internalType":"uint256","name":"flashloanable","type":"uint256"},{"internalType":"uint256","name":"stableRateModeEnabled","type":"uint256"},{"internalType":"uint256","name":"borrowableInIsolation","type":"uint256"},{"internalType":"uint256","name":"withSiloedBorrowing","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"}],"internalType":"struct IAaveV3ConfigEngine.BorrowUpdate[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"capsUpdates","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"}],"internalType":"struct IAaveV3ConfigEngine.CapsUpdate[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralsUpdates","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liqThreshold","type":"uint256"},{"internalType":"uint256","name":"liqBonus","type":"uint256"},{"internalType":"uint256","name":"debtCeiling","type":"uint256"},{"internalType":"uint256","name":"liqProtocolFee","type":"uint256"},{"internalType":"uint256","name":"eModeCategory","type":"uint256"}],"internalType":"struct IAaveV3ConfigEngine.CollateralUpdate[]","name":"collateralUpdates","type":"tuple[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPoolContext","outputs":[{"components":[{"internalType":"string","name":"networkName","type":"string"},{"internalType":"string","name":"networkAbbreviation","type":"string"}],"internalType":"struct IAaveV3ConfigEngine.PoolContext","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"newListings","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"string","name":"assetSymbol","type":"string"},{"internalType":"address","name":"priceFeed","type":"address"},{"components":[{"internalType":"uint256","name":"optimalUsageRatio","type":"uint256"},{"internalType":"uint256","name":"baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"baseStableRateOffset","type":"uint256"},{"internalType":"uint256","name":"stableRateExcessOffset","type":"uint256"},{"internalType":"uint256","name":"optimalStableToTotalDebtRatio","type":"uint256"}],"internalType":"struct IV3RateStrategyFactory.RateStrategyParams","name":"rateStrategyParams","type":"tuple"},{"internalType":"uint256","name":"enabledToBorrow","type":"uint256"},{"internalType":"uint256","name":"stableRateModeEnabled","type":"uint256"},{"internalType":"uint256","name":"borrowableInIsolation","type":"uint256"},{"internalType":"uint256","name":"withSiloedBorrowing","type":"uint256"},{"internalType":"uint256","name":"flashloanable","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liqThreshold","type":"uint256"},{"internalType":"uint256","name":"liqBonus","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"debtCeiling","type":"uint256"},{"internalType":"uint256","name":"liqProtocolFee","type":"uint256"},{"internalType":"uint8","name":"eModeCategory","type":"uint8"}],"internalType":"struct IAaveV3ConfigEngine.Listing[]","name":"","type":"tuple[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"newListingsCustom","outputs":[{"components":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"string","name":"assetSymbol","type":"string"},{"internalType":"address","name":"priceFeed","type":"address"},{"components":[{"internalType":"uint256","name":"optimalUsageRatio","type":"uint256"},{"internalType":"uint256","name":"baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"baseStableRateOffset","type":"uint256"},{"internalType":"uint256","name":"stableRateExcessOffset","type":"uint256"},{"internalType":"uint256","name":"optimalStableToTotalDebtRatio","type":"uint256"}],"internalType":"struct IV3RateStrategyFactory.RateStrategyParams","name":"rateStrategyParams","type":"tuple"},{"internalType":"uint256","name":"enabledToBorrow","type":"uint256"},{"internalType":"uint256","name":"stableRateModeEnabled","type":"uint256"},{"internalType":"uint256","name":"borrowableInIsolation","type":"uint256"},{"internalType":"uint256","name":"withSiloedBorrowing","type":"uint256"},{"internalType":"uint256","name":"flashloanable","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liqThreshold","type":"uint256"},{"internalType":"uint256","name":"liqBonus","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"debtCeiling","type":"uint256"},{"internalType":"uint256","name":"liqProtocolFee","type":"uint256"},{"internalType":"uint8","name":"eModeCategory","type":"uint8"}],"internalType":"struct IAaveV3ConfigEngine.Listing","name":"base","type":"tuple"},{"components":[{"internalType":"address","name":"aToken","type":"address"},{"internalType":"address","name":"vToken","type":"address"},{"internalType":"address","name":"sToken","type":"address"}],"internalType":"struct IAaveV3ConfigEngine.TokenImplementations","name":"implementations","type":"tuple"}],"internalType":"struct IAaveV3ConfigEngine.ListingWithCustomImpl[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeedsUpdates","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"priceFeed","type":"address"}],"internalType":"struct IAaveV3ConfigEngine.PriceFeedUpdate[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateStrategiesUpdates","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"components":[{"internalType":"uint256","name":"optimalUsageRatio","type":"uint256"},{"internalType":"uint256","name":"baseVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"variableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope1","type":"uint256"},{"internalType":"uint256","name":"stableRateSlope2","type":"uint256"},{"internalType":"uint256","name":"baseStableRateOffset","type":"uint256"},{"internalType":"uint256","name":"stableRateExcessOffset","type":"uint256"},{"internalType":"uint256","name":"optimalStableToTotalDebtRatio","type":"uint256"}],"internalType":"struct IV3RateStrategyFactory.RateStrategyParams","name":"params","type":"tuple"}],"internalType":"struct IAaveV3ConfigEngine.RateStrategyUpdate[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610100604052348015610010575f80fd5b50733254f7cd0565aa67eedc86c2fb608be48d5ccd7860805273356f19cb575cf40c7ff33a5117f9a9264c23f6e860c052731d54a093b8fddfcc6fbb411d9af31d96e034b3d560a05260805160a05160c05160e051612bb16101095f395f818161016d0152818161045701526104a101525f818161013c015281816103c9015261042801525f81816101a301528181610334015261039301525f818160d401528181610b760152818161105f015281816111c0015281816112b0015281816113c7015281816114bb015281816115d6015281816116ca015281816117e5015281816118d901528181611e0d0152611f110152612bb15ff3fe608060405234801561000f575f80fd5b50600436106100cb575f3560e01c806395a93cb111610088578063c0a2558011610063578063c0a25580146101d4578063d0c38c27146101e9578063fabe3463146101f8578063fbb256f614610207575f80fd5b806395a93cb11461018f578063b14e01271461019e578063b1af0d0d146101c5575f80fd5b80630a4aa3fa146100cf5780631850edd8146101135780632b179434146101225780634c80312514610137578063614619541461015e5780636256d8ad14610168575b5f80fd5b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b606060405161010a91906122c7565b61012a61021c565b60405161010a9190612314565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b61016661032a565b005b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b606060405161010a9190612355565b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b606060405161010a91906123b6565b6101dc6104d0565b60405161010a91906125f6565b606060405161010a9190612608565b606060405161010a91906126e4565b61020f610a86565b60405161010a919061272c565b604080516001808252818301909252606091816020015b6102756040518060e001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b8152602001906001900390816102335750506040805160e0810190915273cbb7c0000ab88b473b1f5afd9ef808440eed33bf8152909150602081016102bc602a5f19612752565b81526020016102cd602a5f19612752565b81526020016102de602a5f19612752565b81526020016102ef602a5f19612752565b8152602001610300602a5f19612752565b81526020016003815250815f8151811061031c5761031c612765565b602002602001018190525090565b610332610ae5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156103c7576103c7734dbd4fc535ac27206064b68ffcf827b0a60bab3f73212871a1c235892f86cab30e937e18c94aed84746103b77f0000000000000000000000000000000000000000000000000000000000000000610ca0565b620f4240640ba43b740048610e94565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156104555761045573866e82a600a1414e583f7f13623f1ac5d58b0afa73fda082e00ef89185d9db7e5dcd8c5505070f5a3b61044c7f0000000000000000000000000000000000000000000000000000000000000000610ca0565b620f4240610fab565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156104ce576104ce73c4218c1127cb24a0d6c1e7d25dc34e10f2625f5a6104c57f0000000000000000000000000000000000000000000000000000000000000000610ca0565b620f424061100e565b565b60408051600480825260a082019092526060915f9190816020015b6104f36121a9565b8152602001906001900390816104eb579050509050604051806102400160405280738236a87084f8b84306f72007f36f2618a56344946001600160a01b03168152602001604051806040016040528060048152602001634c42544360e01b8152508152602001734219aa1a99f3fe90c2acb97fcbc1204f6485b5376001600160a01b03168152602001604051806101200160405280610593611194611033565b81526020016105a36101f4611033565b81526020016105b36105dc611033565b81526020016105c3617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f81526020016119648152602001611b58815260200161032081526020016105dc815260200160fa81526020015f81526020015f81526020016103e88152602001600360ff16815250815f8151811061065c5761065c612765565b60200260200101819052506040518061024001604052807318084fba666a33d37592fa2633fd49a74dd93a886001600160a01b03168152602001604051806040016040528060048152602001637442544360e01b8152508152602001734219aa1a99f3fe90c2acb97fcbc1204f6485b5376001600160a01b031681526020016040518061012001604052806106f2611770611033565b81526020015f8152602001610708610190611033565b8152602001610718617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f8152508152602001600181526020015f81526020015f81526020015f8152602001600181526020016119648152602001611b58815260200161032081526020016107d08152602001607d8152602001601981526020015f81526020016103e881526020015f60ff16815250816001815181106107b4576107b4612765565b602002602001018190525060405180610240016040528073bf5495efe5db9ce00f80364c8b423567e58d21106001600160a01b03168152602001604051806040016040528060058152602001640caf48aa8960db1b81525081526020017352e85eb49e07df74c8a9466d2164b4c4ca60014a6001600160a01b0316815260200160405180610120016040528061084b611194611033565b815260200161085b6101f4611033565b815260200161086b6105dc611033565b815260200161087b617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f8152602001611c208152602001611c8481526020016103e881526020016105dc81526020016107d081526020015f81526020015f81526020016103e881526020015f60ff168152508160028151811061091557610915612765565b602002602001018190525060405180610240016040528073a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b03168152602001604051806040016040528060058152602001640e4e68aa8960db1b81525081526020017370942d6b580741cf50a7906f4100063ee037b8eb6001600160a01b031681526020016040518061012001604052806109ac611194611033565b81526020016109bc6101f4611033565b81526020016109cc6105dc611033565b81526020016109dc617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f8152602001611c208152602001611c8481526020016103e881526020016105dc81526020016107d081526020015f81526020015f81526020016103e881526020015f60ff1681525081600381518110610a7657610a76612765565b6020908102919091010152919050565b60408051808201909152606080825260208201525060408051608081018252600881830190815267457468657265756d60c01b606083015281528151808301909252600382526208ae8d60eb1b60208381019190915281019190915290565b610aed61105d565b5f610af66104d0565b90506060805f610b0461021c565b84519091506060908190819015610b9e57610b9c633cb6502d60e01b610b28610a86565b89604051602401610b3a929190612779565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061116f565b505b855115610bcc57610bca6314d8093760e21b610bb8610a86565b88604051602401610b3a92919061279d565b505b825115610bf357604051610bf19063bb06653560e01b90610b3a9086906024016122c7565b505b835115610c1a57604051610c1890636e17618760e11b90610b3a908790602401612314565b505b805115610c4157604051610c3f906324f4c44560e01b90610b3a908490602401612608565b505b815115610c6857604051610c669063927c400360e01b90610b3a9085906024016123b6565b505b845115610c8f57604051610c8d906355caa16360e01b90610b3a908890602401612355565b505b610c9761119b565b50505050505050565b6040805160018082528183019092526060915f91906020808301908036833750506040805160018082528183019092529293505f9291506020808301908036833750506040805160018082528183019092529293505f929150602082015b6060815260200190600190039081610cfe5750506040805160018082528183019092529192505f9190602082015b6060815260200190600190039081610d2c5750506040805160018082528183019092529192505f91906020808301908036833701905050905086855f81518110610d7857610d78612765565b60200260200101906001600160a01b031690816001600160a01b0316815250505f845f81518110610dab57610dab612765565b6020026020010181815250506040518060400160405280600981526020016865786563757465282960b81b815250835f81518110610deb57610deb612765565b602002602001018190525060405180602001604052805f815250825f81518110610e1757610e17612765565b60200260200101819052506001815f81518110610e3657610e36612765565b91151560209283029190910190910152604051610e5f9086908690869086908690602401612877565b60408051601f198184030181529190526020810180516001600160e01b031663d9a4cbdf60e01b179052979650505050505050565b835160405163a66b327d60e01b81525f916001600160a01b0389169163a66b327d91610ecd918690600401918252602082015260400190565b602060405180830381865afa158015610ee8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0c9190612916565b90505f610f19848661292d565b90506001600160a01b03881663679b6ded610f348385612944565b895f865f808c8c8f6040518a63ffffffff1660e01b8152600401610f5f989796959493929190612957565b60206040518083038185885af1158015610f7b573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fa09190612916565b505050505050505050565b604051633dbb202b60e01b81526001600160a01b03851690633dbb202b90610fdb908690869086906004016129b1565b5f604051808303815f87803b158015610ff2575f80fd5b505af1158015611004573d5f803e3d5ffd5b5050505050505050565b61102e734c36d2919e407f0cc2ee3c993ccf8ac26d9ce64e848484612016565b505050565b5f61271061104d836b033b2e3c9fd0803ce800000061292d565b61105791906129ea565b92915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110dd9190612a20565b604051633067587960e21b8152600360048201819052612134602483015261232860448301526127d860648301525f608483015260c060a483015260c48201526242544360e81b60e48201526001600160a01b03919091169063c19d61e490610104015f604051808303815f87803b158015611157575f80fd5b505af1158015611169573d5f803e3d5ffd5b50505050565b60606111948383604051806060016040528060278152602001612b5560279139612086565b9392505050565b738236a87084f8b84306f72007f36f2618a56344946001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123e9190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015261271060248201526044016020604051808303815f875af1158015611289573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112ad9190612a3b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132e9190612a20565b6001600160a01b031663617ba037738236a87084f8b84306f72007f36f2618a5634494612710305f6040518563ffffffff1660e01b81526004016113759493929190612a5a565b5f604051808303815f87803b15801561138c575f80fd5b505af115801561139e573d5f803e3d5ffd5b505050507318084fba666a33d37592fa2633fd49a74dd93a886001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611421573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114459190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af1158015611494573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114b89190612a3b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611515573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115399190612a20565b6001600160a01b031663617ba0377318084fba666a33d37592fa2633fd49a74dd93a88655af3107a4000305f6040518563ffffffff1660e01b81526004016115849493929190612a5a565b5f604051808303815f87803b15801561159b575f80fd5b505af11580156115ad573d5f803e3d5ffd5b5050505073bf5495efe5db9ce00f80364c8b423567e58d21106001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611630573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116549190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af11580156116a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c79190612a3b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611724573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117489190612a20565b6001600160a01b031663617ba03773bf5495efe5db9ce00f80364c8b423567e58d2110655af3107a4000305f6040518563ffffffff1660e01b81526004016117939493929190612a5a565b5f604051808303815f87803b1580156117aa575f80fd5b505af11580156117bc573d5f803e3d5ffd5b5050505073a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118639190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af11580156118b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d69190612a3b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611933573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119579190612a20565b6001600160a01b031663617ba03773a1290d69c65a6fe4df752f95823fae25cb99e5a7655af3107a4000305f6040518563ffffffff1660e01b81526004016119a29493929190612a5a565b5f604051808303815f87803b1580156119b9575f80fd5b505af11580156119cb573d5f803e3d5ffd5b505060405163b28c909f60e01b8152732276f52afba7cf2525fd0a050df464ac8532d0ef925082915063b28c909f90611a2790738236a87084f8b84306f72007f36f2618a5634494906109c49060fa9061a8c090600401612a87565b5f604051808303815f87803b158015611a3e575f80fd5b505af1158015611a50573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611a9f907318084fba666a33d37592fa2633fd49a74dd93a88906101f490607d9061a8c090600401612a87565b5f604051808303815f87803b158015611ab6575f80fd5b505af1158015611ac8573d5f803e3d5ffd5b50506040516328e7733d60e01b81526001600160a01b03841692506328e7733d9150611b16907318084fba666a33d37592fa2633fd49a74dd93a889060fa9060199061a8c090600401612a87565b5f604051808303815f87803b158015611b2d575f80fd5b505af1158015611b3f573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611b8f9073bf5495efe5db9ce00f80364c8b423567e58d211090614e20906107d09061a8c090600401612a87565b5f604051808303815f87803b158015611ba6575f80fd5b505af1158015611bb8573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611c089073a1290d69c65a6fe4df752f95823fae25cb99e5a790614e20906107d09061a8c090600401612a87565b5f604051808303815f87803b158015611c1f575f80fd5b505af1158015611c31573d5f803e3d5ffd5b50506040805160a081018252736b175474e89094c44da98b954eedeac495271d0f81527350d2c7992b802eef16c04feadab310f31866a54560208201527339a695eb6d0c01f6977521e5e79ea8bc232b506a8183015273870ac11d48b15db9a138cf899d20f13f79ba00bc6060820152670cb2bba6f17b800060808201529051633b24c2bf60e01b81527373e65dbd630f90604062f6e02fab9138e713edd99350633b24c2bf9250611cf391906af8277896582678ac00000090600401612aad565b5f604051808303815f87803b158015611d0a575f80fd5b505af1158015611d1c573d5f803e3d5ffd5b50506040805160a081018252736b175474e89094c44da98b954eedeac495271d0f815273917459337caac939d41d7493b3999f571d20d667602082015273fcae69bef9b6c96d89d58664d8aea84bddce2e5c8183015273870ac11d48b15db9a138cf899d20f13f79ba00bc6060820152670cb2bba6f17b800060808201529051633b24c2bf60e01b81527373e65dbd630f90604062f6e02fab9138e713edd99350633b24c2bf9250611dde91906aa56fa5b99019a5c800000090600401612aad565b5f604051808303815f87803b158015611df5575f80fd5b505af1158015611e07573d5f803e3d5ffd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8b9190612a20565b604051631d2118f960e01b8152736b175474e89094c44da98b954eedeac495271d0f6004820152735a7e7a32331189a794ac33fec76c0a1dd3ddcf9c60248201526001600160a01b039190911690631d2118f9906044015f604051808303815f87803b158015611ef9575f80fd5b505af1158015611f0b573d5f803e3d5ffd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8f9190612a20565b604051631d2118f960e01b815273dc035d45d973e3ec169d2276ddab16f1e407384f600482015273d94ba511284d2c56f59a687c3338441d33304e0760248201526001600160a01b039190911690631d2118f9906044015f604051808303815f87803b158015611ffd575f80fd5b505af115801561200f573d5f803e3d5ffd5b5050505050565b60405163dc8601b360e01b81526001600160a01b0385169063dc8601b39061204690869086908690600401612af9565b6020604051808303815f875af1158015612062573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200f9190612916565b60605f80856001600160a01b0316856040516120a29190612b2c565b5f60405180830381855af49150503d805f81146120da576040519150601f19603f3d011682016040523d82523d5f602084013e6120df565b606091505b50915091506120f0868383876120fa565b9695505050505050565b6060831561216d5782515f03612166576001600160a01b0385163b6121665760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081612177565b612177838361217f565b949350505050565b81511561218f5781518083602001fd5b8060405162461bcd60e51b815260040161215d9190612b42565b6040518061024001604052805f6001600160a01b03168152602001606081526020015f6001600160a01b031681526020016122206040518061012001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f60ff1681525090565b80516001600160a01b031682526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0818101519083015260c090810151910152565b602080825282518282018190525f9190848201906040850190845b81811015612308576122f583855161227d565b9284019260e092909201916001016122e2565b50909695505050505050565b602080825282518282018190525f9190848201906040850190845b818110156123085761234283855161227d565b9284019260e0929092019160010161232f565b602080825282518282018190525f919060409081850190868401855b828110156123a957815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101612371565b5091979650505050505050565b602080825282518282018190525f919060409081850190868401855b828110156123a957815180516001600160a01b03908116865290870151168685015292840192908501906001016123d2565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152505050565b80516001600160a01b031682525f61034060208301518160208601526124b482860182612404565b91505060408301516124d160408601826001600160a01b03169052565b5060608301516124e46060860182612432565b5060808301516101808581019190915260a08401516101a08087019190915260c08501516101c08088019190915260e08601516101e080890191909152610100870151610200808a0191909152610120880151610220808b01919091526101408901516102408b01526101608901516102608b0152948801516102808a0152928701516102a0890152908601516102c08801528501516102e087015284015161030086015283015160ff8116610320860152509392505050565b5f8282518085526020808601955060208260051b840101602086015f5b848110156125e957601f198684030189526125d783835161248c565b988401989250908301906001016125bb565b5090979650505050505050565b602081525f611194602083018461259e565b602080825282518282018190525f9190848201906040850190845b8181101561230857835180516001600160a01b0316845285015161264986850182612432565b50928401926101409290920191600101612623565b5f82825180855260208086019550808260051b8401018186015f5b848110156125e957601f1986840301895281516080815181865261269f8287018261248c565b9287015180516001600160a01b03908116888a01528189015181166040808a019190915290910151166060909601959095525098840198925090830190600101612679565b602081525f611194602083018461265e565b5f81516040845261270a6040850182612404565b9050602083015184820360208601526127238282612404565b95945050505050565b602081525f61119460208301846126f6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156110575761105761273e565b634e487b7160e01b5f52603260045260245ffd5b604081525f61278b60408301856126f6565b8281036020840152612723818561259e565b604081525f6127af60408301856126f6565b8281036020840152612723818561265e565b5f815180845260208085019450602084015f5b838110156127f0578151875295820195908201906001016127d4565b509495945050505050565b5f8282518085526020808601955060208260051b840101602086015f5b848110156125e957601f19868403018952612834838351612404565b98840198925090830190600101612818565b5f815180845260208085019450602084015f5b838110156127f0578151151587529582019590820190600101612859565b60a080825286519082018190525f9060209060c0840190828a01845b828110156128b85781516001600160a01b031684529284019290840190600101612893565b50505083810360208501526128cd81896127c1565b91505082810360408401526128e281876127fb565b905082810360608401526128f681866127fb565b9050828103608084015261290a8185612846565b98975050505050505050565b5f60208284031215612926575f80fd5b5051919050565b80820281158282048414176110575761105761273e565b808201808211156110575761105761273e565b5f61010060018060a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e08401526129a281840185612404565b9b9a5050505050505050505050565b6001600160a01b03841681526060602082018190525f906129d490830185612404565b905063ffffffff83166040830152949350505050565b5f82612a0457634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0381168114612a1d575f80fd5b50565b5f60208284031215612a30575f80fd5b815161119481612a09565b5f60208284031215612a4b575f80fd5b81518015158114611194575f80fd5b6001600160a01b03948516815260208101939093529216604082015261ffff909116606082015260800190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b82516001600160a01b039081168252602080850151821690830152604080850151821690830152606080850151909116908201526080928301519281019290925260a082015260c00190565b6001600160a01b03841681526060602082018190525f90612b1c90830185612404565b9050826040830152949350505050565b5f82518060208501845e5f920191825250919050565b602081525f611194602083018461240456fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212207a985120478b94fe29fa08a0c0939b0e2686a6db5bc061c08f7607d8423fb4da64736f6c63430008190033
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100cb575f3560e01c806395a93cb111610088578063c0a2558011610063578063c0a25580146101d4578063d0c38c27146101e9578063fabe3463146101f8578063fbb256f614610207575f80fd5b806395a93cb11461018f578063b14e01271461019e578063b1af0d0d146101c5575f80fd5b80630a4aa3fa146100cf5780631850edd8146101135780632b179434146101225780634c80312514610137578063614619541461015e5780636256d8ad14610168575b5f80fd5b6100f67f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd7881565b6040516001600160a01b0390911681526020015b60405180910390f35b606060405161010a91906122c7565b61012a61021c565b60405161010a9190612314565b6100f67f000000000000000000000000356f19cb575cf40c7ff33a5117f9a9264c23f6e881565b61016661032a565b005b6100f67f000000000000000000000000000000000000000000000000000000000000000081565b606060405161010a9190612355565b6100f67f0000000000000000000000001d54a093b8fddfcc6fbb411d9af31d96e034b3d581565b606060405161010a91906123b6565b6101dc6104d0565b60405161010a91906125f6565b606060405161010a9190612608565b606060405161010a91906126e4565b61020f610a86565b60405161010a919061272c565b604080516001808252818301909252606091816020015b6102756040518060e001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b8152602001906001900390816102335750506040805160e0810190915273cbb7c0000ab88b473b1f5afd9ef808440eed33bf8152909150602081016102bc602a5f19612752565b81526020016102cd602a5f19612752565b81526020016102de602a5f19612752565b81526020016102ef602a5f19612752565b8152602001610300602a5f19612752565b81526020016003815250815f8151811061031c5761031c612765565b602002602001018190525090565b610332610ae5565b7f0000000000000000000000001d54a093b8fddfcc6fbb411d9af31d96e034b3d56001600160a01b0316156103c7576103c7734dbd4fc535ac27206064b68ffcf827b0a60bab3f73212871a1c235892f86cab30e937e18c94aed84746103b77f0000000000000000000000001d54a093b8fddfcc6fbb411d9af31d96e034b3d5610ca0565b620f4240640ba43b740048610e94565b7f000000000000000000000000356f19cb575cf40c7ff33a5117f9a9264c23f6e86001600160a01b0316156104555761045573866e82a600a1414e583f7f13623f1ac5d58b0afa73fda082e00ef89185d9db7e5dcd8c5505070f5a3b61044c7f000000000000000000000000356f19cb575cf40c7ff33a5117f9a9264c23f6e8610ca0565b620f4240610fab565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156104ce576104ce73c4218c1127cb24a0d6c1e7d25dc34e10f2625f5a6104c57f0000000000000000000000000000000000000000000000000000000000000000610ca0565b620f424061100e565b565b60408051600480825260a082019092526060915f9190816020015b6104f36121a9565b8152602001906001900390816104eb579050509050604051806102400160405280738236a87084f8b84306f72007f36f2618a56344946001600160a01b03168152602001604051806040016040528060048152602001634c42544360e01b8152508152602001734219aa1a99f3fe90c2acb97fcbc1204f6485b5376001600160a01b03168152602001604051806101200160405280610593611194611033565b81526020016105a36101f4611033565b81526020016105b36105dc611033565b81526020016105c3617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f81526020016119648152602001611b58815260200161032081526020016105dc815260200160fa81526020015f81526020015f81526020016103e88152602001600360ff16815250815f8151811061065c5761065c612765565b60200260200101819052506040518061024001604052807318084fba666a33d37592fa2633fd49a74dd93a886001600160a01b03168152602001604051806040016040528060048152602001637442544360e01b8152508152602001734219aa1a99f3fe90c2acb97fcbc1204f6485b5376001600160a01b031681526020016040518061012001604052806106f2611770611033565b81526020015f8152602001610708610190611033565b8152602001610718617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f8152508152602001600181526020015f81526020015f81526020015f8152602001600181526020016119648152602001611b58815260200161032081526020016107d08152602001607d8152602001601981526020015f81526020016103e881526020015f60ff16815250816001815181106107b4576107b4612765565b602002602001018190525060405180610240016040528073bf5495efe5db9ce00f80364c8b423567e58d21106001600160a01b03168152602001604051806040016040528060058152602001640caf48aa8960db1b81525081526020017352e85eb49e07df74c8a9466d2164b4c4ca60014a6001600160a01b0316815260200160405180610120016040528061084b611194611033565b815260200161085b6101f4611033565b815260200161086b6105dc611033565b815260200161087b617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f8152602001611c208152602001611c8481526020016103e881526020016105dc81526020016107d081526020015f81526020015f81526020016103e881526020015f60ff168152508160028151811061091557610915612765565b602002602001018190525060405180610240016040528073a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b03168152602001604051806040016040528060058152602001640e4e68aa8960db1b81525081526020017370942d6b580741cf50a7906f4100063ee037b8eb6001600160a01b031681526020016040518061012001604052806109ac611194611033565b81526020016109bc6101f4611033565b81526020016109cc6105dc611033565b81526020016109dc617530611033565b81526020015f81526020015f81526020015f81526020015f81526020015f81525081526020015f81526020015f81526020015f81526020015f81526020015f8152602001611c208152602001611c8481526020016103e881526020016105dc81526020016107d081526020015f81526020015f81526020016103e881526020015f60ff1681525081600381518110610a7657610a76612765565b6020908102919091010152919050565b60408051808201909152606080825260208201525060408051608081018252600881830190815267457468657265756d60c01b606083015281528151808301909252600382526208ae8d60eb1b60208381019190915281019190915290565b610aed61105d565b5f610af66104d0565b90506060805f610b0461021c565b84519091506060908190819015610b9e57610b9c633cb6502d60e01b610b28610a86565b89604051602401610b3a929190612779565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b037f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd78169061116f565b505b855115610bcc57610bca6314d8093760e21b610bb8610a86565b88604051602401610b3a92919061279d565b505b825115610bf357604051610bf19063bb06653560e01b90610b3a9086906024016122c7565b505b835115610c1a57604051610c1890636e17618760e11b90610b3a908790602401612314565b505b805115610c4157604051610c3f906324f4c44560e01b90610b3a908490602401612608565b505b815115610c6857604051610c669063927c400360e01b90610b3a9085906024016123b6565b505b845115610c8f57604051610c8d906355caa16360e01b90610b3a908890602401612355565b505b610c9761119b565b50505050505050565b6040805160018082528183019092526060915f91906020808301908036833750506040805160018082528183019092529293505f9291506020808301908036833750506040805160018082528183019092529293505f929150602082015b6060815260200190600190039081610cfe5750506040805160018082528183019092529192505f9190602082015b6060815260200190600190039081610d2c5750506040805160018082528183019092529192505f91906020808301908036833701905050905086855f81518110610d7857610d78612765565b60200260200101906001600160a01b031690816001600160a01b0316815250505f845f81518110610dab57610dab612765565b6020026020010181815250506040518060400160405280600981526020016865786563757465282960b81b815250835f81518110610deb57610deb612765565b602002602001018190525060405180602001604052805f815250825f81518110610e1757610e17612765565b60200260200101819052506001815f81518110610e3657610e36612765565b91151560209283029190910190910152604051610e5f9086908690869086908690602401612877565b60408051601f198184030181529190526020810180516001600160e01b031663d9a4cbdf60e01b179052979650505050505050565b835160405163a66b327d60e01b81525f916001600160a01b0389169163a66b327d91610ecd918690600401918252602082015260400190565b602060405180830381865afa158015610ee8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0c9190612916565b90505f610f19848661292d565b90506001600160a01b03881663679b6ded610f348385612944565b895f865f808c8c8f6040518a63ffffffff1660e01b8152600401610f5f989796959493929190612957565b60206040518083038185885af1158015610f7b573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fa09190612916565b505050505050505050565b604051633dbb202b60e01b81526001600160a01b03851690633dbb202b90610fdb908690869086906004016129b1565b5f604051808303815f87803b158015610ff2575f80fd5b505af1158015611004573d5f803e3d5ffd5b5050505050505050565b61102e734c36d2919e407f0cc2ee3c993ccf8ac26d9ce64e848484612016565b505050565b5f61271061104d836b033b2e3c9fd0803ce800000061292d565b61105791906129ea565b92915050565b7f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110dd9190612a20565b604051633067587960e21b8152600360048201819052612134602483015261232860448301526127d860648301525f608483015260c060a483015260c48201526242544360e81b60e48201526001600160a01b03919091169063c19d61e490610104015f604051808303815f87803b158015611157575f80fd5b505af1158015611169573d5f803e3d5ffd5b50505050565b60606111948383604051806060016040528060278152602001612b5560279139612086565b9392505050565b738236a87084f8b84306f72007f36f2618a56344946001600160a01b031663095ea7b37f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123e9190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015261271060248201526044016020604051808303815f875af1158015611289573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112ad9190612a3b565b507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132e9190612a20565b6001600160a01b031663617ba037738236a87084f8b84306f72007f36f2618a5634494612710305f6040518563ffffffff1660e01b81526004016113759493929190612a5a565b5f604051808303815f87803b15801561138c575f80fd5b505af115801561139e573d5f803e3d5ffd5b505050507318084fba666a33d37592fa2633fd49a74dd93a886001600160a01b031663095ea7b37f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611421573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114459190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af1158015611494573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114b89190612a3b565b507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611515573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115399190612a20565b6001600160a01b031663617ba0377318084fba666a33d37592fa2633fd49a74dd93a88655af3107a4000305f6040518563ffffffff1660e01b81526004016115849493929190612a5a565b5f604051808303815f87803b15801561159b575f80fd5b505af11580156115ad573d5f803e3d5ffd5b5050505073bf5495efe5db9ce00f80364c8b423567e58d21106001600160a01b031663095ea7b37f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611630573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116549190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af11580156116a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c79190612a3b565b507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611724573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117489190612a20565b6001600160a01b031663617ba03773bf5495efe5db9ce00f80364c8b423567e58d2110655af3107a4000305f6040518563ffffffff1660e01b81526004016117939493929190612a5a565b5f604051808303815f87803b1580156117aa575f80fd5b505af11580156117bc573d5f803e3d5ffd5b5050505073a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b031663095ea7b37f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118639190612a20565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152655af3107a400060248201526044016020604051808303815f875af11580156118b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d69190612a3b565b507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b0316637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015611933573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119579190612a20565b6001600160a01b031663617ba03773a1290d69c65a6fe4df752f95823fae25cb99e5a7655af3107a4000305f6040518563ffffffff1660e01b81526004016119a29493929190612a5a565b5f604051808303815f87803b1580156119b9575f80fd5b505af11580156119cb573d5f803e3d5ffd5b505060405163b28c909f60e01b8152732276f52afba7cf2525fd0a050df464ac8532d0ef925082915063b28c909f90611a2790738236a87084f8b84306f72007f36f2618a5634494906109c49060fa9061a8c090600401612a87565b5f604051808303815f87803b158015611a3e575f80fd5b505af1158015611a50573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611a9f907318084fba666a33d37592fa2633fd49a74dd93a88906101f490607d9061a8c090600401612a87565b5f604051808303815f87803b158015611ab6575f80fd5b505af1158015611ac8573d5f803e3d5ffd5b50506040516328e7733d60e01b81526001600160a01b03841692506328e7733d9150611b16907318084fba666a33d37592fa2633fd49a74dd93a889060fa9060199061a8c090600401612a87565b5f604051808303815f87803b158015611b2d575f80fd5b505af1158015611b3f573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611b8f9073bf5495efe5db9ce00f80364c8b423567e58d211090614e20906107d09061a8c090600401612a87565b5f604051808303815f87803b158015611ba6575f80fd5b505af1158015611bb8573d5f803e3d5ffd5b505060405163b28c909f60e01b81526001600160a01b038416925063b28c909f9150611c089073a1290d69c65a6fe4df752f95823fae25cb99e5a790614e20906107d09061a8c090600401612a87565b5f604051808303815f87803b158015611c1f575f80fd5b505af1158015611c31573d5f803e3d5ffd5b50506040805160a081018252736b175474e89094c44da98b954eedeac495271d0f81527350d2c7992b802eef16c04feadab310f31866a54560208201527339a695eb6d0c01f6977521e5e79ea8bc232b506a8183015273870ac11d48b15db9a138cf899d20f13f79ba00bc6060820152670cb2bba6f17b800060808201529051633b24c2bf60e01b81527373e65dbd630f90604062f6e02fab9138e713edd99350633b24c2bf9250611cf391906af8277896582678ac00000090600401612aad565b5f604051808303815f87803b158015611d0a575f80fd5b505af1158015611d1c573d5f803e3d5ffd5b50506040805160a081018252736b175474e89094c44da98b954eedeac495271d0f815273917459337caac939d41d7493b3999f571d20d667602082015273fcae69bef9b6c96d89d58664d8aea84bddce2e5c8183015273870ac11d48b15db9a138cf899d20f13f79ba00bc6060820152670cb2bba6f17b800060808201529051633b24c2bf60e01b81527373e65dbd630f90604062f6e02fab9138e713edd99350633b24c2bf9250611dde91906aa56fa5b99019a5c800000090600401612aad565b5f604051808303815f87803b158015611df5575f80fd5b505af1158015611e07573d5f803e3d5ffd5b505050507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8b9190612a20565b604051631d2118f960e01b8152736b175474e89094c44da98b954eedeac495271d0f6004820152735a7e7a32331189a794ac33fec76c0a1dd3ddcf9c60248201526001600160a01b039190911690631d2118f9906044015f604051808303815f87803b158015611ef9575f80fd5b505af1158015611f0b573d5f803e3d5ffd5b505050507f0000000000000000000000003254f7cd0565aa67eedc86c2fb608be48d5ccd786001600160a01b031663587250846040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8f9190612a20565b604051631d2118f960e01b815273dc035d45d973e3ec169d2276ddab16f1e407384f600482015273d94ba511284d2c56f59a687c3338441d33304e0760248201526001600160a01b039190911690631d2118f9906044015f604051808303815f87803b158015611ffd575f80fd5b505af115801561200f573d5f803e3d5ffd5b5050505050565b60405163dc8601b360e01b81526001600160a01b0385169063dc8601b39061204690869086908690600401612af9565b6020604051808303815f875af1158015612062573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200f9190612916565b60605f80856001600160a01b0316856040516120a29190612b2c565b5f60405180830381855af49150503d805f81146120da576040519150601f19603f3d011682016040523d82523d5f602084013e6120df565b606091505b50915091506120f0868383876120fa565b9695505050505050565b6060831561216d5782515f03612166576001600160a01b0385163b6121665760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081612177565b612177838361217f565b949350505050565b81511561218f5781518083602001fd5b8060405162461bcd60e51b815260040161215d9190612b42565b6040518061024001604052805f6001600160a01b03168152602001606081526020015f6001600160a01b031681526020016122206040518061012001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f60ff1681525090565b80516001600160a01b031682526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0818101519083015260c090810151910152565b602080825282518282018190525f9190848201906040850190845b81811015612308576122f583855161227d565b9284019260e092909201916001016122e2565b50909695505050505050565b602080825282518282018190525f9190848201906040850190845b818110156123085761234283855161227d565b9284019260e0929092019160010161232f565b602080825282518282018190525f919060409081850190868401855b828110156123a957815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101612371565b5091979650505050505050565b602080825282518282018190525f919060409081850190868401855b828110156123a957815180516001600160a01b03908116865290870151168685015292840192908501906001016123d2565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152505050565b80516001600160a01b031682525f61034060208301518160208601526124b482860182612404565b91505060408301516124d160408601826001600160a01b03169052565b5060608301516124e46060860182612432565b5060808301516101808581019190915260a08401516101a08087019190915260c08501516101c08088019190915260e08601516101e080890191909152610100870151610200808a0191909152610120880151610220808b01919091526101408901516102408b01526101608901516102608b0152948801516102808a0152928701516102a0890152908601516102c08801528501516102e087015284015161030086015283015160ff8116610320860152509392505050565b5f8282518085526020808601955060208260051b840101602086015f5b848110156125e957601f198684030189526125d783835161248c565b988401989250908301906001016125bb565b5090979650505050505050565b602081525f611194602083018461259e565b602080825282518282018190525f9190848201906040850190845b8181101561230857835180516001600160a01b0316845285015161264986850182612432565b50928401926101409290920191600101612623565b5f82825180855260208086019550808260051b8401018186015f5b848110156125e957601f1986840301895281516080815181865261269f8287018261248c565b9287015180516001600160a01b03908116888a01528189015181166040808a019190915290910151166060909601959095525098840198925090830190600101612679565b602081525f611194602083018461265e565b5f81516040845261270a6040850182612404565b9050602083015184820360208601526127238282612404565b95945050505050565b602081525f61119460208301846126f6565b634e487b7160e01b5f52601160045260245ffd5b818103818111156110575761105761273e565b634e487b7160e01b5f52603260045260245ffd5b604081525f61278b60408301856126f6565b8281036020840152612723818561259e565b604081525f6127af60408301856126f6565b8281036020840152612723818561265e565b5f815180845260208085019450602084015f5b838110156127f0578151875295820195908201906001016127d4565b509495945050505050565b5f8282518085526020808601955060208260051b840101602086015f5b848110156125e957601f19868403018952612834838351612404565b98840198925090830190600101612818565b5f815180845260208085019450602084015f5b838110156127f0578151151587529582019590820190600101612859565b60a080825286519082018190525f9060209060c0840190828a01845b828110156128b85781516001600160a01b031684529284019290840190600101612893565b50505083810360208501526128cd81896127c1565b91505082810360408401526128e281876127fb565b905082810360608401526128f681866127fb565b9050828103608084015261290a8185612846565b98975050505050505050565b5f60208284031215612926575f80fd5b5051919050565b80820281158282048414176110575761105761273e565b808201808211156110575761105761273e565b5f61010060018060a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e08401526129a281840185612404565b9b9a5050505050505050505050565b6001600160a01b03841681526060602082018190525f906129d490830185612404565b905063ffffffff83166040830152949350505050565b5f82612a0457634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0381168114612a1d575f80fd5b50565b5f60208284031215612a30575f80fd5b815161119481612a09565b5f60208284031215612a4b575f80fd5b81518015158114611194575f80fd5b6001600160a01b03948516815260208101939093529216604082015261ffff909116606082015260800190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b82516001600160a01b039081168252602080850151821690830152604080850151821690830152606080850151909116908201526080928301519281019290925260a082015260c00190565b6001600160a01b03841681526060602082018190525f90612b1c90830185612404565b9050826040830152949350505050565b5f82518060208501845e5f920191825250919050565b602081525f611194602083018461240456fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212207a985120478b94fe29fa08a0c0939b0e2686a6db5bc061c08f7607d8423fb4da64736f6c63430008190033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.