From 1c797847cdaba013549ab182ff459873c91dfd82 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 29 Apr 2024 13:59:17 +0530 Subject: [PATCH 01/11] feat: repo refactor --- certora/applyHarness.patch | 20 +- certora/conf/NEW-pool-no-summarizations.conf | 14 +- certora/conf/NEW-pool-simple-properties.conf | 10 +- certora/harness/ATokenHarness.sol | 12 +- certora/harness/PoolHarness.sol | 12 +- .../harness/ReserveConfigurationHarness.sol | 5 +- certora/harness/SimpleERC20.sol | 4 +- certora/harness/StableDebtTokenHarness.sol | 7 +- certora/harness/SymbolicPriceOracle.sol | 3 +- certora/harness/UserConfigurationHarness.sol | 7 +- certora/harness/VariableDebtTokenHarness.sol | 6 +- .../misc/DeployAaveV3MarketBatchedBase.sol | 12 +- scripts/misc/LibraryPreCompileOne.sol | 8 +- scripts/misc/LibraryPreCompileTwo.sol | 8 +- .../chainlink/AggregatorInterface.sol | 0 .../gnosis/contracts/GPv2SafeERC20.sol | 0 .../openzeppelin/ReentrancyGuard.sol | 0 .../openzeppelin/contracts/AccessControl.sol | 0 .../openzeppelin/contracts/Address.sol | 0 .../openzeppelin/contracts/Context.sol | 0 .../openzeppelin/contracts/ECDSA.sol | 180 +++++ .../openzeppelin/contracts/ERC165.sol | 0 .../openzeppelin/contracts/ERC20.sol | 0 .../openzeppelin/contracts/IAccessControl.sol | 0 .../openzeppelin/contracts/IERC165.sol | 0 .../openzeppelin/contracts/IERC20.sol | 0 .../openzeppelin/contracts/IERC20Detailed.sol | 0 .../openzeppelin/contracts/Ownable.sol | 0 .../openzeppelin/contracts/SafeCast.sol | 0 .../openzeppelin/contracts/SafeERC20.sol | 0 .../openzeppelin/contracts/SafeMath.sol | 0 .../openzeppelin/contracts/Strings.sol | 0 .../AdminUpgradeabilityProxy.sol | 0 .../BaseAdminUpgradeabilityProxy.sol | 0 .../BaseUpgradeabilityProxy.sol | 0 .../upgradeability/Initializable.sol | 0 .../InitializableAdminUpgradeabilityProxy.sol | 0 .../InitializableUpgradeabilityProxy.sol | 0 .../openzeppelin/upgradeability/Proxy.sol | 0 .../upgradeability/UpgradeabilityProxy.sol | 0 src/contracts/dependencies/solmate/ERC20.sol | 207 +++++ .../contracts/dependencies/weth/WETH9.sol | 0 .../AaveParaSwapFeeClaimer.sol | 2 +- .../BaseParaSwapAdapter.sol | 20 +- .../BaseParaSwapBuyAdapter.sol | 10 +- .../BaseParaSwapSellAdapter.sol | 10 +- .../ParaSwapLiquiditySwapAdapter.sol | 10 +- .../ParaSwapRepayAdapter.sol | 14 +- .../ParaSwapWithdrawSwapAdapter.sol | 8 +- .../interfaces/IFeeClaimer.sol | 2 +- .../interfaces/IParaSwapAugustus.sol | 0 .../interfaces/IParaSwapAugustusRegistry.sol | 0 .../extensions/static-a-token/README.md | 38 + .../extensions/static-a-token/StataOracle.sol | 41 + .../static-a-token/StaticATokenErrors.sol | 14 + .../static-a-token/StaticATokenFactory.sol | 86 +++ .../static-a-token/StaticATokenLM.sol | 712 ++++++++++++++++++ .../static-a-token/interfaces/IAToken.sol | 16 + .../static-a-token/interfaces/IERC4626.sol | 241 ++++++ .../IInitializableStaticATokenLM.sol | 32 + .../interfaces/IStataOracle.sol | 31 + .../interfaces/IStaticATokenFactory.sol | 24 + .../interfaces/IStaticATokenLM.sol | 214 ++++++ .../v3-config-engine/AaveV3ConfigEngine.sol | 2 +- .../v3-config-engine/AaveV3Payload.sol | 4 +- .../v3-config-engine/EngineFlags.sol | 2 +- .../v3-config-engine/IAaveV3ConfigEngine.sol | 8 +- .../extensions/v3-config-engine/README.md | 62 ++ .../libraries/BorrowEngine.sol | 6 +- .../v3-config-engine/libraries/CapsEngine.sol | 2 +- .../libraries/CollateralEngine.sol | 8 +- .../libraries/EModeEngine.sol | 6 +- .../libraries/ListingEngine.sol | 6 +- .../libraries/PriceFeedEngine.sol | 4 +- .../v3-config-engine/libraries/RateEngine.sol | 6 +- .../helpers}/AaveProtocolDataProvider.sol | 0 .../misc => contracts/helpers}/L2Encoder.sol | 0 .../helpers}/UiIncentiveDataProviderV3.sol | 12 +- .../helpers}/UiPoolDataProviderV3.sol | 26 +- .../helpers}/WalletBalanceProvider.sol | 16 +- .../helpers}/WrappedTokenGatewayV3.sol | 20 +- .../interfaces/IEACAggregatorProxy.sol | 0 .../interfaces/IERC20DetailedBytes.sol | 2 +- .../interfaces/IUiIncentiveDataProviderV3.sol | 2 +- .../interfaces/IUiPoolDataProviderV3.sol | 2 +- .../helpers}/interfaces/IWETH.sol | 0 .../interfaces/IWrappedTokenGatewayV3.sol | 0 .../instances/ATokenInstance.sol | 2 +- .../instances/L2PoolInstance.sol | 4 +- .../instances/PoolConfiguratorInstance.sol | 2 +- .../instances/PoolInstance.sol | 6 +- .../instances/StableDebtTokenInstance.sol | 2 +- .../instances/VariableDebtTokenInstance.sol | 2 +- .../contracts/interfaces/IACLManager.sol | 0 .../contracts/interfaces/IAToken.sol | 0 .../interfaces/IAaveIncentivesController.sol | 0 .../contracts/interfaces/IAaveOracle.sol | 0 .../interfaces/ICreditDelegationToken.sol | 0 .../IDefaultInterestRateStrategyV2.sol | 0 .../contracts/interfaces/IDelegationToken.sol | 0 .../contracts/interfaces/IERC20WithPermit.sol | 0 .../interfaces/IInitializableAToken.sol | 0 .../interfaces/IInitializableDebtToken.sol | 0 .../contracts/interfaces/IL2Pool.sol | 0 src/{core => }/contracts/interfaces/IPool.sol | 0 .../interfaces/IPoolAddressesProvider.sol | 0 .../IPoolAddressesProviderRegistry.sol | 0 .../interfaces/IPoolConfigurator.sol | 0 .../interfaces/IPoolDataProvider.sol | 0 .../contracts/interfaces/IPriceOracle.sol | 0 .../interfaces/IPriceOracleGetter.sol | 0 .../interfaces/IPriceOracleSentinel.sol | 0 .../IReserveInterestRateStrategy.sol | 0 .../interfaces/IScaledBalanceToken.sol | 0 .../contracts/interfaces/ISequencerOracle.sol | 0 .../contracts/interfaces/IStableDebtToken.sol | 0 .../interfaces/IVariableDebtToken.sol | 0 src/{core => }/contracts/misc/AaveOracle.sol | 0 .../DefaultReserveInterestRateStrategyV2.sol | 16 +- .../misc}/PriceOracleSentinel.sol | 10 +- .../BaseImmutableAdminUpgradeabilityProxy.sol | 2 +- ...zableImmutableAdminUpgradeabilityProxy.sol | 4 +- .../VersionedInitializable.sol | 0 .../flashloan/base/FlashLoanReceiverBase.sol | 4 +- .../base/FlashLoanSimpleReceiverBase.sol | 4 +- .../interfaces/IFlashLoanReceiver.sol | 4 +- .../interfaces/IFlashLoanSimpleReceiver.sol | 4 +- .../misc}/libraries/DataTypesHelper.sol | 4 +- .../libraries/RayMathExplicitRounding.sol | 42 ++ .../contracts/mocks/ATokenMock.sol | 0 .../mocks/MockBadTransferStrategy.sol | 4 +- .../contracts/mocks/WETH9Mock.sol | 4 +- .../mocks/flashloan/MockFlashLoanReceiver.sol | 2 +- .../flashloan/MockSimpleFlashLoanReceiver.sol | 2 +- .../helpers/MockIncentivesController.sol | 0 .../contracts/mocks/helpers/MockL2Pool.sol | 4 +- .../mocks/helpers/MockPeripheryContract.sol | 0 .../contracts/mocks/helpers/MockPool.sol | 2 +- .../helpers/MockReserveConfiguration.sol | 0 .../oracle/CLAggregators/MockAggregator.sol | 0 .../contracts/mocks/oracle/PriceOracle.sol | 0 .../mocks/oracle/SequencerOracle.sol | 0 .../mocks/swap/MockParaSwapAugustus.sol | 6 +- .../swap/MockParaSwapAugustusRegistry.sol | 2 +- .../mocks/swap/MockParaSwapFeeClaimer.sol | 6 +- .../swap/MockParaSwapTokenTransferProxy.sol | 4 +- .../mocks/testnet-helpers/Faucet.sol | 2 +- .../mocks/testnet-helpers/IFaucet.sol | 0 .../mocks/testnet-helpers/TestnetERC20.sol | 6 +- .../mocks/tests/FlashloanAttacker.sol | 2 +- .../mocks/tests/MathUtilsWrapper.sol | 0 .../tests/MockReserveInterestRateStrategy.sol | 2 +- .../mocks/tests/PercentageMathWrapper.sol | 0 .../mocks/tests/WadRayMathWrapper.sol | 0 .../mocks/tokens/MintableDelegationERC20.sol | 0 .../contracts/mocks/tokens/MintableERC20.sol | 0 .../mocks/tokens/MockATokenRepayment.sol | 2 +- .../contracts/mocks/tokens/MockDebtTokens.sol | 4 +- .../mocks/tokens/MockScaledToken.sol | 5 +- .../contracts/mocks/tokens/WETH9Mocked.sol | 0 .../mocks/upgradeability/MockAToken.sol | 2 +- .../MockInitializableImplementation.sol | 2 +- .../upgradeability/MockStableDebtToken.sol | 2 +- .../upgradeability/MockVariableDebtToken.sol | 2 +- .../protocol/configuration/ACLManager.sol | 0 .../configuration/PoolAddressesProvider.sol | 2 +- .../PoolAddressesProviderRegistry.sol | 0 .../configuration/ReserveConfiguration.sol | 0 .../configuration/UserConfiguration.sol | 0 .../protocol/libraries/helpers/Errors.sol | 0 .../protocol/libraries/helpers/Helpers.sol | 0 .../protocol/libraries/logic/BorrowLogic.sol | 0 .../protocol/libraries/logic/BridgeLogic.sol | 0 .../libraries/logic/CalldataLogic.sol | 0 .../libraries/logic/ConfiguratorLogic.sol | 2 +- .../protocol/libraries/logic/EModeLogic.sol | 0 .../libraries/logic/FlashLoanLogic.sol | 4 +- .../protocol/libraries/logic/GenericLogic.sol | 0 .../libraries/logic/IsolationModeLogic.sol | 0 .../libraries/logic/LiquidationLogic.sol | 0 .../protocol/libraries/logic/PoolLogic.sol | 0 .../protocol/libraries/logic/ReserveLogic.sol | 0 .../protocol/libraries/logic/SupplyLogic.sol | 0 .../libraries/logic/ValidationLogic.sol | 0 .../protocol/libraries/math/MathUtils.sol | 0 .../libraries/math/PercentageMath.sol | 0 .../protocol/libraries/math/WadRayMath.sol | 0 .../types/ConfiguratorInputTypes.sol | 0 .../protocol/libraries/types/DataTypes.sol | 0 .../contracts/protocol/pool/L2Pool.sol | 0 .../contracts/protocol/pool/Pool.sol | 2 +- .../protocol/pool/PoolConfigurator.sol | 2 +- .../contracts/protocol/pool/PoolStorage.sol | 0 .../protocol/tokenization/AToken.sol | 2 +- .../protocol/tokenization/StableDebtToken.sol | 2 +- .../tokenization/VariableDebtToken.sol | 2 +- .../tokenization/base/DebtTokenBase.sol | 2 +- .../protocol/tokenization/base/EIP712Base.sol | 0 .../tokenization/base/IncentivizedERC20.sol | 0 .../base/MintableIncentivizedERC20.sol | 0 .../base/ScaledBalanceTokenBase.sol | 0 .../contracts/rewards/EmissionManager.sol | 4 +- .../contracts/rewards/RewardsController.sol | 8 +- .../contracts/rewards/RewardsDistributor.sol | 6 +- .../rewards/interfaces/IEmissionManager.sol | 2 +- .../IPullRewardsTransferStrategy.sol | 0 .../rewards/interfaces/IRewardsController.sol | 2 +- .../interfaces/IRewardsDistributor.sol | 0 .../rewards/interfaces/IStakedToken.sol | 0 .../IStakedTokenTransferStrategy.sol | 0 .../interfaces/ITransferStrategyBase.sol | 0 .../rewards/libraries/RewardsDataTypes.sol | 2 +- .../PullRewardsTransferStrategy.sol | 4 +- .../StakedTokenTransferStrategy.sol | 4 +- .../TransferStrategyBase.sol | 4 +- .../contracts/treasury/Collector.sol | 8 +- .../contracts/treasury/ICollector.sol | 2 +- src/core/contracts/flashloan/base/LICENSE.md | 12 - .../contracts/flashloan/interfaces/LICENSE.md | 12 - src/core/contracts/interfaces/LICENSE.md | 12 - src/core/contracts/misc/interfaces/LICENSE.md | 12 - .../AaveV3DefaultRateStrategyProcedure.sol | 2 +- .../procedures/AaveV3GettersProcedureOne.sol | 12 +- .../procedures/AaveV3GettersProcedureTwo.sol | 6 +- .../procedures/AaveV3HelpersProcedureOne.sol | 63 ++ .../procedures/AaveV3HelpersProcedureTwo.sol | 42 ++ .../procedures/AaveV3IncentiveProcedure.sol | 4 +- .../procedures/AaveV3L2PoolProcedure.sol | 6 +- .../procedures/AaveV3MiscProcedure.sol | 34 + .../procedures/AaveV3OracleProcedure.sol | 2 +- .../procedures/AaveV3ParaswapProcedure.sol | 12 +- .../procedures/AaveV3PoolConfigProcedure.sol | 8 +- .../procedures/AaveV3PoolProcedure.sol | 6 +- .../procedures/AaveV3SetupProcedure.sol | 27 +- .../procedures/AaveV3TokensProcedure.sol | 10 +- .../procedures/AaveV3TreasuryProcedure.sol | 2 +- .../contracts/utilities/MarketReportUtils.sol | 4 +- .../contracts/utilities/MetadataReporter.sol | 8 + src/deployments/interfaces/IErrors.sol | 1 + .../interfaces/IMarketReportTypes.sol | 81 +- .../AaveV3BatchOrchestration.sol | 95 ++- .../batches/AaveV3HelpersBatchOne.sol | 37 + .../batches/AaveV3HelpersBatchTwo.sol | 25 + .../batches/AaveV3MiscBatch.sol | 29 + .../batches/AaveV3PeripheryBatch.sol | 6 +- .../batches/AaveV3SetupBatch.sol | 8 +- .../AaveV3LibrariesBatch1.sol | 8 +- .../AaveV3LibrariesBatch2.sol | 8 +- src/periphery/contracts/libraries/LICENSE.md | 12 - src/periphery/contracts/misc/LICENSE.md | 12 - .../contracts/misc/interfaces/IWETH.sol | 12 - .../contracts/misc/interfaces/LICENSE.md | 12 - src/periphery/contracts/mocks/LICENSE.md | 12 - .../contracts/rewards/interfaces/LICENSE.md | 12 - .../contracts/rewards/libraries/LICENSE.md | 12 - .../rewards/transfer-strategies/LICENSE.md | 12 - tests/AaveV3BatchTests.t.sol | 158 ---- .../AaveV3BatchDeployment.t.sol | 39 +- tests/deployments/AaveV3BatchTests.t.sol | 213 ++++++ .../AaveV3PermissionsTest.t.sol | 20 +- .../DeploymentsGasLimits.t.sol | 115 ++- .../paraswap-adapters}/ParaswapAdapters.t.sol | 30 +- .../static-a-token/StataOracle.t.sol | 54 ++ .../static-a-token/StaticATokenLM.t.sol | 613 +++++++++++++++ .../StaticATokenMetaTransactions.t.sol | 251 ++++++ .../static-a-token/StaticATokenNoLM.t.sol | 51 ++ tests/extensions/static-a-token/TestBase.sol | 94 +++ .../AaveV3ConfigEngineTest.t.sol | 644 ++++++++++++++++ .../mocks/AaveV3MockAssetEModeUpdate.sol | 32 + .../mocks/AaveV3MockBorrowUpdate.sol | 38 + .../mocks/AaveV3MockBorrowUpdateNoChange.sol | 36 + .../mocks/AaveV3MockCapUpdate.sol | 33 + .../mocks/AaveV3MockCollateralUpdate.sol | 36 + .../AaveV3MockCollateralUpdateNoChange.sol | 36 + .../AaveV3MockCollateralUpdateWrongBonus.sol | 68 ++ .../mocks/AaveV3MockEModeCategoryUpdate.sol | 72 ++ .../AaveV3MockEModeCategoryUpdateNoChange.sol | 37 + .../mocks/AaveV3MockListing.sol | 56 ++ .../mocks/AaveV3MockListingCustom.sol | 74 ++ .../mocks/AaveV3MockPriceFeedUpdate.sol | 35 + .../mocks/AaveV3MockRatesUpdate.sol | 42 ++ tests/harness/StableDebtToken.sol | 2 +- tests/harness/VariableDebtToken.sol | 2 +- .../WrappedTokenGateway.t.sol | 14 +- tests/{core => misc}/AaveOracle.t.sol | 8 +- .../{core => misc}/PriceOracleSentinel.t.sol | 10 +- ...bleImmutableAdminUpgradeabilityProxy.t.sol | 6 +- tests/{core => misc/rates}/RateStrategy.t.sol | 10 +- .../{core => misc/rates}/RatesOverflow.t.sol | 10 +- .../rates}/ZeroInteresRateStrategy.t.sol | 7 +- tests/mocks/AaveV3TestListing.sol | 12 +- tests/mocks/MockFlashLoanATokenReceiver.sol | 8 +- tests/{periphery => }/mocks/StakeMock.sol | 0 .../configuration}/ACLManager.t.sol | 8 +- .../AddressesProviderRegistry.t.sol | 4 +- .../PoolAddressesProvider.t.sol | 16 +- .../libraries/logic}/BridgeLogic.t.sol | 18 +- .../logic}/PoolLogic.initReserves.edge.t.sol | 4 +- .../libraries/math}/MathUtils.t.sol | 4 +- .../libraries/math}/PercentageMath.t.sol | 4 +- .../libraries/math}/WadRayMath.t.sol | 2 +- tests/{core => protocol/pool}/L2Pool.t.sol | 20 +- .../{core => protocol/pool}/Pool.Borrow.t.sol | 30 +- .../pool}/Pool.FlashLoans.t.sol | 28 +- .../pool}/Pool.Liquidations.t.sol | 34 +- .../{core => protocol/pool}/Pool.Repay.t.sol | 26 +- .../{core => protocol/pool}/Pool.Supply.t.sol | 12 +- .../pool}/Pool.Withdraw.t.sol | 6 +- tests/{core => protocol/pool}/Pool.t.sol | 18 +- .../PoolConfigurator.ACLModifiers.t.sol | 8 +- .../PoolConfigurator.borrowCaps.t.sol | 8 +- .../PoolConfigurator.eMode.sol | 8 +- .../PoolConfigurator.initReserves.t.sol | 16 +- .../PoolConfigurator.liquidationFee.t.sol | 4 +- .../PoolConfigurator.pendingLTV.t.sol | 8 +- .../PoolConfigurator.reserveRiskConfig.t.sol | 12 +- .../PoolConfigurator.supplyCaps.t.sol | 6 +- .../PoolConfigurator.upgradeabilty.t.sol | 52 +- .../tokenization}/ATokenEdgeCases.t.sol | 8 +- .../tokenization}/ATokenEvents.t.sol | 12 +- .../tokenization}/ATokenModifiers.t.sol | 6 +- .../tokenization}/ATokenPermit.t.sol | 8 +- .../tokenization}/ATokenRepay.t.sol | 8 +- .../tokenization}/ATokenRescueTokens.sol | 6 +- .../tokenization}/ATokenTransfers.t.sol | 16 +- .../ScaledBalanceTokenBase.t.sol | 7 +- .../tokenization}/StableDebtToken.t.sol | 14 +- .../tokenization}/VariableDebtToken.t.sol | 18 +- .../EmissionsManager.t.sol | 19 +- .../RewardsController.t.sol | 19 +- .../StakedTokenTransferStrategy.t.sol | 4 +- tests/utils/BatchTestProcedures.sol | 63 +- tests/utils/ConfigEngineDeployer.sol | 60 -- tests/utils/ProtocolV3TestBase.sol | 36 +- tests/utils/SigUtils.sol | 117 +++ tests/utils/TestnetProcedures.sol | 34 +- 336 files changed, 5820 insertions(+), 1128 deletions(-) rename src/{core => }/contracts/dependencies/chainlink/AggregatorInterface.sol (100%) rename src/{core => }/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol (100%) rename src/{periphery => }/contracts/dependencies/openzeppelin/ReentrancyGuard.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/AccessControl.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/Address.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/Context.sol (100%) create mode 100644 src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol rename src/{core => }/contracts/dependencies/openzeppelin/contracts/ERC165.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/ERC20.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/IERC165.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/IERC20.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/Ownable.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/SafeCast.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/SafeMath.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/contracts/Strings.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol (100%) rename src/{core => }/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol (100%) create mode 100644 src/contracts/dependencies/solmate/ERC20.sol rename src/{core => }/contracts/dependencies/weth/WETH9.sol (100%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/AaveParaSwapFeeClaimer.sol (95%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/BaseParaSwapAdapter.sol (79%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/BaseParaSwapBuyAdapter.sol (89%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/BaseParaSwapSellAdapter.sol (89%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/ParaSwapLiquiditySwapAdapter.sol (94%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/ParaSwapRepayAdapter.sol (92%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/ParaSwapWithdrawSwapAdapter.sol (87%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/interfaces/IFeeClaimer.sol (97%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/interfaces/IParaSwapAugustus.sol (100%) rename src/{periphery/contracts/adapters/paraswap => contracts/extensions/paraswap-adapters}/interfaces/IParaSwapAugustusRegistry.sol (100%) create mode 100644 src/contracts/extensions/static-a-token/README.md create mode 100644 src/contracts/extensions/static-a-token/StataOracle.sol create mode 100644 src/contracts/extensions/static-a-token/StaticATokenErrors.sol create mode 100644 src/contracts/extensions/static-a-token/StaticATokenFactory.sol create mode 100644 src/contracts/extensions/static-a-token/StaticATokenLM.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IAToken.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IERC4626.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol create mode 100644 src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/AaveV3ConfigEngine.sol (99%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/AaveV3Payload.sol (98%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/EngineFlags.sol (97%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/IAaveV3ConfigEngine.sol (97%) create mode 100644 src/contracts/extensions/v3-config-engine/README.md rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/BorrowEngine.sol (91%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/CapsEngine.sol (96%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/CollateralEngine.sol (91%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/EModeEngine.sol (94%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/ListingEngine.sol (96%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/PriceFeedEngine.sol (88%) rename src/{periphery/contracts => contracts/extensions}/v3-config-engine/libraries/RateEngine.sol (93%) rename src/{core/contracts/misc => contracts/helpers}/AaveProtocolDataProvider.sol (100%) rename src/{core/contracts/misc => contracts/helpers}/L2Encoder.sol (100%) rename src/{periphery/contracts/misc => contracts/helpers}/UiIncentiveDataProviderV3.sol (96%) rename src/{periphery/contracts/misc => contracts/helpers}/UiPoolDataProviderV3.sol (89%) rename src/{periphery/contracts/misc => contracts/helpers}/WalletBalanceProvider.sol (83%) rename src/{periphery/contracts/misc => contracts/helpers}/WrappedTokenGatewayV3.sol (89%) rename src/{periphery/contracts/misc => contracts/helpers}/interfaces/IEACAggregatorProxy.sol (100%) rename src/{periphery/contracts/misc => contracts/helpers}/interfaces/IERC20DetailedBytes.sol (73%) rename src/{periphery/contracts/misc => contracts/helpers}/interfaces/IUiIncentiveDataProviderV3.sol (95%) rename src/{periphery/contracts/misc => contracts/helpers}/interfaces/IUiPoolDataProviderV3.sol (96%) rename src/{core/contracts/misc => contracts/helpers}/interfaces/IWETH.sol (100%) rename src/{periphery/contracts/misc => contracts/helpers}/interfaces/IWrappedTokenGatewayV3.sol (100%) rename src/{core => contracts}/instances/ATokenInstance.sol (93%) rename src/{core => contracts}/instances/L2PoolInstance.sol (60%) rename src/{core => contracts}/instances/PoolConfiguratorInstance.sol (87%) rename src/{core => contracts}/instances/PoolInstance.sol (80%) rename src/{core => contracts}/instances/StableDebtTokenInstance.sol (91%) rename src/{core => contracts}/instances/VariableDebtTokenInstance.sol (91%) rename src/{core => }/contracts/interfaces/IACLManager.sol (100%) rename src/{core => }/contracts/interfaces/IAToken.sol (100%) rename src/{core => }/contracts/interfaces/IAaveIncentivesController.sol (100%) rename src/{core => }/contracts/interfaces/IAaveOracle.sol (100%) rename src/{core => }/contracts/interfaces/ICreditDelegationToken.sol (100%) rename src/{core => }/contracts/interfaces/IDefaultInterestRateStrategyV2.sol (100%) rename src/{core => }/contracts/interfaces/IDelegationToken.sol (100%) rename src/{core => }/contracts/interfaces/IERC20WithPermit.sol (100%) rename src/{core => }/contracts/interfaces/IInitializableAToken.sol (100%) rename src/{core => }/contracts/interfaces/IInitializableDebtToken.sol (100%) rename src/{core => }/contracts/interfaces/IL2Pool.sol (100%) rename src/{core => }/contracts/interfaces/IPool.sol (100%) rename src/{core => }/contracts/interfaces/IPoolAddressesProvider.sol (100%) rename src/{core => }/contracts/interfaces/IPoolAddressesProviderRegistry.sol (100%) rename src/{core => }/contracts/interfaces/IPoolConfigurator.sol (100%) rename src/{core => }/contracts/interfaces/IPoolDataProvider.sol (100%) rename src/{core => }/contracts/interfaces/IPriceOracle.sol (100%) rename src/{core => }/contracts/interfaces/IPriceOracleGetter.sol (100%) rename src/{core => }/contracts/interfaces/IPriceOracleSentinel.sol (100%) rename src/{core => }/contracts/interfaces/IReserveInterestRateStrategy.sol (100%) rename src/{core => }/contracts/interfaces/IScaledBalanceToken.sol (100%) rename src/{core => }/contracts/interfaces/ISequencerOracle.sol (100%) rename src/{core => }/contracts/interfaces/IStableDebtToken.sol (100%) rename src/{core => }/contracts/interfaces/IVariableDebtToken.sol (100%) rename src/{core => }/contracts/misc/AaveOracle.sol (100%) rename src/{core/contracts/protocol/pool => contracts/misc}/DefaultReserveInterestRateStrategyV2.sol (93%) rename src/{core/contracts/protocol/configuration => contracts/misc}/PriceOracleSentinel.sol (89%) rename src/{core/contracts/protocol/libraries => contracts/misc}/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol (95%) rename src/{core/contracts/protocol/libraries => contracts/misc}/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol (79%) rename src/{core/contracts/protocol/libraries => contracts/misc}/aave-upgradeability/VersionedInitializable.sol (100%) rename src/{core/contracts => contracts/misc}/flashloan/base/FlashLoanReceiverBase.sol (79%) rename src/{core/contracts => contracts/misc}/flashloan/base/FlashLoanSimpleReceiverBase.sol (80%) rename src/{core/contracts => contracts/misc}/flashloan/interfaces/IFlashLoanReceiver.sol (90%) rename src/{core/contracts => contracts/misc}/flashloan/interfaces/IFlashLoanSimpleReceiver.sol (89%) rename src/{periphery/contracts => contracts/misc}/libraries/DataTypesHelper.sol (80%) create mode 100644 src/contracts/misc/libraries/RayMathExplicitRounding.sol rename src/{periphery => }/contracts/mocks/ATokenMock.sol (100%) rename src/{periphery => }/contracts/mocks/MockBadTransferStrategy.sol (82%) rename src/{periphery => }/contracts/mocks/WETH9Mock.sol (72%) rename src/{core => }/contracts/mocks/flashloan/MockFlashLoanReceiver.sol (96%) rename src/{core => }/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol (95%) rename src/{core => }/contracts/mocks/helpers/MockIncentivesController.sol (100%) rename src/{core => }/contracts/mocks/helpers/MockL2Pool.sol (68%) rename src/{core => }/contracts/mocks/helpers/MockPeripheryContract.sol (100%) rename src/{core => }/contracts/mocks/helpers/MockPool.sol (92%) rename src/{core => }/contracts/mocks/helpers/MockReserveConfiguration.sol (100%) rename src/{core => }/contracts/mocks/oracle/CLAggregators/MockAggregator.sol (100%) rename src/{core => }/contracts/mocks/oracle/PriceOracle.sol (100%) rename src/{core => }/contracts/mocks/oracle/SequencerOracle.sol (100%) rename src/{periphery => }/contracts/mocks/swap/MockParaSwapAugustus.sol (91%) rename src/{periphery => }/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol (74%) rename src/{periphery => }/contracts/mocks/swap/MockParaSwapFeeClaimer.sol (88%) rename src/{periphery => }/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol (60%) rename src/{periphery => }/contracts/mocks/testnet-helpers/Faucet.sol (95%) rename src/{periphery => }/contracts/mocks/testnet-helpers/IFaucet.sol (100%) rename src/{periphery => }/contracts/mocks/testnet-helpers/TestnetERC20.sol (90%) rename src/{core => }/contracts/mocks/tests/FlashloanAttacker.sol (95%) rename src/{core => }/contracts/mocks/tests/MathUtilsWrapper.sol (100%) rename src/{core => }/contracts/mocks/tests/MockReserveInterestRateStrategy.sol (88%) rename src/{core => }/contracts/mocks/tests/PercentageMathWrapper.sol (100%) rename src/{core => }/contracts/mocks/tests/WadRayMathWrapper.sol (100%) rename src/{core => }/contracts/mocks/tokens/MintableDelegationERC20.sol (100%) rename src/{core => }/contracts/mocks/tokens/MintableERC20.sol (100%) rename src/{core => }/contracts/mocks/tokens/MockATokenRepayment.sol (88%) rename src/{core => }/contracts/mocks/tokens/MockDebtTokens.sol (74%) rename src/{core => }/contracts/mocks/tokens/MockScaledToken.sol (85%) rename src/{core => }/contracts/mocks/tokens/WETH9Mocked.sol (100%) rename src/{core => }/contracts/mocks/upgradeability/MockAToken.sol (80%) rename src/{core => }/contracts/mocks/upgradeability/MockInitializableImplementation.sol (96%) rename src/{core => }/contracts/mocks/upgradeability/MockStableDebtToken.sol (78%) rename src/{core => }/contracts/mocks/upgradeability/MockVariableDebtToken.sol (77%) rename src/{core => }/contracts/protocol/configuration/ACLManager.sol (100%) rename src/{core => }/contracts/protocol/configuration/PoolAddressesProvider.sol (98%) rename src/{core => }/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol (100%) rename src/{core => }/contracts/protocol/libraries/configuration/ReserveConfiguration.sol (100%) rename src/{core => }/contracts/protocol/libraries/configuration/UserConfiguration.sol (100%) rename src/{core => }/contracts/protocol/libraries/helpers/Errors.sol (100%) rename src/{core => }/contracts/protocol/libraries/helpers/Helpers.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/BorrowLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/BridgeLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/CalldataLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/ConfiguratorLogic.sol (99%) rename src/{core => }/contracts/protocol/libraries/logic/EModeLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/FlashLoanLogic.sol (98%) rename src/{core => }/contracts/protocol/libraries/logic/GenericLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/IsolationModeLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/LiquidationLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/PoolLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/ReserveLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/SupplyLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/logic/ValidationLogic.sol (100%) rename src/{core => }/contracts/protocol/libraries/math/MathUtils.sol (100%) rename src/{core => }/contracts/protocol/libraries/math/PercentageMath.sol (100%) rename src/{core => }/contracts/protocol/libraries/math/WadRayMath.sol (100%) rename src/{core => }/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol (100%) rename src/{core => }/contracts/protocol/libraries/types/DataTypes.sol (100%) rename src/{core => }/contracts/protocol/pool/L2Pool.sol (100%) rename src/{core => }/contracts/protocol/pool/Pool.sol (99%) rename src/{core => }/contracts/protocol/pool/PoolConfigurator.sol (99%) rename src/{core => }/contracts/protocol/pool/PoolStorage.sol (100%) rename src/{core => }/contracts/protocol/tokenization/AToken.sol (98%) rename src/{core => }/contracts/protocol/tokenization/StableDebtToken.sol (97%) rename src/{core => }/contracts/protocol/tokenization/VariableDebtToken.sol (97%) rename src/{core => }/contracts/protocol/tokenization/base/DebtTokenBase.sol (97%) rename src/{core => }/contracts/protocol/tokenization/base/EIP712Base.sol (100%) rename src/{core => }/contracts/protocol/tokenization/base/IncentivizedERC20.sol (100%) rename src/{core => }/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol (100%) rename src/{core => }/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol (100%) rename src/{periphery => }/contracts/rewards/EmissionManager.sol (95%) rename src/{periphery => }/contracts/rewards/RewardsController.sol (96%) rename src/{periphery => }/contracts/rewards/RewardsDistributor.sol (98%) rename src/{periphery => }/contracts/rewards/interfaces/IEmissionManager.sol (98%) rename src/{periphery => }/contracts/rewards/interfaces/IPullRewardsTransferStrategy.sol (100%) rename src/{periphery => }/contracts/rewards/interfaces/IRewardsController.sol (99%) rename src/{periphery => }/contracts/rewards/interfaces/IRewardsDistributor.sol (100%) rename src/{periphery => }/contracts/rewards/interfaces/IStakedToken.sol (100%) rename src/{periphery => }/contracts/rewards/interfaces/IStakedTokenTransferStrategy.sol (100%) rename src/{periphery => }/contracts/rewards/interfaces/ITransferStrategyBase.sol (100%) rename src/{periphery => }/contracts/rewards/libraries/RewardsDataTypes.sol (94%) rename src/{periphery => }/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol (88%) rename src/{periphery => }/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol (92%) rename src/{periphery => }/contracts/rewards/transfer-strategies/TransferStrategyBase.sol (89%) rename src/{periphery => }/contracts/treasury/Collector.sol (96%) rename src/{periphery => }/contracts/treasury/ICollector.sol (98%) delete mode 100644 src/core/contracts/flashloan/base/LICENSE.md delete mode 100644 src/core/contracts/flashloan/interfaces/LICENSE.md delete mode 100644 src/core/contracts/interfaces/LICENSE.md delete mode 100644 src/core/contracts/misc/interfaces/LICENSE.md create mode 100644 src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol create mode 100644 src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol create mode 100644 src/deployments/contracts/procedures/AaveV3MiscProcedure.sol create mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol create mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol create mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol delete mode 100644 src/periphery/contracts/libraries/LICENSE.md delete mode 100644 src/periphery/contracts/misc/LICENSE.md delete mode 100644 src/periphery/contracts/misc/interfaces/IWETH.sol delete mode 100644 src/periphery/contracts/misc/interfaces/LICENSE.md delete mode 100644 src/periphery/contracts/mocks/LICENSE.md delete mode 100644 src/periphery/contracts/rewards/interfaces/LICENSE.md delete mode 100644 src/periphery/contracts/rewards/libraries/LICENSE.md delete mode 100644 src/periphery/contracts/rewards/transfer-strategies/LICENSE.md delete mode 100644 tests/AaveV3BatchTests.t.sol rename tests/{ => deployments}/AaveV3BatchDeployment.t.sol (62%) create mode 100644 tests/deployments/AaveV3BatchTests.t.sol rename tests/{ => deployments}/AaveV3PermissionsTest.t.sol (86%) rename tests/{ => deployments}/DeploymentsGasLimits.t.sol (54%) rename tests/{periphery => extensions/paraswap-adapters}/ParaswapAdapters.t.sol (95%) create mode 100644 tests/extensions/static-a-token/StataOracle.t.sol create mode 100644 tests/extensions/static-a-token/StaticATokenLM.t.sol create mode 100644 tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol create mode 100644 tests/extensions/static-a-token/StaticATokenNoLM.t.sol create mode 100644 tests/extensions/static-a-token/TestBase.sol create mode 100644 tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol create mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol rename tests/{periphery => helpers}/WrappedTokenGateway.t.sol (95%) rename tests/{core => misc}/AaveOracle.t.sol (95%) rename tests/{core => misc}/PriceOracleSentinel.t.sol (89%) rename tests/{core => misc/aave-upgradeability}/InitializableImmutableAdminUpgradeabilityProxy.t.sol (96%) rename tests/{core => misc/rates}/RateStrategy.t.sol (99%) rename tests/{core => misc/rates}/RatesOverflow.t.sol (83%) rename tests/{core => misc/rates}/ZeroInteresRateStrategy.t.sol (86%) rename tests/{periphery => }/mocks/StakeMock.sol (100%) rename tests/{core => protocol/configuration}/ACLManager.t.sol (96%) rename tests/{core => protocol/configuration}/AddressesProviderRegistry.t.sol (97%) rename tests/{core => protocol/configuration}/PoolAddressesProvider.t.sol (95%) rename tests/{core => protocol/libraries/logic}/BridgeLogic.t.sol (92%) rename tests/{core => protocol/libraries/logic}/PoolLogic.initReserves.edge.t.sol (94%) rename tests/{core => protocol/libraries/math}/MathUtils.t.sol (88%) rename tests/{core => protocol/libraries/math}/PercentageMath.t.sol (89%) rename tests/{core => protocol/libraries/math}/WadRayMath.t.sol (97%) rename tests/{core => protocol/pool}/L2Pool.t.sol (92%) rename tests/{core => protocol/pool}/Pool.Borrow.t.sol (95%) rename tests/{core => protocol/pool}/Pool.FlashLoans.t.sol (92%) rename tests/{core => protocol/pool}/Pool.Liquidations.t.sol (96%) rename tests/{core => protocol/pool}/Pool.Repay.t.sol (95%) rename tests/{core => protocol/pool}/Pool.Supply.t.sol (95%) rename tests/{core => protocol/pool}/Pool.Withdraw.t.sol (97%) rename tests/{core => protocol/pool}/Pool.t.sol (97%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.ACLModifiers.t.sol (97%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.borrowCaps.t.sol (93%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.eMode.sol (96%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.initReserves.t.sol (94%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.liquidationFee.t.sol (94%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.pendingLTV.t.sol (92%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.reserveRiskConfig.t.sol (98%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.supplyCaps.t.sol (94%) rename tests/{core => protocol/pool/pool-configurator}/PoolConfigurator.upgradeabilty.t.sol (81%) rename tests/{core => protocol/tokenization}/ATokenEdgeCases.t.sol (95%) rename tests/{core => protocol/tokenization}/ATokenEvents.t.sol (96%) rename tests/{core => protocol/tokenization}/ATokenModifiers.t.sol (85%) rename tests/{core => protocol/tokenization}/ATokenPermit.t.sol (96%) rename tests/{core => protocol/tokenization}/ATokenRepay.t.sol (91%) rename tests/{core => protocol/tokenization}/ATokenRescueTokens.sol (90%) rename tests/{core => protocol/tokenization}/ATokenTransfers.t.sol (95%) rename tests/{core => protocol/tokenization}/ScaledBalanceTokenBase.t.sol (94%) rename tests/{core => protocol/tokenization}/StableDebtToken.t.sol (96%) rename tests/{core => protocol/tokenization}/VariableDebtToken.t.sol (96%) rename tests/{periphery => rewards}/EmissionsManager.t.sol (76%) rename tests/{periphery => rewards}/RewardsController.t.sol (94%) rename tests/{periphery => rewards}/StakedTokenTransferStrategy.t.sol (94%) delete mode 100644 tests/utils/ConfigEngineDeployer.sol create mode 100644 tests/utils/SigUtils.sol diff --git a/certora/applyHarness.patch b/certora/applyHarness.patch index 62c1705e..06b4e1ca 100644 --- a/certora/applyHarness.patch +++ b/certora/applyHarness.patch @@ -1,22 +1,22 @@ -diff -ruN core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol ---- core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol 2024-03-27 12:57:15.497294747 +0200 -+++ core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol 2024-03-27 13:08:22.155984803 +0200 +diff -ruN contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol +--- contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol 2024-03-27 12:57:15.497294747 +0200 ++++ contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol 2024-03-27 13:08:22.155984803 +0200 @@ -34,7 +34,7 @@ } - + /// @inheritdoc IScaledBalanceToken - function scaledBalanceOf(address user) external view override returns (uint256) { + function scaledBalanceOf(address user) public view override returns (uint256) { return super.balanceOf(user); } - -diff -ruN core/instances/ATokenInstance.sol core/instances/ATokenInstance.sol ---- core/instances/ATokenInstance.sol 2024-03-27 12:57:15.497294747 +0200 -+++ core/instances/ATokenInstance.sol 2024-03-27 13:14:17.971198372 +0200 + +diff -ruN contracts/instances/ATokenInstance.sol contracts/instances/ATokenInstance.sol +--- contracts/instances/ATokenInstance.sol 2024-03-27 12:57:15.497294747 +0200 ++++ contracts/instances/ATokenInstance.sol 2024-03-27 13:14:17.971198372 +0200 @@ -35,15 +35,15 @@ - + _domainSeparator = _calculateDomainSeparator(); - + - emit Initialized( - underlyingAsset, - address(POOL), diff --git a/certora/conf/NEW-pool-no-summarizations.conf b/certora/conf/NEW-pool-no-summarizations.conf index 11f62350..cd2365aa 100644 --- a/certora/conf/NEW-pool-no-summarizations.conf +++ b/certora/conf/NEW-pool-no-summarizations.conf @@ -4,13 +4,13 @@ "certora/harness/PoolHarness.sol", "certora/harness/StableDebtTokenHarness.sol", "certora/harness/SimpleERC20.sol", - "src/core/instances/VariableDebtTokenInstance.sol", - "src/core/contracts/misc/AaveProtocolDataProvider.sol", - "src/core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol", - "src/core/contracts/protocol/configuration/ACLManager.sol", - "src/core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol", - "src/core/contracts/protocol/configuration/PriceOracleSentinel.sol", - "src/core/contracts/protocol/configuration/PoolAddressesProvider.sol", + "src/contracts/instances/VariableDebtTokenInstance.sol", + "src/contracts/helpers/AaveProtocolDataProvider.sol", + "src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol", + "src/contracts/protocol/configuration/ACLManager.sol", + "src/contracts/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol", + "src/contracts/misc/PriceOracleSentinel.sol", + "src/contracts/protocol/configuration/PoolAddressesProvider.sol", ], "link": [ "ATokenHarness:POOL=PoolHarness", diff --git a/certora/conf/NEW-pool-simple-properties.conf b/certora/conf/NEW-pool-simple-properties.conf index 96a78c78..e5606325 100644 --- a/certora/conf/NEW-pool-simple-properties.conf +++ b/certora/conf/NEW-pool-simple-properties.conf @@ -4,11 +4,11 @@ "certora/harness/PoolHarness.sol", "certora/harness/StableDebtTokenHarness.sol", "certora/harness/SimpleERC20.sol", - "src/core/instances/VariableDebtTokenInstance.sol", - "src/core/contracts/misc/AaveProtocolDataProvider.sol", - "src/core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol", - "src/core/contracts/protocol/libraries/types/DataTypes.sol", - "src/core/contracts/protocol/configuration/PoolAddressesProvider.sol", + "src/contracts/instances/VariableDebtTokenInstance.sol", + "src/contracts/helpers/AaveProtocolDataProvider.sol", + "src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol", + "src/contracts/protocol/libraries/types/DataTypes.sol", + "src/contracts/protocol/configuration/PoolAddressesProvider.sol", ], "link": [ "ATokenHarness:POOL=PoolHarness", diff --git a/certora/harness/ATokenHarness.sol b/certora/harness/ATokenHarness.sol index cc23245c..bcb5d32a 100644 --- a/certora/harness/ATokenHarness.sol +++ b/certora/harness/ATokenHarness.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.19; -import {Pool} from '../munged/core/contracts/protocol/pool/Pool.sol'; -import {ATokenInstance} from '../munged/core/instances/ATokenInstance.sol'; -import {WadRayMath} from '../munged/core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {ScaledBalanceTokenBase} from '../munged/core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol'; -import {IScaledBalanceToken} from '../munged/core/contracts/interfaces/IScaledBalanceToken.sol'; +import {Pool} from '../munged/contracts/protocol/pool/Pool.sol'; +import {ATokenInstance} from '../munged/contracts/instances/ATokenInstance.sol'; +import {WadRayMath} from '../munged/contracts/protocol/libraries/math/WadRayMath.sol'; +import {ScaledBalanceTokenBase} from '../munged/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol'; +import {IScaledBalanceToken} from '../munged/contracts/interfaces/IScaledBalanceToken.sol'; -/** +/* * @title Certora harness for Aave ERC20 AToken * * @dev Certora's harness contract for the verification of Aave ERC20 AToken. diff --git a/certora/harness/PoolHarness.sol b/certora/harness/PoolHarness.sol index 70deadf9..a914b868 100644 --- a/certora/harness/PoolHarness.sol +++ b/certora/harness/PoolHarness.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {PoolInstance} from '../munged/core/instances/PoolInstance.sol'; -import {DataTypes} from '../munged/core/contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveLogic} from '../munged/core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {IPoolAddressesProvider} from '../munged/core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {PoolInstance} from '../munged/contracts/instances/PoolInstance.sol'; +import {DataTypes} from '../munged/contracts/protocol/libraries/types/DataTypes.sol'; +import {ReserveLogic} from '../munged/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import {IPoolAddressesProvider} from '../munged/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IERC20} from '../../src/core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {ReserveConfiguration} from '../munged/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IERC20} from '../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {ReserveConfiguration} from '../munged/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; contract PoolHarness is PoolInstance { using ReserveLogic for DataTypes.ReserveData; diff --git a/certora/harness/ReserveConfigurationHarness.sol b/certora/harness/ReserveConfigurationHarness.sol index d4edade2..c4c35d96 100644 --- a/certora/harness/ReserveConfigurationHarness.sol +++ b/certora/harness/ReserveConfigurationHarness.sol @@ -1,8 +1,9 @@ +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; pragma experimental ABIEncoderV2; -import {ReserveConfiguration} from '../munged/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {DataTypes} from '../munged/core/contracts/protocol/libraries/types/DataTypes.sol'; +import {ReserveConfiguration} from '../munged/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {DataTypes} from '../munged/contracts/protocol/libraries/types/DataTypes.sol'; contract ReserveConfigurationHarness { DataTypes.ReserveConfigurationMap public reservesConfig; diff --git a/certora/harness/SimpleERC20.sol b/certora/harness/SimpleERC20.sol index 81d12bad..68733603 100644 --- a/certora/harness/SimpleERC20.sol +++ b/certora/harness/SimpleERC20.sol @@ -1,7 +1,7 @@ -// SPDX-License-Identifier: agpl-3.0 +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {IERC20} from '../munged/core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20} from '../munged/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; /** A simple ERC implementation used as the underlying_asset for the verification process. diff --git a/certora/harness/StableDebtTokenHarness.sol b/certora/harness/StableDebtTokenHarness.sol index 99ce3355..8702fe24 100644 --- a/certora/harness/StableDebtTokenHarness.sol +++ b/certora/harness/StableDebtTokenHarness.sol @@ -1,8 +1,9 @@ +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {StableDebtTokenInstance} from '../munged/core/instances/StableDebtTokenInstance.sol'; -import {IncentivizedERC20} from '../munged/core/contracts/protocol/tokenization/base/IncentivizedERC20.sol'; -import {IPool} from '../munged/core/contracts/interfaces/IPool.sol'; +import {StableDebtTokenInstance} from '../munged/contracts/instances/StableDebtTokenInstance.sol'; +import {IncentivizedERC20} from '../munged/contracts/protocol/tokenization/base/IncentivizedERC20.sol'; +import {IPool} from '../munged/contracts/interfaces/IPool.sol'; contract StableDebtTokenHarness is StableDebtTokenInstance { constructor(IPool pool) public StableDebtTokenInstance(pool) {} diff --git a/certora/harness/SymbolicPriceOracle.sol b/certora/harness/SymbolicPriceOracle.sol index b90e21dd..d268e5d0 100644 --- a/certora/harness/SymbolicPriceOracle.sol +++ b/certora/harness/SymbolicPriceOracle.sol @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {IPriceOracleGetter} from '../munged/interfaces/IPriceOracleGetter.sol'; +import {IPriceOracleGetter} from '../munged/contracts/interfaces/IPriceOracleGetter.sol'; contract SymbolicPriceOracle is IPriceOracleGetter { address public base; diff --git a/certora/harness/UserConfigurationHarness.sol b/certora/harness/UserConfigurationHarness.sol index 4c82a29b..3f1637ea 100644 --- a/certora/harness/UserConfigurationHarness.sol +++ b/certora/harness/UserConfigurationHarness.sol @@ -1,9 +1,10 @@ +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; pragma experimental ABIEncoderV2; -import {UserConfiguration} from '../munged/core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from '../munged/core/contracts/protocol/libraries/types/DataTypes.sol'; -import {PoolStorage} from '../munged/core/contracts/protocol/pool/PoolStorage.sol'; +import {UserConfiguration} from '../munged/contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import {DataTypes} from '../munged/contracts/protocol/libraries/types/DataTypes.sol'; +import {PoolStorage} from '../munged/contracts/protocol/pool/PoolStorage.sol'; /* A wrapper contract for calling functions from the library UserConfiguration. diff --git a/certora/harness/VariableDebtTokenHarness.sol b/certora/harness/VariableDebtTokenHarness.sol index 33da454f..ca2696a6 100644 --- a/certora/harness/VariableDebtTokenHarness.sol +++ b/certora/harness/VariableDebtTokenHarness.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {VariableDebtTokenInstance} from '../munged/core/instances/VariableDebtTokenInstance.sol'; -import {WadRayMath} from '../munged/core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {IPool} from '../munged/core/contracts/interfaces/IPool.sol'; +import {VariableDebtTokenInstance} from '../munged/contracts/instances/VariableDebtTokenInstance.sol'; +import {WadRayMath} from '../munged/contracts/protocol/libraries/math/WadRayMath.sol'; +import {IPool} from '../munged/contracts/interfaces/IPool.sol'; contract VariableDebtTokenHarness is VariableDebtTokenInstance { using WadRayMath for uint256; diff --git a/scripts/misc/DeployAaveV3MarketBatchedBase.sol b/scripts/misc/DeployAaveV3MarketBatchedBase.sol index e6fddd33..961b0f38 100644 --- a/scripts/misc/DeployAaveV3MarketBatchedBase.sol +++ b/scripts/misc/DeployAaveV3MarketBatchedBase.sol @@ -25,7 +25,7 @@ abstract contract DeployAaveV3MarketBatchedBase is DeployUtils, MarketInput, Scr (roles, config, flags, report) = _getMarketInput(msg.sender); - _loadWarnings(config); + _loadWarnings(config, flags); vm.startBroadcast(); report = AaveV3BatchOrchestration.deployAaveV3(msg.sender, roles, config, flags, report); @@ -38,12 +38,20 @@ abstract contract DeployAaveV3MarketBatchedBase is DeployUtils, MarketInput, Scr metadataReporter.writeJsonReportMarket(report); } - function _loadWarnings(MarketConfig memory config) internal view { + function _loadWarnings(MarketConfig memory config, DeployFlags memory flags) internal view { if (config.paraswapAugustusRegistry == address(0)) { console.log( 'Warning: Paraswap Adapters will be skipped at deployment due missing config.paraswapAugustusRegistry' ); } + if ( + (flags.l2 && + (config.l2SequencerUptimeFeed == address(0) || config.l2PriceOracleSentinelGracePeriod == 0)) + ) { + console.log( + 'Warning: L2 Sequencer uptime feed wont be set at deployment due missing config.l2SequencerUptimeFeed config.l2PriceOracleSentinelGracePeriod' + ); + } if ( config.networkBaseTokenPriceInUsdProxyAggregator == address(0) || config.marketReferenceCurrencyPriceInUsdProxyAggregator == address(0) diff --git a/scripts/misc/LibraryPreCompileOne.sol b/scripts/misc/LibraryPreCompileOne.sol index 502b5cdf..746a7920 100644 --- a/scripts/misc/LibraryPreCompileOne.sol +++ b/scripts/misc/LibraryPreCompileOne.sol @@ -71,16 +71,16 @@ contract LibraryPreCompileOne is FfiUtils, Script, DeployUtils { return string( abi.encodePacked( - 'aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol:BorrowLogic:', + 'src/contracts/protocol/libraries/logic/BorrowLogic.sol:BorrowLogic:', vm.toString(report.borrowLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol:BridgeLogic:', + 'src/contracts/protocol/libraries/logic/BridgeLogic.sol:BridgeLogic:', vm.toString(report.bridgeLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol:ConfiguratorLogic:', + 'src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol:ConfiguratorLogic:', vm.toString(report.configuratorLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol:EModeLogic:', + 'src/contracts/protocol/libraries/logic/EModeLogic.sol:EModeLogic:', vm.toString(report.eModeLogic) ) ); diff --git a/scripts/misc/LibraryPreCompileTwo.sol b/scripts/misc/LibraryPreCompileTwo.sol index cab49cec..9b381a66 100644 --- a/scripts/misc/LibraryPreCompileTwo.sol +++ b/scripts/misc/LibraryPreCompileTwo.sol @@ -71,16 +71,16 @@ contract LibraryPreCompileTwo is FfiUtils, Script, DeployUtils { string( abi.encodePacked( ',', - 'aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol:FlashLoanLogic:', + 'src/contracts/protocol/libraries/logic/FlashLoanLogic.sol:FlashLoanLogic:', vm.toString(report.flashLoanLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol:LiquidationLogic:', + 'src/contracts/protocol/libraries/logic/LiquidationLogic.sol:LiquidationLogic:', vm.toString(report.liquidationLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol:PoolLogic:', + 'src/contracts/protocol/libraries/logic/PoolLogic.sol:PoolLogic:', vm.toString(report.poolLogic), ',', - 'aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol:SupplyLogic:', + 'src/contracts/protocol/libraries/logic/SupplyLogic.sol:SupplyLogic:', vm.toString(report.supplyLogic) ) ); diff --git a/src/core/contracts/dependencies/chainlink/AggregatorInterface.sol b/src/contracts/dependencies/chainlink/AggregatorInterface.sol similarity index 100% rename from src/core/contracts/dependencies/chainlink/AggregatorInterface.sol rename to src/contracts/dependencies/chainlink/AggregatorInterface.sol diff --git a/src/core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol b/src/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol similarity index 100% rename from src/core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol rename to src/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol diff --git a/src/periphery/contracts/dependencies/openzeppelin/ReentrancyGuard.sol b/src/contracts/dependencies/openzeppelin/ReentrancyGuard.sol similarity index 100% rename from src/periphery/contracts/dependencies/openzeppelin/ReentrancyGuard.sol rename to src/contracts/dependencies/openzeppelin/ReentrancyGuard.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol b/src/contracts/dependencies/openzeppelin/contracts/AccessControl.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol rename to src/contracts/dependencies/openzeppelin/contracts/AccessControl.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/Address.sol b/src/contracts/dependencies/openzeppelin/contracts/Address.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/Address.sol rename to src/contracts/dependencies/openzeppelin/contracts/Address.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/Context.sol b/src/contracts/dependencies/openzeppelin/contracts/Context.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/Context.sol rename to src/contracts/dependencies/openzeppelin/contracts/Context.sol diff --git a/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol b/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol new file mode 100644 index 00000000..e58805c6 --- /dev/null +++ b/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) +pragma solidity ^0.8.0; + +/** + * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. + * + * These functions can be used to verify that a message was signed by the holder + * of the private keys of a given address. + */ +library ECDSA { + enum RecoverError { + NoError, + InvalidSignature, + InvalidSignatureLength, + InvalidSignatureS + } + + /** + * @dev The signature derives the `address(0)`. + */ + error ECDSAInvalidSignature(); + + /** + * @dev The signature has an invalid length. + */ + error ECDSAInvalidSignatureLength(uint256 length); + + /** + * @dev The signature has an S value that is in the upper half order. + */ + error ECDSAInvalidSignatureS(bytes32 s); + + /** + * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not + * return address(0) without also returning an error description. Errors are documented using an enum (error type) + * and a bytes32 providing additional information about the error. + * + * If no error is returned, then the address can be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + * + * Documentation for signature generation: + * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] + * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] + */ + function tryRecover( + bytes32 hash, + bytes memory signature + ) internal pure returns (address, RecoverError, bytes32) { + if (signature.length == 65) { + bytes32 r; + bytes32 s; + uint8 v; + // ecrecover takes the signature parameters, and the only way to get them + // currently is to use assembly. + /// @solidity memory-safe-assembly + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + return tryRecover(hash, v, r, s); + } else { + return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); + } + } + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature`. This address can then be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + */ + function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. + * + * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] + */ + function tryRecover( + bytes32 hash, + bytes32 r, + bytes32 vs + ) internal pure returns (address, RecoverError, bytes32) { + unchecked { + bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); + // We do not check for an overflow here since the shift operation results in 0 or 1. + uint8 v = uint8((uint256(vs) >> 255) + 27); + return tryRecover(hash, v, r, s); + } + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. + */ + function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function tryRecover( + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s + ) internal pure returns (address, RecoverError, bytes32) { + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + return (address(0), RecoverError.InvalidSignatureS, s); + } + + // If the signature is valid (and not malleable), return the signer address + address signer = ecrecover(hash, v, r, s); + if (signer == address(0)) { + return (address(0), RecoverError.InvalidSignature, bytes32(0)); + } + + return (signer, RecoverError.NoError, bytes32(0)); + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. + */ + function _throwError(RecoverError error, bytes32 errorArg) private pure { + if (error == RecoverError.NoError) { + return; // no error: do nothing + } else if (error == RecoverError.InvalidSignature) { + revert ECDSAInvalidSignature(); + } else if (error == RecoverError.InvalidSignatureLength) { + revert ECDSAInvalidSignatureLength(uint256(errorArg)); + } else if (error == RecoverError.InvalidSignatureS) { + revert ECDSAInvalidSignatureS(errorArg); + } + } +} diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/ERC165.sol b/src/contracts/dependencies/openzeppelin/contracts/ERC165.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/ERC165.sol rename to src/contracts/dependencies/openzeppelin/contracts/ERC165.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/ERC20.sol b/src/contracts/dependencies/openzeppelin/contracts/ERC20.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/ERC20.sol rename to src/contracts/dependencies/openzeppelin/contracts/ERC20.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol b/src/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol rename to src/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/IERC165.sol b/src/contracts/dependencies/openzeppelin/contracts/IERC165.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/IERC165.sol rename to src/contracts/dependencies/openzeppelin/contracts/IERC165.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/IERC20.sol b/src/contracts/dependencies/openzeppelin/contracts/IERC20.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/IERC20.sol rename to src/contracts/dependencies/openzeppelin/contracts/IERC20.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol b/src/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol rename to src/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/Ownable.sol b/src/contracts/dependencies/openzeppelin/contracts/Ownable.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/Ownable.sol rename to src/contracts/dependencies/openzeppelin/contracts/Ownable.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol b/src/contracts/dependencies/openzeppelin/contracts/SafeCast.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol rename to src/contracts/dependencies/openzeppelin/contracts/SafeCast.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol b/src/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol rename to src/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol b/src/contracts/dependencies/openzeppelin/contracts/SafeMath.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol rename to src/contracts/dependencies/openzeppelin/contracts/SafeMath.sol diff --git a/src/core/contracts/dependencies/openzeppelin/contracts/Strings.sol b/src/contracts/dependencies/openzeppelin/contracts/Strings.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/contracts/Strings.sol rename to src/contracts/dependencies/openzeppelin/contracts/Strings.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol b/src/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol diff --git a/src/core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol b/src/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol similarity index 100% rename from src/core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol rename to src/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol diff --git a/src/contracts/dependencies/solmate/ERC20.sol b/src/contracts/dependencies/solmate/ERC20.sol new file mode 100644 index 00000000..47d7b549 --- /dev/null +++ b/src/contracts/dependencies/solmate/ERC20.sol @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity >=0.8.0; + +import {ECDSA} from '../openzeppelin/contracts/ECDSA.sol'; + +/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) +/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) +/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. +abstract contract ERC20 { + bytes32 public constant PERMIT_TYPEHASH = + keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); + + /* ////////////////////////////////////////////////////////////// + EVENTS + ////////////////////////////////////////////////////////////// */ + + event Transfer(address indexed from, address indexed to, uint256 amount); + + event Approval(address indexed owner, address indexed spender, uint256 amount); + + /* ////////////////////////////////////////////////////////////// + METADATA STORAGE + ////////////////////////////////////////////////////////////// */ + + string public name; + + string public symbol; + + uint8 public decimals; + + /* ////////////////////////////////////////////////////////////// + ERC20 STORAGE + ////////////////////////////////////////////////////////////// */ + + uint256 public totalSupply; + + mapping(address => uint256) public balanceOf; + + mapping(address => mapping(address => uint256)) public allowance; + + /* ////////////////////////////////////////////////////////////// + EIP-2612 STORAGE + ////////////////////////////////////////////////////////////// */ + + mapping(address => uint256) public nonces; + + /* ////////////////////////////////////////////////////////////// + CONSTRUCTOR + ////////////////////////////////////////////////////////////// */ + + constructor(string memory _name, string memory _symbol, uint8 _decimals) { + name = _name; + symbol = _symbol; + decimals = _decimals; + } + + /* ////////////////////////////////////////////////////////////// + ERC20 LOGIC + ////////////////////////////////////////////////////////////// */ + + function approve(address spender, uint256 amount) public virtual returns (bool) { + allowance[msg.sender][spender] = amount; + + emit Approval(msg.sender, spender, amount); + + return true; + } + + function transfer(address to, uint256 amount) public virtual returns (bool) { + _beforeTokenTransfer(msg.sender, to, amount); + balanceOf[msg.sender] -= amount; + + // Cannot overflow because the sum of all user + // balances can't exceed the max uint256 value. + unchecked { + balanceOf[to] += amount; + } + + emit Transfer(msg.sender, to, amount); + + return true; + } + + function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) { + _beforeTokenTransfer(from, to, amount); + uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. + + if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; + + balanceOf[from] -= amount; + + // Cannot overflow because the sum of all user + // balances can't exceed the max uint256 value. + unchecked { + balanceOf[to] += amount; + } + + emit Transfer(from, to, amount); + + return true; + } + + /* ////////////////////////////////////////////////////////////// + EIP-2612 LOGIC + ////////////////////////////////////////////////////////////// */ + + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual { + require(deadline >= block.timestamp, 'PERMIT_DEADLINE_EXPIRED'); + + // Unchecked because the only math done is incrementing + // the owner's nonce which cannot realistically overflow. + unchecked { + address signer = ECDSA.recover( + keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR(), + keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) + ) + ), + v, + r, + s + ); + + require(signer == owner, 'INVALID_SIGNER'); + + allowance[signer][spender] = value; + } + + emit Approval(owner, spender, value); + } + + function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { + return computeDomainSeparator(); + } + + function computeDomainSeparator() internal view virtual returns (bytes32) { + return + keccak256( + abi.encode( + keccak256( + 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' + ), + keccak256(bytes(name)), + keccak256('1'), + block.chainid, + address(this) + ) + ); + } + + /* ////////////////////////////////////////////////////////////// + INTERNAL MINT/BURN LOGIC + ////////////////////////////////////////////////////////////// */ + + function _mint(address to, uint256 amount) internal virtual { + _beforeTokenTransfer(address(0), to, amount); + totalSupply += amount; + + // Cannot overflow because the sum of all user + // balances can't exceed the max uint256 value. + unchecked { + balanceOf[to] += amount; + } + + emit Transfer(address(0), to, amount); + } + + function _burn(address from, uint256 amount) internal virtual { + _beforeTokenTransfer(from, address(0), amount); + balanceOf[from] -= amount; + + // Cannot underflow because a user's balance + // will never be larger than the total supply. + unchecked { + totalSupply -= amount; + } + + emit Transfer(from, address(0), amount); + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be to transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} +} diff --git a/src/core/contracts/dependencies/weth/WETH9.sol b/src/contracts/dependencies/weth/WETH9.sol similarity index 100% rename from src/core/contracts/dependencies/weth/WETH9.sol rename to src/contracts/dependencies/weth/WETH9.sol diff --git a/src/periphery/contracts/adapters/paraswap/AaveParaSwapFeeClaimer.sol b/src/contracts/extensions/paraswap-adapters/AaveParaSwapFeeClaimer.sol similarity index 95% rename from src/periphery/contracts/adapters/paraswap/AaveParaSwapFeeClaimer.sol rename to src/contracts/extensions/paraswap-adapters/AaveParaSwapFeeClaimer.sol index 5a0bb34a..2d47b182 100644 --- a/src/periphery/contracts/adapters/paraswap/AaveParaSwapFeeClaimer.sol +++ b/src/contracts/extensions/paraswap-adapters/AaveParaSwapFeeClaimer.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {IFeeClaimer} from './interfaces/IFeeClaimer.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title AaveParaSwapFeeClaimer diff --git a/src/periphery/contracts/adapters/paraswap/BaseParaSwapAdapter.sol b/src/contracts/extensions/paraswap-adapters/BaseParaSwapAdapter.sol similarity index 79% rename from src/periphery/contracts/adapters/paraswap/BaseParaSwapAdapter.sol rename to src/contracts/extensions/paraswap-adapters/BaseParaSwapAdapter.sol index 247f4437..45988edf 100644 --- a/src/periphery/contracts/adapters/paraswap/BaseParaSwapAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/BaseParaSwapAdapter.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {FlashLoanSimpleReceiverBase} from 'aave-v3-core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IERC20WithPermit} from 'aave-v3-core/contracts/interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPriceOracleGetter} from 'aave-v3-core/contracts/interfaces/IPriceOracleGetter.sol'; -import {SafeMath} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol'; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; +import {FlashLoanSimpleReceiverBase} from '../../misc/flashloan/base/FlashLoanSimpleReceiverBase.sol'; +import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; +import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; +import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; /** * @title BaseParaSwapAdapter diff --git a/src/periphery/contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol b/src/contracts/extensions/paraswap-adapters/BaseParaSwapBuyAdapter.sol similarity index 89% rename from src/periphery/contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol rename to src/contracts/extensions/paraswap-adapters/BaseParaSwapBuyAdapter.sol index 9fcfdc11..5d9db556 100644 --- a/src/periphery/contracts/adapters/paraswap/BaseParaSwapBuyAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/BaseParaSwapBuyAdapter.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {SafeERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {SafeMath} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; +import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol'; diff --git a/src/periphery/contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol b/src/contracts/extensions/paraswap-adapters/BaseParaSwapSellAdapter.sol similarity index 89% rename from src/periphery/contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol rename to src/contracts/extensions/paraswap-adapters/BaseParaSwapSellAdapter.sol index 8086a5c0..5292a3b8 100644 --- a/src/periphery/contracts/adapters/paraswap/BaseParaSwapSellAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/BaseParaSwapSellAdapter.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {SafeERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {SafeMath} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; +import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {BaseParaSwapAdapter} from './BaseParaSwapAdapter.sol'; diff --git a/src/periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol b/src/contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol similarity index 94% rename from src/periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol rename to src/contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol index 7852f16e..db855a33 100644 --- a/src/periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IERC20WithPermit} from 'aave-v3-core/contracts/interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {SafeERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {SafeMath} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; diff --git a/src/periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol b/src/contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol similarity index 92% rename from src/periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol rename to src/contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol index f776c757..6cfb3f22 100644 --- a/src/periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {IERC20WithPermit} from 'aave-v3-core/contracts/interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {SafeERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {SafeMath} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol'; +import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {BaseParaSwapBuyAdapter} from './BaseParaSwapBuyAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; diff --git a/src/periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol b/src/contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol similarity index 87% rename from src/periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol rename to src/contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol index 499c7d6a..2522ee88 100644 --- a/src/periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol +++ b/src/contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IERC20WithPermit} from 'aave-v3-core/contracts/interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol'; import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol'; -import {SafeERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol'; import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol'; diff --git a/src/periphery/contracts/adapters/paraswap/interfaces/IFeeClaimer.sol b/src/contracts/extensions/paraswap-adapters/interfaces/IFeeClaimer.sol similarity index 97% rename from src/periphery/contracts/adapters/paraswap/interfaces/IFeeClaimer.sol rename to src/contracts/extensions/paraswap-adapters/interfaces/IFeeClaimer.sol index 5fd9d59a..161bcd51 100644 --- a/src/periphery/contracts/adapters/paraswap/interfaces/IFeeClaimer.sol +++ b/src/contracts/extensions/paraswap-adapters/interfaces/IFeeClaimer.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: ISC pragma solidity ^0.8.0; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; interface IFeeClaimer { /** diff --git a/src/periphery/contracts/adapters/paraswap/interfaces/IParaSwapAugustus.sol b/src/contracts/extensions/paraswap-adapters/interfaces/IParaSwapAugustus.sol similarity index 100% rename from src/periphery/contracts/adapters/paraswap/interfaces/IParaSwapAugustus.sol rename to src/contracts/extensions/paraswap-adapters/interfaces/IParaSwapAugustus.sol diff --git a/src/periphery/contracts/adapters/paraswap/interfaces/IParaSwapAugustusRegistry.sol b/src/contracts/extensions/paraswap-adapters/interfaces/IParaSwapAugustusRegistry.sol similarity index 100% rename from src/periphery/contracts/adapters/paraswap/interfaces/IParaSwapAugustusRegistry.sol rename to src/contracts/extensions/paraswap-adapters/interfaces/IParaSwapAugustusRegistry.sol diff --git a/src/contracts/extensions/static-a-token/README.md b/src/contracts/extensions/static-a-token/README.md new file mode 100644 index 00000000..9ced57a6 --- /dev/null +++ b/src/contracts/extensions/static-a-token/README.md @@ -0,0 +1,38 @@ +# stataToken - Static aToken vault/wrapper + +

+ +

+ +## About + +The static-a-token contains an [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) generic token vault/wrapper for all Aave v3 pools. + +## Features + +- **Full [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) compatibility.** +- **Accounting for any potential liquidity mining rewards.** Let’s say some team of the Aave ecosystem (or the Aave community itself) decides to incentivize deposits of USDC on Aave v3 Ethereum. By holding `stataUSDC`, the user will still be eligible for those incentives. + It is important to highlight that while currently the wrapper supports infinite reward tokens by design (e.g. AAVE incentivizing stETH & Lido incentivizing stETH as well), each reward needs to be permissionlessly registered which bears some [⁽¹⁾](#limitations). +- **Meta-transactions support.** To enable interfaces to offer gas-less transactions to deposit/withdraw on the wrapper/Aave protocol (also supported on Aave v3). Including permit() for transfers of the `stataAToken` itself. +- **Upgradable by the Aave governance.** Similar to other contracts of the Aave ecosystem, the Level 1 executor (short executor) will be able to add new features to the deployed instances of the `stataTokens`. +- **Powered by a stataToken Factory.** Whenever a token will be listed on Aave v3, anybody will be able to call the stataToken Factory to deploy an instance for the new asset, permissionless, but still assuring the code used and permissions are properly configured without any extra headache. + +See [IStaticATokenLM.sol](./interfaces/IStaticATokenLM.sol) for detailed method documentation. + +## Deployed Addresses + +The staticATokenFactory is deployed for all major Aave v3 pools. +An up to date address can be fetched from the respective [address-book pool library](https://github.com/bgd-labs/aave-address-book/blob/main/src/AaveV3Ethereum.sol). + +## Limitations + +The `stataToken` is not natively integrated into the aave protocol and therefore cannot hook into the emissionManager. +This means a `reward` added **after** `statToken` creation needs to be registered manually on the token via the permissionless `refreshRewardTokens()` method. +As this process is not currently automated users might be missing out on rewards until the method is called. + +## Security procedures + +For this project, the security procedures applied/being finished are: + +- The test suite of the codebase itself. +- Certora audit/property checking for all the dynamics of the `stataToken`, including respecting all the specs of [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626). diff --git a/src/contracts/extensions/static-a-token/StataOracle.sol b/src/contracts/extensions/static-a-token/StataOracle.sol new file mode 100644 index 00000000..50715593 --- /dev/null +++ b/src/contracts/extensions/static-a-token/StataOracle.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {IAaveOracle} from '../../interfaces/IAaveOracle.sol'; +import {IStataOracle} from './interfaces/IStataOracle.sol'; +import {IERC4626} from './interfaces/IERC4626.sol'; + +/** + * @title StataOracle + * @author BGD Labs + * @notice Contract to get asset prices of stata tokens + */ +contract StataOracle is IStataOracle { + /// @inheritdoc IStataOracle + IPool public immutable POOL; + /// @inheritdoc IStataOracle + IAaveOracle public immutable AAVE_ORACLE; + + constructor(IPoolAddressesProvider provider) { + POOL = IPool(provider.getPool()); + AAVE_ORACLE = IAaveOracle(provider.getPriceOracle()); + } + + /// @inheritdoc IStataOracle + function getAssetPrice(address asset) public view returns (uint256) { + address underlying = IERC4626(asset).asset(); + return + (AAVE_ORACLE.getAssetPrice(underlying) * POOL.getReserveNormalizedIncome(underlying)) / 1e27; + } + + /// @inheritdoc IStataOracle + function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory) { + uint256[] memory prices = new uint256[](assets.length); + for (uint256 i = 0; i < assets.length; i++) { + prices[i] = getAssetPrice(assets[i]); + } + return prices; + } +} diff --git a/src/contracts/extensions/static-a-token/StaticATokenErrors.sol b/src/contracts/extensions/static-a-token/StaticATokenErrors.sol new file mode 100644 index 00000000..bec417df --- /dev/null +++ b/src/contracts/extensions/static-a-token/StaticATokenErrors.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +library StaticATokenErrors { + string public constant INVALID_OWNER = '1'; + string public constant INVALID_EXPIRATION = '2'; + string public constant INVALID_SIGNATURE = '3'; + string public constant INVALID_DEPOSITOR = '4'; + string public constant INVALID_RECIPIENT = '5'; + string public constant INVALID_CLAIMER = '6'; + string public constant ONLY_ONE_AMOUNT_FORMAT_ALLOWED = '7'; + string public constant INVALID_ZERO_AMOUNT = '8'; + string public constant REWARD_NOT_INITIALIZED = '9'; +} diff --git a/src/contracts/extensions/static-a-token/StaticATokenFactory.sol b/src/contracts/extensions/static-a-token/StaticATokenFactory.sol new file mode 100644 index 00000000..bf307197 --- /dev/null +++ b/src/contracts/extensions/static-a-token/StaticATokenFactory.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {IPool, DataTypes} from '../../interfaces/IPool.sol'; +import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; +import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; +import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol'; +import {StaticATokenLM} from './StaticATokenLM.sol'; +import {IStaticATokenFactory} from './interfaces/IStaticATokenFactory.sol'; + +/** + * @title StaticATokenFactory + * @notice Factory contract that keeps track of all deployed static aToken wrappers for a specified pool. + * This registry also acts as a factory, allowing to deploy new static aTokens on demand. + * There can only be one static aToken per underlying on the registry at a time. + * @author BGD labs + */ +contract StaticATokenFactory is Initializable, IStaticATokenFactory { + IPool public immutable POOL; + address public immutable ADMIN; + ITransparentProxyFactory public immutable TRANSPARENT_PROXY_FACTORY; + address public immutable STATIC_A_TOKEN_IMPL; + + mapping(address => address) internal _underlyingToStaticAToken; + address[] internal _staticATokens; + + event StaticTokenCreated(address indexed staticAToken, address indexed underlying); + + constructor( + IPool pool, + address proxyAdmin, + ITransparentProxyFactory transparentProxyFactory, + address staticATokenImpl + ) { + POOL = pool; + ADMIN = proxyAdmin; + TRANSPARENT_PROXY_FACTORY = transparentProxyFactory; + STATIC_A_TOKEN_IMPL = staticATokenImpl; + } + + function initialize() external initializer {} + + ///@inheritdoc IStaticATokenFactory + function createStaticATokens(address[] memory underlyings) external returns (address[] memory) { + address[] memory staticATokens = new address[](underlyings.length); + for (uint256 i = 0; i < underlyings.length; i++) { + address cachedStaticAToken = _underlyingToStaticAToken[underlyings[i]]; + if (cachedStaticAToken == address(0)) { + DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(underlyings[i]); + require(reserveData.aTokenAddress != address(0), 'UNDERLYING_NOT_LISTED'); + bytes memory symbol = abi.encodePacked( + 'stat', + IERC20Metadata(reserveData.aTokenAddress).symbol() + ); + address staticAToken = TRANSPARENT_PROXY_FACTORY.createDeterministic( + STATIC_A_TOKEN_IMPL, + ADMIN, + abi.encodeWithSelector( + StaticATokenLM.initialize.selector, + reserveData.aTokenAddress, + string(abi.encodePacked('Static ', IERC20Metadata(reserveData.aTokenAddress).name())), + string(symbol) + ), + bytes32(uint256(uint160(underlyings[i]))) + ); + _underlyingToStaticAToken[underlyings[i]] = staticAToken; + staticATokens[i] = staticAToken; + _staticATokens.push(staticAToken); + emit StaticTokenCreated(staticAToken, underlyings[i]); + } else { + staticATokens[i] = cachedStaticAToken; + } + } + return staticATokens; + } + + ///@inheritdoc IStaticATokenFactory + function getStaticATokens() external view returns (address[] memory) { + return _staticATokens; + } + + ///@inheritdoc IStaticATokenFactory + function getStaticAToken(address underlying) external view returns (address) { + return _underlyingToStaticAToken[underlying]; + } +} diff --git a/src/contracts/extensions/static-a-token/StaticATokenLM.sol b/src/contracts/extensions/static-a-token/StaticATokenLM.sol new file mode 100644 index 00000000..cb74ee88 --- /dev/null +++ b/src/contracts/extensions/static-a-token/StaticATokenLM.sol @@ -0,0 +1,712 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {IPool} from '../../interfaces/IPool.sol'; +import {DataTypes, ReserveConfiguration} from '../../protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IRewardsController} from '../../rewards/interfaces/IRewardsController.sol'; +import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; +import {MathUtils} from '../../protocol/libraries/math/MathUtils.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; +import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {IERC20WithPermit} from 'solidity-utils/contracts/oz-common/interfaces/IERC20WithPermit.sol'; + +import {IStaticATokenLM} from './interfaces/IStaticATokenLM.sol'; +import {IAToken} from './interfaces/IAToken.sol'; +import {ERC20} from '../../dependencies/solmate/ERC20.sol'; +import {IInitializableStaticATokenLM} from './interfaces/IInitializableStaticATokenLM.sol'; +import {StaticATokenErrors} from './StaticATokenErrors.sol'; +import {RayMathExplicitRounding, Rounding} from '../../misc/libraries/RayMathExplicitRounding.sol'; +import {IERC4626} from './interfaces/IERC4626.sol'; + +/** + * @title StaticATokenLM + * @notice Wrapper smart contract that allows to deposit tokens on the Aave protocol and receive + * a token which balance doesn't increase automatically, but uses an ever-increasing exchange rate. + * It supports claiming liquidity mining rewards from the Aave system. + * @author BGD labs + */ +contract StaticATokenLM is + Initializable, + ERC20('STATIC__aToken_IMPL', 'STATIC__aToken_IMPL', 18), + IStaticATokenLM, + IERC4626 +{ + using SafeERC20 for IERC20; + using SafeCast for uint256; + using WadRayMath for uint256; + using RayMathExplicitRounding for uint256; + + bytes32 public constant METADEPOSIT_TYPEHASH = + keccak256( + 'Deposit(address depositor,address receiver,uint256 assets,uint16 referralCode,bool depositToAave,uint256 nonce,uint256 deadline,PermitParams permit)' + ); + bytes32 public constant METAWITHDRAWAL_TYPEHASH = + keccak256( + 'Withdraw(address owner,address receiver,uint256 shares,uint256 assets,bool withdrawFromAave,uint256 nonce,uint256 deadline)' + ); + + uint256 public constant STATIC__ATOKEN_LM_REVISION = 2; + + IPool public immutable POOL; + IRewardsController public immutable INCENTIVES_CONTROLLER; + + IERC20 internal _aToken; + address internal _aTokenUnderlying; + address[] internal _rewardTokens; + mapping(address => RewardIndexCache) internal _startIndex; + mapping(address => mapping(address => UserRewardsData)) internal _userRewardsData; + + constructor(IPool pool, IRewardsController rewardsController) { + POOL = pool; + INCENTIVES_CONTROLLER = rewardsController; + } + + ///@inheritdoc IInitializableStaticATokenLM + function initialize( + address newAToken, + string calldata staticATokenName, + string calldata staticATokenSymbol + ) external initializer { + require(IAToken(newAToken).POOL() == address(POOL)); + _aToken = IERC20(newAToken); + + name = staticATokenName; + symbol = staticATokenSymbol; + decimals = IERC20Metadata(newAToken).decimals(); + + _aTokenUnderlying = IAToken(newAToken).UNDERLYING_ASSET_ADDRESS(); + IERC20(_aTokenUnderlying).forceApprove(address(POOL), type(uint256).max); + + if (INCENTIVES_CONTROLLER != IRewardsController(address(0))) { + refreshRewardTokens(); + } + + emit Initialized(newAToken, staticATokenName, staticATokenSymbol); + } + + ///@inheritdoc IStaticATokenLM + function refreshRewardTokens() public override { + address[] memory rewards = INCENTIVES_CONTROLLER.getRewardsByAsset(address(_aToken)); + for (uint256 i = 0; i < rewards.length; i++) { + _registerRewardToken(rewards[i]); + } + } + + ///@inheritdoc IStaticATokenLM + function isRegisteredRewardToken(address reward) public view override returns (bool) { + return _startIndex[reward].isRegistered; + } + + ///@inheritdoc IStaticATokenLM + function deposit( + uint256 assets, + address receiver, + uint16 referralCode, + bool depositToAave + ) external returns (uint256) { + (uint256 shares, ) = _deposit(msg.sender, receiver, 0, assets, referralCode, depositToAave); + return shares; + } + + ///@inheritdoc IStaticATokenLM + function metaDeposit( + address depositor, + address receiver, + uint256 assets, + uint16 referralCode, + bool depositToAave, + uint256 deadline, + PermitParams calldata permit, + SignatureParams calldata sigParams + ) external returns (uint256) { + require(depositor != address(0), StaticATokenErrors.INVALID_DEPOSITOR); + //solium-disable-next-line + require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); + uint256 nonce = nonces[depositor]; + + // Unchecked because the only math done is incrementing + // the owner's nonce which cannot realistically overflow. + unchecked { + bytes32 digest = keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR(), + keccak256( + abi.encode( + METADEPOSIT_TYPEHASH, + depositor, + receiver, + assets, + referralCode, + depositToAave, + nonce, + deadline, + permit + ) + ) + ) + ); + nonces[depositor] = nonce + 1; + require( + depositor == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), + StaticATokenErrors.INVALID_SIGNATURE + ); + } + // assume if deadline 0 no permit was supplied + if (permit.deadline != 0) { + try + IERC20WithPermit(depositToAave ? address(_aTokenUnderlying) : address(_aToken)).permit( + depositor, + address(this), + permit.value, + permit.deadline, + permit.v, + permit.r, + permit.s + ) + {} catch {} + } + (uint256 shares, ) = _deposit(depositor, receiver, 0, assets, referralCode, depositToAave); + return shares; + } + + ///@inheritdoc IStaticATokenLM + function metaWithdraw( + address owner, + address receiver, + uint256 shares, + uint256 assets, + bool withdrawFromAave, + uint256 deadline, + SignatureParams calldata sigParams + ) external returns (uint256, uint256) { + require(owner != address(0), StaticATokenErrors.INVALID_OWNER); + //solium-disable-next-line + require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); + uint256 nonce = nonces[owner]; + // Unchecked because the only math done is incrementing + // the owner's nonce which cannot realistically overflow. + unchecked { + bytes32 digest = keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR(), + keccak256( + abi.encode( + METAWITHDRAWAL_TYPEHASH, + owner, + receiver, + shares, + assets, + withdrawFromAave, + nonce, + deadline + ) + ) + ) + ); + nonces[owner] = nonce + 1; + require( + owner == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), + StaticATokenErrors.INVALID_SIGNATURE + ); + } + return _withdraw(owner, receiver, shares, assets, withdrawFromAave); + } + + ///@inheritdoc IERC4626 + function previewRedeem(uint256 shares) public view virtual returns (uint256) { + return _convertToAssets(shares, Rounding.DOWN); + } + + ///@inheritdoc IERC4626 + function previewMint(uint256 shares) public view virtual returns (uint256) { + return _convertToAssets(shares, Rounding.UP); + } + + ///@inheritdoc IERC4626 + function previewWithdraw(uint256 assets) public view virtual returns (uint256) { + return _convertToShares(assets, Rounding.UP); + } + + ///@inheritdoc IERC4626 + function previewDeposit(uint256 assets) public view virtual returns (uint256) { + return _convertToShares(assets, Rounding.DOWN); + } + + ///@inheritdoc IStaticATokenLM + function rate() public view returns (uint256) { + return POOL.getReserveNormalizedIncome(_aTokenUnderlying); + } + + ///@inheritdoc IStaticATokenLM + function collectAndUpdateRewards(address reward) public returns (uint256) { + if (reward == address(0)) { + return 0; + } + + address[] memory assets = new address[](1); + assets[0] = address(_aToken); + + return INCENTIVES_CONTROLLER.claimRewards(assets, type(uint256).max, address(this), reward); + } + + ///@inheritdoc IStaticATokenLM + function claimRewardsOnBehalf( + address onBehalfOf, + address receiver, + address[] memory rewards + ) external { + require( + msg.sender == onBehalfOf || msg.sender == INCENTIVES_CONTROLLER.getClaimer(onBehalfOf), + StaticATokenErrors.INVALID_CLAIMER + ); + _claimRewardsOnBehalf(onBehalfOf, receiver, rewards); + } + + ///@inheritdoc IStaticATokenLM + function claimRewards(address receiver, address[] memory rewards) external { + _claimRewardsOnBehalf(msg.sender, receiver, rewards); + } + + ///@inheritdoc IStaticATokenLM + function claimRewardsToSelf(address[] memory rewards) external { + _claimRewardsOnBehalf(msg.sender, msg.sender, rewards); + } + + ///@inheritdoc IStaticATokenLM + function getCurrentRewardsIndex(address reward) public view returns (uint256) { + if (address(reward) == address(0)) { + return 0; + } + (, uint256 nextIndex) = INCENTIVES_CONTROLLER.getAssetIndex(address(_aToken), reward); + return nextIndex; + } + + ///@inheritdoc IStaticATokenLM + function getTotalClaimableRewards(address reward) external view returns (uint256) { + if (reward == address(0)) { + return 0; + } + + address[] memory assets = new address[](1); + assets[0] = address(_aToken); + uint256 freshRewards = INCENTIVES_CONTROLLER.getUserRewards(assets, address(this), reward); + return IERC20(reward).balanceOf(address(this)) + freshRewards; + } + + ///@inheritdoc IStaticATokenLM + function getClaimableRewards(address user, address reward) external view returns (uint256) { + return _getClaimableRewards(user, reward, balanceOf[user], getCurrentRewardsIndex(reward)); + } + + ///@inheritdoc IStaticATokenLM + function getUnclaimedRewards(address user, address reward) external view returns (uint256) { + return _userRewardsData[user][reward].unclaimedRewards; + } + + ///@inheritdoc IERC4626 + function asset() external view returns (address) { + return address(_aTokenUnderlying); + } + + ///@inheritdoc IStaticATokenLM + function aToken() external view returns (IERC20) { + return _aToken; + } + + ///@inheritdoc IStaticATokenLM + function rewardTokens() external view returns (address[] memory) { + return _rewardTokens; + } + + ///@inheritdoc IERC4626 + function totalAssets() external view returns (uint256) { + return _aToken.balanceOf(address(this)); + } + + ///@inheritdoc IERC4626 + function convertToShares(uint256 assets) external view returns (uint256) { + return _convertToShares(assets, Rounding.DOWN); + } + + ///@inheritdoc IERC4626 + function convertToAssets(uint256 shares) external view returns (uint256) { + return _convertToAssets(shares, Rounding.DOWN); + } + + ///@inheritdoc IERC4626 + function maxMint(address) public view virtual returns (uint256) { + uint256 assets = maxDeposit(address(0)); + if (assets == type(uint256).max) return type(uint256).max; + return _convertToShares(assets, Rounding.DOWN); + } + + ///@inheritdoc IERC4626 + function maxWithdraw(address owner) public view virtual returns (uint256) { + uint256 shares = maxRedeem(owner); + return _convertToAssets(shares, Rounding.DOWN); + } + + ///@inheritdoc IERC4626 + function maxRedeem(address owner) public view virtual returns (uint256) { + address cachedATokenUnderlying = _aTokenUnderlying; + DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(cachedATokenUnderlying); + + // if paused or inactive users cannot withdraw underlying + if ( + !ReserveConfiguration.getActive(reserveData.configuration) || + ReserveConfiguration.getPaused(reserveData.configuration) + ) { + return 0; + } + + // otherwise users can withdraw up to the available amount + uint256 underlyingTokenBalanceInShares = _convertToShares( + IERC20(cachedATokenUnderlying).balanceOf(reserveData.aTokenAddress), + Rounding.DOWN + ); + uint256 cachedUserBalance = balanceOf[owner]; + return + underlyingTokenBalanceInShares >= cachedUserBalance + ? cachedUserBalance + : underlyingTokenBalanceInShares; + } + + ///@inheritdoc IERC4626 + function maxDeposit(address) public view virtual returns (uint256) { + DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(_aTokenUnderlying); + + // if inactive, paused or frozen users cannot deposit underlying + if ( + !ReserveConfiguration.getActive(reserveData.configuration) || + ReserveConfiguration.getPaused(reserveData.configuration) || + ReserveConfiguration.getFrozen(reserveData.configuration) + ) { + return 0; + } + + uint256 supplyCap = ReserveConfiguration.getSupplyCap(reserveData.configuration) * + (10 ** ReserveConfiguration.getDecimals(reserveData.configuration)); + // if no supply cap deposit is unlimited + if (supplyCap == 0) return type(uint256).max; + // return remaining supply cap margin + uint256 currentSupply = (IAToken(reserveData.aTokenAddress).scaledTotalSupply() + + reserveData.accruedToTreasury).rayMulRoundUp(_getNormalizedIncome(reserveData)); + return currentSupply > supplyCap ? 0 : supplyCap - currentSupply; + } + + ///@inheritdoc IERC4626 + function deposit(uint256 assets, address receiver) external virtual returns (uint256) { + (uint256 shares, ) = _deposit(msg.sender, receiver, 0, assets, 0, true); + return shares; + } + + ///@inheritdoc IERC4626 + function mint(uint256 shares, address receiver) external virtual returns (uint256) { + (, uint256 assets) = _deposit(msg.sender, receiver, shares, 0, 0, true); + + return assets; + } + + ///@inheritdoc IERC4626 + function withdraw( + uint256 assets, + address receiver, + address owner + ) external virtual returns (uint256) { + (uint256 shares, ) = _withdraw(owner, receiver, 0, assets, true); + + return shares; + } + + ///@inheritdoc IERC4626 + function redeem( + uint256 shares, + address receiver, + address owner + ) external virtual returns (uint256) { + (, uint256 assets) = _withdraw(owner, receiver, shares, 0, true); + + return assets; + } + + ///@inheritdoc IStaticATokenLM + function redeem( + uint256 shares, + address receiver, + address owner, + bool withdrawFromAave + ) external virtual returns (uint256, uint256) { + return _withdraw(owner, receiver, shares, 0, withdrawFromAave); + } + + function _deposit( + address depositor, + address receiver, + uint256 _shares, + uint256 _assets, + uint16 referralCode, + bool depositToAave + ) internal returns (uint256, uint256) { + require(receiver != address(0), StaticATokenErrors.INVALID_RECIPIENT); + require(_shares == 0 || _assets == 0, StaticATokenErrors.ONLY_ONE_AMOUNT_FORMAT_ALLOWED); + + uint256 assets = _assets; + uint256 shares = _shares; + if (shares > 0) { + if (depositToAave) { + require(shares <= maxMint(receiver), 'ERC4626: mint more than max'); + } + assets = previewMint(shares); + } else { + if (depositToAave) { + require(assets <= maxDeposit(receiver), 'ERC4626: deposit more than max'); + } + shares = previewDeposit(assets); + } + require(shares != 0, StaticATokenErrors.INVALID_ZERO_AMOUNT); + + if (depositToAave) { + address cachedATokenUnderlying = _aTokenUnderlying; + IERC20(cachedATokenUnderlying).safeTransferFrom(depositor, address(this), assets); + POOL.deposit(cachedATokenUnderlying, assets, address(this), referralCode); + } else { + _aToken.safeTransferFrom(depositor, address(this), assets); + } + + _mint(receiver, shares); + + emit Deposit(depositor, receiver, assets, shares); + + return (shares, assets); + } + + function _withdraw( + address owner, + address receiver, + uint256 _shares, + uint256 _assets, + bool withdrawFromAave + ) internal returns (uint256, uint256) { + require(receiver != address(0), StaticATokenErrors.INVALID_RECIPIENT); + require(_shares == 0 || _assets == 0, StaticATokenErrors.ONLY_ONE_AMOUNT_FORMAT_ALLOWED); + require(_shares != _assets, StaticATokenErrors.INVALID_ZERO_AMOUNT); + + uint256 assets = _assets; + uint256 shares = _shares; + + if (shares > 0) { + if (withdrawFromAave) { + require(shares <= maxRedeem(owner), 'ERC4626: redeem more than max'); + } + assets = previewRedeem(shares); + } else { + if (withdrawFromAave) { + require(assets <= maxWithdraw(owner), 'ERC4626: withdraw more than max'); + } + shares = previewWithdraw(assets); + } + + if (msg.sender != owner) { + uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. + + if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; + } + + _burn(owner, shares); + + emit Withdraw(msg.sender, receiver, owner, assets, shares); + + if (withdrawFromAave) { + POOL.withdraw(_aTokenUnderlying, assets, receiver); + } else { + _aToken.safeTransfer(receiver, assets); + } + + return (shares, assets); + } + + /** + * @notice Updates rewards for senders and receiver in a transfer (not updating rewards for address(0)) + * @param from The address of the sender of tokens + * @param to The address of the receiver of tokens + */ + function _beforeTokenTransfer(address from, address to, uint256) internal override { + for (uint256 i = 0; i < _rewardTokens.length; i++) { + address rewardToken = address(_rewardTokens[i]); + uint256 rewardsIndex = getCurrentRewardsIndex(rewardToken); + if (from != address(0)) { + _updateUser(from, rewardsIndex, rewardToken); + } + if (to != address(0) && from != to) { + _updateUser(to, rewardsIndex, rewardToken); + } + } + } + + /** + * @notice Adding the pending rewards to the unclaimed for specific user and updating user index + * @param user The address of the user to update + * @param currentRewardsIndex The current rewardIndex + * @param rewardToken The address of the reward token + */ + function _updateUser(address user, uint256 currentRewardsIndex, address rewardToken) internal { + uint256 balance = balanceOf[user]; + if (balance > 0) { + _userRewardsData[user][rewardToken].unclaimedRewards = _getClaimableRewards( + user, + rewardToken, + balance, + currentRewardsIndex + ).toUint128(); + } + _userRewardsData[user][rewardToken].rewardsIndexOnLastInteraction = currentRewardsIndex + .toUint128(); + } + + /** + * @notice Compute the pending in WAD. Pending is the amount to add (not yet unclaimed) rewards in WAD. + * @param balance The balance of the user + * @param rewardsIndexOnLastInteraction The index which was on the last interaction of the user + * @param currentRewardsIndex The current rewards index in the system + * @param assetUnit One unit of asset (10**decimals) + * @return The amount of pending rewards in WAD + */ + function _getPendingRewards( + uint256 balance, + uint256 rewardsIndexOnLastInteraction, + uint256 currentRewardsIndex, + uint256 assetUnit + ) internal pure returns (uint256) { + if (balance == 0) { + return 0; + } + return (balance * (currentRewardsIndex - rewardsIndexOnLastInteraction)) / assetUnit; + } + + /** + * @notice Compute the claimable rewards for a user + * @param user The address of the user + * @param reward The address of the reward + * @param balance The balance of the user in WAD + * @param currentRewardsIndex The current rewards index + * @return The total rewards that can be claimed by the user (if `fresh` flag true, after updating rewards) + */ + function _getClaimableRewards( + address user, + address reward, + uint256 balance, + uint256 currentRewardsIndex + ) internal view returns (uint256) { + RewardIndexCache memory rewardsIndexCache = _startIndex[reward]; + require(rewardsIndexCache.isRegistered == true, StaticATokenErrors.REWARD_NOT_INITIALIZED); + UserRewardsData memory currentUserRewardsData = _userRewardsData[user][reward]; + uint256 assetUnit = 10 ** decimals; + return + currentUserRewardsData.unclaimedRewards + + _getPendingRewards( + balance, + currentUserRewardsData.rewardsIndexOnLastInteraction == 0 + ? rewardsIndexCache.lastUpdatedIndex + : currentUserRewardsData.rewardsIndexOnLastInteraction, + currentRewardsIndex, + assetUnit + ); + } + + /** + * @notice Claim rewards on behalf of a user and send them to a receiver + * @param onBehalfOf The address to claim on behalf of + * @param rewards The addresses of the rewards + * @param receiver The address to receive the rewards + */ + function _claimRewardsOnBehalf( + address onBehalfOf, + address receiver, + address[] memory rewards + ) internal { + for (uint256 i = 0; i < rewards.length; i++) { + if (address(rewards[i]) == address(0)) { + continue; + } + uint256 currentRewardsIndex = getCurrentRewardsIndex(rewards[i]); + uint256 balance = balanceOf[onBehalfOf]; + uint256 userReward = _getClaimableRewards( + onBehalfOf, + rewards[i], + balance, + currentRewardsIndex + ); + uint256 totalRewardTokenBalance = IERC20(rewards[i]).balanceOf(address(this)); + uint256 unclaimedReward = 0; + + if (userReward > totalRewardTokenBalance) { + totalRewardTokenBalance += collectAndUpdateRewards(address(rewards[i])); + } + + if (userReward > totalRewardTokenBalance) { + unclaimedReward = userReward - totalRewardTokenBalance; + userReward = totalRewardTokenBalance; + } + if (userReward > 0) { + _userRewardsData[onBehalfOf][rewards[i]].unclaimedRewards = unclaimedReward.toUint128(); + _userRewardsData[onBehalfOf][rewards[i]].rewardsIndexOnLastInteraction = currentRewardsIndex + .toUint128(); + IERC20(rewards[i]).safeTransfer(receiver, userReward); + } + } + } + + function _convertToShares(uint256 assets, Rounding rounding) internal view returns (uint256) { + if (rounding == Rounding.UP) return assets.rayDivRoundUp(rate()); + return assets.rayDivRoundDown(rate()); + } + + function _convertToAssets(uint256 shares, Rounding rounding) internal view returns (uint256) { + if (rounding == Rounding.UP) return shares.rayMulRoundUp(rate()); + return shares.rayMulRoundDown(rate()); + } + + /** + * @notice Initializes a new rewardToken + * @param reward The reward token to be registered + */ + function _registerRewardToken(address reward) internal { + if (isRegisteredRewardToken(reward)) return; + uint256 startIndex = getCurrentRewardsIndex(reward); + + _rewardTokens.push(reward); + _startIndex[reward] = RewardIndexCache(true, startIndex.toUint240()); + + emit RewardTokenRegistered(reward, startIndex); + } + + /** + * Copy of https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ReserveLogic.sol#L47 with memory instead of calldata + * @notice Returns the ongoing normalized income for the reserve. + * @dev A value of 1e27 means there is no income. As time passes, the income is accrued + * @dev A value of 2*1e27 means for each unit of asset one unit of income has been accrued + * @param reserve The reserve object + * @return The normalized income, expressed in ray + */ + function _getNormalizedIncome( + DataTypes.ReserveDataLegacy memory reserve + ) internal view returns (uint256) { + uint40 timestamp = reserve.lastUpdateTimestamp; + + //solium-disable-next-line + if (timestamp == block.timestamp) { + //if the index was updated in the same block, no need to perform any calculation + return reserve.liquidityIndex; + } else { + return + MathUtils.calculateLinearInterest(reserve.currentLiquidityRate, timestamp).rayMul( + reserve.liquidityIndex + ); + } + } +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IAToken.sol b/src/contracts/extensions/static-a-token/interfaces/IAToken.sol new file mode 100644 index 00000000..31e9a805 --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IAToken.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +interface IAToken { + function POOL() external view returns (address); + + function getIncentivesController() external view returns (address); + + function UNDERLYING_ASSET_ADDRESS() external view returns (address); + + /** + * @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); +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol b/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol new file mode 100644 index 00000000..08f14f90 --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) + +pragma solidity ^0.8.10; + +/** + * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in + * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. + * + * _Available since v4.7._ + */ +interface IERC4626 { + 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 unless due to integer overflow caused by an unreasonably large input. + * + * 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. + * While deposit of aToken is not affected by aave pool configrations, deposit of the aTokenUnderlying will need to deposit to aave + * so it is affected by current aave pool configuration. + * Reference: https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ValidationLogic.sol#L57 + * - 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 unless due to integer overflow caused by an unreasonably large input. + */ + 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 to the aToken underlying. + * While redeem of aToken is not affected by aave pool configrations, redeeming of the aTokenUnderlying will need to redeem from aave + * so it is affected by current aave pool configuration. + * Reference: https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ValidationLogic.sol#L87 + * - 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); +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol b/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol new file mode 100644 index 00000000..586a935a --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {IPool} from '../../../interfaces/IPool.sol'; +import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; + +/** + * @title IInitializableStaticATokenLM + * @notice Interface for the initialize function on StaticATokenLM + * @author Aave + **/ +interface IInitializableStaticATokenLM { + /** + * @dev Emitted when a StaticATokenLM is initialized + * @param aToken The address of the underlying aToken (aWETH) + * @param staticATokenName The name of the Static aToken + * @param staticATokenSymbol The symbol of the Static aToken + **/ + event Initialized(address indexed aToken, string staticATokenName, string staticATokenSymbol); + + /** + * @dev Initializes the StaticATokenLM + * @param aToken The address of the underlying aToken (aWETH) + * @param staticATokenName The name of the Static aToken + * @param staticATokenSymbol The symbol of the Static aToken + */ + function initialize( + address aToken, + string calldata staticATokenName, + string calldata staticATokenSymbol + ) external; +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol b/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol new file mode 100644 index 00000000..d08f2a29 --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {IPool} from '../../../interfaces/IPool.sol'; +import {IAaveOracle} from '../../../interfaces/IAaveOracle.sol'; + +interface IStataOracle { + /** + * @return The pool used for fetching the rate on the aggregator oracle + */ + function POOL() external view returns (IPool); + + /** + * @return The aave oracle used for fetching the price of the underlying + */ + function AAVE_ORACLE() external view returns (IAaveOracle); + + /** + * @notice Returns the prices of an asset address + * @param asset The asset address + * @return The prices of the given asset + */ + function getAssetPrice(address asset) external view returns (uint256); + + /** + * @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); +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol new file mode 100644 index 00000000..7532e92c --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +interface IStaticATokenFactory { + /** + * @notice Creates new staticATokens + * @param underlyings the addresses of the underlyings to create. + * @return address[] addresses of the new staticATokens. + */ + function createStaticATokens(address[] memory underlyings) external returns (address[] memory); + + /** + * @notice Returns all tokens deployed via this registry. + * @return address[] list of tokens + */ + function getStaticATokens() external view returns (address[] memory); + + /** + * @notice Returns the staticAToken for a given underlying. + * @param underlying the address of the underlying. + * @return address the staticAToken address. + */ + function getStaticAToken(address underlying) external view returns (address); +} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol new file mode 100644 index 00000000..eed469f3 --- /dev/null +++ b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {IInitializableStaticATokenLM} from './IInitializableStaticATokenLM.sol'; + +interface IStaticATokenLM is IInitializableStaticATokenLM { + struct SignatureParams { + uint8 v; + bytes32 r; + bytes32 s; + } + + struct PermitParams { + address owner; + address spender; + uint256 value; + uint256 deadline; + uint8 v; + bytes32 r; + bytes32 s; + } + + struct UserRewardsData { + uint128 rewardsIndexOnLastInteraction; // (in RAYs) + uint128 unclaimedRewards; // (in RAYs) + } + + struct RewardIndexCache { + bool isRegistered; + uint248 lastUpdatedIndex; + } + + event RewardTokenRegistered(address indexed reward, uint256 startIndex); + + /** + * @notice Burns `amount` of static aToken, with receiver receiving the corresponding amount of `ASSET` + * @param shares The amount to withdraw, in static balance of StaticAToken + * @param receiver The address that will receive the amount of `ASSET` withdrawn from the Aave protocol + * @param withdrawFromAave bool + * - `true` for the receiver to get underlying tokens (e.g. USDC) + * - `false` for the receiver to get aTokens (e.g. aUSDC) + * @return amountToBurn: StaticATokens burnt, static balance + * @return amountToWithdraw: underlying/aToken send to `receiver`, dynamic balance + **/ + function redeem( + uint256 shares, + address receiver, + address owner, + bool withdrawFromAave + ) external returns (uint256, uint256); + + /** + * @notice Deposits `ASSET` in the Aave protocol and mints static aTokens to msg.sender + * @param assets The amount of underlying `ASSET` to deposit (e.g. deposit of 100 USDC) + * @param receiver The address that will receive the static 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 + * @param depositToAave bool + * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) + * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) + * @return uint256 The amount of StaticAToken minted, static balance + **/ + function deposit( + uint256 assets, + address receiver, + uint16 referralCode, + bool depositToAave + ) external returns (uint256); + + /** + * @notice Allows to deposit on Aave via meta-transaction + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param depositor Address from which the funds to deposit are going to be pulled + * @param receiver Address that will receive the staticATokens, in the average case, same as the `depositor` + * @param assets The amount to deposit + * @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 depositToAave bool + * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) + * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param sigParams Signature params: v,r,s + * @return uint256 The amount of StaticAToken minted, static balance + */ + function metaDeposit( + address depositor, + address receiver, + uint256 assets, + uint16 referralCode, + bool depositToAave, + uint256 deadline, + PermitParams calldata permit, + SignatureParams calldata sigParams + ) external returns (uint256); + + /** + * @notice Allows to withdraw from Aave via meta-transaction + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param owner Address owning the staticATokens + * @param receiver Address that will receive the underlying withdrawn from Aave + * @param shares The amount of staticAToken to withdraw. If > 0, `assets` needs to be 0 + * @param assets The amount of underlying/aToken to withdraw. If > 0, `shares` needs to be 0 + * @param withdrawFromAave bool + * - `true` for the receiver to get underlying tokens (e.g. USDC) + * - `false` for the receiver to get aTokens (e.g. aUSDC) + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param sigParams Signature params: v,r,s + * @return amountToBurn: StaticATokens burnt, static balance + * @return amountToWithdraw: underlying/aToken send to `receiver`, dynamic balance + */ + function metaWithdraw( + address owner, + address receiver, + uint256 shares, + uint256 assets, + bool withdrawFromAave, + uint256 deadline, + SignatureParams calldata sigParams + ) external returns (uint256, uint256); + + /** + * @notice Returns the Aave liquidity index of the underlying aToken, denominated rate here + * as it can be considered as an ever-increasing exchange rate + * @return The liquidity index + **/ + function rate() external view returns (uint256); + + /** + * @notice Claims rewards from `INCENTIVES_CONTROLLER` and updates internal accounting of rewards. + * @param reward The reward to claim + * @return uint256 Amount collected + */ + function collectAndUpdateRewards(address reward) external returns (uint256); + + /** + * @notice Claim rewards on behalf of a user and send them to a receiver + * @dev Only callable by if sender is onBehalfOf or sender is approved claimer + * @param onBehalfOf The address to claim on behalf of + * @param receiver The address to receive the rewards + * @param rewards The rewards to claim + */ + function claimRewardsOnBehalf( + address onBehalfOf, + address receiver, + address[] memory rewards + ) external; + + /** + * @notice Claim rewards and send them to a receiver + * @param receiver The address to receive the rewards + * @param rewards The rewards to claim + */ + function claimRewards(address receiver, address[] memory rewards) external; + + /** + * @notice Claim rewards + * @param rewards The rewards to claim + */ + function claimRewardsToSelf(address[] memory rewards) external; + + /** + * @notice Get the total claimable rewards of the contract. + * @param reward The reward to claim + * @return uint256 The current balance + pending rewards from the `_incentivesController` + */ + function getTotalClaimableRewards(address reward) external view returns (uint256); + + /** + * @notice Get the total claimable rewards for a user in WAD + * @param user The address of the user + * @param reward The reward to claim + * @return uint256 The claimable amount of rewards in WAD + */ + function getClaimableRewards(address user, address reward) external view returns (uint256); + + /** + * @notice The unclaimed rewards for a user in WAD + * @param user The address of the user + * @param reward The reward to claim + * @return uint256 The unclaimed amount of rewards in WAD + */ + function getUnclaimedRewards(address user, address reward) external view returns (uint256); + + /** + * @notice The underlying asset reward index in RAY + * @param reward The reward to claim + * @return uint256 The underlying asset reward index in RAY + */ + function getCurrentRewardsIndex(address reward) external view returns (uint256); + + /** + * @notice The aToken used inside the 4626 vault. + * @return IERC20 The aToken IERC20. + */ + function aToken() external view returns (IERC20); + + /** + * @notice The IERC20s that are currently rewarded to addresses of the vault via LM on incentivescontroller. + * @return IERC20 The IERC20s of the rewards. + */ + function rewardTokens() external view returns (address[] memory); + + /** + * @notice Fetches all rewardTokens from the incentivecontroller and registers the missing ones. + */ + function refreshRewardTokens() external; + + /** + * @notice Checks if the passed token is a registered reward. + * @return bool signaling if token is a registered reward. + */ + function isRegisteredRewardToken(address reward) external view returns (bool); +} diff --git a/src/periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol b/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol similarity index 99% rename from src/periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol rename to src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol index 2d5cd360..25b07174 100644 --- a/src/periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol +++ b/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {CapsEngine} from './libraries/CapsEngine.sol'; diff --git a/src/periphery/contracts/v3-config-engine/AaveV3Payload.sol b/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol similarity index 98% rename from src/periphery/contracts/v3-config-engine/AaveV3Payload.sol rename to src/contracts/extensions/v3-config-engine/AaveV3Payload.sol index 003d3d3e..065263b1 100644 --- a/src/periphery/contracts/v3-config-engine/AaveV3Payload.sol +++ b/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol @@ -1,8 +1,8 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Address} from 'solidity-utils/contracts/oz-common/Address.sol'; -import {WadRayMath} from '../../../core/contracts/protocol/libraries/math/WadRayMath.sol'; +import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; import {IAaveV3ConfigEngine as IEngine} from './IAaveV3ConfigEngine.sol'; import {EngineFlags} from './EngineFlags.sol'; diff --git a/src/periphery/contracts/v3-config-engine/EngineFlags.sol b/src/contracts/extensions/v3-config-engine/EngineFlags.sol similarity index 97% rename from src/periphery/contracts/v3-config-engine/EngineFlags.sol rename to src/contracts/extensions/v3-config-engine/EngineFlags.sol index de54c40d..822292a6 100644 --- a/src/periphery/contracts/v3-config-engine/EngineFlags.sol +++ b/src/contracts/extensions/v3-config-engine/EngineFlags.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; library EngineFlags { diff --git a/src/periphery/contracts/v3-config-engine/IAaveV3ConfigEngine.sol b/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol similarity index 97% rename from src/periphery/contracts/v3-config-engine/IAaveV3ConfigEngine.sol rename to src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol index ddbcdf13..c2007d35 100644 --- a/src/periphery/contracts/v3-config-engine/IAaveV3ConfigEngine.sol +++ b/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; -import {IPool} from '../../../core/contracts/interfaces/IPool.sol'; -import {IPoolConfigurator} from '../../../core/contracts/interfaces/IPoolConfigurator.sol'; -import {IAaveOracle} from '../../../core/contracts/interfaces/IAaveOracle.sol'; -import {IDefaultInterestRateStrategyV2} from '../../../core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; +import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolConfigurator} from '../../interfaces/IPoolConfigurator.sol'; +import {IAaveOracle} from '../../interfaces/IAaveOracle.sol'; +import {IDefaultInterestRateStrategyV2} from '../../interfaces/IDefaultInterestRateStrategyV2.sol'; /// @dev Examples here assume the usage of the `AaveV3Payload` base contracts /// contained in this same repository diff --git a/src/contracts/extensions/v3-config-engine/README.md b/src/contracts/extensions/v3-config-engine/README.md new file mode 100644 index 00000000..7308dde5 --- /dev/null +++ b/src/contracts/extensions/v3-config-engine/README.md @@ -0,0 +1,62 @@ +## Aave v3 config engine + +![Config Engine Diagram](../../../../resources/configs-engine.svg) + +## What is the AaveV3ConfigEngine? + +The `AaveV3ConfigEngine` is a helper smart contract to abstract good practices when doing "admin" interactions with the Aave v3 protocol, but built on top, without touching the core contracts. + +At the same time, it defines a new interface oriented to simplify developer experience when coding proposal payloads: the `AaveV3ConfigEngine` is built from our experience supervising governance payloads review, for actions like full cycle of listing assets, modify caps (supply/borrow), changing collateral or borrow related parameters and changing the price feeds of assets. + +_Note: In an effort for unification and streamlining deployment procedures, the config engine has been migrated from the [aave-helpers](https://github.com/bgd-labs/aave-helpers) repository to this location._ + +## How to use the engine? + +The engine is not designed to be used directly when writing a payload, but through abstract contracts that we will call `Base Aave v3 Payloads`. + +This [aave-helpers](https://github.com/bgd-labs/aave-helpers) repository contains `Base Aave v3 Payloads` for all the Aave v3 instances, under the hood powered by this config engine and aave-address-book, and abstracting all the complexity: ordering of execution of actions, extra validations, deciding when to keep a current configured parameter and how to get it, etc. + +As base for any payload, you only need to inherit from the corresponding (per pool) `Base Aave v3 Payload`, for example inheriting from `AaveV3PayloadEthereum` in the case of Ethereum, `AaveV3PayloadAvalanche` in the case of Avalanche, and so on. + +If you want just to do one or multiple listings, you only need to define the listing within a `newListings()` function, and the base payload will take care of executing it correctly for you. + +Do you want instead to update supply/borrow caps? Same approach as with the listings, you only need to define the update of caps within a `capsUpdates()` function, and the base payload will take care of the rest. + +Do you want to update the price-feed of an asset? You only need to define the update of price feed within a `priceFeedsUpdates()` function, and the base payload will take care of the rest. + +Change collateral-related parameters? Same approach as previous, you only need to define the update within a `collateralsUpdates()` function, and the base payload will take care of the rest. + +Change Borrow-related parameters? Same as previous, just define the update within a `borrowsUpdates()` function, and the base payload will take care of the rest. + +Change eMode category configuration? Same as previous, just define the update within a `eModeCategoriesUpdates()` function, and the base payload will take care of the rest. + +Change eMode category of a particular asset? Same as previous, just define the update within a `assetsEModeUpdates()` function, and the base payload will take care of the rest. + +### Internal aspects to consider + +- Frequently, at the same time that you want to do an update of parameters or listing, you also want to do something extra before or after. +The `Base Aave v3 Payload` defines `_preExecute()` and `_postExecute()` hook functions, that you can redefine on your payload and will the execute before and after all configs changes/listings you define. + +- The payload also allow you to group changes of parameters and listings, just by defining at the same time the aforementioned `newListings()`, `capsUpdate()` and/or `collateralsUpdates()` and so on. For reference, the execution ordering is the following: + 1. `_preExecute()` + 2. `eModeCategoriesUpdates()` + 3. `newListings()` + 4. `newListingsCustom()` + 5. `borrowsUpdates()` + 6. `collateralsUpdates()` + 7. `rateStrategiesUpdates()` + 8. `priceFeedsUpdates()` + 9. `assetsEModeUpdates()` + 10. `capsUpdates()` + 11. `_postExecute()` + +## Links to examples +- [Simple mock listing on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockListing.sol) +- [Simple custom mock listing on Aave V3 with custom token impl](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockListingCustom.sol) +- [Mock e-mode category update on Aave V3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol) +- [Mock e-mode asset update on Aave V3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol) +- [Mock caps updates (only supply, keeping current borrow cap) on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockCapUpdate.sol) +- [Mock collateral updates (changing some, keeping current values on others), on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol) +- [Mock borrow updates (changing some, keeping current values on others), on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol) +- [Mock rates updates (changing some, keeping current values on others), on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol) +- [Mock price feed updates on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol) diff --git a/src/periphery/contracts/v3-config-engine/libraries/BorrowEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/BorrowEngine.sol similarity index 91% rename from src/periphery/contracts/v3-config-engine/libraries/BorrowEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/BorrowEngine.sol index 4fa237b6..7a9d2ddf 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/BorrowEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/BorrowEngine.sol @@ -1,9 +1,9 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {EngineFlags} from '../EngineFlags.sol'; -import {DataTypes} from '../../../../core/contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveConfiguration} from '../../../../core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {DataTypes} from '../../../protocol/libraries/types/DataTypes.sol'; +import {ReserveConfiguration} from '../../../protocol/libraries/configuration/ReserveConfiguration.sol'; import {IAaveV3ConfigEngine as IEngine, IPoolConfigurator, IPool} from '../IAaveV3ConfigEngine.sol'; library BorrowEngine { diff --git a/src/periphery/contracts/v3-config-engine/libraries/CapsEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/CapsEngine.sol similarity index 96% rename from src/periphery/contracts/v3-config-engine/libraries/CapsEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/CapsEngine.sol index b06c61fc..084ebc26 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/CapsEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/CapsEngine.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {EngineFlags} from '../EngineFlags.sol'; diff --git a/src/periphery/contracts/v3-config-engine/libraries/CollateralEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/CollateralEngine.sol similarity index 91% rename from src/periphery/contracts/v3-config-engine/libraries/CollateralEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/CollateralEngine.sol index 73e9a7f0..174068bd 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/CollateralEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/CollateralEngine.sol @@ -1,10 +1,10 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; -import {DataTypes} from '../../../../core/contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveConfiguration} from '../../../../core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {DataTypes} from '../../../protocol/libraries/types/DataTypes.sol'; +import {ReserveConfiguration} from '../../../protocol/libraries/configuration/ReserveConfiguration.sol'; import {IAaveV3ConfigEngine as IEngine, IPoolConfigurator, IPool} from '../IAaveV3ConfigEngine.sol'; -import {PercentageMath} from '../../../../core/contracts/protocol/libraries/math/PercentageMath.sol'; +import {PercentageMath} from '../../../protocol/libraries/math/PercentageMath.sol'; import {EngineFlags} from '../EngineFlags.sol'; library CollateralEngine { diff --git a/src/periphery/contracts/v3-config-engine/libraries/EModeEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol similarity index 94% rename from src/periphery/contracts/v3-config-engine/libraries/EModeEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol index 5ccf4231..6780a9f6 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/EModeEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol @@ -1,10 +1,10 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {EngineFlags} from '../EngineFlags.sol'; -import {DataTypes} from '../../../../core/contracts/protocol/libraries/types/DataTypes.sol'; +import {DataTypes} from '../../../protocol/libraries/types/DataTypes.sol'; import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; -import {PercentageMath} from '../../../../core/contracts/protocol/libraries/math/PercentageMath.sol'; +import {PercentageMath} from '../../../protocol/libraries/math/PercentageMath.sol'; import {IAaveV3ConfigEngine as IEngine, IPoolConfigurator, IPool} from '../IAaveV3ConfigEngine.sol'; library EModeEngine { diff --git a/src/periphery/contracts/v3-config-engine/libraries/ListingEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/ListingEngine.sol similarity index 96% rename from src/periphery/contracts/v3-config-engine/libraries/ListingEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/ListingEngine.sol index 15550697..861491be 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/ListingEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/ListingEngine.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; @@ -8,9 +8,9 @@ import {CapsEngine} from './CapsEngine.sol'; import {BorrowEngine} from './BorrowEngine.sol'; import {CollateralEngine} from './CollateralEngine.sol'; import {EModeEngine} from './EModeEngine.sol'; -import {ConfiguratorInputTypes} from '../../../../core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol'; +import {ConfiguratorInputTypes} from '../../../protocol/libraries/types/ConfiguratorInputTypes.sol'; import {Address} from 'solidity-utils/contracts/oz-common/Address.sol'; -import {SafeCast} from '../../../../core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; +import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; library ListingEngine { using Address for address; diff --git a/src/periphery/contracts/v3-config-engine/libraries/PriceFeedEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/PriceFeedEngine.sol similarity index 88% rename from src/periphery/contracts/v3-config-engine/libraries/PriceFeedEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/PriceFeedEngine.sol index d7186082..75cc49f4 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/PriceFeedEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/PriceFeedEngine.sol @@ -1,8 +1,8 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; import {IAaveV3ConfigEngine as IEngine, IAaveOracle} from '../IAaveV3ConfigEngine.sol'; -import {IEACAggregatorProxy} from '../../../../periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol'; +import {IEACAggregatorProxy} from '../../../helpers/interfaces/IEACAggregatorProxy.sol'; library PriceFeedEngine { function executePriceFeedsUpdate( diff --git a/src/periphery/contracts/v3-config-engine/libraries/RateEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/RateEngine.sol similarity index 93% rename from src/periphery/contracts/v3-config-engine/libraries/RateEngine.sol rename to src/contracts/extensions/v3-config-engine/libraries/RateEngine.sol index db9c37d3..8ae88e2b 100644 --- a/src/periphery/contracts/v3-config-engine/libraries/RateEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/RateEngine.sol @@ -1,8 +1,8 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; -import {IDefaultInterestRateStrategyV2} from '../../../../core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; -import {SafeCast} from '../../../../core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; +import {IDefaultInterestRateStrategyV2} from '../../../interfaces/IDefaultInterestRateStrategyV2.sol'; +import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; import {EngineFlags} from '../EngineFlags.sol'; import {IAaveV3ConfigEngine as IEngine, IPoolConfigurator} from '../IAaveV3ConfigEngine.sol'; diff --git a/src/core/contracts/misc/AaveProtocolDataProvider.sol b/src/contracts/helpers/AaveProtocolDataProvider.sol similarity index 100% rename from src/core/contracts/misc/AaveProtocolDataProvider.sol rename to src/contracts/helpers/AaveProtocolDataProvider.sol diff --git a/src/core/contracts/misc/L2Encoder.sol b/src/contracts/helpers/L2Encoder.sol similarity index 100% rename from src/core/contracts/misc/L2Encoder.sol rename to src/contracts/helpers/L2Encoder.sol diff --git a/src/periphery/contracts/misc/UiIncentiveDataProviderV3.sol b/src/contracts/helpers/UiIncentiveDataProviderV3.sol similarity index 96% rename from src/periphery/contracts/misc/UiIncentiveDataProviderV3.sol rename to src/contracts/helpers/UiIncentiveDataProviderV3.sol index 5c8f3e7f..d5d620d9 100644 --- a/src/periphery/contracts/misc/UiIncentiveDataProviderV3.sol +++ b/src/contracts/helpers/UiIncentiveDataProviderV3.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IncentivizedERC20} from 'aave-v3-core/contracts/protocol/tokenization/base/IncentivizedERC20.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../interfaces/IPool.sol'; +import {IncentivizedERC20} from '../protocol/tokenization/base/IncentivizedERC20.sol'; +import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IRewardsController} from '../rewards/interfaces/IRewardsController.sol'; import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.sol'; import {IUiIncentiveDataProviderV3} from './interfaces/IUiIncentiveDataProviderV3.sol'; diff --git a/src/periphery/contracts/misc/UiPoolDataProviderV3.sol b/src/contracts/helpers/UiPoolDataProviderV3.sol similarity index 89% rename from src/periphery/contracts/misc/UiPoolDataProviderV3.sol rename to src/contracts/helpers/UiPoolDataProviderV3.sol index cee7a456..343855bf 100644 --- a/src/periphery/contracts/misc/UiPoolDataProviderV3.sol +++ b/src/contracts/helpers/UiPoolDataProviderV3.sol @@ -1,19 +1,19 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {IStableDebtToken} from 'aave-v3-core/contracts/interfaces/IStableDebtToken.sol'; -import {IDefaultInterestRateStrategyV2} from 'aave-v3-core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; -import {AaveProtocolDataProvider} from 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../interfaces/IPool.sol'; +import {IAaveOracle} from '../interfaces/IAaveOracle.sol'; +import {IAToken} from '../interfaces/IAToken.sol'; +import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; +import {IStableDebtToken} from '../interfaces/IStableDebtToken.sol'; +import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol'; +import {AaveProtocolDataProvider} from './AaveProtocolDataProvider.sol'; +import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; +import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; +import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IEACAggregatorProxy} from './interfaces/IEACAggregatorProxy.sol'; import {IERC20DetailedBytes} from './interfaces/IERC20DetailedBytes.sol'; import {IUiPoolDataProviderV3} from './interfaces/IUiPoolDataProviderV3.sol'; diff --git a/src/periphery/contracts/misc/WalletBalanceProvider.sol b/src/contracts/helpers/WalletBalanceProvider.sol similarity index 83% rename from src/periphery/contracts/misc/WalletBalanceProvider.sol rename to src/contracts/helpers/WalletBalanceProvider.sol index f215610c..c074ac3f 100644 --- a/src/periphery/contracts/misc/WalletBalanceProvider.sol +++ b/src/contracts/helpers/WalletBalanceProvider.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {Address} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Address.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; - -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {Address} from '../dependencies/openzeppelin/contracts/Address.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; + +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../interfaces/IPool.sol'; +import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title WalletBalanceProvider contract diff --git a/src/periphery/contracts/misc/WrappedTokenGatewayV3.sol b/src/contracts/helpers/WrappedTokenGatewayV3.sol similarity index 89% rename from src/periphery/contracts/misc/WrappedTokenGatewayV3.sol rename to src/contracts/helpers/WrappedTokenGatewayV3.sol index a120eeab..eb2c6dd3 100644 --- a/src/periphery/contracts/misc/WrappedTokenGatewayV3.sol +++ b/src/contracts/helpers/WrappedTokenGatewayV3.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IWETH} from 'aave-v3-core/contracts/misc/interfaces/IWETH.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; +import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IWETH} from './interfaces/IWETH.sol'; +import {IPool} from '../interfaces/IPool.sol'; +import {IAToken} from '../interfaces/IAToken.sol'; +import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; +import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {IWrappedTokenGatewayV3} from './interfaces/IWrappedTokenGatewayV3.sol'; -import {DataTypesHelper} from '../libraries/DataTypesHelper.sol'; +import {DataTypesHelper} from '../misc/libraries/DataTypesHelper.sol'; /** * @dev This contract is an upgrade of the WrappedTokenGatewayV3 contract, with immutable pool address. diff --git a/src/periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol b/src/contracts/helpers/interfaces/IEACAggregatorProxy.sol similarity index 100% rename from src/periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol rename to src/contracts/helpers/interfaces/IEACAggregatorProxy.sol diff --git a/src/periphery/contracts/misc/interfaces/IERC20DetailedBytes.sol b/src/contracts/helpers/interfaces/IERC20DetailedBytes.sol similarity index 73% rename from src/periphery/contracts/misc/interfaces/IERC20DetailedBytes.sol rename to src/contracts/helpers/interfaces/IERC20DetailedBytes.sol index 3e213158..0541f0da 100644 --- a/src/periphery/contracts/misc/interfaces/IERC20DetailedBytes.sol +++ b/src/contracts/helpers/interfaces/IERC20DetailedBytes.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; interface IERC20DetailedBytes is IERC20 { function name() external view returns (bytes32); diff --git a/src/periphery/contracts/misc/interfaces/IUiIncentiveDataProviderV3.sol b/src/contracts/helpers/interfaces/IUiIncentiveDataProviderV3.sol similarity index 95% rename from src/periphery/contracts/misc/interfaces/IUiIncentiveDataProviderV3.sol rename to src/contracts/helpers/interfaces/IUiIncentiveDataProviderV3.sol index fb3bb00c..910c662b 100644 --- a/src/periphery/contracts/misc/interfaces/IUiIncentiveDataProviderV3.sol +++ b/src/contracts/helpers/interfaces/IUiIncentiveDataProviderV3.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; interface IUiIncentiveDataProviderV3 { struct AggregatedReserveIncentiveData { diff --git a/src/periphery/contracts/misc/interfaces/IUiPoolDataProviderV3.sol b/src/contracts/helpers/interfaces/IUiPoolDataProviderV3.sol similarity index 96% rename from src/periphery/contracts/misc/interfaces/IUiPoolDataProviderV3.sol rename to src/contracts/helpers/interfaces/IUiPoolDataProviderV3.sol index 42944eb8..9ee2402a 100644 --- a/src/periphery/contracts/misc/interfaces/IUiPoolDataProviderV3.sol +++ b/src/contracts/helpers/interfaces/IUiPoolDataProviderV3.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; interface IUiPoolDataProviderV3 { struct InterestRates { diff --git a/src/core/contracts/misc/interfaces/IWETH.sol b/src/contracts/helpers/interfaces/IWETH.sol similarity index 100% rename from src/core/contracts/misc/interfaces/IWETH.sol rename to src/contracts/helpers/interfaces/IWETH.sol diff --git a/src/periphery/contracts/misc/interfaces/IWrappedTokenGatewayV3.sol b/src/contracts/helpers/interfaces/IWrappedTokenGatewayV3.sol similarity index 100% rename from src/periphery/contracts/misc/interfaces/IWrappedTokenGatewayV3.sol rename to src/contracts/helpers/interfaces/IWrappedTokenGatewayV3.sol diff --git a/src/core/instances/ATokenInstance.sol b/src/contracts/instances/ATokenInstance.sol similarity index 93% rename from src/core/instances/ATokenInstance.sol rename to src/contracts/instances/ATokenInstance.sol index e778f91e..8e646385 100644 --- a/src/core/instances/ATokenInstance.sol +++ b/src/contracts/instances/ATokenInstance.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {AToken, IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../contracts/protocol/tokenization/AToken.sol'; +import {AToken, IPool, IAaveIncentivesController, IInitializableAToken, Errors, VersionedInitializable} from '../protocol/tokenization/AToken.sol'; contract ATokenInstance is AToken { uint256 public constant ATOKEN_REVISION = 1; diff --git a/src/core/instances/L2PoolInstance.sol b/src/contracts/instances/L2PoolInstance.sol similarity index 60% rename from src/core/instances/L2PoolInstance.sol rename to src/contracts/instances/L2PoolInstance.sol index 80bd406f..0c61f19e 100644 --- a/src/core/instances/L2PoolInstance.sol +++ b/src/contracts/instances/L2PoolInstance.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {L2Pool} from '../contracts/protocol/pool/L2Pool.sol'; -import {IPoolAddressesProvider} from '../contracts/interfaces/IPoolAddressesProvider.sol'; +import {L2Pool} from '../protocol/pool/L2Pool.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; import {PoolInstance} from './PoolInstance.sol'; contract L2PoolInstance is L2Pool, PoolInstance { diff --git a/src/core/instances/PoolConfiguratorInstance.sol b/src/contracts/instances/PoolConfiguratorInstance.sol similarity index 87% rename from src/core/instances/PoolConfiguratorInstance.sol rename to src/contracts/instances/PoolConfiguratorInstance.sol index 03ae6105..fefcc236 100644 --- a/src/core/instances/PoolConfiguratorInstance.sol +++ b/src/contracts/instances/PoolConfiguratorInstance.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {PoolConfigurator, IPoolAddressesProvider, IPool, VersionedInitializable} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; +import {PoolConfigurator, IPoolAddressesProvider, IPool, VersionedInitializable} from '../protocol/pool/PoolConfigurator.sol'; contract PoolConfiguratorInstance is PoolConfigurator { uint256 public constant CONFIGURATOR_REVISION = 3; diff --git a/src/core/instances/PoolInstance.sol b/src/contracts/instances/PoolInstance.sol similarity index 80% rename from src/core/instances/PoolInstance.sol rename to src/contracts/instances/PoolInstance.sol index 0af51bbe..88b0744a 100644 --- a/src/core/instances/PoolInstance.sol +++ b/src/contracts/instances/PoolInstance.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Pool} from '../contracts/protocol/pool/Pool.sol'; -import {IPoolAddressesProvider} from '../contracts/interfaces/IPoolAddressesProvider.sol'; -import {Errors} from '../contracts/protocol/libraries/helpers/Errors.sol'; +import {Pool} from '../protocol/pool/Pool.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; +import {Errors} from '../protocol/libraries/helpers/Errors.sol'; contract PoolInstance is Pool { uint256 public constant POOL_REVISION = 4; diff --git a/src/core/instances/StableDebtTokenInstance.sol b/src/contracts/instances/StableDebtTokenInstance.sol similarity index 91% rename from src/core/instances/StableDebtTokenInstance.sol rename to src/contracts/instances/StableDebtTokenInstance.sol index 00f91a58..a4913414 100644 --- a/src/core/instances/StableDebtTokenInstance.sol +++ b/src/contracts/instances/StableDebtTokenInstance.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {StableDebtToken, IPool, IInitializableDebtToken, VersionedInitializable, IAaveIncentivesController, Errors} from '../contracts/protocol/tokenization/StableDebtToken.sol'; +import {StableDebtToken, IPool, IInitializableDebtToken, VersionedInitializable, IAaveIncentivesController, Errors} from '../protocol/tokenization/StableDebtToken.sol'; contract StableDebtTokenInstance is StableDebtToken { uint256 public constant DEBT_TOKEN_REVISION = 1; diff --git a/src/core/instances/VariableDebtTokenInstance.sol b/src/contracts/instances/VariableDebtTokenInstance.sol similarity index 91% rename from src/core/instances/VariableDebtTokenInstance.sol rename to src/contracts/instances/VariableDebtTokenInstance.sol index 11ac68e6..b2c3dc89 100644 --- a/src/core/instances/VariableDebtTokenInstance.sol +++ b/src/contracts/instances/VariableDebtTokenInstance.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {VariableDebtToken, IPool, IInitializableDebtToken, VersionedInitializable, IAaveIncentivesController, Errors} from '../contracts/protocol/tokenization/VariableDebtToken.sol'; +import {VariableDebtToken, IPool, IInitializableDebtToken, VersionedInitializable, IAaveIncentivesController, Errors} from '../protocol/tokenization/VariableDebtToken.sol'; contract VariableDebtTokenInstance is VariableDebtToken { uint256 public constant DEBT_TOKEN_REVISION = 1; diff --git a/src/core/contracts/interfaces/IACLManager.sol b/src/contracts/interfaces/IACLManager.sol similarity index 100% rename from src/core/contracts/interfaces/IACLManager.sol rename to src/contracts/interfaces/IACLManager.sol diff --git a/src/core/contracts/interfaces/IAToken.sol b/src/contracts/interfaces/IAToken.sol similarity index 100% rename from src/core/contracts/interfaces/IAToken.sol rename to src/contracts/interfaces/IAToken.sol diff --git a/src/core/contracts/interfaces/IAaveIncentivesController.sol b/src/contracts/interfaces/IAaveIncentivesController.sol similarity index 100% rename from src/core/contracts/interfaces/IAaveIncentivesController.sol rename to src/contracts/interfaces/IAaveIncentivesController.sol diff --git a/src/core/contracts/interfaces/IAaveOracle.sol b/src/contracts/interfaces/IAaveOracle.sol similarity index 100% rename from src/core/contracts/interfaces/IAaveOracle.sol rename to src/contracts/interfaces/IAaveOracle.sol diff --git a/src/core/contracts/interfaces/ICreditDelegationToken.sol b/src/contracts/interfaces/ICreditDelegationToken.sol similarity index 100% rename from src/core/contracts/interfaces/ICreditDelegationToken.sol rename to src/contracts/interfaces/ICreditDelegationToken.sol diff --git a/src/core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol b/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol similarity index 100% rename from src/core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol rename to src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol diff --git a/src/core/contracts/interfaces/IDelegationToken.sol b/src/contracts/interfaces/IDelegationToken.sol similarity index 100% rename from src/core/contracts/interfaces/IDelegationToken.sol rename to src/contracts/interfaces/IDelegationToken.sol diff --git a/src/core/contracts/interfaces/IERC20WithPermit.sol b/src/contracts/interfaces/IERC20WithPermit.sol similarity index 100% rename from src/core/contracts/interfaces/IERC20WithPermit.sol rename to src/contracts/interfaces/IERC20WithPermit.sol diff --git a/src/core/contracts/interfaces/IInitializableAToken.sol b/src/contracts/interfaces/IInitializableAToken.sol similarity index 100% rename from src/core/contracts/interfaces/IInitializableAToken.sol rename to src/contracts/interfaces/IInitializableAToken.sol diff --git a/src/core/contracts/interfaces/IInitializableDebtToken.sol b/src/contracts/interfaces/IInitializableDebtToken.sol similarity index 100% rename from src/core/contracts/interfaces/IInitializableDebtToken.sol rename to src/contracts/interfaces/IInitializableDebtToken.sol diff --git a/src/core/contracts/interfaces/IL2Pool.sol b/src/contracts/interfaces/IL2Pool.sol similarity index 100% rename from src/core/contracts/interfaces/IL2Pool.sol rename to src/contracts/interfaces/IL2Pool.sol diff --git a/src/core/contracts/interfaces/IPool.sol b/src/contracts/interfaces/IPool.sol similarity index 100% rename from src/core/contracts/interfaces/IPool.sol rename to src/contracts/interfaces/IPool.sol diff --git a/src/core/contracts/interfaces/IPoolAddressesProvider.sol b/src/contracts/interfaces/IPoolAddressesProvider.sol similarity index 100% rename from src/core/contracts/interfaces/IPoolAddressesProvider.sol rename to src/contracts/interfaces/IPoolAddressesProvider.sol diff --git a/src/core/contracts/interfaces/IPoolAddressesProviderRegistry.sol b/src/contracts/interfaces/IPoolAddressesProviderRegistry.sol similarity index 100% rename from src/core/contracts/interfaces/IPoolAddressesProviderRegistry.sol rename to src/contracts/interfaces/IPoolAddressesProviderRegistry.sol diff --git a/src/core/contracts/interfaces/IPoolConfigurator.sol b/src/contracts/interfaces/IPoolConfigurator.sol similarity index 100% rename from src/core/contracts/interfaces/IPoolConfigurator.sol rename to src/contracts/interfaces/IPoolConfigurator.sol diff --git a/src/core/contracts/interfaces/IPoolDataProvider.sol b/src/contracts/interfaces/IPoolDataProvider.sol similarity index 100% rename from src/core/contracts/interfaces/IPoolDataProvider.sol rename to src/contracts/interfaces/IPoolDataProvider.sol diff --git a/src/core/contracts/interfaces/IPriceOracle.sol b/src/contracts/interfaces/IPriceOracle.sol similarity index 100% rename from src/core/contracts/interfaces/IPriceOracle.sol rename to src/contracts/interfaces/IPriceOracle.sol diff --git a/src/core/contracts/interfaces/IPriceOracleGetter.sol b/src/contracts/interfaces/IPriceOracleGetter.sol similarity index 100% rename from src/core/contracts/interfaces/IPriceOracleGetter.sol rename to src/contracts/interfaces/IPriceOracleGetter.sol diff --git a/src/core/contracts/interfaces/IPriceOracleSentinel.sol b/src/contracts/interfaces/IPriceOracleSentinel.sol similarity index 100% rename from src/core/contracts/interfaces/IPriceOracleSentinel.sol rename to src/contracts/interfaces/IPriceOracleSentinel.sol diff --git a/src/core/contracts/interfaces/IReserveInterestRateStrategy.sol b/src/contracts/interfaces/IReserveInterestRateStrategy.sol similarity index 100% rename from src/core/contracts/interfaces/IReserveInterestRateStrategy.sol rename to src/contracts/interfaces/IReserveInterestRateStrategy.sol diff --git a/src/core/contracts/interfaces/IScaledBalanceToken.sol b/src/contracts/interfaces/IScaledBalanceToken.sol similarity index 100% rename from src/core/contracts/interfaces/IScaledBalanceToken.sol rename to src/contracts/interfaces/IScaledBalanceToken.sol diff --git a/src/core/contracts/interfaces/ISequencerOracle.sol b/src/contracts/interfaces/ISequencerOracle.sol similarity index 100% rename from src/core/contracts/interfaces/ISequencerOracle.sol rename to src/contracts/interfaces/ISequencerOracle.sol diff --git a/src/core/contracts/interfaces/IStableDebtToken.sol b/src/contracts/interfaces/IStableDebtToken.sol similarity index 100% rename from src/core/contracts/interfaces/IStableDebtToken.sol rename to src/contracts/interfaces/IStableDebtToken.sol diff --git a/src/core/contracts/interfaces/IVariableDebtToken.sol b/src/contracts/interfaces/IVariableDebtToken.sol similarity index 100% rename from src/core/contracts/interfaces/IVariableDebtToken.sol rename to src/contracts/interfaces/IVariableDebtToken.sol diff --git a/src/core/contracts/misc/AaveOracle.sol b/src/contracts/misc/AaveOracle.sol similarity index 100% rename from src/core/contracts/misc/AaveOracle.sol rename to src/contracts/misc/AaveOracle.sol diff --git a/src/core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol b/src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol similarity index 93% rename from src/core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol rename to src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol index 40a25683..a723e331 100644 --- a/src/core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol +++ b/src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {WadRayMath} from '../libraries/math/WadRayMath.sol'; -import {PercentageMath} from '../libraries/math/PercentageMath.sol'; -import {DataTypes} from '../libraries/types/DataTypes.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IDefaultInterestRateStrategyV2} from '../../interfaces/IDefaultInterestRateStrategyV2.sol'; -import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; +import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; +import {PercentageMath} from '../protocol/libraries/math/PercentageMath.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; +import {Errors} from '../protocol/libraries/helpers/Errors.sol'; +import {IDefaultInterestRateStrategyV2} from '../interfaces/IDefaultInterestRateStrategyV2.sol'; +import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; /** * @title DefaultReserveInterestRateStrategyV2 contract diff --git a/src/core/contracts/protocol/configuration/PriceOracleSentinel.sol b/src/contracts/misc/PriceOracleSentinel.sol similarity index 89% rename from src/core/contracts/protocol/configuration/PriceOracleSentinel.sol rename to src/contracts/misc/PriceOracleSentinel.sol index 2ff1584f..69d5f772 100644 --- a/src/core/contracts/protocol/configuration/PriceOracleSentinel.sol +++ b/src/contracts/misc/PriceOracleSentinel.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPriceOracleSentinel} from '../../interfaces/IPriceOracleSentinel.sol'; -import {ISequencerOracle} from '../../interfaces/ISequencerOracle.sol'; -import {IACLManager} from '../../interfaces/IACLManager.sol'; +import {Errors} from '../protocol/libraries/helpers/Errors.sol'; +import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; +import {IPriceOracleSentinel} from '../interfaces/IPriceOracleSentinel.sol'; +import {ISequencerOracle} from '../interfaces/ISequencerOracle.sol'; +import {IACLManager} from '../interfaces/IACLManager.sol'; /** * @title PriceOracleSentinel diff --git a/src/core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol b/src/contracts/misc/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol similarity index 95% rename from src/core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol rename to src/contracts/misc/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol index 06d2f827..252b4a4b 100644 --- a/src/core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol +++ b/src/contracts/misc/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {BaseUpgradeabilityProxy} from '../../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol'; +import {BaseUpgradeabilityProxy} from '../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol'; /** * @title BaseImmutableAdminUpgradeabilityProxy diff --git a/src/core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol b/src/contracts/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol similarity index 79% rename from src/core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol rename to src/contracts/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol index 0deceb5b..6913a19d 100644 --- a/src/core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol +++ b/src/contracts/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {InitializableUpgradeabilityProxy} from '../../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol'; -import {Proxy} from '../../../dependencies/openzeppelin/upgradeability/Proxy.sol'; +import {InitializableUpgradeabilityProxy} from '../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol'; +import {Proxy} from '../../dependencies/openzeppelin/upgradeability/Proxy.sol'; import {BaseImmutableAdminUpgradeabilityProxy} from './BaseImmutableAdminUpgradeabilityProxy.sol'; /** diff --git a/src/core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol b/src/contracts/misc/aave-upgradeability/VersionedInitializable.sol similarity index 100% rename from src/core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol rename to src/contracts/misc/aave-upgradeability/VersionedInitializable.sol diff --git a/src/core/contracts/flashloan/base/FlashLoanReceiverBase.sol b/src/contracts/misc/flashloan/base/FlashLoanReceiverBase.sol similarity index 79% rename from src/core/contracts/flashloan/base/FlashLoanReceiverBase.sol rename to src/contracts/misc/flashloan/base/FlashLoanReceiverBase.sol index cd43c2e1..55fbe6d2 100644 --- a/src/core/contracts/flashloan/base/FlashLoanReceiverBase.sol +++ b/src/contracts/misc/flashloan/base/FlashLoanReceiverBase.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.10; import {IFlashLoanReceiver} from '../interfaces/IFlashLoanReceiver.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../interfaces/IPool.sol'; /** * @title FlashLoanReceiverBase diff --git a/src/core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol b/src/contracts/misc/flashloan/base/FlashLoanSimpleReceiverBase.sol similarity index 80% rename from src/core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol rename to src/contracts/misc/flashloan/base/FlashLoanSimpleReceiverBase.sol index 25af62b2..2980a0cc 100644 --- a/src/core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol +++ b/src/contracts/misc/flashloan/base/FlashLoanSimpleReceiverBase.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.10; import {IFlashLoanSimpleReceiver} from '../interfaces/IFlashLoanSimpleReceiver.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../interfaces/IPool.sol'; /** * @title FlashLoanSimpleReceiverBase diff --git a/src/core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol b/src/contracts/misc/flashloan/interfaces/IFlashLoanReceiver.sol similarity index 90% rename from src/core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol rename to src/contracts/misc/flashloan/interfaces/IFlashLoanReceiver.sol index fae79a9f..a3a55684 100644 --- a/src/core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol +++ b/src/contracts/misc/flashloan/interfaces/IFlashLoanReceiver.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../interfaces/IPool.sol'; /** * @title IFlashLoanReceiver diff --git a/src/core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol b/src/contracts/misc/flashloan/interfaces/IFlashLoanSimpleReceiver.sol similarity index 89% rename from src/core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol rename to src/contracts/misc/flashloan/interfaces/IFlashLoanSimpleReceiver.sol index 05c45739..bff21ae4 100644 --- a/src/core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol +++ b/src/contracts/misc/flashloan/interfaces/IFlashLoanSimpleReceiver.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../interfaces/IPool.sol'; /** * @title IFlashLoanSimpleReceiver diff --git a/src/periphery/contracts/libraries/DataTypesHelper.sol b/src/contracts/misc/libraries/DataTypesHelper.sol similarity index 80% rename from src/periphery/contracts/libraries/DataTypesHelper.sol rename to src/contracts/misc/libraries/DataTypesHelper.sol index 492678a5..eed218ec 100644 --- a/src/periphery/contracts/libraries/DataTypesHelper.sol +++ b/src/contracts/misc/libraries/DataTypesHelper.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; /** * @title DataTypesHelper diff --git a/src/contracts/misc/libraries/RayMathExplicitRounding.sol b/src/contracts/misc/libraries/RayMathExplicitRounding.sol new file mode 100644 index 00000000..8d3f3dcb --- /dev/null +++ b/src/contracts/misc/libraries/RayMathExplicitRounding.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.8.10; + +enum Rounding { + UP, + DOWN +} + +/** + * Simplified version of RayMath that instead of half-up rounding does explicit rounding in a specified direction. + * This is needed to have a 4626 complient implementation, that always predictable rounds in favor of the vault / static a token. + */ +library RayMathExplicitRounding { + uint256 internal constant RAY = 1e27; + uint256 internal constant WAD_RAY_RATIO = 1e9; + + function rayMulRoundDown(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0 || b == 0) { + return 0; + } + return (a * b) / RAY; + } + + function rayMulRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0 || b == 0) { + return 0; + } + return ((a * b) + RAY - 1) / RAY; + } + + function rayDivRoundDown(uint256 a, uint256 b) internal pure returns (uint256) { + return (a * RAY) / b; + } + + function rayDivRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { + return ((a * RAY) + b - 1) / b; + } + + function rayToWadRoundDown(uint256 a) internal pure returns (uint256) { + return a / WAD_RAY_RATIO; + } +} diff --git a/src/periphery/contracts/mocks/ATokenMock.sol b/src/contracts/mocks/ATokenMock.sol similarity index 100% rename from src/periphery/contracts/mocks/ATokenMock.sol rename to src/contracts/mocks/ATokenMock.sol diff --git a/src/periphery/contracts/mocks/MockBadTransferStrategy.sol b/src/contracts/mocks/MockBadTransferStrategy.sol similarity index 82% rename from src/periphery/contracts/mocks/MockBadTransferStrategy.sol rename to src/contracts/mocks/MockBadTransferStrategy.sol index 2f62c89d..696b3396 100644 --- a/src/periphery/contracts/mocks/MockBadTransferStrategy.sol +++ b/src/contracts/mocks/MockBadTransferStrategy.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../rewards/interfaces/ITransferStrategyBase.sol'; import {TransferStrategyBase} from '../rewards/transfer-strategies/TransferStrategyBase.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {GPv2SafeERC20} from '../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title MockBadTransferStrategy diff --git a/src/periphery/contracts/mocks/WETH9Mock.sol b/src/contracts/mocks/WETH9Mock.sol similarity index 72% rename from src/periphery/contracts/mocks/WETH9Mock.sol rename to src/contracts/mocks/WETH9Mock.sol index 1bc1bc48..2372ffeb 100644 --- a/src/periphery/contracts/mocks/WETH9Mock.sol +++ b/src/contracts/mocks/WETH9Mock.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {WETH9} from '../dependencies/weth/WETH9.sol'; +import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; contract WETH9Mock is WETH9, Ownable { constructor(string memory mockName, string memory mockSymbol, address owner) { diff --git a/src/core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol b/src/contracts/mocks/flashloan/MockFlashLoanReceiver.sol similarity index 96% rename from src/core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol rename to src/contracts/mocks/flashloan/MockFlashLoanReceiver.sol index 516b4b38..f8877274 100644 --- a/src/core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol +++ b/src/contracts/mocks/flashloan/MockFlashLoanReceiver.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanReceiverBase} from '../../flashloan/base/FlashLoanReceiverBase.sol'; +import {FlashLoanReceiverBase} from '../../misc/flashloan/base/FlashLoanReceiverBase.sol'; import {MintableERC20} from '../tokens/MintableERC20.sol'; contract MockFlashLoanReceiver is FlashLoanReceiverBase { diff --git a/src/core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol b/src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol similarity index 95% rename from src/core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol rename to src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol index 1edd24a2..b3be47bc 100644 --- a/src/core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol +++ b/src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol @@ -6,7 +6,7 @@ import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanSimpleReceiverBase} from '../../flashloan/base/FlashLoanSimpleReceiverBase.sol'; +import {FlashLoanSimpleReceiverBase} from '../../misc/flashloan/base/FlashLoanSimpleReceiverBase.sol'; import {MintableERC20} from '../tokens/MintableERC20.sol'; contract MockFlashLoanSimpleReceiver is FlashLoanSimpleReceiverBase { diff --git a/src/core/contracts/mocks/helpers/MockIncentivesController.sol b/src/contracts/mocks/helpers/MockIncentivesController.sol similarity index 100% rename from src/core/contracts/mocks/helpers/MockIncentivesController.sol rename to src/contracts/mocks/helpers/MockIncentivesController.sol diff --git a/src/core/contracts/mocks/helpers/MockL2Pool.sol b/src/contracts/mocks/helpers/MockL2Pool.sol similarity index 68% rename from src/core/contracts/mocks/helpers/MockL2Pool.sol rename to src/contracts/mocks/helpers/MockL2Pool.sol index c37a7f70..9035cddd 100644 --- a/src/core/contracts/mocks/helpers/MockL2Pool.sol +++ b/src/contracts/mocks/helpers/MockL2Pool.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {L2PoolInstance, PoolInstance} from '../../../instances/L2PoolInstance.sol'; -import {VersionedInitializable} from '../../protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; +import {L2PoolInstance, PoolInstance} from '../../instances/L2PoolInstance.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; contract MockL2Pool is L2PoolInstance { function getRevision() diff --git a/src/core/contracts/mocks/helpers/MockPeripheryContract.sol b/src/contracts/mocks/helpers/MockPeripheryContract.sol similarity index 100% rename from src/core/contracts/mocks/helpers/MockPeripheryContract.sol rename to src/contracts/mocks/helpers/MockPeripheryContract.sol diff --git a/src/core/contracts/mocks/helpers/MockPool.sol b/src/contracts/mocks/helpers/MockPool.sol similarity index 92% rename from src/core/contracts/mocks/helpers/MockPool.sol rename to src/contracts/mocks/helpers/MockPool.sol index c66b83a6..7a27bf14 100644 --- a/src/core/contracts/mocks/helpers/MockPool.sol +++ b/src/contracts/mocks/helpers/MockPool.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {PoolInstance} from '../../../instances/PoolInstance.sol'; +import {PoolInstance} from '../../instances/PoolInstance.sol'; contract MockPoolInherited is PoolInstance { uint16 internal _maxNumberOfReserves = 128; diff --git a/src/core/contracts/mocks/helpers/MockReserveConfiguration.sol b/src/contracts/mocks/helpers/MockReserveConfiguration.sol similarity index 100% rename from src/core/contracts/mocks/helpers/MockReserveConfiguration.sol rename to src/contracts/mocks/helpers/MockReserveConfiguration.sol diff --git a/src/core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol b/src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol similarity index 100% rename from src/core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol rename to src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol diff --git a/src/core/contracts/mocks/oracle/PriceOracle.sol b/src/contracts/mocks/oracle/PriceOracle.sol similarity index 100% rename from src/core/contracts/mocks/oracle/PriceOracle.sol rename to src/contracts/mocks/oracle/PriceOracle.sol diff --git a/src/core/contracts/mocks/oracle/SequencerOracle.sol b/src/contracts/mocks/oracle/SequencerOracle.sol similarity index 100% rename from src/core/contracts/mocks/oracle/SequencerOracle.sol rename to src/contracts/mocks/oracle/SequencerOracle.sol diff --git a/src/periphery/contracts/mocks/swap/MockParaSwapAugustus.sol b/src/contracts/mocks/swap/MockParaSwapAugustus.sol similarity index 91% rename from src/periphery/contracts/mocks/swap/MockParaSwapAugustus.sol rename to src/contracts/mocks/swap/MockParaSwapAugustus.sol index cf41670b..5970c3b7 100644 --- a/src/periphery/contracts/mocks/swap/MockParaSwapAugustus.sol +++ b/src/contracts/mocks/swap/MockParaSwapAugustus.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IParaSwapAugustus} from '../../adapters/paraswap/interfaces/IParaSwapAugustus.sol'; +import {IParaSwapAugustus} from '../../extensions/paraswap-adapters/interfaces/IParaSwapAugustus.sol'; import {MockParaSwapTokenTransferProxy} from './MockParaSwapTokenTransferProxy.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {MintableERC20} from 'aave-v3-core/contracts/mocks/tokens/MintableERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {MintableERC20} from '../tokens/MintableERC20.sol'; contract MockParaSwapAugustus is IParaSwapAugustus { MockParaSwapTokenTransferProxy immutable TOKEN_TRANSFER_PROXY; diff --git a/src/periphery/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol b/src/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol similarity index 74% rename from src/periphery/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol rename to src/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol index 5e34d659..82fa93f8 100644 --- a/src/periphery/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol +++ b/src/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IParaSwapAugustusRegistry} from '../../adapters/paraswap/interfaces/IParaSwapAugustusRegistry.sol'; +import {IParaSwapAugustusRegistry} from '../../extensions/paraswap-adapters/interfaces/IParaSwapAugustusRegistry.sol'; contract MockParaSwapAugustusRegistry is IParaSwapAugustusRegistry { address immutable AUGUSTUS; diff --git a/src/periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol b/src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol similarity index 88% rename from src/periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol rename to src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol index efec5e9d..80f41d19 100644 --- a/src/periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol +++ b/src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IFeeClaimer} from '../../adapters/paraswap/interfaces/IFeeClaimer.sol'; +import {IFeeClaimer} from '../../extensions/paraswap-adapters/interfaces/IFeeClaimer.sol'; import {MockParaSwapTokenTransferProxy} from './MockParaSwapTokenTransferProxy.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {MintableERC20} from 'aave-v3-core/contracts/mocks/tokens/MintableERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {MintableERC20} from '../tokens/MintableERC20.sol'; contract MockParaSwapFeeClaimer is IFeeClaimer { MockParaSwapTokenTransferProxy immutable TOKEN_TRANSFER_PROXY; diff --git a/src/periphery/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol b/src/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol similarity index 60% rename from src/periphery/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol rename to src/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol index 711012e8..b36e6a44 100644 --- a/src/periphery/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol +++ b/src/contracts/mocks/swap/MockParaSwapTokenTransferProxy.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; contract MockParaSwapTokenTransferProxy is Ownable { function transferFrom( diff --git a/src/periphery/contracts/mocks/testnet-helpers/Faucet.sol b/src/contracts/mocks/testnet-helpers/Faucet.sol similarity index 95% rename from src/periphery/contracts/mocks/testnet-helpers/Faucet.sol rename to src/contracts/mocks/testnet-helpers/Faucet.sol index 539aee46..47a2a3f6 100644 --- a/src/periphery/contracts/mocks/testnet-helpers/Faucet.sol +++ b/src/contracts/mocks/testnet-helpers/Faucet.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; import {TestnetERC20} from './TestnetERC20.sol'; import {IFaucet} from './IFaucet.sol'; diff --git a/src/periphery/contracts/mocks/testnet-helpers/IFaucet.sol b/src/contracts/mocks/testnet-helpers/IFaucet.sol similarity index 100% rename from src/periphery/contracts/mocks/testnet-helpers/IFaucet.sol rename to src/contracts/mocks/testnet-helpers/IFaucet.sol diff --git a/src/periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol b/src/contracts/mocks/testnet-helpers/TestnetERC20.sol similarity index 90% rename from src/periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol rename to src/contracts/mocks/testnet-helpers/TestnetERC20.sol index 58e4ddf2..efe94186 100644 --- a/src/periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol +++ b/src/contracts/mocks/testnet-helpers/TestnetERC20.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; -import {ERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC20.sol'; -import {IERC20WithPermit} from 'aave-v3-core/contracts/interfaces/IERC20WithPermit.sol'; +import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; +import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; /** * @title TestnetERC20 diff --git a/src/core/contracts/mocks/tests/FlashloanAttacker.sol b/src/contracts/mocks/tests/FlashloanAttacker.sol similarity index 95% rename from src/core/contracts/mocks/tests/FlashloanAttacker.sol rename to src/contracts/mocks/tests/FlashloanAttacker.sol index 63d09b1b..9f32fbd9 100644 --- a/src/core/contracts/mocks/tests/FlashloanAttacker.sol +++ b/src/contracts/mocks/tests/FlashloanAttacker.sol @@ -6,7 +6,7 @@ import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanSimpleReceiverBase} from '../../flashloan/base/FlashLoanSimpleReceiverBase.sol'; +import {FlashLoanSimpleReceiverBase} from '../../misc/flashloan/base/FlashLoanSimpleReceiverBase.sol'; import {MintableERC20} from '../tokens/MintableERC20.sol'; import {IPool} from '../../interfaces/IPool.sol'; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; diff --git a/src/core/contracts/mocks/tests/MathUtilsWrapper.sol b/src/contracts/mocks/tests/MathUtilsWrapper.sol similarity index 100% rename from src/core/contracts/mocks/tests/MathUtilsWrapper.sol rename to src/contracts/mocks/tests/MathUtilsWrapper.sol diff --git a/src/core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol b/src/contracts/mocks/tests/MockReserveInterestRateStrategy.sol similarity index 88% rename from src/core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol rename to src/contracts/mocks/tests/MockReserveInterestRateStrategy.sol index 082d7651..fd7b1f25 100644 --- a/src/core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol +++ b/src/contracts/mocks/tests/MockReserveInterestRateStrategy.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {DefaultReserveInterestRateStrategyV2} from '../../protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; +import {DefaultReserveInterestRateStrategyV2} from '../../misc/DefaultReserveInterestRateStrategyV2.sol'; import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; contract MockReserveInterestRateStrategy is DefaultReserveInterestRateStrategyV2 { diff --git a/src/core/contracts/mocks/tests/PercentageMathWrapper.sol b/src/contracts/mocks/tests/PercentageMathWrapper.sol similarity index 100% rename from src/core/contracts/mocks/tests/PercentageMathWrapper.sol rename to src/contracts/mocks/tests/PercentageMathWrapper.sol diff --git a/src/core/contracts/mocks/tests/WadRayMathWrapper.sol b/src/contracts/mocks/tests/WadRayMathWrapper.sol similarity index 100% rename from src/core/contracts/mocks/tests/WadRayMathWrapper.sol rename to src/contracts/mocks/tests/WadRayMathWrapper.sol diff --git a/src/core/contracts/mocks/tokens/MintableDelegationERC20.sol b/src/contracts/mocks/tokens/MintableDelegationERC20.sol similarity index 100% rename from src/core/contracts/mocks/tokens/MintableDelegationERC20.sol rename to src/contracts/mocks/tokens/MintableDelegationERC20.sol diff --git a/src/core/contracts/mocks/tokens/MintableERC20.sol b/src/contracts/mocks/tokens/MintableERC20.sol similarity index 100% rename from src/core/contracts/mocks/tokens/MintableERC20.sol rename to src/contracts/mocks/tokens/MintableERC20.sol diff --git a/src/core/contracts/mocks/tokens/MockATokenRepayment.sol b/src/contracts/mocks/tokens/MockATokenRepayment.sol similarity index 88% rename from src/core/contracts/mocks/tokens/MockATokenRepayment.sol rename to src/contracts/mocks/tokens/MockATokenRepayment.sol index 4e2c0dd2..c0f77de5 100644 --- a/src/core/contracts/mocks/tokens/MockATokenRepayment.sol +++ b/src/contracts/mocks/tokens/MockATokenRepayment.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {ATokenInstance} from '../../../instances/ATokenInstance.sol'; +import {ATokenInstance} from '../../instances/ATokenInstance.sol'; import {IPool} from '../../interfaces/IPool.sol'; contract MockATokenRepayment is ATokenInstance { diff --git a/src/core/contracts/mocks/tokens/MockDebtTokens.sol b/src/contracts/mocks/tokens/MockDebtTokens.sol similarity index 74% rename from src/core/contracts/mocks/tokens/MockDebtTokens.sol rename to src/contracts/mocks/tokens/MockDebtTokens.sol index 8c186b82..7418dab3 100644 --- a/src/core/contracts/mocks/tokens/MockDebtTokens.sol +++ b/src/contracts/mocks/tokens/MockDebtTokens.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {VariableDebtTokenInstance} from '../../../instances/VariableDebtTokenInstance.sol'; -import {StableDebtTokenInstance} from '../../../instances/StableDebtTokenInstance.sol'; +import {VariableDebtTokenInstance} from '../../instances/VariableDebtTokenInstance.sol'; +import {StableDebtTokenInstance} from '../../instances/StableDebtTokenInstance.sol'; import {IPool} from '../../interfaces/IPool.sol'; contract MockVariableDebtToken is VariableDebtTokenInstance { diff --git a/src/core/contracts/mocks/tokens/MockScaledToken.sol b/src/contracts/mocks/tokens/MockScaledToken.sol similarity index 85% rename from src/core/contracts/mocks/tokens/MockScaledToken.sol rename to src/contracts/mocks/tokens/MockScaledToken.sol index 854f4356..f3a26e2e 100644 --- a/src/core/contracts/mocks/tokens/MockScaledToken.sol +++ b/src/contracts/mocks/tokens/MockScaledToken.sol @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import 'aave-v3-core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol'; -import 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; +import '../../protocol/tokenization/base/ScaledBalanceTokenBase.sol'; +import '../../protocol/libraries/math/WadRayMath.sol'; contract MockScaledToken is ScaledBalanceTokenBase { using WadRayMath for uint256; diff --git a/src/core/contracts/mocks/tokens/WETH9Mocked.sol b/src/contracts/mocks/tokens/WETH9Mocked.sol similarity index 100% rename from src/core/contracts/mocks/tokens/WETH9Mocked.sol rename to src/contracts/mocks/tokens/WETH9Mocked.sol diff --git a/src/core/contracts/mocks/upgradeability/MockAToken.sol b/src/contracts/mocks/upgradeability/MockAToken.sol similarity index 80% rename from src/core/contracts/mocks/upgradeability/MockAToken.sol rename to src/contracts/mocks/upgradeability/MockAToken.sol index bcdc8c1c..14bbf1a8 100644 --- a/src/core/contracts/mocks/upgradeability/MockAToken.sol +++ b/src/contracts/mocks/upgradeability/MockAToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {ATokenInstance} from '../../../instances/ATokenInstance.sol'; +import {ATokenInstance} from '../../instances/ATokenInstance.sol'; import {IPool} from '../../interfaces/IPool.sol'; contract MockAToken is ATokenInstance { diff --git a/src/core/contracts/mocks/upgradeability/MockInitializableImplementation.sol b/src/contracts/mocks/upgradeability/MockInitializableImplementation.sol similarity index 96% rename from src/core/contracts/mocks/upgradeability/MockInitializableImplementation.sol rename to src/contracts/mocks/upgradeability/MockInitializableImplementation.sol index 9f63a598..ed48f44b 100644 --- a/src/core/contracts/mocks/upgradeability/MockInitializableImplementation.sol +++ b/src/contracts/mocks/upgradeability/MockInitializableImplementation.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {VersionedInitializable} from '../../protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; contract MockInitializableImple is VersionedInitializable { diff --git a/src/core/contracts/mocks/upgradeability/MockStableDebtToken.sol b/src/contracts/mocks/upgradeability/MockStableDebtToken.sol similarity index 78% rename from src/core/contracts/mocks/upgradeability/MockStableDebtToken.sol rename to src/contracts/mocks/upgradeability/MockStableDebtToken.sol index ea9d5cca..ecbd73c9 100644 --- a/src/core/contracts/mocks/upgradeability/MockStableDebtToken.sol +++ b/src/contracts/mocks/upgradeability/MockStableDebtToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {StableDebtTokenInstance} from '../../../instances/StableDebtTokenInstance.sol'; +import {StableDebtTokenInstance} from '../../instances/StableDebtTokenInstance.sol'; import {IPool} from '../../interfaces/IPool.sol'; contract MockStableDebtToken is StableDebtTokenInstance { diff --git a/src/core/contracts/mocks/upgradeability/MockVariableDebtToken.sol b/src/contracts/mocks/upgradeability/MockVariableDebtToken.sol similarity index 77% rename from src/core/contracts/mocks/upgradeability/MockVariableDebtToken.sol rename to src/contracts/mocks/upgradeability/MockVariableDebtToken.sol index 211821f5..a75db430 100644 --- a/src/core/contracts/mocks/upgradeability/MockVariableDebtToken.sol +++ b/src/contracts/mocks/upgradeability/MockVariableDebtToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {VariableDebtTokenInstance} from '../../../instances/VariableDebtTokenInstance.sol'; +import {VariableDebtTokenInstance} from '../../instances/VariableDebtTokenInstance.sol'; import {IPool} from '../../interfaces/IPool.sol'; contract MockVariableDebtToken is VariableDebtTokenInstance { diff --git a/src/core/contracts/protocol/configuration/ACLManager.sol b/src/contracts/protocol/configuration/ACLManager.sol similarity index 100% rename from src/core/contracts/protocol/configuration/ACLManager.sol rename to src/contracts/protocol/configuration/ACLManager.sol diff --git a/src/core/contracts/protocol/configuration/PoolAddressesProvider.sol b/src/contracts/protocol/configuration/PoolAddressesProvider.sol similarity index 98% rename from src/core/contracts/protocol/configuration/PoolAddressesProvider.sol rename to src/contracts/protocol/configuration/PoolAddressesProvider.sol index 06fa9333..009f4e5c 100644 --- a/src/core/contracts/protocol/configuration/PoolAddressesProvider.sol +++ b/src/contracts/protocol/configuration/PoolAddressesProvider.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {InitializableImmutableAdminUpgradeabilityProxy} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; +import {InitializableImmutableAdminUpgradeabilityProxy} from '../../misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; /** * @title PoolAddressesProvider diff --git a/src/core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol b/src/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol similarity index 100% rename from src/core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol rename to src/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol diff --git a/src/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol similarity index 100% rename from src/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol rename to src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol diff --git a/src/core/contracts/protocol/libraries/configuration/UserConfiguration.sol b/src/contracts/protocol/libraries/configuration/UserConfiguration.sol similarity index 100% rename from src/core/contracts/protocol/libraries/configuration/UserConfiguration.sol rename to src/contracts/protocol/libraries/configuration/UserConfiguration.sol diff --git a/src/core/contracts/protocol/libraries/helpers/Errors.sol b/src/contracts/protocol/libraries/helpers/Errors.sol similarity index 100% rename from src/core/contracts/protocol/libraries/helpers/Errors.sol rename to src/contracts/protocol/libraries/helpers/Errors.sol diff --git a/src/core/contracts/protocol/libraries/helpers/Helpers.sol b/src/contracts/protocol/libraries/helpers/Helpers.sol similarity index 100% rename from src/core/contracts/protocol/libraries/helpers/Helpers.sol rename to src/contracts/protocol/libraries/helpers/Helpers.sol diff --git a/src/core/contracts/protocol/libraries/logic/BorrowLogic.sol b/src/contracts/protocol/libraries/logic/BorrowLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/BorrowLogic.sol rename to src/contracts/protocol/libraries/logic/BorrowLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/BridgeLogic.sol b/src/contracts/protocol/libraries/logic/BridgeLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/BridgeLogic.sol rename to src/contracts/protocol/libraries/logic/BridgeLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/CalldataLogic.sol b/src/contracts/protocol/libraries/logic/CalldataLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/CalldataLogic.sol rename to src/contracts/protocol/libraries/logic/CalldataLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol b/src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol similarity index 99% rename from src/core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol rename to src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol index e0b14e7b..244a2a55 100644 --- a/src/core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol +++ b/src/contracts/protocol/libraries/logic/ConfiguratorLogic.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.10; import {IPool} from '../../../interfaces/IPool.sol'; import {IInitializableAToken} from '../../../interfaces/IInitializableAToken.sol'; import {IInitializableDebtToken} from '../../../interfaces/IInitializableDebtToken.sol'; -import {InitializableImmutableAdminUpgradeabilityProxy} from '../aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; +import {InitializableImmutableAdminUpgradeabilityProxy} from '../../../misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; import {DataTypes} from '../types/DataTypes.sol'; diff --git a/src/core/contracts/protocol/libraries/logic/EModeLogic.sol b/src/contracts/protocol/libraries/logic/EModeLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/EModeLogic.sol rename to src/contracts/protocol/libraries/logic/EModeLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/FlashLoanLogic.sol b/src/contracts/protocol/libraries/logic/FlashLoanLogic.sol similarity index 98% rename from src/core/contracts/protocol/libraries/logic/FlashLoanLogic.sol rename to src/contracts/protocol/libraries/logic/FlashLoanLogic.sol index 615b2fdd..efb4feae 100644 --- a/src/core/contracts/protocol/libraries/logic/FlashLoanLogic.sol +++ b/src/contracts/protocol/libraries/logic/FlashLoanLogic.sol @@ -6,8 +6,8 @@ import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.so import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IAToken} from '../../../interfaces/IAToken.sol'; import {IPool} from '../../../interfaces/IPool.sol'; -import {IFlashLoanReceiver} from '../../../flashloan/interfaces/IFlashLoanReceiver.sol'; -import {IFlashLoanSimpleReceiver} from '../../../flashloan/interfaces/IFlashLoanSimpleReceiver.sol'; +import {IFlashLoanReceiver} from '../../../misc/flashloan/interfaces/IFlashLoanReceiver.sol'; +import {IFlashLoanSimpleReceiver} from '../../../misc/flashloan/interfaces/IFlashLoanSimpleReceiver.sol'; import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; diff --git a/src/core/contracts/protocol/libraries/logic/GenericLogic.sol b/src/contracts/protocol/libraries/logic/GenericLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/GenericLogic.sol rename to src/contracts/protocol/libraries/logic/GenericLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/IsolationModeLogic.sol b/src/contracts/protocol/libraries/logic/IsolationModeLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/IsolationModeLogic.sol rename to src/contracts/protocol/libraries/logic/IsolationModeLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/LiquidationLogic.sol b/src/contracts/protocol/libraries/logic/LiquidationLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/LiquidationLogic.sol rename to src/contracts/protocol/libraries/logic/LiquidationLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/PoolLogic.sol b/src/contracts/protocol/libraries/logic/PoolLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/PoolLogic.sol rename to src/contracts/protocol/libraries/logic/PoolLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/ReserveLogic.sol b/src/contracts/protocol/libraries/logic/ReserveLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/ReserveLogic.sol rename to src/contracts/protocol/libraries/logic/ReserveLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/SupplyLogic.sol b/src/contracts/protocol/libraries/logic/SupplyLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/SupplyLogic.sol rename to src/contracts/protocol/libraries/logic/SupplyLogic.sol diff --git a/src/core/contracts/protocol/libraries/logic/ValidationLogic.sol b/src/contracts/protocol/libraries/logic/ValidationLogic.sol similarity index 100% rename from src/core/contracts/protocol/libraries/logic/ValidationLogic.sol rename to src/contracts/protocol/libraries/logic/ValidationLogic.sol diff --git a/src/core/contracts/protocol/libraries/math/MathUtils.sol b/src/contracts/protocol/libraries/math/MathUtils.sol similarity index 100% rename from src/core/contracts/protocol/libraries/math/MathUtils.sol rename to src/contracts/protocol/libraries/math/MathUtils.sol diff --git a/src/core/contracts/protocol/libraries/math/PercentageMath.sol b/src/contracts/protocol/libraries/math/PercentageMath.sol similarity index 100% rename from src/core/contracts/protocol/libraries/math/PercentageMath.sol rename to src/contracts/protocol/libraries/math/PercentageMath.sol diff --git a/src/core/contracts/protocol/libraries/math/WadRayMath.sol b/src/contracts/protocol/libraries/math/WadRayMath.sol similarity index 100% rename from src/core/contracts/protocol/libraries/math/WadRayMath.sol rename to src/contracts/protocol/libraries/math/WadRayMath.sol diff --git a/src/core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol b/src/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol similarity index 100% rename from src/core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol rename to src/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol diff --git a/src/core/contracts/protocol/libraries/types/DataTypes.sol b/src/contracts/protocol/libraries/types/DataTypes.sol similarity index 100% rename from src/core/contracts/protocol/libraries/types/DataTypes.sol rename to src/contracts/protocol/libraries/types/DataTypes.sol diff --git a/src/core/contracts/protocol/pool/L2Pool.sol b/src/contracts/protocol/pool/L2Pool.sol similarity index 100% rename from src/core/contracts/protocol/pool/L2Pool.sol rename to src/contracts/protocol/pool/L2Pool.sol diff --git a/src/core/contracts/protocol/pool/Pool.sol b/src/contracts/protocol/pool/Pool.sol similarity index 99% rename from src/core/contracts/protocol/pool/Pool.sol rename to src/contracts/protocol/pool/Pool.sol index 4397323d..c58a78d5 100644 --- a/src/core/contracts/protocol/pool/Pool.sol +++ b/src/contracts/protocol/pool/Pool.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {PoolLogic} from '../libraries/logic/PoolLogic.sol'; diff --git a/src/core/contracts/protocol/pool/PoolConfigurator.sol b/src/contracts/protocol/pool/PoolConfigurator.sol similarity index 99% rename from src/core/contracts/protocol/pool/PoolConfigurator.sol rename to src/contracts/protocol/pool/PoolConfigurator.sol index 041943e1..b22581b0 100644 --- a/src/core/contracts/protocol/pool/PoolConfigurator.sol +++ b/src/contracts/protocol/pool/PoolConfigurator.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; import {IDefaultInterestRateStrategyV2} from '../../interfaces/IDefaultInterestRateStrategyV2.sol'; diff --git a/src/core/contracts/protocol/pool/PoolStorage.sol b/src/contracts/protocol/pool/PoolStorage.sol similarity index 100% rename from src/core/contracts/protocol/pool/PoolStorage.sol rename to src/contracts/protocol/pool/PoolStorage.sol diff --git a/src/core/contracts/protocol/tokenization/AToken.sol b/src/contracts/protocol/tokenization/AToken.sol similarity index 98% rename from src/core/contracts/protocol/tokenization/AToken.sol rename to src/contracts/protocol/tokenization/AToken.sol index 126801bf..47ba03d9 100644 --- a/src/core/contracts/protocol/tokenization/AToken.sol +++ b/src/contracts/protocol/tokenization/AToken.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {SafeCast} from '../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {IPool} from '../../interfaces/IPool.sol'; diff --git a/src/core/contracts/protocol/tokenization/StableDebtToken.sol b/src/contracts/protocol/tokenization/StableDebtToken.sol similarity index 97% rename from src/core/contracts/protocol/tokenization/StableDebtToken.sol rename to src/contracts/protocol/tokenization/StableDebtToken.sol index e7c785e6..74995247 100644 --- a/src/core/contracts/protocol/tokenization/StableDebtToken.sol +++ b/src/contracts/protocol/tokenization/StableDebtToken.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; import {IInitializableDebtToken} from '../../interfaces/IInitializableDebtToken.sol'; diff --git a/src/core/contracts/protocol/tokenization/VariableDebtToken.sol b/src/contracts/protocol/tokenization/VariableDebtToken.sol similarity index 97% rename from src/core/contracts/protocol/tokenization/VariableDebtToken.sol rename to src/contracts/protocol/tokenization/VariableDebtToken.sol index 0987494b..37494c85 100644 --- a/src/core/contracts/protocol/tokenization/VariableDebtToken.sol +++ b/src/contracts/protocol/tokenization/VariableDebtToken.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {SafeCast} from '../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../misc/aave-upgradeability/VersionedInitializable.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {IPool} from '../../interfaces/IPool.sol'; diff --git a/src/core/contracts/protocol/tokenization/base/DebtTokenBase.sol b/src/contracts/protocol/tokenization/base/DebtTokenBase.sol similarity index 97% rename from src/core/contracts/protocol/tokenization/base/DebtTokenBase.sol rename to src/contracts/protocol/tokenization/base/DebtTokenBase.sol index 8dc79203..3280add0 100644 --- a/src/core/contracts/protocol/tokenization/base/DebtTokenBase.sol +++ b/src/contracts/protocol/tokenization/base/DebtTokenBase.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol'; import {Errors} from '../../libraries/helpers/Errors.sol'; -import {VersionedInitializable} from '../../libraries/aave-upgradeability/VersionedInitializable.sol'; +import {VersionedInitializable} from '../../../misc/aave-upgradeability/VersionedInitializable.sol'; import {ICreditDelegationToken} from '../../../interfaces/ICreditDelegationToken.sol'; import {EIP712Base} from './EIP712Base.sol'; diff --git a/src/core/contracts/protocol/tokenization/base/EIP712Base.sol b/src/contracts/protocol/tokenization/base/EIP712Base.sol similarity index 100% rename from src/core/contracts/protocol/tokenization/base/EIP712Base.sol rename to src/contracts/protocol/tokenization/base/EIP712Base.sol diff --git a/src/core/contracts/protocol/tokenization/base/IncentivizedERC20.sol b/src/contracts/protocol/tokenization/base/IncentivizedERC20.sol similarity index 100% rename from src/core/contracts/protocol/tokenization/base/IncentivizedERC20.sol rename to src/contracts/protocol/tokenization/base/IncentivizedERC20.sol diff --git a/src/core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol b/src/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol similarity index 100% rename from src/core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol rename to src/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol diff --git a/src/core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol b/src/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol similarity index 100% rename from src/core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol rename to src/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol diff --git a/src/periphery/contracts/rewards/EmissionManager.sol b/src/contracts/rewards/EmissionManager.sol similarity index 95% rename from src/periphery/contracts/rewards/EmissionManager.sol rename to src/contracts/rewards/EmissionManager.sol index 19138df8..b18473ff 100644 --- a/src/periphery/contracts/rewards/EmissionManager.sol +++ b/src/contracts/rewards/EmissionManager.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; -import {IEACAggregatorProxy} from '../misc/interfaces/IEACAggregatorProxy.sol'; +import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; +import {IEACAggregatorProxy} from '../helpers/interfaces/IEACAggregatorProxy.sol'; import {IEmissionManager} from './interfaces/IEmissionManager.sol'; import {ITransferStrategyBase} from './interfaces/ITransferStrategyBase.sol'; import {IRewardsController} from './interfaces/IRewardsController.sol'; diff --git a/src/periphery/contracts/rewards/RewardsController.sol b/src/contracts/rewards/RewardsController.sol similarity index 96% rename from src/periphery/contracts/rewards/RewardsController.sol rename to src/contracts/rewards/RewardsController.sol index 0c369a60..3a817f60 100644 --- a/src/periphery/contracts/rewards/RewardsController.sol +++ b/src/contracts/rewards/RewardsController.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {VersionedInitializable} from 'aave-v3-core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; -import {SafeCast} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IScaledBalanceToken} from 'aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol'; +import {VersionedInitializable} from '../misc/aave-upgradeability/VersionedInitializable.sol'; +import {SafeCast} from '../dependencies/openzeppelin/contracts/SafeCast.sol'; +import {IScaledBalanceToken} from '../interfaces/IScaledBalanceToken.sol'; import {RewardsDistributor} from './RewardsDistributor.sol'; import {IRewardsController} from './interfaces/IRewardsController.sol'; import {ITransferStrategyBase} from './interfaces/ITransferStrategyBase.sol'; import {RewardsDataTypes} from './libraries/RewardsDataTypes.sol'; -import {IEACAggregatorProxy} from '../misc/interfaces/IEACAggregatorProxy.sol'; +import {IEACAggregatorProxy} from '../helpers/interfaces/IEACAggregatorProxy.sol'; /** * @title RewardsController diff --git a/src/periphery/contracts/rewards/RewardsDistributor.sol b/src/contracts/rewards/RewardsDistributor.sol similarity index 98% rename from src/periphery/contracts/rewards/RewardsDistributor.sol rename to src/contracts/rewards/RewardsDistributor.sol index ffc03d05..c8aa7a23 100644 --- a/src/periphery/contracts/rewards/RewardsDistributor.sol +++ b/src/contracts/rewards/RewardsDistributor.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IScaledBalanceToken} from 'aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {SafeCast} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; +import {IScaledBalanceToken} from '../interfaces/IScaledBalanceToken.sol'; +import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {SafeCast} from '../dependencies/openzeppelin/contracts/SafeCast.sol'; import {IRewardsDistributor} from './interfaces/IRewardsDistributor.sol'; import {RewardsDataTypes} from './libraries/RewardsDataTypes.sol'; diff --git a/src/periphery/contracts/rewards/interfaces/IEmissionManager.sol b/src/contracts/rewards/interfaces/IEmissionManager.sol similarity index 98% rename from src/periphery/contracts/rewards/interfaces/IEmissionManager.sol rename to src/contracts/rewards/interfaces/IEmissionManager.sol index 2f1f7eac..4853af21 100644 --- a/src/periphery/contracts/rewards/interfaces/IEmissionManager.sol +++ b/src/contracts/rewards/interfaces/IEmissionManager.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol'; +import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; import {RewardsDataTypes} from '../libraries/RewardsDataTypes.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; import {IRewardsController} from './IRewardsController.sol'; diff --git a/src/periphery/contracts/rewards/interfaces/IPullRewardsTransferStrategy.sol b/src/contracts/rewards/interfaces/IPullRewardsTransferStrategy.sol similarity index 100% rename from src/periphery/contracts/rewards/interfaces/IPullRewardsTransferStrategy.sol rename to src/contracts/rewards/interfaces/IPullRewardsTransferStrategy.sol diff --git a/src/periphery/contracts/rewards/interfaces/IRewardsController.sol b/src/contracts/rewards/interfaces/IRewardsController.sol similarity index 99% rename from src/periphery/contracts/rewards/interfaces/IRewardsController.sol rename to src/contracts/rewards/interfaces/IRewardsController.sol index 952da7cb..cdb2ac29 100644 --- a/src/periphery/contracts/rewards/interfaces/IRewardsController.sol +++ b/src/contracts/rewards/interfaces/IRewardsController.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {IRewardsDistributor} from './IRewardsDistributor.sol'; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; -import {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol'; +import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; import {RewardsDataTypes} from '../libraries/RewardsDataTypes.sol'; /** diff --git a/src/periphery/contracts/rewards/interfaces/IRewardsDistributor.sol b/src/contracts/rewards/interfaces/IRewardsDistributor.sol similarity index 100% rename from src/periphery/contracts/rewards/interfaces/IRewardsDistributor.sol rename to src/contracts/rewards/interfaces/IRewardsDistributor.sol diff --git a/src/periphery/contracts/rewards/interfaces/IStakedToken.sol b/src/contracts/rewards/interfaces/IStakedToken.sol similarity index 100% rename from src/periphery/contracts/rewards/interfaces/IStakedToken.sol rename to src/contracts/rewards/interfaces/IStakedToken.sol diff --git a/src/periphery/contracts/rewards/interfaces/IStakedTokenTransferStrategy.sol b/src/contracts/rewards/interfaces/IStakedTokenTransferStrategy.sol similarity index 100% rename from src/periphery/contracts/rewards/interfaces/IStakedTokenTransferStrategy.sol rename to src/contracts/rewards/interfaces/IStakedTokenTransferStrategy.sol diff --git a/src/periphery/contracts/rewards/interfaces/ITransferStrategyBase.sol b/src/contracts/rewards/interfaces/ITransferStrategyBase.sol similarity index 100% rename from src/periphery/contracts/rewards/interfaces/ITransferStrategyBase.sol rename to src/contracts/rewards/interfaces/ITransferStrategyBase.sol diff --git a/src/periphery/contracts/rewards/libraries/RewardsDataTypes.sol b/src/contracts/rewards/libraries/RewardsDataTypes.sol similarity index 94% rename from src/periphery/contracts/rewards/libraries/RewardsDataTypes.sol rename to src/contracts/rewards/libraries/RewardsDataTypes.sol index 4cafda32..38fe87c5 100644 --- a/src/periphery/contracts/rewards/libraries/RewardsDataTypes.sol +++ b/src/contracts/rewards/libraries/RewardsDataTypes.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; -import {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol'; +import {IEACAggregatorProxy} from '../../helpers/interfaces/IEACAggregatorProxy.sol'; library RewardsDataTypes { struct RewardsConfigInput { diff --git a/src/periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol b/src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol similarity index 88% rename from src/periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol rename to src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol index 46620b3e..dc4b5a9b 100644 --- a/src/periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol +++ b/src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.10; import {IPullRewardsTransferStrategy} from '../interfaces/IPullRewardsTransferStrategy.sol'; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {TransferStrategyBase} from './TransferStrategyBase.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title PullRewardsTransferStrategy diff --git a/src/periphery/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol b/src/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol similarity index 92% rename from src/periphery/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol rename to src/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol index bb3901c3..9ca6f8c3 100644 --- a/src/periphery/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol +++ b/src/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol @@ -5,8 +5,8 @@ import {IStakedToken} from '../interfaces/IStakedToken.sol'; import {IStakedTokenTransferStrategy} from '../interfaces/IStakedTokenTransferStrategy.sol'; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {TransferStrategyBase} from './TransferStrategyBase.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title StakedTokenTransferStrategy diff --git a/src/periphery/contracts/rewards/transfer-strategies/TransferStrategyBase.sol b/src/contracts/rewards/transfer-strategies/TransferStrategyBase.sol similarity index 89% rename from src/periphery/contracts/rewards/transfer-strategies/TransferStrategyBase.sol rename to src/contracts/rewards/transfer-strategies/TransferStrategyBase.sol index 2f26b958..5064606d 100644 --- a/src/periphery/contracts/rewards/transfer-strategies/TransferStrategyBase.sol +++ b/src/contracts/rewards/transfer-strategies/TransferStrategyBase.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; -import {GPv2SafeERC20} from 'aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; +import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title TransferStrategyStorage diff --git a/src/periphery/contracts/treasury/Collector.sol b/src/contracts/treasury/Collector.sol similarity index 96% rename from src/periphery/contracts/treasury/Collector.sol rename to src/contracts/treasury/Collector.sol index 22cf3e2f..daf6b7a3 100644 --- a/src/periphery/contracts/treasury/Collector.sol +++ b/src/contracts/treasury/Collector.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import {ICollector} from './ICollector.sol'; import {ReentrancyGuard} from '../dependencies/openzeppelin/ReentrancyGuard.sol'; -import {VersionedInitializable} from '../../../core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; -import {IERC20} from '../../../core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {SafeERC20} from '../../../core/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {Address} from '../../../core/contracts/dependencies/openzeppelin/contracts/Address.sol'; +import {VersionedInitializable} from '../misc/aave-upgradeability/VersionedInitializable.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; +import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol'; +import {Address} from '../dependencies/openzeppelin/contracts/Address.sol'; /** * @title Collector diff --git a/src/periphery/contracts/treasury/ICollector.sol b/src/contracts/treasury/ICollector.sol similarity index 98% rename from src/periphery/contracts/treasury/ICollector.sol rename to src/contracts/treasury/ICollector.sol index ae92353d..94103d48 100644 --- a/src/periphery/contracts/treasury/ICollector.sol +++ b/src/contracts/treasury/ICollector.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IERC20} from '../../../core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; interface ICollector { struct Stream { diff --git a/src/core/contracts/flashloan/base/LICENSE.md b/src/core/contracts/flashloan/base/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/core/contracts/flashloan/base/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/core/contracts/flashloan/interfaces/LICENSE.md b/src/core/contracts/flashloan/interfaces/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/core/contracts/flashloan/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/core/contracts/interfaces/LICENSE.md b/src/core/contracts/interfaces/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/core/contracts/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/core/contracts/misc/interfaces/LICENSE.md b/src/core/contracts/misc/interfaces/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/core/contracts/misc/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/deployments/contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol b/src/deployments/contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol index db3e2bc8..d26419e7 100644 --- a/src/deployments/contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; -import {DefaultReserveInterestRateStrategyV2} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; +import {DefaultReserveInterestRateStrategyV2} from '../../../contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; contract AaveV3DefaultRateStrategyProcedure { function _deployDefaultRateStrategyV2(address poolAddressesProvider) internal returns (address) { diff --git a/src/deployments/contracts/procedures/AaveV3GettersProcedureOne.sol b/src/deployments/contracts/procedures/AaveV3GettersProcedureOne.sol index ffa52d4d..8aa66732 100644 --- a/src/deployments/contracts/procedures/AaveV3GettersProcedureOne.sol +++ b/src/deployments/contracts/procedures/AaveV3GettersProcedureOne.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {WalletBalanceProvider} from 'aave-v3-periphery/contracts/misc/WalletBalanceProvider.sol'; -import {UiPoolDataProviderV3} from 'aave-v3-periphery/contracts/misc/UiPoolDataProviderV3.sol'; -import {UiIncentiveDataProviderV3} from 'aave-v3-periphery/contracts/misc/UiIncentiveDataProviderV3.sol'; -import {IEACAggregatorProxy} from 'aave-v3-periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol'; -import {AaveProtocolDataProvider} from 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {WalletBalanceProvider} from '../../../contracts/helpers/WalletBalanceProvider.sol'; +import {UiPoolDataProviderV3} from '../../../contracts/helpers/UiPoolDataProviderV3.sol'; +import {UiIncentiveDataProviderV3} from '../../../contracts/helpers/UiIncentiveDataProviderV3.sol'; +import {IEACAggregatorProxy} from '../../../contracts/helpers/interfaces/IEACAggregatorProxy.sol'; +import {AaveProtocolDataProvider} from '../../../contracts/helpers/AaveProtocolDataProvider.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; contract AaveV3GettersProcedureOne { struct GettersReportBatchOne { diff --git a/src/deployments/contracts/procedures/AaveV3GettersProcedureTwo.sol b/src/deployments/contracts/procedures/AaveV3GettersProcedureTwo.sol index eaaddb17..947cc7a9 100644 --- a/src/deployments/contracts/procedures/AaveV3GettersProcedureTwo.sol +++ b/src/deployments/contracts/procedures/AaveV3GettersProcedureTwo.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {WrappedTokenGatewayV3} from 'aave-v3-periphery/contracts/misc/WrappedTokenGatewayV3.sol'; -import {L2Encoder} from 'aave-v3-core/contracts/misc/L2Encoder.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; +import {WrappedTokenGatewayV3} from '../../../contracts/helpers/WrappedTokenGatewayV3.sol'; +import {L2Encoder} from '../../../contracts/helpers/L2Encoder.sol'; contract AaveV3GettersProcedureTwo { struct GettersReportBatchTwo { diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol new file mode 100644 index 00000000..952b02af --- /dev/null +++ b/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {Create2Utils} from '../utilities/Create2Utils.sol'; +import {ConfigEngineReport} from '../../interfaces/IMarketReportTypes.sol'; +import {AaveV3ConfigEngine, IAaveV3ConfigEngine, CapsEngine, BorrowEngine, CollateralEngine, RateEngine, PriceFeedEngine, EModeEngine, ListingEngine} from '../../../contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; +import {IPoolConfigurator} from '../../../contracts/interfaces/IPoolConfigurator.sol'; +import {IAaveOracle} from '../../../contracts/interfaces/IAaveOracle.sol'; + +contract AaveV3HelpersProcedureOne { + function _deployConfigEngine( + address pool, + address poolConfigurator, + address defaultInterestRateStrategy, + address aaveOracle, + address rewardsController, + address collector, + address aTokenImpl, + address vTokenImpl, + address sTokenImpl + ) internal returns (ConfigEngineReport memory configEngineReport) { + IAaveV3ConfigEngine.EngineLibraries memory engineLibraries = IAaveV3ConfigEngine + .EngineLibraries({ + listingEngine: Create2Utils._create2Deploy('v1', type(ListingEngine).creationCode), + eModeEngine: Create2Utils._create2Deploy('v1', type(EModeEngine).creationCode), + borrowEngine: Create2Utils._create2Deploy('v1', type(BorrowEngine).creationCode), + collateralEngine: Create2Utils._create2Deploy('v1', type(CollateralEngine).creationCode), + priceFeedEngine: Create2Utils._create2Deploy('v1', type(PriceFeedEngine).creationCode), + rateEngine: Create2Utils._create2Deploy('v1', type(RateEngine).creationCode), + capsEngine: Create2Utils._create2Deploy('v1', type(CapsEngine).creationCode) + }); + + IAaveV3ConfigEngine.EngineConstants memory engineConstants = IAaveV3ConfigEngine + .EngineConstants({ + pool: IPool(pool), + poolConfigurator: IPoolConfigurator(poolConfigurator), + defaultInterestRateStrategy: defaultInterestRateStrategy, + oracle: IAaveOracle(aaveOracle), + rewardsController: rewardsController, + collector: collector + }); + + configEngineReport.listingEngine = engineLibraries.listingEngine; + configEngineReport.eModeEngine = engineLibraries.eModeEngine; + configEngineReport.borrowEngine = engineLibraries.borrowEngine; + configEngineReport.collateralEngine = engineLibraries.collateralEngine; + configEngineReport.priceFeedEngine = engineLibraries.priceFeedEngine; + configEngineReport.rateEngine = engineLibraries.rateEngine; + configEngineReport.capsEngine = engineLibraries.capsEngine; + + configEngineReport.configEngine = address( + new AaveV3ConfigEngine( + aTokenImpl, + vTokenImpl, + sTokenImpl, + engineConstants, + engineLibraries + ) + ); + return configEngineReport; + } +} diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol new file mode 100644 index 00000000..f455b2e9 --- /dev/null +++ b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../interfaces/IMarketReportTypes.sol'; +import {TransparentProxyFactory, ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; +import {StaticATokenLM} from '../../../contracts/extensions/static-a-token/StaticATokenLM.sol'; +import {StaticATokenFactory} from '../../../contracts/extensions/static-a-token/StaticATokenFactory.sol'; +import {IErrors} from '../../interfaces/IErrors.sol'; + +contract AaveV3HelpersProcedureTwo is IErrors { + function _deployStaticAToken( + address pool, + address rewardsController, + address proxyAdmin + ) internal returns (StaticATokenReport memory staticATokenReport) { + if (proxyAdmin == address(0)) revert ProxyAdminNotFound(); + + staticATokenReport.transparentProxyFactory = address(new TransparentProxyFactory()); + staticATokenReport.staticATokenImplementation = address( + new StaticATokenLM( + IPool(pool), + IRewardsController(rewardsController) + ) + ); + staticATokenReport.staticATokenFactoryImplementation = address( + new StaticATokenFactory( + IPool(pool), + proxyAdmin, + ITransparentProxyFactory(staticATokenReport.transparentProxyFactory), + staticATokenReport.staticATokenImplementation + ) + ); + + staticATokenReport.staticATokenFactoryProxy = ITransparentProxyFactory(staticATokenReport.transparentProxyFactory).create( + staticATokenReport.staticATokenFactoryImplementation, + proxyAdmin, + abi.encodeWithSelector(StaticATokenFactory.initialize.selector) + ); + + return staticATokenReport; + } +} diff --git a/src/deployments/contracts/procedures/AaveV3IncentiveProcedure.sol b/src/deployments/contracts/procedures/AaveV3IncentiveProcedure.sol index 1801a748..b940f795 100644 --- a/src/deployments/contracts/procedures/AaveV3IncentiveProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3IncentiveProcedure.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {EmissionManager} from 'aave-v3-periphery/contracts/rewards/EmissionManager.sol'; -import {RewardsController} from 'aave-v3-periphery/contracts/rewards/RewardsController.sol'; +import {EmissionManager} from '../../../contracts/rewards/EmissionManager.sol'; +import {RewardsController} from '../../../contracts/rewards/RewardsController.sol'; contract AaveV3IncentiveProcedure { function _deployIncentives(address tempOwner) internal returns (address, address) { diff --git a/src/deployments/contracts/procedures/AaveV3L2PoolProcedure.sol b/src/deployments/contracts/procedures/AaveV3L2PoolProcedure.sol index 20c7965d..f6fcba67 100644 --- a/src/deployments/contracts/procedures/AaveV3L2PoolProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3L2PoolProcedure.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {L2PoolInstance} from 'aave-v3-core/instances/L2PoolInstance.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {L2PoolInstance} from '../../../contracts/instances/L2PoolInstance.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; import {AaveV3PoolConfigProcedure} from './AaveV3PoolConfigProcedure.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; import {IErrors} from '../../interfaces/IErrors.sol'; import '../../interfaces/IMarketReportTypes.sol'; diff --git a/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol b/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol new file mode 100644 index 00000000..bd6bac8b --- /dev/null +++ b/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../interfaces/IMarketReportTypes.sol'; +import {PriceOracleSentinel, ISequencerOracle} from '../../../contracts/misc/PriceOracleSentinel.sol'; +import {DefaultReserveInterestRateStrategyV2} from '../../../contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; +import {IErrors} from '../../interfaces/IErrors.sol'; + +contract AaveV3MiscProcedure is IErrors { + function _deploySentinelAndDefaultIR( + bool l2Flag, + address poolAddressesProvider, + address sequencerUptimeOracle, + uint256 gracePeriod + ) internal returns (MiscReport memory miscReport) { + if (poolAddressesProvider == address(0)) revert ProviderNotFound(); + + if (l2Flag && sequencerUptimeOracle != address(0) && gracePeriod != 0) { + miscReport.priceOracleSentinel = address( + new PriceOracleSentinel( + IPoolAddressesProvider(poolAddressesProvider), + ISequencerOracle(sequencerUptimeOracle), + gracePeriod + ) + ); + } + + miscReport.defaultInterestRateStrategy = address( + new DefaultReserveInterestRateStrategyV2(poolAddressesProvider) + ); + + return miscReport; + } +} diff --git a/src/deployments/contracts/procedures/AaveV3OracleProcedure.sol b/src/deployments/contracts/procedures/AaveV3OracleProcedure.sol index 7acc6c91..77e97a40 100644 --- a/src/deployments/contracts/procedures/AaveV3OracleProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3OracleProcedure.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; -import {AaveOracle} from 'aave-v3-core/contracts/misc/AaveOracle.sol'; +import {AaveOracle} from '../../../contracts/misc/AaveOracle.sol'; contract AaveV3OracleProcedure { function _deployAaveOracle( diff --git a/src/deployments/contracts/procedures/AaveV3ParaswapProcedure.sol b/src/deployments/contracts/procedures/AaveV3ParaswapProcedure.sol index 8e6e8b17..b89457b6 100644 --- a/src/deployments/contracts/procedures/AaveV3ParaswapProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3ParaswapProcedure.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {ParaSwapLiquiditySwapAdapter, IParaSwapAugustusRegistry} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol'; -import {ParaSwapRepayAdapter} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol'; -import {ParaSwapWithdrawSwapAdapter} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol'; -import {AaveParaSwapFeeClaimer} from 'aave-v3-periphery/contracts/adapters/paraswap/AaveParaSwapFeeClaimer.sol'; -import {IFeeClaimer} from 'aave-v3-periphery/contracts/adapters/paraswap/interfaces/IFeeClaimer.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {ParaSwapLiquiditySwapAdapter, IParaSwapAugustusRegistry} from '../../../contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol'; +import {ParaSwapRepayAdapter} from '../../../contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol'; +import {ParaSwapWithdrawSwapAdapter} from '../../../contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol'; +import {AaveParaSwapFeeClaimer} from '../../../contracts/extensions/paraswap-adapters/AaveParaSwapFeeClaimer.sol'; +import {IFeeClaimer} from '../../../contracts/extensions/paraswap-adapters/interfaces/IFeeClaimer.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; contract AaveV3ParaswapProcedure { struct ParaswapAdapters { diff --git a/src/deployments/contracts/procedures/AaveV3PoolConfigProcedure.sol b/src/deployments/contracts/procedures/AaveV3PoolConfigProcedure.sol index fb968ec7..6f508ab8 100644 --- a/src/deployments/contracts/procedures/AaveV3PoolConfigProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3PoolConfigProcedure.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {PoolConfiguratorInstance} from 'aave-v3-core/instances/PoolConfiguratorInstance.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {AaveOracle} from 'aave-v3-core/contracts/misc/AaveOracle.sol'; +import {PoolConfiguratorInstance} from '../../../contracts/instances/PoolConfiguratorInstance.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; +import {AaveOracle} from '../../../contracts/misc/AaveOracle.sol'; contract AaveV3PoolConfigProcedure { function _deployPoolConfigurator(address poolAddressesProvider) internal returns (address) { diff --git a/src/deployments/contracts/procedures/AaveV3PoolProcedure.sol b/src/deployments/contracts/procedures/AaveV3PoolProcedure.sol index 0bf84a5d..cc3cc694 100644 --- a/src/deployments/contracts/procedures/AaveV3PoolProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3PoolProcedure.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {PoolInstance} from 'aave-v3-core/instances/PoolInstance.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; +import {PoolInstance} from '../../../contracts/instances/PoolInstance.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; import {AaveV3PoolConfigProcedure} from './AaveV3PoolConfigProcedure.sol'; import {IErrors} from '../../interfaces/IErrors.sol'; import '../../interfaces/IMarketReportTypes.sol'; diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index ce411cc5..9d85884b 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -3,13 +3,13 @@ pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {IPoolConfigurator} from 'aave-v3-core/contracts/interfaces/IPoolConfigurator.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {PoolAddressesProvider} from 'aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol'; -import {PoolAddressesProviderRegistry} from 'aave-v3-core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol'; -import {IEmissionManager} from 'aave-v3-periphery/contracts/rewards/interfaces/IEmissionManager.sol'; -import {IRewardsController} from 'aave-v3-periphery/contracts/rewards/interfaces/IRewardsController.sol'; +import {ACLManager} from '../../../contracts/protocol/configuration/ACLManager.sol'; +import {IPoolConfigurator} from '../../../contracts/interfaces/IPoolConfigurator.sol'; +import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; +import {PoolAddressesProvider} from '../../../contracts/protocol/configuration/PoolAddressesProvider.sol'; +import {PoolAddressesProviderRegistry} from '../../../contracts/protocol/configuration/PoolAddressesProviderRegistry.sol'; +import {IEmissionManager} from '../../../contracts/rewards/interfaces/IEmissionManager.sol'; +import {IRewardsController} from '../../../contracts/rewards/interfaces/IRewardsController.sol'; contract AaveV3SetupProcedure { function _initialDeployment( @@ -38,7 +38,8 @@ contract AaveV3SetupProcedure { address poolConfiguratorImplementation, address protocolDataProvider, address aaveOracle, - address rewardsControllerImplementation + address rewardsControllerImplementation, + address priceOracleSentinel ) internal returns (SetupReport memory) { _validateMarketSetup(roles); @@ -49,7 +50,8 @@ contract AaveV3SetupProcedure { protocolDataProvider, roles.poolAdmin, aaveOracle, - rewardsControllerImplementation + rewardsControllerImplementation, + priceOracleSentinel ); report.aclManager = _setupACL( @@ -94,7 +96,8 @@ contract AaveV3SetupProcedure { address protocolDataProvider, address poolAdmin, address aaveOracle, - address rewardsControllerImplementation + address rewardsControllerImplementation, + address priceOracleSentinel ) internal returns (SetupReport memory) { SetupReport memory report; @@ -107,6 +110,10 @@ contract AaveV3SetupProcedure { report.poolProxy = address(provider.getPool()); report.poolConfiguratorProxy = address(provider.getPoolConfigurator()); + if (priceOracleSentinel != address(0)) { + provider.setPriceOracleSentinel(priceOracleSentinel); + } + bytes32 controllerId = keccak256('INCENTIVES_CONTROLLER'); provider.setAddressAsProxy(controllerId, rewardsControllerImplementation); report.rewardsControllerProxy = provider.getAddress(controllerId); diff --git a/src/deployments/contracts/procedures/AaveV3TokensProcedure.sol b/src/deployments/contracts/procedures/AaveV3TokensProcedure.sol index 51668cf8..342a6926 100644 --- a/src/deployments/contracts/procedures/AaveV3TokensProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3TokensProcedure.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {ATokenInstance} from 'aave-v3-core/instances/ATokenInstance.sol'; -import {VariableDebtTokenInstance} from 'aave-v3-core/instances/VariableDebtTokenInstance.sol'; -import {StableDebtTokenInstance} from 'aave-v3-core/instances/StableDebtTokenInstance.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IAaveIncentivesController} from 'aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol'; +import {ATokenInstance} from '../../../contracts/instances/ATokenInstance.sol'; +import {VariableDebtTokenInstance} from '../../../contracts/instances/VariableDebtTokenInstance.sol'; +import {StableDebtTokenInstance} from '../../../contracts/instances/StableDebtTokenInstance.sol'; +import {IPool} from '../../../contracts/interfaces/IPool.sol'; +import {IAaveIncentivesController} from '../../../contracts/interfaces/IAaveIncentivesController.sol'; contract AaveV3TokensProcedure { struct TokensReport { diff --git a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol index 8fddece8..d0169fc5 100644 --- a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; -import {Collector} from '../../../periphery/contracts/treasury/Collector.sol'; +import {Collector} from '../../../contracts/treasury/Collector.sol'; import '../../interfaces/IMarketReportTypes.sol'; contract AaveV3TreasuryProcedure { diff --git a/src/deployments/contracts/utilities/MarketReportUtils.sol b/src/deployments/contracts/utilities/MarketReportUtils.sol index 34e10e87..341a64c2 100644 --- a/src/deployments/contracts/utilities/MarketReportUtils.sol +++ b/src/deployments/contracts/utilities/MarketReportUtils.sol @@ -21,8 +21,8 @@ library MarketReportUtils { aaveOracle: IAaveOracle(report.aaveOracle), aclManager: IACLManager(report.aclManager), treasury: ICollector(report.treasury), - defaultInterestRateStrategyV2: IDefaultInterestRateStrategyV2( - report.defaultInterestRateStrategyV2 + defaultInterestRateStrategy: IDefaultInterestRateStrategyV2( + report.defaultInterestRateStrategy ), proxyAdmin: ProxyAdmin(report.proxyAdmin), treasuryImplementation: ICollector(report.treasuryImplementation), diff --git a/src/deployments/contracts/utilities/MetadataReporter.sol b/src/deployments/contracts/utilities/MetadataReporter.sol index a3a9b8ab..7fc3a262 100644 --- a/src/deployments/contracts/utilities/MetadataReporter.sol +++ b/src/deployments/contracts/utilities/MetadataReporter.sol @@ -69,6 +69,14 @@ contract MetadataReporter is IMetadataReporter { report.paraSwapWithdrawSwapAdapter ); vm.serializeAddress(jsonReport, 'aaveParaSwapFeeClaimer', report.aaveParaSwapFeeClaimer); + vm.serializeAddress(jsonReport, 'defaultInterestRateStrategy', report.defaultInterestRateStrategy); + vm.serializeAddress(jsonReport, 'priceOracleSentinel', report.priceOracleSentinel); + vm.serializeAddress(jsonReport, 'configEngine', report.configEngine); + vm.serializeAddress(jsonReport, 'staticATokenFactoryImplementation', report.staticATokenFactoryImplementation); + vm.serializeAddress(jsonReport, 'staticATokenFactoryProxy', report.staticATokenFactoryProxy); + vm.serializeAddress(jsonReport, 'staticATokenImplementation', report.staticATokenImplementation); + vm.serializeAddress(jsonReport, 'transparentProxyFactory', report.transparentProxyFactory); + string memory output = vm.serializeAddress( jsonReport, 'paraSwapRepayAdapter', diff --git a/src/deployments/interfaces/IErrors.sol b/src/deployments/interfaces/IErrors.sol index 5faefcc5..7d0df80a 100644 --- a/src/deployments/interfaces/IErrors.sol +++ b/src/deployments/interfaces/IErrors.sol @@ -5,4 +5,5 @@ interface IErrors { error L2MustBeEnabled(); error L2MustBeDisabled(); error ProviderNotFound(); + error ProxyAdminNotFound(); } diff --git a/src/deployments/interfaces/IMarketReportTypes.sol b/src/deployments/interfaces/IMarketReportTypes.sol index 2eb742f9..b838a0db 100644 --- a/src/deployments/interfaces/IMarketReportTypes.sol +++ b/src/deployments/interfaces/IMarketReportTypes.sol @@ -1,27 +1,28 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import 'aave-v3-core/contracts/interfaces/IPoolAddressesProviderRegistry.sol'; -import 'aave-v3-core/contracts/interfaces/IPool.sol'; -import 'aave-v3-core/contracts/interfaces/IPoolConfigurator.sol'; -import 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import 'aave-v3-core/contracts/interfaces/IStableDebtToken.sol'; -import 'aave-v3-core/contracts/interfaces/IACLManager.sol'; -import 'aave-v3-core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; -import 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; -import 'aave-v3-periphery/contracts/misc/UiPoolDataProviderV3.sol'; -import 'aave-v3-periphery/contracts/misc/UiIncentiveDataProviderV3.sol'; -import 'aave-v3-periphery/contracts/rewards/interfaces/IEmissionManager.sol'; -import 'aave-v3-periphery/contracts/rewards/interfaces/IRewardsController.sol'; -import 'aave-v3-periphery/contracts/misc/WalletBalanceProvider.sol'; -import 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol'; -import 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol'; -import 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol'; -import 'aave-v3-periphery/contracts/misc/interfaces/IWrappedTokenGatewayV3.sol'; -import 'aave-v3-core/contracts/misc/L2Encoder.sol'; -import {ICollector} from 'aave-v3-periphery/contracts/treasury/ICollector.sol'; + +import '../../contracts/interfaces/IPoolAddressesProvider.sol'; +import '../../contracts/interfaces/IPoolAddressesProviderRegistry.sol'; +import '../../contracts/interfaces/IPool.sol'; +import '../../contracts/interfaces/IPoolConfigurator.sol'; +import '../../contracts/interfaces/IAaveOracle.sol'; +import '../../contracts/interfaces/IAToken.sol'; +import '../../contracts/interfaces/IVariableDebtToken.sol'; +import '../../contracts/interfaces/IStableDebtToken.sol'; +import '../../contracts/interfaces/IACLManager.sol'; +import '../../contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; +import '../../contracts/helpers/AaveProtocolDataProvider.sol'; +import '../../contracts/helpers/UiPoolDataProviderV3.sol'; +import '../../contracts/helpers/UiIncentiveDataProviderV3.sol'; +import '../../contracts/rewards/interfaces/IEmissionManager.sol'; +import '../../contracts/rewards/interfaces/IRewardsController.sol'; +import '../../contracts/helpers/WalletBalanceProvider.sol'; +import '../../contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol'; +import '../../contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol'; +import '../../contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol'; +import '../../contracts/helpers/interfaces/IWrappedTokenGatewayV3.sol'; +import '../../contracts/helpers/L2Encoder.sol'; +import {ICollector} from '../../contracts/treasury/ICollector.sol'; import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; struct ContractsReport { @@ -35,7 +36,7 @@ struct ContractsReport { IAaveOracle aaveOracle; IACLManager aclManager; ICollector treasury; - IDefaultInterestRateStrategyV2 defaultInterestRateStrategyV2; + IDefaultInterestRateStrategyV2 defaultInterestRateStrategy; ProxyAdmin proxyAdmin; ICollector treasuryImplementation; IWrappedTokenGatewayV3 wrappedTokenGateway; @@ -63,7 +64,8 @@ struct MarketReport { address poolConfiguratorImplementation; address protocolDataProvider; address aaveOracle; - address defaultInterestRateStrategyV2; + address defaultInterestRateStrategy; + address priceOracleSentinel; address aclManager; address treasury; address proxyAdmin; @@ -83,6 +85,11 @@ struct MarketReport { address emissionManager; address rewardsControllerImplementation; address rewardsControllerProxy; + address configEngine; + address transparentProxyFactory; + address staticATokenFactoryImplementation; + address staticATokenFactoryProxy; + address staticATokenImplementation; } struct LibrariesReport { @@ -109,6 +116,8 @@ struct MarketConfig { uint8 oracleDecimals; address paraswapAugustusRegistry; address paraswapFeeClaimer; + address l2SequencerUptimeFeed; + uint256 l2PriceOracleSentinelGracePeriod; uint256 providerId; bytes32 salt; address wrappedNativeToken; @@ -126,6 +135,29 @@ struct PoolReport { address poolConfiguratorImplementation; } +struct MiscReport { + address priceOracleSentinel; + address defaultInterestRateStrategy; +} + +struct ConfigEngineReport { + address configEngine; + address listingEngine; + address eModeEngine; + address borrowEngine; + address collateralEngine; + address priceFeedEngine; + address rateEngine; + address capsEngine; +} + +struct StaticATokenReport { + address transparentProxyFactory; + address staticATokenImplementation; + address staticATokenFactoryImplementation; + address staticATokenFactoryProxy; +} + struct InitialReport { address poolAddressesProvider; address poolAddressesProviderRegistry; @@ -145,7 +177,6 @@ struct PeripheryReport { address treasuryImplementation; address emissionManager; address rewardsControllerImplementation; - address defaultInterestRateStrategyV2; } struct ParaswapReport { diff --git a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol index 1512596b..ec93fc80 100644 --- a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol +++ b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol @@ -10,6 +10,9 @@ import {AaveV3GettersProcedureTwo} from '../../contracts/procedures/AaveV3Getter import {AaveV3PeripheryBatch} from './batches/AaveV3PeripheryBatch.sol'; import {AaveV3ParaswapBatch} from './batches/AaveV3ParaswapBatch.sol'; import {AaveV3SetupBatch} from './batches/AaveV3SetupBatch.sol'; +import {AaveV3HelpersBatchOne} from './batches/AaveV3HelpersBatchOne.sol'; +import {AaveV3HelpersBatchTwo} from './batches/AaveV3HelpersBatchTwo.sol'; +import {AaveV3MiscBatch} from './batches/AaveV3MiscBatch.sol'; import '../../interfaces/IMarketReportTypes.sol'; import {IMarketReportStorage} from '../../interfaces/IMarketReportStorage.sol'; import {IPoolReport} from '../../interfaces/IPoolReport.sol'; @@ -52,6 +55,13 @@ library AaveV3BatchOrchestration { address(setupBatch) ); + MiscReport memory miscReport = _deployMisc( + flags.l2, + initialReport.poolAddressesProvider, + config.l2SequencerUptimeFeed, + config.l2PriceOracleSentinelGracePeriod + ); + SetupReport memory setupReport = setupBatch.setupAaveV3Market( roles, config, @@ -59,7 +69,8 @@ library AaveV3BatchOrchestration { poolReport.poolConfiguratorImplementation, gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, - peripheryReport.rewardsControllerImplementation + peripheryReport.rewardsControllerImplementation, + miscReport.priceOracleSentinel ); ParaswapReport memory paraswapReport = _deployParaswapAdapters( @@ -78,6 +89,19 @@ library AaveV3BatchOrchestration { AaveV3TokensBatch.TokensReport memory tokensReport = _deployTokens(setupReport.poolProxy); + ConfigEngineReport memory configEngineReport = _deployHelpersBatch1( + setupReport, + miscReport, + peripheryReport, + tokensReport + ); + + StaticATokenReport memory staticATokenReport = _deployHelpersBatch2( + setupReport.poolProxy, + setupReport.rewardsControllerProxy, + peripheryReport.proxyAdmin + ); + // Save final report at AaveV3SetupBatch contract MarketReport memory report = _generateMarketReport( initialReport, @@ -85,9 +109,12 @@ library AaveV3BatchOrchestration { gettersReport2, poolReport, peripheryReport, + miscReport, paraswapReport, setupReport, - tokensReport + tokensReport, + configEngineReport, + staticATokenReport ); setupBatch.setMarketReport(report); @@ -137,6 +164,57 @@ library AaveV3BatchOrchestration { }); } + function _deployHelpersBatch1( + SetupReport memory setupReport, + MiscReport memory miscReport, + PeripheryReport memory peripheryReport, + AaveV3TokensBatch.TokensReport memory tokensReport + ) internal returns (ConfigEngineReport memory) { + AaveV3HelpersBatchOne helpersBatchOne = new AaveV3HelpersBatchOne( + setupReport.poolProxy, + setupReport.poolConfiguratorProxy, + miscReport.defaultInterestRateStrategy, + peripheryReport.aaveOracle, + setupReport.rewardsControllerProxy, + peripheryReport.treasury, + tokensReport.aToken, + tokensReport.variableDebtToken, + tokensReport.stableDebtToken + ); + + return helpersBatchOne.getConfigEngineReport(); + } + + function _deployHelpersBatch2( + address pool, + address rewardsController, + address proxyAdmin + ) internal returns (StaticATokenReport memory) { + AaveV3HelpersBatchTwo helpersBatchTwo = new AaveV3HelpersBatchTwo( + pool, + rewardsController, + proxyAdmin + ); + + return helpersBatchTwo.staticATokenReport(); + } + + function _deployMisc( + bool l2Flag, + address poolAddressesProvider, + address sequencerUptimeOracle, + uint256 gracePeriod + ) internal returns (MiscReport memory) { + AaveV3MiscBatch miscBatch = new AaveV3MiscBatch( + l2Flag, + poolAddressesProvider, + sequencerUptimeOracle, + gracePeriod + ); + + return miscBatch.getMiscReport(); + } + function _deployPoolImplementations( address poolAddressesProvider, DeployFlags memory flags @@ -207,9 +285,12 @@ library AaveV3BatchOrchestration { AaveV3GettersBatchTwo.GettersReportBatchTwo memory gettersReportTwo, PoolReport memory poolReport, PeripheryReport memory peripheryReport, + MiscReport memory miscReport, ParaswapReport memory paraswapReport, SetupReport memory setupReport, - AaveV3TokensBatch.TokensReport memory tokensReport + AaveV3TokensBatch.TokensReport memory tokensReport, + ConfigEngineReport memory configEngineReport, + StaticATokenReport memory staticATokenReport ) internal pure returns (MarketReport memory) { MarketReport memory report; @@ -240,7 +321,13 @@ library AaveV3BatchOrchestration { report.aToken = tokensReport.aToken; report.variableDebtToken = tokensReport.variableDebtToken; report.stableDebtToken = tokensReport.stableDebtToken; - report.defaultInterestRateStrategyV2 = peripheryReport.defaultInterestRateStrategyV2; + report.priceOracleSentinel = miscReport.priceOracleSentinel; + report.defaultInterestRateStrategy = miscReport.defaultInterestRateStrategy; + report.configEngine = configEngineReport.configEngine; + report.staticATokenFactoryImplementation = staticATokenReport.staticATokenFactoryImplementation; + report.staticATokenFactoryProxy = staticATokenReport.staticATokenFactoryProxy; + report.staticATokenImplementation = staticATokenReport.staticATokenImplementation; + report.transparentProxyFactory = staticATokenReport.transparentProxyFactory; return report; } diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol new file mode 100644 index 00000000..f841b657 --- /dev/null +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {AaveV3HelpersProcedureOne} from '../../../contracts/procedures/AaveV3HelpersProcedureOne.sol'; +import '../../../interfaces/IMarketReportTypes.sol'; + +contract AaveV3HelpersBatchOne is AaveV3HelpersProcedureOne { + ConfigEngineReport internal _report; + + constructor( + address poolProxy, + address poolConfiguratorProxy, + address defaultInterestRateStrategy, + address aaveOracle, + address rewardsController, + address collector, + address aTokenImpl, + address vTokenImpl, + address sTokenImpl + ) { + _report = _deployConfigEngine( + poolProxy, + poolConfiguratorProxy, + defaultInterestRateStrategy, + aaveOracle, + rewardsController, + collector, + aTokenImpl, + vTokenImpl, + sTokenImpl + ); + } + + function getConfigEngineReport() external view returns (ConfigEngineReport memory) { + return _report; + } +} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol new file mode 100644 index 00000000..b145b257 --- /dev/null +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {AaveV3HelpersProcedureTwo} from '../../../contracts/procedures/AaveV3HelpersProcedureTwo.sol'; +import '../../../interfaces/IMarketReportTypes.sol'; + +contract AaveV3HelpersBatchTwo is AaveV3HelpersProcedureTwo { + StaticATokenReport internal _report; + + constructor( + address pool, + address rewardsController, + address proxyAdmin + ) { + _report = _deployStaticAToken( + pool, + rewardsController, + proxyAdmin + ); + } + + function staticATokenReport() external view returns (StaticATokenReport memory) { + return _report; + } +} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol new file mode 100644 index 00000000..a841d76a --- /dev/null +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {AaveV3MiscProcedure} from '../../../contracts/procedures/AaveV3MiscProcedure.sol'; +import '../../../interfaces/IMarketReportTypes.sol'; + +contract AaveV3MiscBatch is AaveV3MiscProcedure { + MiscReport internal _report; + + constructor( + bool l2Flag, + address poolAddressesProvider, + address sequencerUptimeOracle, + uint256 gracePeriod + ) { + MiscReport memory miscReport = _deploySentinelAndDefaultIR( + l2Flag, + poolAddressesProvider, + sequencerUptimeOracle, + gracePeriod + ); + _report.priceOracleSentinel = miscReport.priceOracleSentinel; + _report.defaultInterestRateStrategy = miscReport.defaultInterestRateStrategy; + } + + function getMiscReport() external view returns (MiscReport memory) { + return _report; + } +} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index 43a25d9b..f2a3ec54 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -4,14 +4,12 @@ pragma solidity ^0.8.0; import {AaveV3TreasuryProcedure} from '../../../contracts/procedures/AaveV3TreasuryProcedure.sol'; import {AaveV3OracleProcedure} from '../../../contracts/procedures/AaveV3OracleProcedure.sol'; import {AaveV3IncentiveProcedure} from '../../../contracts/procedures/AaveV3IncentiveProcedure.sol'; -import {AaveV3DefaultRateStrategyProcedure} from '../../../contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol'; import '../../../interfaces/IMarketReportTypes.sol'; contract AaveV3PeripheryBatch is AaveV3TreasuryProcedure, AaveV3OracleProcedure, - AaveV3IncentiveProcedure, - AaveV3DefaultRateStrategyProcedure + AaveV3IncentiveProcedure { PeripheryReport internal _report; @@ -34,8 +32,6 @@ contract AaveV3PeripheryBatch is (_report.emissionManager, _report.rewardsControllerImplementation) = _deployIncentives( setupBatch ); - - _report.defaultInterestRateStrategyV2 = _deployDefaultRateStrategyV2(poolAddressesProvider); } function getPeripheryReport() external view returns (PeripheryReport memory) { diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol index 78db0c47..abed9a61 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {Ownable} from '../../../../contracts/dependencies/openzeppelin/contracts/Ownable.sol'; import {AaveV3SetupProcedure} from '../../../contracts/procedures/AaveV3SetupProcedure.sol'; import '../../../contracts/MarketReportStorage.sol'; @@ -32,7 +32,8 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable address poolConfiguratorImplementation, address protocolDataProvider, address aaveOracle, - address rewardsControllerImplementation + address rewardsControllerImplementation, + address priceOracleSentinel ) external onlyOwner returns (SetupReport memory) { _setupReport = _setupAaveV3Market( roles, @@ -42,7 +43,8 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable poolConfiguratorImplementation, protocolDataProvider, aaveOracle, - rewardsControllerImplementation + rewardsControllerImplementation, + priceOracleSentinel ); return _setupReport; diff --git a/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch1.sol b/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch1.sol index 1eb97e86..5c292cee 100644 --- a/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch1.sol +++ b/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch1.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import '../../contracts/LibraryReportStorage.sol'; import {Create2Utils} from '../../contracts/utilities/Create2Utils.sol'; -import {BorrowLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol'; -import {BridgeLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol'; -import {ConfiguratorLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol'; -import {EModeLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol'; +import {BorrowLogic} from '../../../contracts/protocol/libraries/logic/BorrowLogic.sol'; +import {BridgeLogic} from '../../../contracts/protocol/libraries/logic/BridgeLogic.sol'; +import {ConfiguratorLogic} from '../../../contracts/protocol/libraries/logic/ConfiguratorLogic.sol'; +import {EModeLogic} from '../../../contracts/protocol/libraries/logic/EModeLogic.sol'; contract AaveV3LibrariesBatch1 is LibraryReportStorage { constructor() { diff --git a/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch2.sol b/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch2.sol index ac1b3ce6..d65db0ac 100644 --- a/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch2.sol +++ b/src/deployments/projects/aave-v3-libraries/AaveV3LibrariesBatch2.sol @@ -4,10 +4,10 @@ pragma solidity ^0.8.0; import '../../contracts/LibraryReportStorage.sol'; import {Create2Utils} from '../../contracts/utilities/Create2Utils.sol'; -import {FlashLoanLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol'; -import {LiquidationLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol'; -import {PoolLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol'; -import {SupplyLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol'; +import {FlashLoanLogic} from '../../../contracts/protocol/libraries/logic/FlashLoanLogic.sol'; +import {LiquidationLogic} from '../../../contracts/protocol/libraries/logic/LiquidationLogic.sol'; +import {PoolLogic} from '../../../contracts/protocol/libraries/logic/PoolLogic.sol'; +import {SupplyLogic} from '../../../contracts/protocol/libraries/logic/SupplyLogic.sol'; contract AaveV3LibrariesBatch2 is LibraryReportStorage { constructor() { diff --git a/src/periphery/contracts/libraries/LICENSE.md b/src/periphery/contracts/libraries/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/libraries/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/misc/LICENSE.md b/src/periphery/contracts/misc/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/misc/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/misc/interfaces/IWETH.sol b/src/periphery/contracts/misc/interfaces/IWETH.sol deleted file mode 100644 index a46ede7f..00000000 --- a/src/periphery/contracts/misc/interfaces/IWETH.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -interface IWETH { - function deposit() external payable; - - function withdraw(uint256) external; - - function approve(address guy, uint256 wad) external returns (bool); - - function transferFrom(address src, address dst, uint256 wad) external returns (bool); -} diff --git a/src/periphery/contracts/misc/interfaces/LICENSE.md b/src/periphery/contracts/misc/interfaces/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/misc/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/mocks/LICENSE.md b/src/periphery/contracts/mocks/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/mocks/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/rewards/interfaces/LICENSE.md b/src/periphery/contracts/rewards/interfaces/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/rewards/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/rewards/libraries/LICENSE.md b/src/periphery/contracts/rewards/libraries/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/rewards/libraries/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/src/periphery/contracts/rewards/transfer-strategies/LICENSE.md b/src/periphery/contracts/rewards/transfer-strategies/LICENSE.md deleted file mode 100644 index 506d18ec..00000000 --- a/src/periphery/contracts/rewards/transfer-strategies/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/tests/AaveV3BatchTests.t.sol b/tests/AaveV3BatchTests.t.sol deleted file mode 100644 index f90652f8..00000000 --- a/tests/AaveV3BatchTests.t.sol +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import 'forge-std/Test.sol'; -import '../src/deployments/interfaces/IMarketReportTypes.sol'; -import {AaveV3TokensBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3TokensBatch.sol'; -import {AaveV3PoolBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3PoolBatch.sol'; -import {AaveV3L2PoolBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3L2PoolBatch.sol'; -import {AaveV3GettersBatchOne} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchOne.sol'; -import {AaveV3GettersBatchTwo} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchTwo.sol'; -import {AaveV3PeripheryBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; -import {AaveV3ParaswapBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; -import {AaveV3SetupBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {AugustusRegistryMock} from './mocks/AugustusRegistryMock.sol'; -import {MockParaSwapFeeClaimer} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; -import {BatchTestProcedures} from './utils/BatchTestProcedures.sol'; -import {AaveV3BatchOrchestration} from '../src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol'; - -contract AaveV3BatchTests is BatchTestProcedures { - address deployer; - address marketOwner; - address emergencyAdmin; - - Roles roles; - MarketConfig config; - DeployFlags flags; - MarketReport deployedContracts; - - InitialReport marketReportOne; - PoolReport poolReportOne; - - AaveV3GettersBatchOne.GettersReportBatchOne gettersReportOne; - AaveV3GettersBatchTwo.GettersReportBatchTwo gettersReportTwo; - - PeripheryReport peripheryReportOne; - ParaswapReport paraswapReportOne; - - SetupReport setupReportTwo; - - AaveV3SetupBatch aaveV3SetupOne; - - event ReportLog(MarketReport report); - - function setUp() public { - deployer = makeAddr('deployer'); - marketOwner = makeAddr('marketOwner'); - poolAdmin = makeAddr('poolAdmin'); - emergencyAdmin = makeAddr('emergencyAdmin'); - bytes32 emptySalt; - roles = Roles(marketOwner, poolAdmin, emergencyAdmin); - config = MarketConfig( - makeAddr('ethUsdOracle'), - makeAddr('ethUsdOracle'), - 'Testnet Market', - 8, - address(new AugustusRegistryMock()), - address(new MockParaSwapFeeClaimer()), - 8080, - emptySalt, - address(new WETH9()), - address(0), - 0.0005e4, - 0.0004e4 - ); - flags = DeployFlags(false); - - ( - marketReportOne, - gettersReportOne, - poolReportOne, - peripheryReportOne, - paraswapReportOne, - aaveV3SetupOne - ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); - (, , gettersReportTwo, , setupReportTwo, , , ) = deployAndSetup( - roles, - config, - flags, - deployedContracts - ); - } - - function testAaveV3FullBatchOrchestration() public { - vm.startPrank(deployer); - MarketReport memory market = AaveV3BatchOrchestration.deployAaveV3( - deployer, - roles, - config, - flags, - deployedContracts - ); - vm.stopPrank(); - checkFullReport(flags, market); - } - - function test0AaveV3SetupDeployment() public { - new AaveV3SetupBatch(msg.sender, roles, config, deployedContracts); - } - - function test1AaveV3GettersDeployment() public { - new AaveV3GettersBatchOne( - marketReportOne.poolAddressesProvider, - config.networkBaseTokenPriceInUsdProxyAggregator, - config.marketReferenceCurrencyPriceInUsdProxyAggregator - ); - - new AaveV3GettersBatchTwo( - setupReportTwo.poolProxy, - roles.poolAdmin, - config.wrappedNativeToken, - flags.l2 - ); - } - - function test2AaveV3PoolDeployment() public { - new AaveV3PoolBatch(marketReportOne.poolAddressesProvider); - } - - function test2AaveV3L2PoolDeployment() public { - new AaveV3L2PoolBatch(marketReportOne.poolAddressesProvider); - } - - function test4PeripheralsRelease() public { - new AaveV3PeripheryBatch( - roles.poolAdmin, - config, - marketReportOne.poolAddressesProvider, - address(aaveV3SetupOne) - ); - } - - function test5PeripheralsRelease() public { - new AaveV3ParaswapBatch( - roles.poolAdmin, - config, - marketReportOne.poolAddressesProvider, - peripheryReportOne.treasury - ); - } - - function test6SetupMarket() public { - vm.prank(roles.marketOwner); - aaveV3SetupOne.setupAaveV3Market( - roles, - config, - poolReportOne.poolImplementation, - poolReportOne.poolConfiguratorImplementation, - gettersReportOne.protocolDataProvider, - peripheryReportOne.aaveOracle, - peripheryReportOne.rewardsControllerImplementation - ); - } - - function test7TokensMarket() public { - new AaveV3TokensBatch(setupReportTwo.poolProxy); - } -} diff --git a/tests/AaveV3BatchDeployment.t.sol b/tests/deployments/AaveV3BatchDeployment.t.sol similarity index 62% rename from tests/AaveV3BatchDeployment.t.sol rename to tests/deployments/AaveV3BatchDeployment.t.sol index 1e7dca5f..aa0cf2d2 100644 --- a/tests/AaveV3BatchDeployment.t.sol +++ b/tests/deployments/AaveV3BatchDeployment.t.sol @@ -2,33 +2,30 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import '../src/deployments/interfaces/IMarketReportTypes.sol'; -import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; - -import {AugustusRegistryMock} from './mocks/AugustusRegistryMock.sol'; -import {MockParaSwapFeeClaimer} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; -import {BatchTestProcedures} from './utils/BatchTestProcedures.sol'; -import {AaveV3TestListing} from './mocks/AaveV3TestListing.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IAaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {AaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol'; +import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; +import {MockParaSwapFeeClaimer} from '../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; +import {BatchTestProcedures} from '../utils/BatchTestProcedures.sol'; +import {AaveV3TestListing} from '../mocks/AaveV3TestListing.sol'; +import {ACLManager} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IAaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; +import {IPool} from '../../src/contracts/interfaces/IPool.sol'; +import {AaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; +import {SequencerOracle} from '../../src/contracts/mocks/oracle/SequencerOracle.sol'; contract AaveV3BatchDeployment is BatchTestProcedures { address public marketOwner; address public emergencyAdmin; Roles public roles; - MarketConfig public config; DeployFlags public flags; + MarketConfig config; MarketReport deployedContracts; address public weth9; - event ReportLog(MarketReport report); - function setUp() public { bytes32 emptySalt; weth9 = address(new WETH9()); @@ -44,6 +41,8 @@ contract AaveV3BatchDeployment is BatchTestProcedures { 8, address(new AugustusRegistryMock()), address(new MockParaSwapFeeClaimer()), + address(0), // l2SequencerUptimeFeed + 0, // l2PriceOracleSentinelGracePeriod 8080, emptySalt, weth9, @@ -63,9 +62,8 @@ contract AaveV3BatchDeployment is BatchTestProcedures { ); checkFullReport(flags, fullReport); - address engine = ConfigEngineDeployer.deployEngine(vm, fullReport); AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(engine), + IAaveV3ConfigEngine(fullReport.configEngine), marketOwner, weth9, fullReport @@ -81,6 +79,8 @@ contract AaveV3BatchDeployment is BatchTestProcedures { function testAaveV3L2BatchDeploymentCheck() public { flags.l2 = true; + config.l2SequencerUptimeFeed = address(new SequencerOracle(poolAdmin)); + config.l2PriceOracleSentinelGracePeriod = 2 hours; MarketReport memory fullReport = deployAaveV3Testnet( marketOwner, @@ -92,9 +92,8 @@ contract AaveV3BatchDeployment is BatchTestProcedures { checkFullReport(flags, fullReport); - address engine = ConfigEngineDeployer.deployEngine(vm, fullReport); AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(engine), + IAaveV3ConfigEngine(fullReport.configEngine), marketOwner, weth9, fullReport diff --git a/tests/deployments/AaveV3BatchTests.t.sol b/tests/deployments/AaveV3BatchTests.t.sol new file mode 100644 index 00000000..0727aac6 --- /dev/null +++ b/tests/deployments/AaveV3BatchTests.t.sol @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {AaveV3TokensBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3TokensBatch.sol'; +import {AaveV3PoolBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PoolBatch.sol'; +import {AaveV3L2PoolBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3L2PoolBatch.sol'; +import {AaveV3GettersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchOne.sol'; +import {AaveV3GettersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchTwo.sol'; +import {AaveV3PeripheryBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; +import {AaveV3ParaswapBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; +import {AaveV3SetupBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; +import {AaveV3MiscBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol'; +import {AaveV3HelpersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol'; +import {AaveV3HelpersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; +import {MockParaSwapFeeClaimer} from 'src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; +import {BatchTestProcedures} from '../utils/BatchTestProcedures.sol'; +import {AaveV3BatchOrchestration} from '../../src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol'; + +contract AaveV3BatchTests is BatchTestProcedures { + address deployer; + address marketOwner; + address emergencyAdmin; + + Roles roles; + MarketConfig config; + DeployFlags flags; + MarketReport deployedContracts; + + InitialReport marketReportOne; + PoolReport poolReportOne; + + AaveV3GettersBatchOne.GettersReportBatchOne gettersReportOne; + AaveV3GettersBatchTwo.GettersReportBatchTwo gettersReportTwo; + + PeripheryReport peripheryReportOne; + ParaswapReport paraswapReportOne; + MiscReport miscReport; + ConfigEngineReport configEngineReport; + StaticATokenReport staticATokenReport; + AaveV3TokensBatch.TokensReport tokensReport; + + SetupReport setupReportTwo; + + AaveV3SetupBatch aaveV3SetupOne; + + function setUp() public { + deployer = makeAddr('deployer'); + marketOwner = makeAddr('marketOwner'); + poolAdmin = makeAddr('poolAdmin'); + emergencyAdmin = makeAddr('emergencyAdmin'); + bytes32 emptySalt; + roles = Roles(marketOwner, poolAdmin, emergencyAdmin); + config = MarketConfig( + makeAddr('ethUsdOracle'), + makeAddr('ethUsdOracle'), + 'Testnet Market', + 8, + address(new AugustusRegistryMock()), + address(new MockParaSwapFeeClaimer()), + address(0), // l2SequencerUptimeFeed + 0, // l2PriceOracleSentinelGracePeriod + 8080, + emptySalt, + address(new WETH9()), + address(0), + 0.0005e4, + 0.0004e4 + ); + flags = DeployFlags(false); + + // Etch the create2 factory + vm.etch( + 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, + hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' + ); + + ( + marketReportOne, + gettersReportOne, + poolReportOne, + peripheryReportOne, + miscReport, + aaveV3SetupOne + ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); + + ( + , + , + gettersReportTwo, + , + setupReportTwo, + , + miscReport, + tokensReport, + paraswapReportOne, + ) = deployAndSetup( + roles, + config, + flags, + deployedContracts + ); + } + + function testAaveV3FullBatchOrchestration() public { + vm.startPrank(deployer); + MarketReport memory market = AaveV3BatchOrchestration.deployAaveV3( + deployer, + roles, + config, + flags, + deployedContracts + ); + vm.stopPrank(); + checkFullReport(flags, market); + } + + function test0AaveV3SetupDeployment() public { + new AaveV3SetupBatch(msg.sender, roles, config, deployedContracts); + } + + function test1AaveV3GettersDeployment() public { + new AaveV3GettersBatchOne( + marketReportOne.poolAddressesProvider, + config.networkBaseTokenPriceInUsdProxyAggregator, + config.marketReferenceCurrencyPriceInUsdProxyAggregator + ); + + new AaveV3GettersBatchTwo( + setupReportTwo.poolProxy, + roles.poolAdmin, + config.wrappedNativeToken, + flags.l2 + ); + } + + function test2AaveV3PoolDeployment() public { + new AaveV3PoolBatch(marketReportOne.poolAddressesProvider); + } + + function test3AaveV3L2PoolDeployment() public { + new AaveV3L2PoolBatch(marketReportOne.poolAddressesProvider); + } + + function test4PeripheralsRelease() public { + new AaveV3PeripheryBatch( + roles.poolAdmin, + config, + marketReportOne.poolAddressesProvider, + address(aaveV3SetupOne) + ); + } + + function test5MiscDeployment() public { + new AaveV3MiscBatch( + flags.l2, + marketReportOne.poolAddressesProvider, + config.l2SequencerUptimeFeed, + config.l2PriceOracleSentinelGracePeriod + ); + } + + function test6ParaswapRelease() public { + new AaveV3ParaswapBatch( + roles.poolAdmin, + config, + marketReportOne.poolAddressesProvider, + peripheryReportOne.treasury + ); + } + + function test7SetupMarket() public { + vm.prank(roles.marketOwner); + aaveV3SetupOne.setupAaveV3Market( + roles, + config, + poolReportOne.poolImplementation, + poolReportOne.poolConfiguratorImplementation, + gettersReportOne.protocolDataProvider, + peripheryReportOne.aaveOracle, + peripheryReportOne.rewardsControllerImplementation, + miscReport.priceOracleSentinel + ); + } + + function test8TokensMarket() public { + new AaveV3TokensBatch(setupReportTwo.poolProxy); + } + + function test9ConfigEngineDeployment() public { + new AaveV3HelpersBatchOne( + setupReportTwo.poolProxy, + setupReportTwo.poolConfiguratorProxy, + miscReport.defaultInterestRateStrategy, + peripheryReportOne.aaveOracle, + setupReportTwo.rewardsControllerProxy, + peripheryReportOne.treasury, + tokensReport.aToken, + tokensReport.variableDebtToken, + tokensReport.stableDebtToken + ); + } + + function test10StaticATokenDeployment() public { + new AaveV3HelpersBatchTwo( + setupReportTwo.poolProxy, + setupReportTwo.rewardsControllerProxy, + peripheryReportOne.proxyAdmin + ); + } +} diff --git a/tests/AaveV3PermissionsTest.t.sol b/tests/deployments/AaveV3PermissionsTest.t.sol similarity index 86% rename from tests/AaveV3PermissionsTest.t.sol rename to tests/deployments/AaveV3PermissionsTest.t.sol index 4224adb2..77b40647 100644 --- a/tests/AaveV3PermissionsTest.t.sol +++ b/tests/deployments/AaveV3PermissionsTest.t.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Ownable} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import '../src/deployments/interfaces/IMarketReportTypes.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {RewardsController} from 'aave-v3-periphery/contracts/rewards/RewardsController.sol'; -import {EmissionManager} from 'aave-v3-periphery/contracts/rewards/EmissionManager.sol'; -import {AugustusRegistryMock} from './mocks/AugustusRegistryMock.sol'; -import {MockParaSwapFeeClaimer} from '../src/periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {BatchTestProcedures} from './utils/BatchTestProcedures.sol'; +import {Ownable} from '../../src/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {ACLManager} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {RewardsController} from '../../src/contracts/rewards/RewardsController.sol'; +import {EmissionManager} from '../../src/contracts/rewards/EmissionManager.sol'; +import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; +import {MockParaSwapFeeClaimer} from '../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import {BatchTestProcedures} from '../utils/BatchTestProcedures.sol'; contract AaveV3PermissionsTest is BatchTestProcedures { /** diff --git a/tests/DeploymentsGasLimits.t.sol b/tests/deployments/DeploymentsGasLimits.t.sol similarity index 54% rename from tests/DeploymentsGasLimits.t.sol rename to tests/deployments/DeploymentsGasLimits.t.sol index ba1082f5..6f33f88d 100644 --- a/tests/DeploymentsGasLimits.t.sol +++ b/tests/deployments/DeploymentsGasLimits.t.sol @@ -2,19 +2,23 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import '../src/deployments/interfaces/IMarketReportTypes.sol'; -import {AaveV3TokensBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3TokensBatch.sol'; -import {AaveV3PoolBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3PoolBatch.sol'; -import {AaveV3L2PoolBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3L2PoolBatch.sol'; -import {AaveV3GettersBatchOne} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchOne.sol'; -import {AaveV3GettersBatchTwo} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchTwo.sol'; -import {AaveV3PeripheryBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; -import {AaveV3ParaswapBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; -import {AaveV3SetupBatch} from '../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {AugustusRegistryMock} from './mocks/AugustusRegistryMock.sol'; -import {MockParaSwapFeeClaimer} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; -import {BatchTestProcedures} from './utils/BatchTestProcedures.sol'; +import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {AaveV3TokensBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3TokensBatch.sol'; +import {AaveV3PoolBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PoolBatch.sol'; +import {AaveV3L2PoolBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3L2PoolBatch.sol'; +import {AaveV3GettersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchOne.sol'; +import {AaveV3GettersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchTwo.sol'; +import {AaveV3PeripheryBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; +import {AaveV3ParaswapBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; +import {AaveV3SetupBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; +import {AaveV3MiscBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol'; +import {AaveV3HelpersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol'; +import {AaveV3HelpersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; +import {MockParaSwapFeeClaimer} from '../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; +import {SequencerOracle} from '../../src/contracts/mocks/oracle/SequencerOracle.sol'; +import {BatchTestProcedures} from '../utils/BatchTestProcedures.sol'; contract DeploymentsGasLimits is BatchTestProcedures { Roles roles; @@ -30,6 +34,8 @@ contract DeploymentsGasLimits is BatchTestProcedures { PeripheryReport peripheryReportOne; ParaswapReport paraswapReportOne; + MiscReport miscReport; + AaveV3TokensBatch.TokensReport tokensReport; SetupReport setupReportTwo; @@ -51,6 +57,8 @@ contract DeploymentsGasLimits is BatchTestProcedures { 8, address(new AugustusRegistryMock()), // replace with mock of augustus registry address(new MockParaSwapFeeClaimer()), + address(new SequencerOracle(poolAdmin)), + 2 hours, // l2PriceOracleSentinelGracePeriod 8080, empty, address(new WETH9()), @@ -58,17 +66,34 @@ contract DeploymentsGasLimits is BatchTestProcedures { 0.0005e4, 0.0004e4 ); - flags = DeployFlags(false); + flags = DeployFlags(true); + + // Etch the create2 factory + vm.etch( + 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, + hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' + ); ( marketReportOne, gettersReportOne, poolReportOne, peripheryReportOne, - paraswapReportOne, + miscReport, aaveV3SetupOne ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); - (, , gettersReportTwo, , setupReportTwo, , , ) = deployAndSetup( + + ( + , + , + gettersReportTwo, + , + setupReportTwo, + , + miscReport, + tokensReport, + paraswapReportOne, + ) = deployAndSetup( roles, config, flags, @@ -114,7 +139,16 @@ contract DeploymentsGasLimits is BatchTestProcedures { ); } - function test6ParaswapDeployment() public { + function test6MiscDeployment() public { + new AaveV3MiscBatch( + flags.l2, + marketReportOne.poolAddressesProvider, + config.l2SequencerUptimeFeed, + config.l2PriceOracleSentinelGracePeriod + ); + } + + function test7ParaswapDeployment() public { new AaveV3ParaswapBatch( roles.poolAdmin, config, @@ -123,7 +157,7 @@ contract DeploymentsGasLimits is BatchTestProcedures { ); } - function test7SetupMarket() public { + function test8SetupMarket() public { vm.prank(roles.marketOwner); aaveV3SetupOne.setupAaveV3Market( roles, @@ -132,14 +166,37 @@ contract DeploymentsGasLimits is BatchTestProcedures { poolReportOne.poolConfiguratorImplementation, gettersReportOne.protocolDataProvider, peripheryReportOne.aaveOracle, - peripheryReportOne.rewardsControllerImplementation + peripheryReportOne.rewardsControllerImplementation, + miscReport.priceOracleSentinel ); } - function test8TokensMarket() public { + function test9TokensMarket() public { new AaveV3TokensBatch(setupReportTwo.poolProxy); } + function test10ConfigEngineDeployment() public { + new AaveV3HelpersBatchOne( + setupReportTwo.poolProxy, + setupReportTwo.poolConfiguratorProxy, + miscReport.defaultInterestRateStrategy, + peripheryReportOne.aaveOracle, + setupReportTwo.rewardsControllerProxy, + peripheryReportOne.treasury, + tokensReport.aToken, + tokensReport.variableDebtToken, + tokensReport.stableDebtToken + ); + } + + function test11StaticATokenDeployment() public { + new AaveV3HelpersBatchTwo( + setupReportTwo.poolProxy, + setupReportTwo.rewardsControllerProxy, + peripheryReportOne.proxyAdmin + ); + } + function testCheckInitCodeSizeBatchs() public view { uint16 maxInitCodeSize = 49152; @@ -147,10 +204,13 @@ contract DeploymentsGasLimits is BatchTestProcedures { console.log('AaveV3L2PoolBatch', type(AaveV3L2PoolBatch).creationCode.length); console.log('AaveV3PoolBatch', type(AaveV3PoolBatch).creationCode.length); console.log('AaveV3PeripheryBatch', type(AaveV3PeripheryBatch).creationCode.length); + console.log('AaveV3MiscBatch', type(AaveV3MiscBatch).creationCode.length); console.log('AaveV3ParaswapBatch', type(AaveV3ParaswapBatch).creationCode.length); console.log('AaveV3GettersBatchOne', type(AaveV3GettersBatchOne).creationCode.length); console.log('AaveV3GettersBatchTwo', type(AaveV3GettersBatchTwo).creationCode.length); console.log('AaveV3TokensBatch', type(AaveV3TokensBatch).creationCode.length); + console.log('AaveV3HelpersBatchOne', type(AaveV3HelpersBatchOne).creationCode.length); + console.log('AaveV3HelpersBatchTwo', type(AaveV3HelpersBatchTwo).creationCode.length); assertLe( type(AaveV3SetupBatch).creationCode.length, @@ -172,6 +232,11 @@ contract DeploymentsGasLimits is BatchTestProcedures { maxInitCodeSize, 'AaveV3PeripheryBatch max init code size' ); + assertLe( + type(AaveV3MiscBatch).creationCode.length, + maxInitCodeSize, + 'AaveV3MiscBatch max init code size' + ); assertLe( type(AaveV3ParaswapBatch).creationCode.length, maxInitCodeSize, @@ -192,5 +257,15 @@ contract DeploymentsGasLimits is BatchTestProcedures { maxInitCodeSize, 'AaveV3TokensBatch max init code size' ); + assertLe( + type(AaveV3HelpersBatchOne).creationCode.length, + maxInitCodeSize, + 'AaveV3HelpersBatchOne max init code size' + ); + assertLe( + type(AaveV3HelpersBatchTwo).creationCode.length, + maxInitCodeSize, + 'AaveV3HelpersBatchTwo max init code size' + ); } } diff --git a/tests/periphery/ParaswapAdapters.t.sol b/tests/extensions/paraswap-adapters/ParaswapAdapters.t.sol similarity index 95% rename from tests/periphery/ParaswapAdapters.t.sol rename to tests/extensions/paraswap-adapters/ParaswapAdapters.t.sol index 56017b0e..42674e83 100644 --- a/tests/periphery/ParaswapAdapters.t.sol +++ b/tests/extensions/paraswap-adapters/ParaswapAdapters.t.sol @@ -1,22 +1,20 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import 'forge-std/Test.sol'; - -import {ParaSwapLiquiditySwapAdapter, IParaSwapAugustus} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol'; -import {ParaSwapRepayAdapter, IParaSwapAugustusRegistry} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol'; -import {ParaSwapWithdrawSwapAdapter} from 'aave-v3-periphery/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol'; -import {AaveParaSwapFeeClaimer, IERC20} from 'aave-v3-periphery/contracts/adapters/paraswap/AaveParaSwapFeeClaimer.sol'; -import {BaseParaSwapAdapter} from 'aave-v3-periphery/contracts/adapters/paraswap/BaseParaSwapAdapter.sol'; -import {IPool, DataTypes} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {MockParaSwapAugustus} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapAugustus.sol'; -import {MockParaSwapFeeClaimer} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; -import {MockParaSwapAugustusRegistry} from 'aave-v3-periphery/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {ParaSwapLiquiditySwapAdapter, IParaSwapAugustus} from '../../../src/contracts/extensions/paraswap-adapters/ParaSwapLiquiditySwapAdapter.sol'; +import {ParaSwapRepayAdapter, IParaSwapAugustusRegistry} from '../../../src/contracts/extensions/paraswap-adapters/ParaSwapRepayAdapter.sol'; +import {ParaSwapWithdrawSwapAdapter} from '../../../src/contracts/extensions/paraswap-adapters/ParaSwapWithdrawSwapAdapter.sol'; +import {AaveParaSwapFeeClaimer, IERC20} from '../../../src/contracts/extensions/paraswap-adapters/AaveParaSwapFeeClaimer.sol'; +import {BaseParaSwapAdapter} from '../../../src/contracts/extensions/paraswap-adapters/BaseParaSwapAdapter.sol'; +import {IPool, DataTypes} from '../../../src/contracts/interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {MockParaSwapAugustus} from '../../../src/contracts/mocks/swap/MockParaSwapAugustus.sol'; +import {MockParaSwapFeeClaimer} from '../../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; +import {MockParaSwapAugustusRegistry} from '../../../src/contracts/mocks/swap/MockParaSwapAugustusRegistry.sol'; +import {IERC20Detailed} from '../../../src/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract ParaswapAdaptersTest is TestnetProcedures { MockParaSwapAugustus internal mockParaSwapAugustus; diff --git a/tests/extensions/static-a-token/StataOracle.t.sol b/tests/extensions/static-a-token/StataOracle.t.sol new file mode 100644 index 00000000..bef3620f --- /dev/null +++ b/tests/extensions/static-a-token/StataOracle.t.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {StataOracle} from '../../../src/contracts/extensions/static-a-token/StataOracle.sol'; +import {StaticATokenLM} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; +import {BaseTest} from './TestBase.sol'; + +contract StataOracleTest is BaseTest { + StataOracle public oracle; + + function setUp() public override { + super.setUp(); + oracle = new StataOracle(contracts.poolAddressesProvider); + + vm.prank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 1_000_000); + } + + function test_assetPrice() public view { + uint256 stataPrice = oracle.getAssetPrice(address(staticATokenLM)); + uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); + assertGe(stataPrice, underlyingPrice); + assertEq(stataPrice, (underlyingPrice * staticATokenLM.convertToAssets(1e18)) / 1e18); + } + + function test_assetsPrices() public view { + address[] memory staticATokens = factory.getStaticATokens(); + uint256[] memory stataPrices = oracle.getAssetsPrices(staticATokens); + + for (uint256 i = 0; i < staticATokens.length; i++) { + address staticAToken = staticATokens[i]; + uint256 stataPrice = stataPrices[i]; + + address underlying = StaticATokenLM(staticAToken).asset(); + uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(underlying); + + assertGe(stataPrice, underlyingPrice); + assertEq(stataPrice, (underlyingPrice * StaticATokenLM(staticAToken).convertToAssets(1e18)) / 1e18); + } + } + + function test_error(uint256 shares) public view { + vm.assume(shares <= staticATokenLM.maxMint(address(0))); + uint256 pricePerShare = oracle.getAssetPrice(address(staticATokenLM)); + uint256 pricePerAsset = contracts.aaveOracle.getAssetPrice(UNDERLYING); + uint256 assets = staticATokenLM.convertToAssets(shares); + + assertApproxEqAbs( + (pricePerShare * shares) / 1e18, + (pricePerAsset * assets) / 1e18, + (assets / 1e18) + 1 // there can be imprecision of 1 wei, which will accumulate for each asset + ); + } +} diff --git a/tests/extensions/static-a-token/StaticATokenLM.t.sol b/tests/extensions/static-a-token/StaticATokenLM.t.sol new file mode 100644 index 00000000..6fcdd428 --- /dev/null +++ b/tests/extensions/static-a-token/StaticATokenLM.t.sol @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {AToken} from '../../../src/contracts/protocol/tokenization/AToken.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IERC20, IERC20Metadata} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; +import {RayMathExplicitRounding} from '../../../src/contracts/misc/libraries/RayMathExplicitRounding.sol'; +import {PullRewardsTransferStrategy} from '../../../src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; +import {RewardsDataTypes} from '../../../src/contracts/rewards/libraries/RewardsDataTypes.sol'; +import {ITransferStrategyBase} from '../../../src/contracts/rewards/interfaces/ITransferStrategyBase.sol'; +import {IEACAggregatorProxy} from '../../../src/contracts/helpers/interfaces/IEACAggregatorProxy.sol'; +import {IStaticATokenLM} from '../../../src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol'; +import {SigUtils} from '../../utils/SigUtils.sol'; +import {BaseTest, TestnetERC20} from './TestBase.sol'; + +contract StaticATokenLMTest is BaseTest { + using RayMathExplicitRounding for uint256; + + address public constant EMISSION_ADMIN = address(25); + + function setUp() public override { + super.setUp(); + + _configureLM(); + _openSupplyAndBorrowPositions(); + + vm.startPrank(user); + } + + function test_initializeShouldRevert() public { + address impl = factory.STATIC_A_TOKEN_IMPL(); + vm.expectRevert(); + IStaticATokenLM(impl).initialize(0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8, 'hey', 'ho'); + } + + function test_getters() public view { + assertEq(staticATokenLM.name(), 'Static Aave Local WETH'); + assertEq(staticATokenLM.symbol(), 'stataLocWETH'); + + IERC20 aToken = staticATokenLM.aToken(); + assertEq(address(aToken), A_TOKEN); + + address underlyingAddress = address(staticATokenLM.asset()); + assertEq(underlyingAddress, UNDERLYING); + + IERC20Metadata underlying = IERC20Metadata(underlyingAddress); + assertEq(staticATokenLM.decimals(), underlying.decimals()); + + assertEq( + address(staticATokenLM.INCENTIVES_CONTROLLER()), + address(AToken(A_TOKEN).getIncentivesController()) + ); + } + + function test_convertersAndPreviews() public view { + uint128 amount = 5 ether; + uint256 shares = staticATokenLM.convertToShares(amount); + assertLe(shares, amount, 'SHARES LOWER'); + assertEq(shares, staticATokenLM.previewDeposit(amount), 'PREVIEW_DEPOSIT'); + assertLe(shares, staticATokenLM.previewWithdraw(amount), 'PREVIEW_WITHDRAW'); + uint256 assets = staticATokenLM.convertToAssets(amount); + assertGe(assets, shares, 'ASSETS GREATER'); + assertLe(assets, staticATokenLM.previewMint(amount), 'PREVIEW_MINT'); + assertEq(assets, staticATokenLM.previewRedeem(amount), 'PREVIEW_REDEEM'); + } + + // Redeem tests + function test_redeem() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + assertEq(staticATokenLM.maxRedeem(user), staticATokenLM.balanceOf(user)); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); + assertEq(staticATokenLM.balanceOf(user), 0); + assertLe(IERC20(UNDERLYING).balanceOf(user), amountToDeposit); + assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user), amountToDeposit, 1); + } + + function test_redeemAToken() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + assertEq(staticATokenLM.maxRedeem(user), staticATokenLM.balanceOf(user)); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user, false); + assertEq(staticATokenLM.balanceOf(user), 0); + assertLe(IERC20(A_TOKEN).balanceOf(user), amountToDeposit); + assertApproxEqAbs(IERC20(A_TOKEN).balanceOf(user), amountToDeposit, 1); + } + + function test_redeemAllowance() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + staticATokenLM.approve(user1, staticATokenLM.maxRedeem(user)); + vm.stopPrank(); + vm.startPrank(user1); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user1, user); + assertEq(staticATokenLM.balanceOf(user), 0); + assertLe(IERC20(UNDERLYING).balanceOf(user1), amountToDeposit); + assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user1), amountToDeposit, 1); + } + + function testFail_redeemOverflowAllowance() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + staticATokenLM.approve(user1, staticATokenLM.maxRedeem(user) / 2); + vm.stopPrank(); + vm.startPrank(user1); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user1, user); + assertEq(staticATokenLM.balanceOf(user), 0); + assertEq(IERC20(A_TOKEN).balanceOf(user1), amountToDeposit); + } + + function testFail_redeemAboveBalance() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user) + 1, user, user); + } + + // Withdraw tests + function test_withdraw() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + assertLe(staticATokenLM.maxWithdraw(user), amountToDeposit); + staticATokenLM.withdraw(staticATokenLM.maxWithdraw(user), user, user); + assertEq(staticATokenLM.balanceOf(user), 0); + assertLe(IERC20(UNDERLYING).balanceOf(user), amountToDeposit); + assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user), amountToDeposit, 1); + } + + function testFail_withdrawAboveBalance() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + _fundUser(amountToDeposit, user1); + + _depositAToken(amountToDeposit, user); + _depositAToken(amountToDeposit, user1); + + assertEq(staticATokenLM.maxWithdraw(user), amountToDeposit); + staticATokenLM.withdraw(staticATokenLM.maxWithdraw(user) + 1, user, user); + } + + // mint + function test_mint() public { + vm.stopPrank(); + + // set supply cap to non-zero + vm.startPrank(poolAdmin); + contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 15_000); + vm.stopPrank(); + + vm.startPrank(user); + + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + IERC20(UNDERLYING).approve(address(staticATokenLM), amountToDeposit); + uint256 shares = 1 ether; + staticATokenLM.mint(shares, user); + assertEq(shares, staticATokenLM.balanceOf(user)); + } + + function testFail_mintAboveBalance() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _underlyingToAToken(amountToDeposit, user); + IERC20(A_TOKEN).approve(address(staticATokenLM), amountToDeposit); + staticATokenLM.mint(amountToDeposit, user); + } + + // test rewards + function test_collectAndUpdateRewards() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); + uint256 claimable = staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN); + staticATokenLM.collectAndUpdateRewards(REWARD_TOKEN); + assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), claimable); + } + + function test_claimRewardsToSelf() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + + uint256 claimable = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + } + + function test_claimRewards() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + + uint256 claimable = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + staticATokenLM.claimRewards(user, rewardTokens); + assertEq(claimable, IERC20(REWARD_TOKEN).balanceOf(user)); + assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + } + + // should fail as user1 is not a valid claimer + function testFail_claimRewardsOnBehalfOf() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + + vm.stopPrank(); + vm.startPrank(user1); + + staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + staticATokenLM.claimRewardsOnBehalf(user, user1, rewardTokens); + } + + function test_depositATokenClaimWithdrawClaim() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + // deposit aweth + _depositAToken(amountToDeposit, user); + + // forward time + _skipBlocks(60); + + // claim + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); + uint256 claimable0 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable0); + assertGt(claimable0, 0); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable0); + + // forward time + _skipBlocks(60); + + // redeem + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); + uint256 claimable1 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable1); + assertGt(claimable1, 0); + + // claim on behalf of other user + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable1 + claimable0); + assertEq(staticATokenLM.balanceOf(user), 0); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); + assertGt(AToken(UNDERLYING).balanceOf(user), 5 ether); + } + + function test_depositWETHClaimWithdrawClaim() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + // forward time + _skipBlocks(60); + + // claim + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); + uint256 claimable0 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable0); + assertGt(claimable0, 0); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable0); + + // forward time + _skipBlocks(60); + + // redeem + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); + uint256 claimable1 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable1); + assertGt(claimable1, 0); + + // claim on behalf of other user + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable1 + claimable0); + assertEq(staticATokenLM.balanceOf(user), 0); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); + assertGt(AToken(UNDERLYING).balanceOf(user), 5 ether); + } + + function test_transfer() public { + uint128 amountToDeposit = 10 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + // transfer to 2nd user + staticATokenLM.transfer(user1, amountToDeposit / 2); + assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); + + // forward time + _skipBlocks(60); + + // redeem for both + uint256 claimableUser = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimableUser); + vm.stopPrank(); + vm.startPrank(user1); + uint256 claimableUser1 = staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user1), user1, user1); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user1), claimableUser1); + assertGt(claimableUser1, 0); + + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); + } + + // getUnclaimedRewards + function test_getUnclaimedRewards() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + uint256 shares = _depositAToken(amountToDeposit, user); + assertEq(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); + _skipBlocks(1000); + staticATokenLM.redeem(shares, user, user); + assertGt(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); + } + + /** + * maxDeposit test + */ + function test_maxDeposit_freeze() public { + vm.stopPrank(); + vm.startPrank(roleList.marketOwner); + contracts.poolConfiguratorProxy.setReserveFreeze(UNDERLYING, true); + + uint256 max = staticATokenLM.maxDeposit(address(0)); + + assertEq(max, 0); + } + + function test_maxDeposit_paused() public { + vm.stopPrank(); + vm.startPrank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setReservePause(UNDERLYING, true); + + uint256 max = staticATokenLM.maxDeposit(address(0)); + + assertEq(max, 0); + } + + function test_maxDeposit_noCap() public { + vm.stopPrank(); + vm.startPrank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 0); + + uint256 maxDeposit = staticATokenLM.maxDeposit(address(0)); + uint256 maxMint = staticATokenLM.maxMint(address(0)); + + assertEq(maxDeposit, type(uint256).max); + assertEq(maxMint, type(uint256).max); + } + + // should be 0 as supply is ~5k + function test_maxDeposit_5kCap() public { + vm.stopPrank(); + vm.startPrank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 5_000); + + uint256 max = staticATokenLM.maxDeposit(address(0)); + assertEq(max, 0); + } + + function test_maxDeposit_50kCap() public { + vm.stopPrank(); + vm.startPrank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 50_000); + + uint256 max = staticATokenLM.maxDeposit(address(0)); + DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(UNDERLYING); + assertEq( + max, + 50_000 * + (10 ** IERC20Metadata(UNDERLYING).decimals()) - + (IERC20Metadata(A_TOKEN).totalSupply() + + uint256(reserveData.accruedToTreasury).rayMulRoundUp(staticATokenLM.rate())) + ); + } + + /** + * maxRedeem test + */ + function test_maxRedeem_paused() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + vm.stopPrank(); + vm.startPrank(address(roleList.marketOwner)); + contracts.poolConfiguratorProxy.setReservePause(UNDERLYING, true); + + uint256 max = staticATokenLM.maxRedeem(address(user)); + + assertEq(max, 0); + } + + function test_maxRedeem_allAvailable() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + uint256 max = staticATokenLM.maxRedeem(address(user)); + + assertEq(max, staticATokenLM.balanceOf(user)); + } + + function test_maxRedeem_partAvailable() public { + uint128 amountToDeposit = 50 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + vm.stopPrank(); + + uint256 maxRedeemBefore = staticATokenLM.previewRedeem(staticATokenLM.maxRedeem(address(user))); + uint256 underlyingBalanceBefore = IERC20Metadata(UNDERLYING).balanceOf(A_TOKEN); + + // create rich user + address borrowUser = address(99); + vm.startPrank(borrowUser); + deal(address(wbtc), borrowUser, 2_000e8); + wbtc.approve(address(POOL), 2_000e8); + POOL.deposit(address(wbtc), 2_000e8, borrowUser, 0); + + // borrow all available + POOL.borrow( + UNDERLYING, + underlyingBalanceBefore - (maxRedeemBefore / 2), + 2, + 0, + borrowUser + ); + + uint256 maxRedeemAfter = staticATokenLM.previewRedeem(staticATokenLM.maxRedeem(address(user))); + assertApproxEqAbs(maxRedeemAfter, (maxRedeemBefore / 2), 1); + } + + function test_maxRedeem_nonAvailable() public { + uint128 amountToDeposit = 50 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + vm.stopPrank(); + + uint256 underlyingBalanceBefore = IERC20Metadata(UNDERLYING).balanceOf(A_TOKEN); + // create rich user + address borrowUser = address(99); + vm.startPrank(borrowUser); + deal(address(wbtc), borrowUser, 2_000e8); + wbtc.approve(address(POOL), 2_000e8); + POOL.deposit(address(wbtc), 2_000e8, borrowUser, 0); + + // borrow all available + contracts.poolProxy.borrow(UNDERLYING, underlyingBalanceBefore, 2, 0, borrowUser); + + uint256 maxRedeemAfter = staticATokenLM.maxRedeem(address(user)); + assertEq(maxRedeemAfter, 0); + } + + function test_permit() public { + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: spender, + value: 1 ether, + nonce: staticATokenLM.nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + staticATokenLM.PERMIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); + + assertEq(staticATokenLM.allowance(permit.owner, spender), permit.value); + } + + function test_permit_expired() public { + // as the default timestamp is 0, we move ahead in time a bit + vm.warp(10 days); + + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: spender, + value: 1 ether, + nonce: staticATokenLM.nonces(user), + deadline: block.timestamp - 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + staticATokenLM.PERMIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + vm.expectRevert('PERMIT_DEADLINE_EXPIRED'); + staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); + } + + function test_permit_invalidSigner() public { + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: address(424242), + spender: spender, + value: 1 ether, + nonce: staticATokenLM.nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + staticATokenLM.PERMIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + vm.expectRevert('INVALID_SIGNER'); + staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); + } + + function _configureLM() internal { + PullRewardsTransferStrategy strat = new PullRewardsTransferStrategy( + report.rewardsControllerProxy, + EMISSION_ADMIN, + EMISSION_ADMIN + ); + + vm.startPrank(poolAdmin); + contracts.emissionManager.setEmissionAdmin(REWARD_TOKEN, EMISSION_ADMIN); + vm.stopPrank(); + + vm.startPrank(EMISSION_ADMIN); + IERC20(REWARD_TOKEN).approve(address(strat), 10_000 ether); + vm.stopPrank(); + + vm.startPrank(OWNER); + TestnetERC20(REWARD_TOKEN).mint(EMISSION_ADMIN, 10_000 ether); + vm.stopPrank(); + + RewardsDataTypes.RewardsConfigInput[] memory config = new RewardsDataTypes.RewardsConfigInput[](1); + config[0] = RewardsDataTypes.RewardsConfigInput( + 0.00385 ether, + 10_000 ether, + uint32(block.timestamp + 30 days), + A_TOKEN, + REWARD_TOKEN, + ITransferStrategyBase(strat), + IEACAggregatorProxy(address(2)) + ); + + vm.prank(EMISSION_ADMIN); + contracts.emissionManager.configureAssets(config); + + staticATokenLM.refreshRewardTokens(); + } + + function _openSupplyAndBorrowPositions() internal { + // this is to open borrow positions so that the aToken balance increases + address whale = address(79); + vm.startPrank(whale); + _fundUser(5_000 ether, whale); + + weth.approve(address(POOL), 5_000 ether); + POOL.deposit(address(weth), 5_000 ether, whale, 0); + + POOL.borrow(address(weth), 1_000 ether, 2, 0, whale); + vm.stopPrank(); + } +} diff --git a/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol b/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol new file mode 100644 index 00000000..748986bb --- /dev/null +++ b/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {IERC20WithPermit} from 'solidity-utils/contracts/oz-common/interfaces/IERC20WithPermit.sol'; +import {StaticATokenLM, IStaticATokenLM, IERC20} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; +import {SigUtils} from '../../utils/SigUtils.sol'; +import {BaseTest, IAToken, IRewardsController, DataTypes} from './TestBase.sol'; + +contract StaticATokenMetaTransactions is BaseTest { + + function setUp() public override { + super.setUp(); + + // Testing meta transactions with USDX as WETH does not support permit + DataTypes.ReserveDataLegacy memory reserveDataUSDX = contracts.poolProxy.getReserveData(address(usdx)); + UNDERLYING = address(usdx); + A_TOKEN = reserveDataUSDX.aTokenAddress; + + staticATokenLM = StaticATokenLM(factory.getStaticAToken(UNDERLYING)); + + vm.startPrank(user); + } + + function test_validateDomainSeparator() public view { + address[] memory staticATokens = factory.getStaticATokens(); + + for (uint256 i = 0; i < staticATokens.length; i++) { + bytes32 separator1 = StaticATokenLM(staticATokens[i]).DOMAIN_SEPARATOR(); + for (uint256 j = 0; j < staticATokens.length; j++) { + if (i != j) { + bytes32 separator2 = StaticATokenLM(staticATokens[j]).DOMAIN_SEPARATOR(); + assertNotEq(separator1, separator2, 'DOMAIN_SEPARATOR_MUST_BE_UNIQUE'); + } + } + } + } + + function test_metaDepositATokenUnderlyingNoPermit() public { + uint128 amountToDeposit = 5e6; + deal(UNDERLYING, user, amountToDeposit); + IERC20(UNDERLYING).approve(address(staticATokenLM), 1e6); + IStaticATokenLM.PermitParams memory permitParams; + + // generate combined permit + SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ + owner: user, + spender: spender, + value: 1e6, + referralCode: 0, + fromUnderlying: true, + nonce: staticATokenLM.nonces(user), + deadline: block.timestamp + 1 days, + permit: permitParams + }); + bytes32 digest = SigUtils.getTypedDepositHash( + depositPermit, + staticATokenLM.METADEPOSIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); + + IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); + + uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); + staticATokenLM.metaDeposit( + depositPermit.owner, + depositPermit.spender, + depositPermit.value, + depositPermit.referralCode, + depositPermit.fromUnderlying, + depositPermit.deadline, + permitParams, + sigParams + ); + + assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); + } + + function test_metaDepositATokenUnderlying() public { + uint128 amountToDeposit = 5e6; + deal(UNDERLYING, user, amountToDeposit); + + // permit for aToken deposit + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: address(staticATokenLM), + value: 1e6, + nonce: IERC20WithPermit(UNDERLYING).nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + staticATokenLM.PERMIT_TYPEHASH(), + IERC20WithPermit(UNDERLYING).DOMAIN_SEPARATOR() + ); + + (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); + + IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( + permit.owner, + permit.spender, + permit.value, + permit.deadline, + pV, + pR, + pS + ); + + // generate combined permit + SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ + owner: user, + spender: spender, + value: permit.value, + referralCode: 0, + fromUnderlying: true, + nonce: staticATokenLM.nonces(user), + deadline: permit.deadline, + permit: permitParams + }); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + userPrivateKey, + SigUtils.getTypedDepositHash( + depositPermit, + staticATokenLM.METADEPOSIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ) + ); + + IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); + + uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); + uint256 shares = staticATokenLM.metaDeposit( + depositPermit.owner, + depositPermit.spender, + depositPermit.value, + depositPermit.referralCode, + depositPermit.fromUnderlying, + depositPermit.deadline, + permitParams, + sigParams + ); + assertEq(shares, previewDeposit); + assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); + } + + function test_metaDepositAToken() public { + uint128 amountToDeposit = 5e6; + _fundUser(amountToDeposit, user); + _underlyingToAToken(amountToDeposit, user); + + // permit for aToken deposit + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: address(staticATokenLM), + value: 1e6, + nonce: IERC20WithPermit(A_TOKEN).nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + staticATokenLM.PERMIT_TYPEHASH(), + IERC20WithPermit(A_TOKEN).DOMAIN_SEPARATOR() + ); + + (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); + + IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( + permit.owner, + permit.spender, + permit.value, + permit.deadline, + pV, + pR, + pS + ); + + // generate combined permit + SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ + owner: user, + spender: spender, + value: permit.value, + referralCode: 0, + fromUnderlying: false, + nonce: staticATokenLM.nonces(user), + deadline: permit.deadline, + permit: permitParams + }); + bytes32 digest = SigUtils.getTypedDepositHash( + depositPermit, + staticATokenLM.METADEPOSIT_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); + + IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); + + uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); + + staticATokenLM.metaDeposit( + depositPermit.owner, + depositPermit.spender, + depositPermit.value, + depositPermit.referralCode, + depositPermit.fromUnderlying, + depositPermit.deadline, + permitParams, + sigParams + ); + + assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); + } + + function test_metaWithdraw() public { + uint128 amountToDeposit = 5e6; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + SigUtils.WithdrawPermit memory permit = SigUtils.WithdrawPermit({ + owner: user, + spender: spender, + staticAmount: 0, + dynamicAmount: 1e6, + toUnderlying: false, + nonce: staticATokenLM.nonces(user), + deadline: block.timestamp + 1 days + }); + bytes32 digest = SigUtils.getTypedWithdrawHash( + permit, + staticATokenLM.METAWITHDRAWAL_TYPEHASH(), + staticATokenLM.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); + + IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); + + staticATokenLM.metaWithdraw( + permit.owner, + permit.spender, + permit.staticAmount, + permit.dynamicAmount, + permit.toUnderlying, + permit.deadline, + sigParams + ); + + assertEq(IERC20(A_TOKEN).balanceOf(permit.spender), permit.dynamicAmount); + } +} diff --git a/tests/extensions/static-a-token/StaticATokenNoLM.t.sol b/tests/extensions/static-a-token/StaticATokenNoLM.t.sol new file mode 100644 index 00000000..f45d197b --- /dev/null +++ b/tests/extensions/static-a-token/StaticATokenNoLM.t.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {BaseTest, IERC20} from './TestBase.sol'; + +/** + * Testing the static token wrapper on a pool that never had LM enabled + * This is a slightly different assumption than a pool that doesn't have LM enabled any more as incentivesController.rewardTokens() will have length=0 + */ +contract StaticATokenNoLMTest is BaseTest { + + function setUp() public override { + super.setUp(); + + vm.startPrank(user); + } + + // test rewards + function test_collectAndUpdateRewardsWithLMDisabled() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); + assertEq(staticATokenLM.collectAndUpdateRewards(REWARD_TOKEN), 0); + assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); + } + + function test_claimRewardsToSelfWithLMDisabled() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + _skipBlocks(60); + + try staticATokenLM.getClaimableRewards(user, REWARD_TOKEN) {} catch Error( + string memory reason + ) { + require(keccak256(bytes(reason)) == keccak256(bytes('9'))); + } + + try staticATokenLM.claimRewardsToSelf(rewardTokens) {} catch Error(string memory reason) { + require(keccak256(bytes(reason)) == keccak256(bytes('9'))); + } + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); + } +} diff --git a/tests/extensions/static-a-token/TestBase.sol b/tests/extensions/static-a-token/TestBase.sol new file mode 100644 index 00000000..7fb215b7 --- /dev/null +++ b/tests/extensions/static-a-token/TestBase.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {IRewardsController} from 'src/contracts/rewards/interfaces/IRewardsController.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; +import {IPool} from '../../../src/contracts/interfaces/IPool.sol'; +import {StaticATokenFactory} from '../../../src/contracts/extensions/static-a-token/StaticATokenFactory.sol'; +import {StaticATokenLM, IStaticATokenLM, IERC20, IERC20Metadata, ERC20} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; +import {IAToken} from '../../../src/contracts/extensions/static-a-token/interfaces/IAToken.sol'; +import {TestnetProcedures, TestnetERC20} from '../../utils/TestnetProcedures.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; + +abstract contract BaseTest is TestnetProcedures { + address constant OWNER = address(1234); + + address public user; + address public user1; + address internal spender; + + uint256 internal userPrivateKey; + uint256 internal spenderPrivateKey; + + StaticATokenLM public staticATokenLM; + address public proxyAdmin; + ITransparentProxyFactory public proxyFactory; + StaticATokenFactory public factory; + + address[] rewardTokens; + + address public UNDERLYING; + address public A_TOKEN; + address public REWARD_TOKEN; + IPool public POOL; + + function setUp() public virtual { + userPrivateKey = 0xA11CE; + spenderPrivateKey = 0xB0B0; + user = address(vm.addr(userPrivateKey)); + user1 = address(vm.addr(2)); + spender = vm.addr(spenderPrivateKey); + + initTestEnvironment(); + DataTypes.ReserveDataLegacy memory reserveDataWETH = contracts.poolProxy.getReserveData(tokenList.weth); + + UNDERLYING = address(weth); + REWARD_TOKEN = address(new TestnetERC20( + 'LM Reward ERC20', + 'RWD', + 18, + OWNER + )); + A_TOKEN = reserveDataWETH.aTokenAddress; + POOL = contracts.poolProxy; + + rewardTokens.push(REWARD_TOKEN); + + proxyFactory = ITransparentProxyFactory(report.transparentProxyFactory); + proxyAdmin = report.proxyAdmin; + + factory = StaticATokenFactory(report.staticATokenFactoryProxy); + factory.createStaticATokens(POOL.getReservesList()); + + staticATokenLM = StaticATokenLM(factory.getStaticAToken(UNDERLYING)); + } + + function _fundUser(uint128 amountToDeposit, address targetUser) internal { + deal(UNDERLYING, targetUser, amountToDeposit); + } + + function _skipBlocks(uint128 blocks) internal { + vm.roll(block.number + blocks); + vm.warp(block.timestamp + blocks * 12); // assuming a block is around 12seconds + } + + function _underlyingToAToken(uint256 amountToDeposit, address targetUser) internal { + IERC20(UNDERLYING).approve(address(POOL), amountToDeposit); + POOL.deposit(UNDERLYING, amountToDeposit, targetUser, 0); + } + + function _depositAToken(uint256 amountToDeposit, address targetUser) internal returns (uint256) { + _underlyingToAToken(amountToDeposit, targetUser); + IERC20(A_TOKEN).approve(address(staticATokenLM), amountToDeposit); + return staticATokenLM.deposit(amountToDeposit, targetUser, 10, false); + } + + function testAdmin() public { + vm.stopPrank(); + vm.startPrank(proxyAdmin); + assertEq(TransparentUpgradeableProxy(payable(address(staticATokenLM))).admin(), proxyAdmin); + assertEq(TransparentUpgradeableProxy(payable(address(factory))).admin(), proxyAdmin); + vm.stopPrank(); + } +} diff --git a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol new file mode 100644 index 00000000..b9e60567 --- /dev/null +++ b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol @@ -0,0 +1,644 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Test.sol'; +import {IAaveV3ConfigEngine} from '../../../src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; +import {AaveV3MockListing} from './mocks/AaveV3MockListing.sol'; +import {AaveV3MockListingCustom} from './mocks/AaveV3MockListingCustom.sol'; +import {AaveV3MockCapUpdate} from './mocks/AaveV3MockCapUpdate.sol'; +import {AaveV3MockCollateralUpdate} from './mocks/AaveV3MockCollateralUpdate.sol'; +import {AaveV3MockCollateralUpdateNoChange} from './mocks/AaveV3MockCollateralUpdateNoChange.sol'; +import {AaveV3MockCollateralUpdateWrongBonus, AaveV3MockCollateralUpdateCorrectBonus} from './mocks/AaveV3MockCollateralUpdateWrongBonus.sol'; +import {AaveV3MockBorrowUpdate} from './mocks/AaveV3MockBorrowUpdate.sol'; +import {AaveV3MockBorrowUpdateNoChange} from './mocks/AaveV3MockBorrowUpdateNoChange.sol'; +import {AaveV3MockRatesUpdate} from './mocks/AaveV3MockRatesUpdate.sol'; +import {AaveV3MockPriceFeedUpdate} from './mocks/AaveV3MockPriceFeedUpdate.sol'; +import {AaveV3MockEModeCategoryUpdate, AaveV3MockEModeCategoryUpdateEdgeBonus} from './mocks/AaveV3MockEModeCategoryUpdate.sol'; +import {AaveV3MockEModeCategoryUpdateNoChange} from './mocks/AaveV3MockEModeCategoryUpdateNoChange.sol'; +import {AaveV3MockAssetEModeUpdate} from './mocks/AaveV3MockAssetEModeUpdate.sol'; + +import {ATokenInstance} from '../../../src/contracts/instances/ATokenInstance.sol'; +import {StableDebtTokenInstance} from '../../../src/contracts/instances/StableDebtTokenInstance.sol'; +import {VariableDebtTokenInstance} from '../../../src/contracts/instances/VariableDebtTokenInstance.sol'; +import {TestnetProcedures, AaveV3ConfigEngine} from '../../utils/TestnetProcedures.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {MockAggregator} from '../../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {IPool, IPoolAddressesProvider} from '../../utils/ProtocolV3TestBase.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {ProtocolV3TestBase, IDefaultInterestRateStrategyV2, ReserveConfig, ReserveTokens, DataTypes as DataTypeOld} from '../../utils/ProtocolV3TestBase.sol'; + +contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { + using stdStorage for StdStorage; + address configEngine; + + function setUp() public { + initTestEnvironment(); + configEngine = report.configEngine; + } + + event CollateralConfigurationChanged( + address indexed asset, + uint256 ltv, + uint256 liquidationThreshold, + uint256 liquidationBonus + ); + + event EModeCategoryAdded( + uint8 indexed categoryId, + uint256 ltv, + uint256 liquidationThreshold, + uint256 liquidationBonus, + address oracle, + string label + ); + + function testListings() public { + address asset = address(new TestnetERC20( + '1INCH', + '1INCH', + 18, + address(this) + )); + + address feed = address(new MockAggregator(int256(25e8))); + AaveV3MockListing payload = new AaveV3MockListing(asset, feed, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineListing', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineListing', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineListing', 'postTestEngineListing'); + + ReserveConfig memory expectedAssetConfig = ReserveConfig({ + symbol: '1INCH', + underlying: asset, + aToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + variableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + stableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + decimals: 18, + ltv: 82_50, + liquidationThreshold: 86_00, + liquidationBonus: 105_00, + liquidationProtocolFee: 10_00, + reserveFactor: 10_00, + usageAsCollateralEnabled: true, + borrowingEnabled: true, + interestRateStrategy: AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), + stableBorrowRateEnabled: false, + isPaused: false, + isActive: true, + isFrozen: false, + isSiloed: false, + isBorrowableInIsolation: false, + isFlashloanable: false, + supplyCap: 85_000, + borrowCap: 60_000, + debtCeiling: 0, + eModeCategory: 0 + }); + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + + _noReservesConfigsChangesApartNewListings(allConfigsBefore, allConfigsAfter); + + _validateReserveTokensImpls( + _findReserveConfigBySymbol(allConfigsAfter, '1INCH'), + ReserveTokens({ + aToken: address(contracts.aToken), + stableDebtToken: address(contracts.stableDebtToken), + variableDebtToken: address(contracts.variableDebtToken) + }) + ); + + _validateAssetSourceOnOracle( + IPoolAddressesProvider(address(contracts.poolAddressesProvider)), + asset, + feed + ); + + _validateInterestRateStrategy( + asset, + contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), + AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), + IDefaultInterestRateStrategyV2.InterestRateDataRay({ + optimalUsageRatio: _bpsToRay(payload.newListings()[0].rateStrategyParams.optimalUsageRatio), + baseVariableBorrowRate: _bpsToRay(payload.newListings()[0].rateStrategyParams.baseVariableBorrowRate), + variableRateSlope1: _bpsToRay(payload.newListings()[0].rateStrategyParams.variableRateSlope1), + variableRateSlope2: _bpsToRay(payload.newListings()[0].rateStrategyParams.variableRateSlope2) + }) + ); + } + + function testListingsCustom() public { + address asset = address(new TestnetERC20( + 'PSP', + 'PSP', + 18, + address(this) + )); + + address feed = address(new MockAggregator(int256(15e8))); + address aTokenImpl = address(new ATokenInstance(contracts.poolProxy)); + address vTokenImpl = address(new VariableDebtTokenInstance(contracts.poolProxy)); + address sTokenImpl = address(new StableDebtTokenInstance(contracts.poolProxy)); + + AaveV3MockListingCustom payload = new AaveV3MockListingCustom(asset, feed, configEngine, aTokenImpl, vTokenImpl, sTokenImpl); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineListingCustom', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineListingCustom', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineListingCustom', 'postTestEngineListingCustom'); + + ReserveConfig memory expectedAssetConfig = ReserveConfig({ + symbol: 'PSP', + underlying: asset, + aToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + variableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + stableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution + decimals: 18, + ltv: 82_50, + liquidationThreshold: 86_00, + liquidationBonus: 105_00, + liquidationProtocolFee: 10_00, + reserveFactor: 10_00, + usageAsCollateralEnabled: true, + borrowingEnabled: true, + interestRateStrategy: AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), + stableBorrowRateEnabled: false, + isPaused: false, + isActive: true, + isFrozen: false, + isSiloed: false, + isBorrowableInIsolation: false, + isFlashloanable: false, + supplyCap: 85_000, + borrowCap: 60_000, + debtCeiling: 0, + eModeCategory: 0 + }); + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + + _noReservesConfigsChangesApartNewListings(allConfigsBefore, allConfigsAfter); + + _validateReserveTokensImpls( + _findReserveConfigBySymbol(allConfigsAfter, 'PSP'), + ReserveTokens({ + aToken: aTokenImpl, + stableDebtToken: sTokenImpl, + variableDebtToken: vTokenImpl + }) + ); + + _validateAssetSourceOnOracle( + IPoolAddressesProvider(address(contracts.poolAddressesProvider)), + asset, + feed + ); + + _validateInterestRateStrategy( + asset, + contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), + AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), + IDefaultInterestRateStrategyV2.InterestRateDataRay({ + optimalUsageRatio: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.optimalUsageRatio), + baseVariableBorrowRate: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.baseVariableBorrowRate), + variableRateSlope1: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope1), + variableRateSlope2: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope2) + }) + ); + } + + function testCapsUpdate() public { + // this asset has been listed before + address asset = tokenList.usdx; + AaveV3MockCapUpdate payload = new AaveV3MockCapUpdate(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineCaps', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineCaps', + IPool(address(contracts.poolProxy)) + ); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + + diffReports('preTestEngineCaps', 'postTestEngineCaps'); + + expectedAssetConfig.supplyCap = 1_000_000; + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + function testCollateralsUpdates() public { + // this asset has been listed before + address asset = tokenList.usdx; + AaveV3MockCollateralUpdate payload = new AaveV3MockCollateralUpdate(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineCollateral', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineCollateral', + IPool(address(contracts.poolProxy)) + ); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + + diffReports('preTestEngineCollateral', 'postTestEngineCollateral'); + + expectedAssetConfig.ltv = 62_00; + expectedAssetConfig.liquidationThreshold = 72_00; + expectedAssetConfig.liquidationBonus = 106_00; // 100_00 + 6_00 + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + + // TODO manage this after testFail* deprecation. + // This should not be necessary, but there seems there is no other way + // of validating that when all collateral params are KEEP_CURRENT, the config + // engine doesn't call the POOL_CONFIGURATOR. + // So the solution is expecting the event emitted on the POOL_CONFIGURATOR, + // and as this doesn't happen, expect the failure of the test + function testFailCollateralsUpdatesNoChange() public { + // this asset has been listed before + address asset = tokenList.usdx; + AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineCollateralNoChange', + IPool(address(contracts.poolProxy)) + ); + + vm.expectEmit(); + emit CollateralConfigurationChanged( + allConfigsBefore[0].underlying, + allConfigsBefore[0].ltv, + allConfigsBefore[0].liquidationThreshold, + allConfigsBefore[0].liquidationBonus + ); + payload.execute(); + } + + // Same as testFailCollateralsUpdatesNoChange, but this time should work, as we are not expecting any event emitted + function testCollateralsUpdatesNoChange() public { + // this asset has been listed before + address asset = tokenList.usdx; + AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineCollateralNoChange', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineCollateralNoChange', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineCollateralNoChange', 'postTestEngineCollateralNoChange'); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + + function testCollateralUpdateWrongBonus() public { + address asset = tokenList.usdx; + AaveV3MockCollateralUpdateWrongBonus payload = new AaveV3MockCollateralUpdateWrongBonus(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + vm.expectRevert(bytes('INVALID_LT_LB_RATIO')); + payload.execute(); + } + + function testCollateralUpdateCorrectBonus() public { + address asset = tokenList.usdx; + AaveV3MockCollateralUpdateCorrectBonus payload = new AaveV3MockCollateralUpdateCorrectBonus(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineCollateralEdgeBonus', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineCollateralEdgeBonus', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineCollateralEdgeBonus', 'postTestEngineCollateralEdgeBonus'); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + expectedAssetConfig.ltv = 62_00; + expectedAssetConfig.liquidationThreshold = 90_00; + expectedAssetConfig.liquidationBonus = 111_00; // 100_00 + 11_00 + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + + function testBorrowsUpdates() public { + address asset = tokenList.usdx; + AaveV3MockBorrowUpdate payload = new AaveV3MockBorrowUpdate(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineBorrow', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineBorrow', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineBorrow', 'postTestEngineBorrow'); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + expectedAssetConfig.reserveFactor = 15_00; + expectedAssetConfig.borrowingEnabled = true; + expectedAssetConfig.isFlashloanable = false; + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + + function testBorrowUpdatesNoChange() public { + address asset = tokenList.usdx; + AaveV3MockBorrowUpdateNoChange payload = new AaveV3MockBorrowUpdateNoChange(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( + 'preTestEngineBorrowNoChange', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( + 'postTestEngineBorrowNoChange', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineBorrowNoChange', 'postTestEngineBorrowNoChange'); + + ReserveConfig memory expectedAssetConfig = _findReserveConfig( + allConfigsBefore, + asset + ); + + _validateReserveConfig(expectedAssetConfig, allConfigsAfter); + } + + function testRateStrategiesUpdates() public { + address asset = tokenList.usdx; + AaveV3MockRatesUpdate payload = new AaveV3MockRatesUpdate(asset, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + createConfigurationSnapshot( + 'preTestEngineRates', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + createConfigurationSnapshot( + 'postTestEngineRates', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineRates', 'postTestEngineRates'); + + _validateInterestRateStrategy( + asset, + contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), + AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), + IDefaultInterestRateStrategyV2.InterestRateDataRay({ + optimalUsageRatio: _bpsToRay(payload.rateStrategiesUpdates()[0].params.optimalUsageRatio), + baseVariableBorrowRate: _bpsToRay(payload.rateStrategiesUpdates()[0].params.baseVariableBorrowRate), + variableRateSlope1: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope1), + variableRateSlope2: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope2) + }) + ); + } + + function testPriceFeedsUpdates() public { + address asset = tokenList.usdx; + address newFeed = address(new MockAggregator(int256(1.05e8))); + AaveV3MockPriceFeedUpdate payload = new AaveV3MockPriceFeedUpdate(asset, newFeed, configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + createConfigurationSnapshot( + 'preTestEnginePriceFeed', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + createConfigurationSnapshot( + 'postTestEnginePriceFeed', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEnginePriceFeed', 'postTestEnginePriceFeed'); + + _validateAssetSourceOnOracle( + IPoolAddressesProvider(address(contracts.poolAddressesProvider)), + asset, + newFeed + ); + } + + function testEModeCategoryUpdates() public { + AaveV3MockEModeCategoryUpdate payload = new AaveV3MockEModeCategoryUpdate(configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + contracts.poolProxy.getEModeCategoryData(1); + + createConfigurationSnapshot( + 'preTestEngineEModeCategoryUpdate', + IPool(address(contracts.poolProxy)) + ); + + payload.execute(); + + createConfigurationSnapshot( + 'postTestEngineEModeCategoryUpdate', + IPool(address(contracts.poolProxy)) + ); + + diffReports('preTestEngineEModeCategoryUpdate', 'postTestEngineEModeCategoryUpdate'); + + DataTypeOld.EModeCategory memory prevEmodeCategoryData; + prevEmodeCategoryData.ltv = 97_40; + prevEmodeCategoryData.liquidationThreshold = 97_60; + prevEmodeCategoryData.liquidationBonus = 101_50; // 100_00 + 1_50 + prevEmodeCategoryData.priceSource = address(0); + prevEmodeCategoryData.label = 'ETH Correlated'; + + _validateEmodeCategory(IPoolAddressesProvider(address(contracts.poolAddressesProvider)), 1, prevEmodeCategoryData); + } + + function testEModeCategoryUpdatesWrongBonus() public { + AaveV3MockEModeCategoryUpdateEdgeBonus payload = new AaveV3MockEModeCategoryUpdateEdgeBonus(configEngine); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + vm.expectRevert(bytes('INVALID_LT_LB_RATIO')); + payload.execute(); + } + + // TODO manage this after testFail* deprecation. + function testFailEModeCategoryUpdatesNoChange() public { + AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange(configEngine); + + DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts.poolProxy.getEModeCategoryData(1); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + vm.expectEmit(true, true, true, true); + emit EModeCategoryAdded( + 1, + eModeCategoryDataBefore.ltv, + eModeCategoryDataBefore.liquidationThreshold, + eModeCategoryDataBefore.liquidationBonus, + eModeCategoryDataBefore.priceSource, + eModeCategoryDataBefore.label + ); + payload.execute(); + } + + // Same as testFailEModeCategoryUpdatesNoChange, but this time should work, as we are not expecting any event emitted + function testEModeCategoryUpdatesNoChange() public { + AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange(configEngine); + + DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts.poolProxy.getEModeCategoryData(1); + + vm.prank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + + createConfigurationSnapshot('preTestEngineEModeCategoryNoChange', IPool(address(contracts.poolProxy))); + + payload.execute(); + + createConfigurationSnapshot('postTestEngineEModeCategoryNoChange', IPool(address(contracts.poolProxy))); + + diffReports('preTestEngineEModeCategoryNoChange', 'postTestEngineEModeCategoryNoChange'); + + DataTypeOld.EModeCategory memory prevEmodeCategoryData; + prevEmodeCategoryData.ltv = eModeCategoryDataBefore.ltv; + prevEmodeCategoryData.liquidationThreshold = eModeCategoryDataBefore.liquidationThreshold; + prevEmodeCategoryData.liquidationBonus = eModeCategoryDataBefore.liquidationBonus; + prevEmodeCategoryData.priceSource = eModeCategoryDataBefore.priceSource; + prevEmodeCategoryData.label = eModeCategoryDataBefore.label; + + _validateEmodeCategory(IPoolAddressesProvider(address(contracts.poolAddressesProvider)), 1, prevEmodeCategoryData); + } + + function testAssetEModeUpdates() public { + address asset = tokenList.usdx; + + AaveV3MockEModeCategoryUpdate payloadToAddEMode = new AaveV3MockEModeCategoryUpdate(configEngine); + AaveV3MockAssetEModeUpdate payload = new AaveV3MockAssetEModeUpdate(asset, configEngine); + + vm.startPrank(roleList.marketOwner); + contracts.aclManager.addPoolAdmin(address(payload)); + contracts.aclManager.addPoolAdmin(address(payloadToAddEMode)); + vm.stopPrank(); + + payloadToAddEMode.execute(); + + createConfigurationSnapshot('preTestEngineAssetEModeUpdate', IPool(address(contracts.poolProxy))); + + payload.execute(); + + createConfigurationSnapshot('postTestEngineAssetEModeUpdate', IPool(address(contracts.poolProxy))); + + diffReports('preTestEngineAssetEModeUpdate', 'postTestEngineAssetEModeUpdate'); + + assertEq( + contracts.protocolDataProvider.getReserveEModeCategory( + asset + ), + 1 + ); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol new file mode 100644 index 00000000..31d67eb0 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock asset e-mode update, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockAssetEModeUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function assetsEModeUpdates() public view override returns (IEngine.AssetEModeUpdate[] memory) { + IEngine.AssetEModeUpdate[] memory eModeUpdate = new IEngine.AssetEModeUpdate[](1); + + eModeUpdate[0] = IEngine.AssetEModeUpdate({ + asset: ASSET_ADDRESS, + eModeCategory: 1 + }); + + return eModeUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol new file mode 100644 index 00000000..d397e9f1 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock borrow update, to be able to test + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine + * @author BGD Labs + */ +contract AaveV3MockBorrowUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function borrowsUpdates() public view override returns (IEngine.BorrowUpdate[] memory) { + IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); + + borrowsUpdate[0] = IEngine.BorrowUpdate({ + asset: ASSET_ADDRESS, + enabledToBorrow: EngineFlags.ENABLED, + flashloanable: EngineFlags.DISABLED, + stableRateModeEnabled: EngineFlags.KEEP_CURRENT, + borrowableInIsolation: EngineFlags.KEEP_CURRENT, + withSiloedBorrowing: EngineFlags.KEEP_CURRENT, + reserveFactor: 15_00 + }); + + return borrowsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol new file mode 100644 index 00000000..b7176035 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock borrow update with no change, to be able to test + * @author BGD Labs + */ +contract AaveV3MockBorrowUpdateNoChange is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function borrowsUpdates() public view override returns (IEngine.BorrowUpdate[] memory) { + IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); + + borrowsUpdate[0] = IEngine.BorrowUpdate({ + asset: ASSET_ADDRESS, + enabledToBorrow: EngineFlags.KEEP_CURRENT, + flashloanable: EngineFlags.KEEP_CURRENT, + stableRateModeEnabled: EngineFlags.KEEP_CURRENT, + borrowableInIsolation: EngineFlags.KEEP_CURRENT, + withSiloedBorrowing: EngineFlags.KEEP_CURRENT, + reserveFactor: EngineFlags.KEEP_CURRENT + }); + + return borrowsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol new file mode 100644 index 00000000..7575fa20 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock caps update, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockCapUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function capsUpdates() public view override returns (IEngine.CapsUpdate[] memory) { + IEngine.CapsUpdate[] memory capsUpdate = new IEngine.CapsUpdate[](1); + + capsUpdate[0] = IEngine.CapsUpdate({ + asset: ASSET_ADDRESS, + supplyCap: 1_000_000, + borrowCap: EngineFlags.KEEP_CURRENT + }); + + return capsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol new file mode 100644 index 00000000..70e38f1e --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock collateral update, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockCollateralUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { + IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); + + collateralsUpdate[0] = IEngine.CollateralUpdate({ + asset: ASSET_ADDRESS, + ltv: 62_00, + liqThreshold: 72_00, + liqBonus: 6_00, + debtCeiling: EngineFlags.KEEP_CURRENT, + liqProtocolFee: EngineFlags.KEEP_CURRENT + }); + + return collateralsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol new file mode 100644 index 00000000..12c9221f --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock collateral update with no changes, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockCollateralUpdateNoChange is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { + IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); + + collateralsUpdate[0] = IEngine.CollateralUpdate({ + asset: ASSET_ADDRESS, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + debtCeiling: EngineFlags.KEEP_CURRENT, + liqProtocolFee: EngineFlags.KEEP_CURRENT + }); + + return collateralsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol new file mode 100644 index 00000000..b41f26d5 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contracts for a mock collateral update, with wrong LT/LB ratio + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockCollateralUpdateWrongBonus is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { + IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); + + collateralsUpdate[0] = IEngine.CollateralUpdate({ + asset: ASSET_ADDRESS, + ltv: 62_00, + liqThreshold: 90_00, + liqBonus: 12_00, + debtCeiling: EngineFlags.KEEP_CURRENT, + liqProtocolFee: EngineFlags.KEEP_CURRENT + }); + + return collateralsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Avalanche', networkAbbreviation: 'Ava'}); + } +} + +/** + * @dev Smart contracts for a mock collateral update, with correct (but edge) LT/LB ratio + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockCollateralUpdateCorrectBonus is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { + IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); + + collateralsUpdate[0] = IEngine.CollateralUpdate({ + asset: ASSET_ADDRESS, + ltv: 62_00, + liqThreshold: 90_00, + liqBonus: 11_00, + debtCeiling: EngineFlags.KEEP_CURRENT, + liqProtocolFee: EngineFlags.KEEP_CURRENT + }); + + return collateralsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol new file mode 100644 index 00000000..796b4009 --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock emode category update, to be able to test + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine + * @author BGD Labs + */ +contract AaveV3MockEModeCategoryUpdate is AaveV3Payload { + constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} + + function eModeCategoriesUpdates() + public + pure + override + returns (IEngine.EModeCategoryUpdate[] memory) + { + IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); + + eModeUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: 1, + ltv: 97_40, + liqThreshold: 97_60, + liqBonus: 1_50, + priceSource: address(0), + label: 'ETH Correlated' + }); + + return eModeUpdates; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Polygon', networkAbbreviation: 'Pol'}); + } +} + +/** + * @dev Smart contract for a mock emode category update, to be able to test + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine + * @author BGD Labs + */ +contract AaveV3MockEModeCategoryUpdateEdgeBonus is AaveV3Payload { + constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} + + function eModeCategoriesUpdates() + public + pure + override + returns (IEngine.EModeCategoryUpdate[] memory) + { + IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); + + eModeUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: 1, + ltv: 97_40, + liqThreshold: 97_60, + liqBonus: 2_50, + priceSource: EngineFlags.KEEP_CURRENT_ADDRESS, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + return eModeUpdates; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol new file mode 100644 index 00000000..b36ce80c --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock e-mode category update with no changes, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockEModeCategoryUpdateNoChange is AaveV3Payload { + constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} + + function eModeCategoriesUpdates() + public + pure + override + returns (IEngine.EModeCategoryUpdate[] memory) + { + IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); + + eModeUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: 1, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + priceSource: EngineFlags.KEEP_CURRENT_ADDRESS, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + return eModeUpdates; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol new file mode 100644 index 00000000..7944629d --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock listing, to be able to test without having a v3 instance on Local + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine + * @author BGD Labs + */ +contract AaveV3MockListing is AaveV3Payload { + address public immutable ASSET_ADDRESS; + address public immutable ASSET_FEED; + + constructor(address assetAddress, address assetFeed, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + ASSET_FEED = assetFeed; + } + + function newListings() public view override returns (IEngine.Listing[] memory) { + IEngine.Listing[] memory listings = new IEngine.Listing[](1); + + listings[0] = IEngine.Listing({ + asset: ASSET_ADDRESS, + assetSymbol: '1INCH', + priceFeed: ASSET_FEED, + rateStrategyParams: IEngine.InterestRateInputData({ + optimalUsageRatio: 80_00, + baseVariableBorrowRate: 25, // 0.25% + variableRateSlope1: 3_00, + variableRateSlope2: 75_00 + }), + enabledToBorrow: EngineFlags.ENABLED, + stableRateModeEnabled: EngineFlags.DISABLED, + borrowableInIsolation: EngineFlags.DISABLED, + withSiloedBorrowing: EngineFlags.DISABLED, + flashloanable: EngineFlags.DISABLED, + ltv: 82_50, + liqThreshold: 86_00, + liqBonus: 5_00, + reserveFactor: 10_00, + supplyCap: 85_000, + borrowCap: 60_000, + debtCeiling: 0, + liqProtocolFee: 10_00, + eModeCategory: 0 + }); + + return listings; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol new file mode 100644 index 00000000..f9a342fd --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock custom listing update, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockListingCustom is AaveV3Payload { + address public immutable ASSET_ADDRESS; + address public immutable ASSET_FEED; + + address public immutable A_TOKEN_IMPL; + address public immutable V_TOKEN_IMPL; + address public immutable S_TOKEN_IMPL; + + constructor(address assetAddress, address assetFeed, address customEngine, address aTokenImpl, address vTokenImpl, address sTokenImpl) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + ASSET_FEED = assetFeed; + A_TOKEN_IMPL = aTokenImpl; + V_TOKEN_IMPL = vTokenImpl; + S_TOKEN_IMPL = sTokenImpl; + } + + function newListingsCustom() + public + view + override + returns (IEngine.ListingWithCustomImpl[] memory) + { + IEngine.ListingWithCustomImpl[] memory listingsCustom = new IEngine.ListingWithCustomImpl[](1); + + listingsCustom[0] = IEngine.ListingWithCustomImpl( + IEngine.Listing({ + asset: ASSET_ADDRESS, + assetSymbol: 'PSP', + priceFeed: ASSET_FEED, + rateStrategyParams: IEngine.InterestRateInputData({ + optimalUsageRatio: 80_00, + baseVariableBorrowRate: 25, // 0.25% + variableRateSlope1: 3_00, + variableRateSlope2: 75_00 + }), + enabledToBorrow: EngineFlags.ENABLED, + stableRateModeEnabled: EngineFlags.DISABLED, + borrowableInIsolation: EngineFlags.DISABLED, + withSiloedBorrowing: EngineFlags.DISABLED, + flashloanable: EngineFlags.DISABLED, + ltv: 82_50, + liqThreshold: 86_00, + liqBonus: 5_00, + reserveFactor: 10_00, + supplyCap: 85_000, + borrowCap: 60_000, + debtCeiling: 0, + liqProtocolFee: 10_00, + eModeCategory: 0 + }), + IEngine.TokenImplementations({ + aToken: A_TOKEN_IMPL, + vToken: V_TOKEN_IMPL, + sToken: S_TOKEN_IMPL + }) + ); + + return listingsCustom; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol new file mode 100644 index 00000000..048c5b9d --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock price feed update, to be able to test + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine + * @author BGD Labs + */ +contract AaveV3MockPriceFeedUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + address public immutable ASSET_FEED; + + constructor(address assetAddress, address feed, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + ASSET_FEED = feed; + } + + function priceFeedsUpdates() public view override returns (IEngine.PriceFeedUpdate[] memory) { + IEngine.PriceFeedUpdate[] memory priceFeedsUpdate = new IEngine.PriceFeedUpdate[](1); + + priceFeedsUpdate[0] = IEngine.PriceFeedUpdate({ + asset: ASSET_ADDRESS, + priceFeed: ASSET_FEED + }); + + return priceFeedsUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol new file mode 100644 index 00000000..42214ccc --- /dev/null +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; + +/** + * @dev Smart contract for a mock rate strategy params update, for testing purposes + * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION + * @author BGD Labs + */ +contract AaveV3MockRatesUpdate is AaveV3Payload { + address public immutable ASSET_ADDRESS; + + constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + ASSET_ADDRESS = assetAddress; + } + + function rateStrategiesUpdates() + public + view + override + returns (IEngine.RateStrategyUpdate[] memory) + { + IEngine.RateStrategyUpdate[] memory ratesUpdate = new IEngine.RateStrategyUpdate[](1); + + ratesUpdate[0] = IEngine.RateStrategyUpdate({ + asset: ASSET_ADDRESS, + params: IEngine.InterestRateInputData({ + optimalUsageRatio: 50_00, + baseVariableBorrowRate: 30, // 0.30% + variableRateSlope1: 4_00, + variableRateSlope2: 76_00 + }) + }); + + return ratesUpdate; + } + + function getPoolContext() public pure override returns (IEngine.PoolContext memory) { + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); + } +} diff --git a/tests/harness/StableDebtToken.sol b/tests/harness/StableDebtToken.sol index c841b9ef..72e42146 100644 --- a/tests/harness/StableDebtToken.sol +++ b/tests/harness/StableDebtToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {StableDebtTokenInstance, IPool} from 'aave-v3-core/instances/StableDebtTokenInstance.sol'; +import {StableDebtTokenInstance, IPool} from '../../src/contracts/instances/StableDebtTokenInstance.sol'; contract StableDebtTokenHarness is StableDebtTokenInstance { constructor(IPool pool) StableDebtTokenInstance(pool) {} diff --git a/tests/harness/VariableDebtToken.sol b/tests/harness/VariableDebtToken.sol index 2ca73a61..73815d97 100644 --- a/tests/harness/VariableDebtToken.sol +++ b/tests/harness/VariableDebtToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {VariableDebtTokenInstance, IPool} from 'aave-v3-core/instances/VariableDebtTokenInstance.sol'; +import {VariableDebtTokenInstance, IPool} from '../../src/contracts/instances/VariableDebtTokenInstance.sol'; contract VariableDebtTokenHarness is VariableDebtTokenInstance { constructor(IPool pool) VariableDebtTokenInstance(pool) {} diff --git a/tests/periphery/WrappedTokenGateway.t.sol b/tests/helpers/WrappedTokenGateway.t.sol similarity index 95% rename from tests/periphery/WrappedTokenGateway.t.sol rename to tests/helpers/WrappedTokenGateway.t.sol index 4b97b910..9a09ac4c 100644 --- a/tests/periphery/WrappedTokenGateway.t.sol +++ b/tests/helpers/WrappedTokenGateway.t.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {AaveOracle} from 'aave-v3-core/contracts/misc/AaveOracle.sol'; -import {WrappedTokenGatewayV3} from 'aave-v3-periphery/contracts/misc/WrappedTokenGatewayV3.sol'; -import {AaveProtocolDataProvider} from 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; -import {AToken} from 'aave-v3-core/contracts/protocol/tokenization/AToken.sol'; -import {StableDebtToken} from 'aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol'; -import {VariableDebtToken} from 'aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {AaveOracle} from '../../src/contracts/misc/AaveOracle.sol'; +import {WrappedTokenGatewayV3} from '../../src/contracts/helpers/WrappedTokenGatewayV3.sol'; +import {AaveProtocolDataProvider} from '../../src/contracts/helpers/AaveProtocolDataProvider.sol'; +import {AToken} from '../../src/contracts/protocol/tokenization/AToken.sol'; +import {StableDebtToken} from '../../src/contracts/protocol/tokenization/StableDebtToken.sol'; +import {VariableDebtToken} from '../../src/contracts/protocol/tokenization/VariableDebtToken.sol'; +import {DataTypes} from '../../src/contracts/protocol/libraries/types/DataTypes.sol'; import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; diff --git a/tests/core/AaveOracle.t.sol b/tests/misc/AaveOracle.t.sol similarity index 95% rename from tests/core/AaveOracle.t.sol rename to tests/misc/AaveOracle.t.sol index 2bbd361f..3ec7335a 100644 --- a/tests/core/AaveOracle.t.sol +++ b/tests/misc/AaveOracle.t.sol @@ -3,11 +3,11 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {MintableERC20} from 'aave-v3-core/contracts/mocks/tokens/MintableERC20.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {MintableERC20} from '../../src/contracts/mocks/tokens/MintableERC20.sol'; +import {MockAggregator} from '../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {PriceOracle} from 'aave-v3-core/contracts/mocks/oracle/PriceOracle.sol'; +import {Errors} from '../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {PriceOracle} from '../../src/contracts/mocks/oracle/PriceOracle.sol'; contract AaveOracleTest is TestnetProcedures { function setUp() public { diff --git a/tests/core/PriceOracleSentinel.t.sol b/tests/misc/PriceOracleSentinel.t.sol similarity index 89% rename from tests/core/PriceOracleSentinel.t.sol rename to tests/misc/PriceOracleSentinel.t.sol index ae4c0418..2ca5313b 100644 --- a/tests/core/PriceOracleSentinel.t.sol +++ b/tests/misc/PriceOracleSentinel.t.sol @@ -3,11 +3,11 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {PriceOracleSentinel} from 'aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {SequencerOracle, ISequencerOracle} from 'aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol'; +import {Errors} from '../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {PriceOracleSentinel} from '../../src/contracts/misc/PriceOracleSentinel.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {ACLManager} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {SequencerOracle, ISequencerOracle} from '../../src/contracts/mocks/oracle/SequencerOracle.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; contract PriceOracleSentinelTest is TestnetProcedures { diff --git a/tests/core/InitializableImmutableAdminUpgradeabilityProxy.t.sol b/tests/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.t.sol similarity index 96% rename from tests/core/InitializableImmutableAdminUpgradeabilityProxy.t.sol rename to tests/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.t.sol index 4740633c..e308ab05 100644 --- a/tests/core/InitializableImmutableAdminUpgradeabilityProxy.t.sol +++ b/tests/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {SlotParser} from '../utils/SlotParser.sol'; -import {MockInitializableImple, MockInitializableImpleV2} from 'aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol'; -import 'aave-v3-core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; +import {SlotParser} from '../../utils/SlotParser.sol'; +import {MockInitializableImple, MockInitializableImpleV2} from '../../../src/contracts/mocks/upgradeability/MockInitializableImplementation.sol'; +import '../../../src/contracts/misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; contract InitializableImmutableAdminUpgradeabilityProxyTests is Test { using stdStorage for StdStorage; diff --git a/tests/core/RateStrategy.t.sol b/tests/misc/rates/RateStrategy.t.sol similarity index 99% rename from tests/core/RateStrategy.t.sol rename to tests/misc/rates/RateStrategy.t.sol index 9cc3e6bb..844c15ec 100644 --- a/tests/core/RateStrategy.t.sol +++ b/tests/misc/rates/RateStrategy.t.sol @@ -3,11 +3,11 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {DefaultReserveInterestRateStrategyV2, IDefaultInterestRateStrategyV2, PercentageMath, IPoolAddressesProvider} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {DefaultReserveInterestRateStrategyV2, IDefaultInterestRateStrategyV2, PercentageMath, IPoolAddressesProvider} from '../../../src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract RateStrategyTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/core/RatesOverflow.t.sol b/tests/misc/rates/RatesOverflow.t.sol similarity index 83% rename from tests/core/RatesOverflow.t.sol rename to tests/misc/rates/RatesOverflow.t.sol index bb99d58f..af12d732 100644 --- a/tests/core/RatesOverflow.t.sol +++ b/tests/misc/rates/RatesOverflow.t.sol @@ -3,11 +3,11 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {MockReserveInterestRateStrategy} from 'aave-v3-core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol'; -import {IPoolConfigurator} from 'aave-v3-core/contracts/interfaces/IPoolConfigurator.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {MockReserveInterestRateStrategy} from '../../../src/contracts/mocks/tests/MockReserveInterestRateStrategy.sol'; +import {IPoolConfigurator} from '../../../src/contracts/interfaces/IPoolConfigurator.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; // @dev Ignored from coverage report, due Foundry Coverage can not detect functions if they return 0. contract RatesOverflowCheckTests is TestnetProcedures { diff --git a/tests/core/ZeroInteresRateStrategy.t.sol b/tests/misc/rates/ZeroInteresRateStrategy.t.sol similarity index 86% rename from tests/core/ZeroInteresRateStrategy.t.sol rename to tests/misc/rates/ZeroInteresRateStrategy.t.sol index 0ce57a59..e037f453 100644 --- a/tests/core/ZeroInteresRateStrategy.t.sol +++ b/tests/misc/rates/ZeroInteresRateStrategy.t.sol @@ -3,10 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/protocol/tokenization/AToken.sol'; -import {DefaultReserveInterestRateStrategyV2, DataTypes, IPoolAddressesProvider} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; -import {IDefaultInterestRateStrategyV2} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken} from '../../../src/contracts/protocol/tokenization/AToken.sol'; +import {DefaultReserveInterestRateStrategyV2, DataTypes, IPoolAddressesProvider, IDefaultInterestRateStrategyV2} from '../../../src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; // @dev Ignored from coverage report, due Foundry Coverage can not detect functions if they return 0. contract ZeroReserveInterestRateStrategyTests is TestnetProcedures { diff --git a/tests/mocks/AaveV3TestListing.sol b/tests/mocks/AaveV3TestListing.sol index 95714b0f..97cc9cce 100644 --- a/tests/mocks/AaveV3TestListing.sol +++ b/tests/mocks/AaveV3TestListing.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import 'aave-v3-periphery/contracts/v3-config-engine/AaveV3Payload.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {MarketReport} from 'src/deployments/interfaces/IMarketReportTypes.sol'; +import '../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; +import {TestnetERC20} from '../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {MockAggregator} from '../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {ACLManager} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {MarketReport} from '../../src/deployments/interfaces/IMarketReportTypes.sol'; /** * @dev Smart contract for token listing, for testing purposes @@ -156,7 +156,7 @@ contract AaveV3TestListing is AaveV3Payload { } function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Ethereum Sepolia', networkAbbreviation: 'EthSep'}); + return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); } function _postExecute() internal override { diff --git a/tests/mocks/MockFlashLoanATokenReceiver.sol b/tests/mocks/MockFlashLoanATokenReceiver.sol index e9711df5..ae8947ec 100644 --- a/tests/mocks/MockFlashLoanATokenReceiver.sol +++ b/tests/mocks/MockFlashLoanATokenReceiver.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {FlashLoanSimpleReceiverBase} from 'aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol'; +import {IERC20} from '../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../src/contracts/interfaces/IPool.sol'; +import {FlashLoanSimpleReceiverBase} from '../../src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol'; /// @dev Helper contract to test donation attacks not possible in the context of a flash loan contract MockFlashLoanATokenReceiver is FlashLoanSimpleReceiverBase { diff --git a/tests/periphery/mocks/StakeMock.sol b/tests/mocks/StakeMock.sol similarity index 100% rename from tests/periphery/mocks/StakeMock.sol rename to tests/mocks/StakeMock.sol diff --git a/tests/core/ACLManager.t.sol b/tests/protocol/configuration/ACLManager.t.sol similarity index 96% rename from tests/core/ACLManager.t.sol rename to tests/protocol/configuration/ACLManager.t.sol index 373c4ee0..717395d7 100644 --- a/tests/core/ACLManager.t.sol +++ b/tests/protocol/configuration/ACLManager.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {PoolAddressesProvider} from 'aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ACLManager} from '../../../src/contracts/protocol/configuration/ACLManager.sol'; +import {PoolAddressesProvider} from '../../../src/contracts/protocol/configuration/PoolAddressesProvider.sol'; contract ACLManagerTest is TestnetProcedures { address internal immutable deployer; diff --git a/tests/core/AddressesProviderRegistry.t.sol b/tests/protocol/configuration/AddressesProviderRegistry.t.sol similarity index 97% rename from tests/core/AddressesProviderRegistry.t.sol rename to tests/protocol/configuration/AddressesProviderRegistry.t.sol index d1e5bb35..d549d752 100644 --- a/tests/core/AddressesProviderRegistry.t.sol +++ b/tests/protocol/configuration/AddressesProviderRegistry.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; contract PoolAddressesProviderRegistryTest is TestnetProcedures { event AddressesProviderRegistered(address indexed addressesProvider, uint256 indexed id); diff --git a/tests/core/PoolAddressesProvider.t.sol b/tests/protocol/configuration/PoolAddressesProvider.t.sol similarity index 95% rename from tests/core/PoolAddressesProvider.t.sol rename to tests/protocol/configuration/PoolAddressesProvider.t.sol index 115219b8..e4003f7c 100644 --- a/tests/core/PoolAddressesProvider.t.sol +++ b/tests/protocol/configuration/PoolAddressesProvider.t.sol @@ -3,14 +3,14 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {PoolAddressesProvider, IPoolAddressesProvider} from 'aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol'; -import {PoolInstance} from 'aave-v3-core/instances/PoolInstance.sol'; -import {MockInitializableV1, MockInitializableV2} from 'aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol'; -import {PoolConfiguratorInstance} from 'aave-v3-core/instances/PoolConfiguratorInstance.sol'; -import {MockPoolInherited} from 'aave-v3-core/contracts/mocks/helpers/MockPool.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {SlotParser} from '../utils/SlotParser.sol'; +import {PoolAddressesProvider, IPoolAddressesProvider} from '../../../src/contracts/protocol/configuration/PoolAddressesProvider.sol'; +import {PoolInstance} from '../../../src/contracts/instances/PoolInstance.sol'; +import {MockInitializableV1, MockInitializableV2} from '../../../src/contracts/mocks/upgradeability/MockInitializableImplementation.sol'; +import {PoolConfiguratorInstance} from '../../../src/contracts/instances/PoolConfiguratorInstance.sol'; +import {MockPoolInherited} from '../../../src/contracts/mocks/helpers/MockPool.sol'; +import {ACLManager} from '../../../src/contracts/protocol/configuration/ACLManager.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {SlotParser} from '../../utils/SlotParser.sol'; contract PoolAddressesProviderTests is TestnetProcedures { using stdStorage for StdStorage; diff --git a/tests/core/BridgeLogic.t.sol b/tests/protocol/libraries/logic/BridgeLogic.t.sol similarity index 92% rename from tests/core/BridgeLogic.t.sol rename to tests/protocol/libraries/logic/BridgeLogic.t.sol index db9ddbe5..18660436 100644 --- a/tests/core/BridgeLogic.t.sol +++ b/tests/protocol/libraries/logic/BridgeLogic.t.sol @@ -3,15 +3,15 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {MathUtils} from 'aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ReserveLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {SafeCast} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {MathUtils} from '../../../../src/contracts/protocol/libraries/math/MathUtils.sol'; +import {WadRayMath} from '../../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ReserveLogic} from '../../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import {PercentageMath} from '../../../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {SafeCast} from '../../../../src/contracts/dependencies/openzeppelin/contracts/SafeCast.sol'; +import {IAToken} from '../../../../src/contracts/interfaces/IAToken.sol'; +import {DataTypes} from '../../../../src/contracts/protocol/libraries/types/DataTypes.sol'; contract BridgeLogicTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/core/PoolLogic.initReserves.edge.t.sol b/tests/protocol/libraries/logic/PoolLogic.initReserves.edge.t.sol similarity index 94% rename from tests/core/PoolLogic.initReserves.edge.t.sol rename to tests/protocol/libraries/logic/PoolLogic.initReserves.edge.t.sol index d7b6053c..695d96ee 100644 --- a/tests/core/PoolLogic.initReserves.edge.t.sol +++ b/tests/protocol/libraries/logic/PoolLogic.initReserves.edge.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {PoolLogic, ReserveLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol'; -import '../utils/TestnetProcedures.sol'; +import {PoolLogic, ReserveLogic} from '../../../../src/contracts/protocol/libraries/logic/PoolLogic.sol'; +import '../../../utils/TestnetProcedures.sol'; contract Mock { string public constant value = 'MOCK'; diff --git a/tests/core/MathUtils.t.sol b/tests/protocol/libraries/math/MathUtils.t.sol similarity index 88% rename from tests/core/MathUtils.t.sol rename to tests/protocol/libraries/math/MathUtils.t.sol index 8f532c8e..ce27b819 100644 --- a/tests/core/MathUtils.t.sol +++ b/tests/protocol/libraries/math/MathUtils.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {MathUtils} from 'aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol'; -import {MathUtilsWrapper} from 'aave-v3-core/contracts/mocks/tests/MathUtilsWrapper.sol'; +import {MathUtils} from '../../../../src/contracts/protocol/libraries/math/MathUtils.sol'; +import {MathUtilsWrapper} from '../../../../src/contracts/mocks/tests/MathUtilsWrapper.sol'; contract MathUtilsTests is Test { MathUtilsWrapper internal w; diff --git a/tests/core/PercentageMath.t.sol b/tests/protocol/libraries/math/PercentageMath.t.sol similarity index 89% rename from tests/core/PercentageMath.t.sol rename to tests/protocol/libraries/math/PercentageMath.t.sol index 1d6abb8c..47f949d2 100644 --- a/tests/core/PercentageMath.t.sol +++ b/tests/protocol/libraries/math/PercentageMath.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {PercentageMathWrapper} from 'aave-v3-core/contracts/mocks/tests/PercentageMathWrapper.sol'; +import {PercentageMath} from '../../../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {PercentageMathWrapper} from '../../../../src/contracts/mocks/tests/PercentageMathWrapper.sol'; contract PercentageMathTests is Test { PercentageMathWrapper internal w; diff --git a/tests/core/WadRayMath.t.sol b/tests/protocol/libraries/math/WadRayMath.t.sol similarity index 97% rename from tests/core/WadRayMath.t.sol rename to tests/protocol/libraries/math/WadRayMath.t.sol index 7a582e34..baefd867 100644 --- a/tests/core/WadRayMath.t.sol +++ b/tests/protocol/libraries/math/WadRayMath.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {WadRayMathWrapper} from 'aave-v3-core/contracts/mocks/tests/WadRayMathWrapper.sol'; +import {WadRayMathWrapper} from '../../../../src/contracts/mocks/tests/WadRayMathWrapper.sol'; contract WadRayMathTests is Test { WadRayMathWrapper internal w; diff --git a/tests/core/L2Pool.t.sol b/tests/protocol/pool/L2Pool.t.sol similarity index 92% rename from tests/core/L2Pool.t.sol rename to tests/protocol/pool/L2Pool.t.sol index 18f73fd3..88b2e261 100644 --- a/tests/core/L2Pool.t.sol +++ b/tests/protocol/pool/L2Pool.t.sol @@ -3,17 +3,17 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {L2Encoder} from 'aave-v3-core/contracts/misc/L2Encoder.sol'; -import {IL2Pool} from 'aave-v3-core/contracts/interfaces/IL2Pool.sol'; -import {IReserveInterestRateStrategy} from 'aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol'; -import {BorrowLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol'; -import {SupplyLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol'; -import {LiquidationLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAaveOracle} from '../../../src/contracts/interfaces/IAaveOracle.sol'; +import {L2Encoder} from '../../../src/contracts/helpers/L2Encoder.sol'; +import {IL2Pool} from '../../../src/contracts/interfaces/IL2Pool.sol'; +import {IReserveInterestRateStrategy} from '../../../src/contracts/interfaces/IReserveInterestRateStrategy.sol'; +import {BorrowLogic} from '../../../src/contracts/protocol/libraries/logic/BorrowLogic.sol'; +import {SupplyLogic} from '../../../src/contracts/protocol/libraries/logic/SupplyLogic.sol'; +import {LiquidationLogic} from '../../../src/contracts/protocol/libraries/logic/LiquidationLogic.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; import {PoolTests, DataTypes, Errors, IERC20, IPool} from './Pool.t.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; /// @dev All Pool.t.sol tests are run as L2Pool via inheriting PoolTests contract L2PoolTests is PoolTests { diff --git a/tests/core/Pool.Borrow.t.sol b/tests/protocol/pool/Pool.Borrow.t.sol similarity index 95% rename from tests/core/Pool.Borrow.t.sol rename to tests/protocol/pool/Pool.Borrow.t.sol index c73a30e8..bddd02e1 100644 --- a/tests/core/Pool.Borrow.t.sol +++ b/tests/protocol/pool/Pool.Borrow.t.sol @@ -3,21 +3,21 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IStableDebtToken} from 'aave-v3-core/contracts/interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {IReserveInterestRateStrategy} from 'aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {ISequencerOracle} from 'aave-v3-core/contracts/interfaces/ISequencerOracle.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {PriceOracleSentinel} from 'aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol'; -import {SequencerOracle} from 'aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IStableDebtToken} from '../../../src/contracts/interfaces/IStableDebtToken.sol'; +import {IVariableDebtToken} from '../../../src/contracts/interfaces/IVariableDebtToken.sol'; +import {IAaveOracle} from '../../../src/contracts/interfaces/IAaveOracle.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {IReserveInterestRateStrategy} from '../../../src/contracts/interfaces/IReserveInterestRateStrategy.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {ISequencerOracle} from '../../../src/contracts/interfaces/ISequencerOracle.sol'; +import {UserConfiguration} from '../../../src/contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import {PriceOracleSentinel} from '../../../src/contracts/misc/PriceOracleSentinel.sol'; +import {SequencerOracle} from '../../../src/contracts/mocks/oracle/SequencerOracle.sol'; +import {MockAggregator} from '../../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {ReserveConfiguration} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IERC20} from '../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract PoolBorrowTests is TestnetProcedures { using UserConfiguration for DataTypes.UserConfigurationMap; diff --git a/tests/core/Pool.FlashLoans.t.sol b/tests/protocol/pool/Pool.FlashLoans.t.sol similarity index 92% rename from tests/core/Pool.FlashLoans.t.sol rename to tests/protocol/pool/Pool.FlashLoans.t.sol index ea9c2e84..a98392c0 100644 --- a/tests/core/Pool.FlashLoans.t.sol +++ b/tests/protocol/pool/Pool.FlashLoans.t.sol @@ -3,20 +3,20 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {FlashLoanLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol'; -import {BorrowLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {MockFlashLoanReceiver} from 'aave-v3-core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol'; -import {MockFlashLoanSimpleReceiver} from 'aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {MockFlashLoanATokenReceiver} from '../mocks/MockFlashLoanATokenReceiver.sol'; -import {TestnetProcedures, TestReserveConfig} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {ReserveConfiguration} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {FlashLoanLogic} from '../../../src/contracts/protocol/libraries/logic/FlashLoanLogic.sol'; +import {BorrowLogic} from '../../../src/contracts/protocol/libraries/logic/BorrowLogic.sol'; +import {PercentageMath} from '../../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {MockFlashLoanReceiver} from '../../../src/contracts/mocks/flashloan/MockFlashLoanReceiver.sol'; +import {MockFlashLoanSimpleReceiver} from '../../../src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {IERC20} from '../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {MockFlashLoanATokenReceiver} from '../../mocks/MockFlashLoanATokenReceiver.sol'; +import {TestnetProcedures, TestReserveConfig} from '../../utils/TestnetProcedures.sol'; contract PoolFlashLoansTests is TestnetProcedures { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; diff --git a/tests/core/Pool.Liquidations.t.sol b/tests/protocol/pool/Pool.Liquidations.t.sol similarity index 96% rename from tests/core/Pool.Liquidations.t.sol rename to tests/protocol/pool/Pool.Liquidations.t.sol index 12c332da..f8466f23 100644 --- a/tests/core/Pool.Liquidations.t.sol +++ b/tests/protocol/pool/Pool.Liquidations.t.sol @@ -3,23 +3,23 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IStableDebtToken} from 'aave-v3-core/contracts/interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {ReserveLogic, IERC20} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {PriceOracleSentinel} from 'aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol'; -import {SequencerOracle, ISequencerOracle} from 'aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {LiquidationLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IStableDebtToken} from '../../../src/contracts/interfaces/IStableDebtToken.sol'; +import {IVariableDebtToken} from '../../../src/contracts/interfaces/IVariableDebtToken.sol'; +import {IAaveOracle} from '../../../src/contracts/interfaces/IAaveOracle.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {UserConfiguration} from '../../../src/contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import {ReserveLogic, IERC20} from '../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import {ReserveConfiguration} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {PriceOracleSentinel} from '../../../src/contracts/misc/PriceOracleSentinel.sol'; +import {SequencerOracle, ISequencerOracle} from '../../../src/contracts/mocks/oracle/SequencerOracle.sol'; +import {MockAggregator} from '../../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {LiquidationLogic} from '../../../src/contracts/protocol/libraries/logic/LiquidationLogic.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {PercentageMath} from '../../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract PoolLiquidationTests is TestnetProcedures { using stdStorage for StdStorage; diff --git a/tests/core/Pool.Repay.t.sol b/tests/protocol/pool/Pool.Repay.t.sol similarity index 95% rename from tests/core/Pool.Repay.t.sol rename to tests/protocol/pool/Pool.Repay.t.sol index 25530d81..79eb415a 100644 --- a/tests/core/Pool.Repay.t.sol +++ b/tests/protocol/pool/Pool.Repay.t.sol @@ -3,19 +3,19 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IStableDebtToken} from 'aave-v3-core/contracts/interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {ISequencerOracle} from 'aave-v3-core/contracts/interfaces/ISequencerOracle.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {UserConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {PriceOracleSentinel} from 'aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol'; -import {SequencerOracle} from 'aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol'; -import {BorrowLogic, IERC20} from 'aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; +import {IStableDebtToken} from '../../../src/contracts/interfaces/IStableDebtToken.sol'; +import {IVariableDebtToken} from '../../../src/contracts/interfaces/IVariableDebtToken.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {ISequencerOracle} from '../../../src/contracts/interfaces/ISequencerOracle.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {UserConfiguration} from '../../../src/contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import {PriceOracleSentinel} from '../../../src/contracts/misc/PriceOracleSentinel.sol'; +import {SequencerOracle} from '../../../src/contracts/mocks/oracle/SequencerOracle.sol'; +import {BorrowLogic, IERC20} from '../../../src/contracts/protocol/libraries/logic/BorrowLogic.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; contract PoolRepayTests is TestnetProcedures { using UserConfiguration for DataTypes.UserConfigurationMap; diff --git a/tests/core/Pool.Supply.t.sol b/tests/protocol/pool/Pool.Supply.t.sol similarity index 95% rename from tests/core/Pool.Supply.t.sol rename to tests/protocol/pool/Pool.Supply.t.sol index 507c4da9..12cc4135 100644 --- a/tests/core/Pool.Supply.t.sol +++ b/tests/protocol/pool/Pool.Supply.t.sol @@ -3,12 +3,12 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IAToken, IERC20} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetERC20, IERC20WithPermit} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; +import {IPool} from '../../../src/contracts/interfaces/IPool.sol'; +import {IAToken, IERC20} from '../../../src/contracts/interfaces/IAToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetERC20, IERC20WithPermit} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; contract PoolSupplyTests is TestnetProcedures { IPool internal pool; diff --git a/tests/core/Pool.Withdraw.t.sol b/tests/protocol/pool/Pool.Withdraw.t.sol similarity index 97% rename from tests/core/Pool.Withdraw.t.sol rename to tests/protocol/pool/Pool.Withdraw.t.sol index bb5fc57f..05598338 100644 --- a/tests/core/Pool.Withdraw.t.sol +++ b/tests/protocol/pool/Pool.Withdraw.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken, IERC20} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken, IERC20} from '../../../src/contracts/interfaces/IAToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract PoolWithdrawTests is TestnetProcedures { address internal aUSDX; diff --git a/tests/core/Pool.t.sol b/tests/protocol/pool/Pool.t.sol similarity index 97% rename from tests/core/Pool.t.sol rename to tests/protocol/pool/Pool.t.sol index 7ae63020..65aae648 100644 --- a/tests/core/Pool.t.sol +++ b/tests/protocol/pool/Pool.t.sol @@ -4,15 +4,15 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import 'forge-std/StdStorage.sol'; -import {IAToken, IERC20} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {IPool, DataTypes} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {PoolInstance} from 'aave-v3-core/instances/PoolInstance.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken, IERC20} from '../../../src/contracts/interfaces/IAToken.sol'; +import {IPool, DataTypes} from '../../../src/contracts/interfaces/IPool.sol'; +import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {PoolInstance} from '../../../src/contracts/instances/PoolInstance.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ReserveConfiguration} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {IAaveOracle} from '../../../src/contracts/interfaces/IAaveOracle.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract PoolTests is TestnetProcedures { using stdStorage for StdStorage; diff --git a/tests/core/PoolConfigurator.ACLModifiers.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol similarity index 97% rename from tests/core/PoolConfigurator.ACLModifiers.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol index aad612d2..a6c86453 100644 --- a/tests/core/PoolConfigurator.ACLModifiers.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ConfiguratorInputTypes} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ConfiguratorInputTypes} from '../../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorACLModifiersTest is TestnetProcedures { function setUp() public { @@ -244,7 +244,6 @@ contract PoolConfiguratorACLModifiersTest is TestnetProcedures { !contracts.aclManager.isRiskAdmin(caller) && caller != address(contracts.poolAddressesProvider) ); - vm.expectRevert(bytes(Errors.CALLER_NOT_RISK_OR_POOL_ADMIN)); vm.prank(caller); @@ -290,7 +289,6 @@ contract PoolConfiguratorACLModifiersTest is TestnetProcedures { ); vm.prank(caller); - vm.expectRevert(bytes(Errors.CALLER_NOT_POOL_OR_EMERGENCY_ADMIN)); contracts.poolConfiguratorProxy.setReservePause(asset, paused, gracePeriod); } diff --git a/tests/core/PoolConfigurator.borrowCaps.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.borrowCaps.t.sol similarity index 93% rename from tests/core/PoolConfigurator.borrowCaps.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.borrowCaps.t.sol index 6f347905..07728b7a 100644 --- a/tests/core/PoolConfigurator.borrowCaps.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.borrowCaps.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {IERC20} from '../../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorBorrowCapTests is TestnetProcedures { address internal aUSDX; diff --git a/tests/core/PoolConfigurator.eMode.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.eMode.sol similarity index 96% rename from tests/core/PoolConfigurator.eMode.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.eMode.sol index 25351978..4a156738 100644 --- a/tests/core/PoolConfigurator.eMode.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.eMode.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {ReserveConfiguration, DataTypes} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {PercentageMath} from '../../../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {ReserveConfiguration, DataTypes} from '../../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorEModeConfigTests is TestnetProcedures { using PercentageMath for uint256; diff --git a/tests/core/PoolConfigurator.initReserves.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol similarity index 94% rename from tests/core/PoolConfigurator.initReserves.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol index a6159b64..c760a736 100644 --- a/tests/core/PoolConfigurator.initReserves.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol @@ -3,12 +3,12 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {AToken} from 'aave-v3-core/contracts/protocol/tokenization/AToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {ConfiguratorInputTypes} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {IDefaultInterestRateStrategyV2} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; -import {TestnetProcedures, TestVars, TestReserveConfig} from '../utils/TestnetProcedures.sol'; +import {AToken} from '../../../../src/contracts/protocol/tokenization/AToken.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetERC20} from '../../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {ConfiguratorInputTypes} from '../../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {IDefaultInterestRateStrategyV2} from '../../../../src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; +import {TestnetProcedures, TestVars, TestReserveConfig} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorInitReservesTest is TestnetProcedures { event ReserveInitialized( @@ -33,7 +33,7 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { t.variableDebtSymbol = 'varDebtMISC'; t.stableDebtName = 'Stable Debt Misc'; t.stableDebtSymbol = 'stableDebtMISC'; - t.rateStrategy = report.defaultInterestRateStrategyV2; + t.rateStrategy = report.defaultInterestRateStrategy; t.interestRateData = abi.encode( IDefaultInterestRateStrategyV2.InterestRateData({ optimalUsageRatio: 80_00, @@ -257,7 +257,7 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { t.variableDebtSymbol = 'varDebtMISC'; t.stableDebtName = 'Stable Debt Misc'; t.stableDebtSymbol = 'stableDebtMISC'; - t.rateStrategy = report.defaultInterestRateStrategyV2; + t.rateStrategy = report.defaultInterestRateStrategy; t.interestRateData = abi.encode( IDefaultInterestRateStrategyV2.InterestRateData({ optimalUsageRatio: 80_00, diff --git a/tests/core/PoolConfigurator.liquidationFee.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.liquidationFee.t.sol similarity index 94% rename from tests/core/PoolConfigurator.liquidationFee.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.liquidationFee.t.sol index d509d49d..628485bb 100644 --- a/tests/core/PoolConfigurator.liquidationFee.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.liquidationFee.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorLiquidationFeeTests is TestnetProcedures { address internal aUSDX; diff --git a/tests/core/PoolConfigurator.pendingLTV.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.pendingLTV.t.sol similarity index 92% rename from tests/core/PoolConfigurator.pendingLTV.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.pendingLTV.t.sol index 5c3582cf..b15d5d01 100644 --- a/tests/core/PoolConfigurator.pendingLTV.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.pendingLTV.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {IERC20} from '../../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorPendingLtvTests is TestnetProcedures { function setUp() public { diff --git a/tests/core/PoolConfigurator.reserveRiskConfig.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol similarity index 98% rename from tests/core/PoolConfigurator.reserveRiskConfig.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol index cd6a28b7..97298c12 100644 --- a/tests/core/PoolConfigurator.reserveRiskConfig.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ReserveLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ReserveLogic} from '../../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; @@ -575,7 +575,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { emit ReservePaused(reserves[x], true); } vm.prank(poolAdmin); - contracts.poolConfiguratorProxy.setPoolPause(true, 0); + contracts.poolConfiguratorProxy.setPoolPause(true); for (uint16 x; x < reserves.length; ++x) { bool isPaused = contracts.protocolDataProvider.getPaused(reserves[x]); @@ -591,7 +591,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { emit ReservePaused(reserves[x], false); } vm.prank(poolAdmin); - contracts.poolConfiguratorProxy.setPoolPause(false, 0); + contracts.poolConfiguratorProxy.setPoolPause(false); for (uint16 x; x < reserves.length; ++x) { bool isPaused = contracts.protocolDataProvider.getPaused(reserves[x]); @@ -735,7 +735,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { function test_setLiquidationGracePeriodReserve(uint40 gracePeriod) public { vm.assume( - gracePeriod <= contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD() && gracePeriod != 0 + gracePeriod < contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD() && gracePeriod != 0 ); address asset = tokenList.usdx; diff --git a/tests/core/PoolConfigurator.supplyCaps.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.supplyCaps.t.sol similarity index 94% rename from tests/core/PoolConfigurator.supplyCaps.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.supplyCaps.t.sol index a1f7c01f..151d29fe 100644 --- a/tests/core/PoolConfigurator.supplyCaps.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.supplyCaps.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {IERC20} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {IERC20} from '../../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorSupplyCapTests is TestnetProcedures { address internal aUSDX; diff --git a/tests/core/PoolConfigurator.upgradeabilty.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol similarity index 81% rename from tests/core/PoolConfigurator.upgradeabilty.t.sol rename to tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol index 2c84f556..a85fd89a 100644 --- a/tests/core/PoolConfigurator.upgradeabilty.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol @@ -3,18 +3,18 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {AToken} from 'aave-v3-core/contracts/protocol/tokenization/AToken.sol'; -import {VariableDebtToken} from 'aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol'; -import {StableDebtToken} from 'aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {ConfiguratorInputTypes, IPool, IPoolAddressesProvider} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {MockATokenRepayment} from 'aave-v3-core/contracts/mocks/tokens/MockATokenRepayment.sol'; -import {MockVariableDebtToken, MockStableDebtToken} from 'aave-v3-core/contracts/mocks/tokens/MockDebtTokens.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; - -import {SlotParser} from '../utils/SlotParser.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {AToken} from '../../../../src/contracts/protocol/tokenization/AToken.sol'; +import {VariableDebtToken} from '../../../../src/contracts/protocol/tokenization/VariableDebtToken.sol'; +import {StableDebtToken} from '../../../../src/contracts/protocol/tokenization/StableDebtToken.sol'; +import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {ConfiguratorInputTypes, IPool, IPoolAddressesProvider} from '../../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {MockATokenRepayment} from '../../../../src/contracts/mocks/tokens/MockATokenRepayment.sol'; +import {MockVariableDebtToken, MockStableDebtToken} from '../../../../src/contracts/mocks/tokens/MockDebtTokens.sol'; +import {DataTypes} from '../../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {ReserveLogic} from '../../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; + +import {SlotParser} from '../../../utils/SlotParser.sol'; +import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorUpgradeabilityTests is TestnetProcedures { using stdStorage for StdStorage; @@ -31,6 +31,12 @@ contract PoolConfiguratorUpgradeabilityTests is TestnetProcedures { address newStrategy ); + event ReserveInterestRateDataChanged( + address indexed asset, + address indexed strategy, + bytes data + ); + event ATokenUpgraded( address indexed asset, address indexed proxy, @@ -85,6 +91,28 @@ contract PoolConfiguratorUpgradeabilityTests is TestnetProcedures { assertEq(newInterestRateStrategy, updatedInterestsRateStrategy); } + function test_setReserveInterestRateData() public { + address currentInterestRateStrategy = contracts + .protocolDataProvider + .getInterestRateStrategyAddress(tokenList.usdx); + + bytes memory newInterestRateData = _getDefaultInterestRatesStrategyData(); + + vm.expectEmit(address(contracts.poolConfiguratorProxy)); + emit ReserveInterestRateDataChanged(tokenList.usdx, currentInterestRateStrategy, newInterestRateData); + + vm.prank(poolAdmin); + contracts.poolConfiguratorProxy.setReserveInterestRateData( + tokenList.usdx, + _getDefaultInterestRatesStrategyData() + ); + + address newInterestRateStrategy = contracts.protocolDataProvider.getInterestRateStrategyAddress( + tokenList.usdx + ); + assertEq(currentInterestRateStrategy, newInterestRateStrategy); + } + function test_interestRateStrategy_update() public { vm.prank(carol); contracts.poolProxy.supply(tokenList.usdx, 100_000e6, carol, 0); diff --git a/tests/core/ATokenEdgeCases.t.sol b/tests/protocol/tokenization/ATokenEdgeCases.t.sol similarity index 95% rename from tests/core/ATokenEdgeCases.t.sol rename to tests/protocol/tokenization/ATokenEdgeCases.t.sol index ddce0cac..247ed6fd 100644 --- a/tests/core/ATokenEdgeCases.t.sol +++ b/tests/protocol/tokenization/ATokenEdgeCases.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {ATokenInstance} from 'aave-v3-core/instances/ATokenInstance.sol'; -import {IAaveIncentivesController} from 'aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; +import {ATokenInstance} from '../../../src/contracts/instances/ATokenInstance.sol'; +import {IAaveIncentivesController} from '../../../src/contracts/interfaces/IAaveIncentivesController.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; contract ATokenEdgeCasesTests is TestnetProcedures { ATokenInstance public aToken; diff --git a/tests/core/ATokenEvents.t.sol b/tests/protocol/tokenization/ATokenEvents.t.sol similarity index 96% rename from tests/core/ATokenEvents.t.sol rename to tests/protocol/tokenization/ATokenEvents.t.sol index 6911d439..9ba61ceb 100644 --- a/tests/core/ATokenEvents.t.sol +++ b/tests/protocol/tokenization/ATokenEvents.t.sol @@ -3,12 +3,12 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {ReserveLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {MathUtils} from 'aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {ReserveLogic} from '../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import {MathUtils} from '../../../src/contracts/protocol/libraries/math/MathUtils.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; contract ATokenEventsTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/core/ATokenModifiers.t.sol b/tests/protocol/tokenization/ATokenModifiers.t.sol similarity index 85% rename from tests/core/ATokenModifiers.t.sol rename to tests/protocol/tokenization/ATokenModifiers.t.sol index e29cb4dc..b29988bb 100644 --- a/tests/core/ATokenModifiers.t.sol +++ b/tests/protocol/tokenization/ATokenModifiers.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; contract ATokenModifiersTests is TestnetProcedures { IAToken public aToken; diff --git a/tests/core/ATokenPermit.t.sol b/tests/protocol/tokenization/ATokenPermit.t.sol similarity index 96% rename from tests/core/ATokenPermit.t.sol rename to tests/protocol/tokenization/ATokenPermit.t.sol index e7d90084..a1f708e4 100644 --- a/tests/core/ATokenPermit.t.sol +++ b/tests/protocol/tokenization/ATokenPermit.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; interface IATokenWithMetadata is IAToken { function name() external view returns (string memory); diff --git a/tests/core/ATokenRepay.t.sol b/tests/protocol/tokenization/ATokenRepay.t.sol similarity index 91% rename from tests/core/ATokenRepay.t.sol rename to tests/protocol/tokenization/ATokenRepay.t.sol index eb650f78..1aee8136 100644 --- a/tests/core/ATokenRepay.t.sol +++ b/tests/protocol/tokenization/ATokenRepay.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {IVariableDebtToken} from '../../../src/contracts/interfaces/IVariableDebtToken.sol'; +import {IERC20Detailed} from '../../../src/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; interface IVariableDebtTokenWithERC20 is IVariableDebtToken, IERC20Detailed {} diff --git a/tests/core/ATokenRescueTokens.sol b/tests/protocol/tokenization/ATokenRescueTokens.sol similarity index 90% rename from tests/core/ATokenRescueTokens.sol rename to tests/protocol/tokenization/ATokenRescueTokens.sol index 19592b12..870b3f9f 100644 --- a/tests/core/ATokenRescueTokens.sol +++ b/tests/protocol/tokenization/ATokenRescueTokens.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken} from '../../../src/contracts/interfaces/IAToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract ATokenRescueTokensTests is TestnetProcedures { IAToken public aTokenUSDX; diff --git a/tests/core/ATokenTransfers.t.sol b/tests/protocol/tokenization/ATokenTransfers.t.sol similarity index 95% rename from tests/core/ATokenTransfers.t.sol rename to tests/protocol/tokenization/ATokenTransfers.t.sol index dbf49542..1304da8b 100644 --- a/tests/core/ATokenTransfers.t.sol +++ b/tests/protocol/tokenization/ATokenTransfers.t.sol @@ -3,14 +3,14 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IAToken, IERC20} from 'aave-v3-core/contracts/interfaces/IAToken.sol'; -import {IVariableDebtToken} from 'aave-v3-core/contracts/interfaces/IVariableDebtToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {SupplyLogic} from 'aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol'; -import {MathUtils} from 'aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {IAToken, IERC20} from '../../../src/contracts/interfaces/IAToken.sol'; +import {IVariableDebtToken} from '../../../src/contracts/interfaces/IVariableDebtToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {SupplyLogic} from '../../../src/contracts/protocol/libraries/logic/SupplyLogic.sol'; +import {MathUtils} from '../../../src/contracts/protocol/libraries/math/MathUtils.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract ATokenTransferTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/core/ScaledBalanceTokenBase.t.sol b/tests/protocol/tokenization/ScaledBalanceTokenBase.t.sol similarity index 94% rename from tests/core/ScaledBalanceTokenBase.t.sol rename to tests/protocol/tokenization/ScaledBalanceTokenBase.t.sol index aab5cfc5..cff2dd15 100644 --- a/tests/core/ScaledBalanceTokenBase.t.sol +++ b/tests/protocol/tokenization/ScaledBalanceTokenBase.t.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {MockScaledToken} from 'aave-v3-core/contracts/mocks/tokens/MockScaledToken.sol'; - -import '../utils/TestnetProcedures.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {MockScaledToken} from '../../../src/contracts/mocks/tokens/MockScaledToken.sol'; +import '../../utils/TestnetProcedures.sol'; contract ScaledBalanceTokenBaseEdgeTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/core/StableDebtToken.t.sol b/tests/protocol/tokenization/StableDebtToken.t.sol similarity index 96% rename from tests/core/StableDebtToken.t.sol rename to tests/protocol/tokenization/StableDebtToken.t.sol index 2394d4b6..06aa317c 100644 --- a/tests/core/StableDebtToken.t.sol +++ b/tests/protocol/tokenization/StableDebtToken.t.sol @@ -3,13 +3,13 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {StableDebtTokenHarness as StableDebtTokenInstance} from '../harness/StableDebtToken.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {IAaveIncentivesController} from 'aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {PoolConfigurator, ConfiguratorInputTypes, IPool} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {StableDebtTokenHarness as StableDebtTokenInstance} from '../../harness/StableDebtToken.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {IAaveIncentivesController} from '../../../src/contracts/interfaces/IAaveIncentivesController.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {PoolConfigurator, ConfiguratorInputTypes, IPool} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract StableDebtTokenEventsTests is TestnetProcedures { StableDebtTokenInstance public stableDebtToken; diff --git a/tests/core/VariableDebtToken.t.sol b/tests/protocol/tokenization/VariableDebtToken.t.sol similarity index 96% rename from tests/core/VariableDebtToken.t.sol rename to tests/protocol/tokenization/VariableDebtToken.t.sol index 9435b543..0c13902e 100644 --- a/tests/core/VariableDebtToken.t.sol +++ b/tests/protocol/tokenization/VariableDebtToken.t.sol @@ -3,15 +3,15 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {VariableDebtTokenHarness as VariableDebtTokenInstance} from '../harness/VariableDebtToken.sol'; -import {IAaveIncentivesController} from 'aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol'; -import {Errors} from 'aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {ReserveLogic, DataTypes} from 'aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {WadRayMath} from 'aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol'; -import {ConfiguratorInputTypes, IPool} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {EIP712SigUtils} from '../utils/EIP712SigUtils.sol'; -import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; +import {VariableDebtTokenHarness as VariableDebtTokenInstance} from '../../harness/VariableDebtToken.sol'; +import {IAaveIncentivesController} from '../../../src/contracts/interfaces/IAaveIncentivesController.sol'; +import {Errors} from '../../../src/contracts/protocol/libraries/helpers/Errors.sol'; +import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {ReserveLogic, DataTypes} from '../../../src/contracts/protocol/libraries/logic/ReserveLogic.sol'; +import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; +import {ConfiguratorInputTypes, IPool} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; +import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; contract VariableDebtTokenEventsTests is TestnetProcedures { using WadRayMath for uint256; diff --git a/tests/periphery/EmissionsManager.t.sol b/tests/rewards/EmissionsManager.t.sol similarity index 76% rename from tests/periphery/EmissionsManager.t.sol rename to tests/rewards/EmissionsManager.t.sol index 2ebc7afd..9c157af1 100644 --- a/tests/periphery/EmissionsManager.t.sol +++ b/tests/rewards/EmissionsManager.t.sol @@ -1,16 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import 'forge-std/Test.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {RewardsController} from 'aave-v3-periphery/contracts/rewards/RewardsController.sol'; -import {EmissionManager} from 'aave-v3-periphery/contracts/rewards/EmissionManager.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {ITransferStrategyBase} from 'aave-v3-periphery/contracts/rewards/interfaces/ITransferStrategyBase.sol'; -import {IEACAggregatorProxy} from 'aave-v3-periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol'; -import {RewardsDataTypes} from 'aave-v3-periphery/contracts/rewards/libraries/RewardsDataTypes.sol'; -import {PullRewardsTransferStrategy} from 'aave-v3-periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; +import {MockAggregator} from '../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {RewardsController} from '../../src/contracts/rewards/RewardsController.sol'; +import {EmissionManager} from '../../src/contracts/rewards/EmissionManager.sol'; +import {DataTypes} from '../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {IPool} from '../../src/contracts/interfaces/IPool.sol'; +import {ITransferStrategyBase} from '../../src/contracts/rewards/interfaces/ITransferStrategyBase.sol'; +import {IEACAggregatorProxy} from '../../src/contracts/helpers/interfaces/IEACAggregatorProxy.sol'; +import {RewardsDataTypes} from '../../src/contracts/rewards/libraries/RewardsDataTypes.sol'; +import {PullRewardsTransferStrategy} from '../../src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; contract EmissionManagerTest is TestnetProcedures { diff --git a/tests/periphery/RewardsController.t.sol b/tests/rewards/RewardsController.t.sol similarity index 94% rename from tests/periphery/RewardsController.t.sol rename to tests/rewards/RewardsController.t.sol index 38dae8cd..26d206ef 100644 --- a/tests/periphery/RewardsController.t.sol +++ b/tests/rewards/RewardsController.t.sol @@ -1,16 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import 'forge-std/Test.sol'; -import {MockAggregator} from 'aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {RewardsController, RewardsDistributor} from 'aave-v3-periphery/contracts/rewards/RewardsController.sol'; -import {EmissionManager} from 'aave-v3-periphery/contracts/rewards/EmissionManager.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {IAToken, IERC20} from 'aave-v3-core/contracts/protocol/tokenization/AToken.sol'; -import {ITransferStrategyBase} from 'aave-v3-periphery/contracts/rewards/interfaces/ITransferStrategyBase.sol'; -import {IEACAggregatorProxy} from 'aave-v3-periphery/contracts/misc/interfaces/IEACAggregatorProxy.sol'; -import {RewardsDataTypes} from 'aave-v3-periphery/contracts/rewards/libraries/RewardsDataTypes.sol'; -import {PullRewardsTransferStrategy} from 'aave-v3-periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; +import {MockAggregator} from '../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; +import {RewardsController, RewardsDistributor} from '../../src/contracts/rewards/RewardsController.sol'; +import {EmissionManager} from '../../src/contracts/rewards/EmissionManager.sol'; +import {DataTypes} from '../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {IAToken, IERC20} from '../../src/contracts/protocol/tokenization/AToken.sol'; +import {ITransferStrategyBase} from '../../src/contracts/rewards/interfaces/ITransferStrategyBase.sol'; +import {IEACAggregatorProxy} from '../../src/contracts/helpers/interfaces/IEACAggregatorProxy.sol'; +import {RewardsDataTypes} from '../../src/contracts/rewards/libraries/RewardsDataTypes.sol'; +import {PullRewardsTransferStrategy} from '../../src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; contract RewardsControllerTest is TestnetProcedures { diff --git a/tests/periphery/StakedTokenTransferStrategy.t.sol b/tests/rewards/StakedTokenTransferStrategy.t.sol similarity index 94% rename from tests/periphery/StakedTokenTransferStrategy.t.sol rename to tests/rewards/StakedTokenTransferStrategy.t.sol index cbb78767..1c3b2775 100644 --- a/tests/periphery/StakedTokenTransferStrategy.t.sol +++ b/tests/rewards/StakedTokenTransferStrategy.t.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {StakedTokenTransferStrategy, IERC20, IStakedToken} from 'aave-v3-periphery/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol'; -import {StakeMock} from './mocks/StakeMock.sol'; +import {StakedTokenTransferStrategy, IERC20, IStakedToken} from '../../src/contracts/rewards/transfer-strategies/StakedTokenTransferStrategy.sol'; +import {StakeMock} from '../mocks/StakeMock.sol'; import {TestnetProcedures} from '../utils/TestnetProcedures.sol'; contract StakedTokenTransferStrategyTest is TestnetProcedures { diff --git a/tests/utils/BatchTestProcedures.sol b/tests/utils/BatchTestProcedures.sol index 00b9efa3..d0418972 100644 --- a/tests/utils/BatchTestProcedures.sol +++ b/tests/utils/BatchTestProcedures.sol @@ -6,17 +6,18 @@ import '../../src/deployments/interfaces/IMarketReportTypes.sol'; import {DeployUtils} from '../../src/deployments/contracts/utilities/DeployUtils.sol'; import {AaveV3GettersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchOne.sol'; import {AaveV3GettersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3GettersBatchTwo.sol'; +import {AaveV3TokensBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3TokensBatch.sol'; import {AaveV3SetupBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; import {FfiUtils} from '../../src/deployments/contracts/utilities/FfiUtils.sol'; import {DefaultMarketInput} from '../../src/deployments/inputs/DefaultMarketInput.sol'; import {AaveV3BatchOrchestration} from '../../src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {ACLManager} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import '../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import '../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import '../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import '../../src/contracts/helpers/AaveProtocolDataProvider.sol'; import {MarketReportUtils} from '../../src/deployments/contracts/utilities/MarketReportUtils.sol'; struct TestVars { @@ -62,7 +63,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput AaveV3GettersBatchOne.GettersReportBatchOne memory gettersReport1, PoolReport memory poolReport, PeripheryReport memory peripheryReport, - ParaswapReport memory paraswapReport, + MiscReport memory miscReport, AaveV3SetupBatch setupContract ) { @@ -91,11 +92,11 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput address(setupContract) ); - paraswapReport = AaveV3BatchOrchestration._deployParaswapAdapters( - roles, - config, + miscReport = AaveV3BatchOrchestration._deployMisc( + flags.l2, initialReport.poolAddressesProvider, - peripheryReport.treasury + config.l2SequencerUptimeFeed, + config.l2PriceOracleSentinelGracePeriod ); return ( @@ -103,7 +104,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput gettersReport1, poolReport, peripheryReport, - paraswapReport, + miscReport, setupContract ); } @@ -122,6 +123,8 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput PoolReport memory poolReport, SetupReport memory setupReport, PeripheryReport memory peripheryReport, + MiscReport memory miscReport, + AaveV3TokensBatch.TokensReport memory tokensReport, ParaswapReport memory paraswapReport, AaveV3SetupBatch setupContract ) @@ -131,7 +134,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput gettersReport1, poolReport, peripheryReport, - paraswapReport, + miscReport, setupContract ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); @@ -143,7 +146,15 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput poolReport.poolConfiguratorImplementation, gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, - peripheryReport.rewardsControllerImplementation + peripheryReport.rewardsControllerImplementation, + miscReport.priceOracleSentinel + ); + + paraswapReport = AaveV3BatchOrchestration._deployParaswapAdapters( + roles, + config, + initialReport.poolAddressesProvider, + peripheryReport.treasury ); gettersReport2 = AaveV3BatchOrchestration._deployGettersBatch2( @@ -153,6 +164,8 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput flags.l2 ); + tokensReport = AaveV3BatchOrchestration._deployTokens(setupReport.poolProxy); + return ( initialReport, gettersReport1, @@ -160,6 +173,8 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput poolReport, setupReport, peripheryReport, + miscReport, + tokensReport, paraswapReport, setupContract ); @@ -175,8 +190,8 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput assertTrue(r.protocolDataProvider != address(0), 'report.protocolDataProvider'); assertTrue(r.aaveOracle != address(0), 'report.aaveOracle'); assertTrue( - r.defaultInterestRateStrategyV2 != address(0), - 'report.defaultInterestRateStrategyV2' + r.defaultInterestRateStrategy != address(0), + 'report.defaultInterestRateStrategy' ); assertTrue(r.aclManager != address(0), 'report.aclManager'); assertTrue(r.treasury != address(0), 'report.treasury'); @@ -193,6 +208,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput if (flags.l2) { assertTrue(r.l2Encoder != address(0), 'report.l2Encoder'); + assertTrue(r.priceOracleSentinel != address(0), 'report.priceOracleSentinel'); } assertTrue(r.aToken != address(0), 'report.aToken'); @@ -204,6 +220,11 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput 'r.rewardsControllerImplementation' ); assertTrue(r.rewardsControllerProxy != address(0), 'report.rewardsControllerProxy'); + assertTrue(r.configEngine != address(0), 'report.configEngine'); + assertTrue(r.staticATokenFactoryImplementation != address(0), 'report.staticATokenFactoryImplementation'); + assertTrue(r.staticATokenFactoryProxy != address(0), 'report.staticATokenFactoryProxy'); + assertTrue(r.staticATokenImplementation != address(0), 'report.staticATokenImplementation'); + assertTrue(r.transparentProxyFactory != address(0), 'report.transparentProxyFactory'); } function deployAaveV3Testnet( @@ -215,6 +236,12 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput ) internal returns (MarketReport memory testReport) { detectFoundryLibrariesAndDelete(); + // Etch the create2 factory + vm.etch( + 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, + hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' + ); + vm.startPrank(deployer); MarketReport memory deployReport = AaveV3BatchOrchestration.deployAaveV3( deployer, @@ -266,7 +293,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput t.variableDebtSymbol = _concatStr('varDebtMISC ', x); t.stableDebtName = _concatStr('Stable Debt Misc ', x); t.stableDebtSymbol = _concatStr('stableDebtMISC ', x); - t.rateStrategy = r.defaultInterestRateStrategyV2; + t.rateStrategy = r.defaultInterestRateStrategy; t.interestRateData = abi.encode( IDefaultInterestRateStrategyV2.InterestRateData({ optimalUsageRatio: 80_00, diff --git a/tests/utils/ConfigEngineDeployer.sol b/tests/utils/ConfigEngineDeployer.sol deleted file mode 100644 index 1c25da03..00000000 --- a/tests/utils/ConfigEngineDeployer.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../src/deployments/interfaces/IMarketReportTypes.sol'; -import {Vm} from 'forge-std/Vm.sol'; -import {Create2Utils} from '../../src/deployments/contracts/utilities/Create2Utils.sol'; -import {AaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol'; -import {IAaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {IPoolAddressesProvider} from '../../src/core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../src/core/contracts/interfaces/IPool.sol'; -import {IPoolConfigurator} from '../../src/core/contracts/interfaces/IPoolConfigurator.sol'; -import {IAaveOracle} from '../../src/core/contracts/interfaces/IAaveOracle.sol'; -import {CapsEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/CapsEngine.sol'; -import {BorrowEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/BorrowEngine.sol'; -import {CollateralEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/CollateralEngine.sol'; -import {RateEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/RateEngine.sol'; -import {PriceFeedEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/PriceFeedEngine.sol'; -import {EModeEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/EModeEngine.sol'; -import {ListingEngine} from 'aave-v3-periphery/contracts/v3-config-engine/libraries/ListingEngine.sol'; - -library ConfigEngineDeployer { - function deployEngine(Vm vm, MarketReport memory report) internal returns (address) { - // Etch the create2 factory in the local env - vm.etch( - 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, - hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' - ); - IAaveV3ConfigEngine.EngineLibraries memory engineLibraries = IAaveV3ConfigEngine - .EngineLibraries({ - listingEngine: Create2Utils._create2Deploy('v1', type(ListingEngine).creationCode), - eModeEngine: Create2Utils._create2Deploy('v1', type(EModeEngine).creationCode), - borrowEngine: Create2Utils._create2Deploy('v1', type(BorrowEngine).creationCode), - collateralEngine: Create2Utils._create2Deploy('v1', type(CollateralEngine).creationCode), - priceFeedEngine: Create2Utils._create2Deploy('v1', type(PriceFeedEngine).creationCode), - rateEngine: Create2Utils._create2Deploy('v1', type(RateEngine).creationCode), - capsEngine: Create2Utils._create2Deploy('v1', type(CapsEngine).creationCode) - }); - - IAaveV3ConfigEngine.EngineConstants memory engineConstants = IAaveV3ConfigEngine - .EngineConstants({ - pool: IPool(report.poolProxy), - poolConfigurator: IPoolConfigurator(report.poolConfiguratorProxy), - defaultInterestRateStrategy: report.defaultInterestRateStrategyV2, - oracle: IAaveOracle(report.aaveOracle), - rewardsController: report.rewardsControllerProxy, - collector: report.treasury - }); - - return - address( - new AaveV3ConfigEngine( - report.aToken, - report.variableDebtToken, - report.stableDebtToken, - engineConstants, - engineLibraries - ) - ); - } -} diff --git a/tests/utils/ProtocolV3TestBase.sol b/tests/utils/ProtocolV3TestBase.sol index 8f4aabad..616442ab 100644 --- a/tests/utils/ProtocolV3TestBase.sol +++ b/tests/utils/ProtocolV3TestBase.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.5 <0.9.0; -import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {IDefaultInterestRateStrategyV2} from 'aave-v3-core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; -import {IPoolDataProvider} from 'aave-v3-core/contracts/interfaces/IPoolDataProvider.sol'; -import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol'; -import {IAaveOracle} from 'aave-v3-core/contracts/interfaces/IAaveOracle.sol'; -import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; -import {IPoolConfigurator} from 'aave-v3-core/contracts/interfaces/IPoolConfigurator.sol'; +import {IERC20Detailed} from '../../src/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; +import {IDefaultInterestRateStrategyV2} from '../../src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; +import {ReserveConfiguration} from '../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPoolDataProvider} from '../../src/contracts/interfaces/IPoolDataProvider.sol'; +import {IPool} from '../../src/contracts/interfaces/IPool.sol'; +import {IAaveOracle} from '../../src/contracts/interfaces/IAaveOracle.sol'; +import {DataTypes} from '../../src/contracts/protocol/libraries/types/DataTypes.sol'; +import {IPoolConfigurator} from '../../src/contracts/interfaces/IPoolConfigurator.sol'; import {ProxyHelpers} from './ProxyHelpers.sol'; import {DiffUtils} from './DiffUtils.sol'; @@ -110,18 +110,6 @@ struct LocalVars { ReserveConfig[] configs; } -struct InterestStrategyValues { - address addressesProvider; - uint256 optimalUsageRatio; - uint256 optimalStableToTotalDebtRatio; - uint256 baseStableBorrowRate; - uint256 stableRateSlope1; - uint256 stableRateSlope2; - uint256 baseVariableBorrowRate; - uint256 variableRateSlope1; - uint256 variableRateSlope2; -} - /** * only applicable to harmony at this point */ @@ -615,7 +603,7 @@ contract ProtocolV3TestBase is DiffUtils { address reserve, address interestRateStrategyAddress, address expectedStrategy, - InterestStrategyValues memory expectedStrategyValues + IDefaultInterestRateStrategyV2.InterestRateDataRay memory expectedStrategyValues ) internal view { IDefaultInterestRateStrategyV2 strategy = IDefaultInterestRateStrategyV2( interestRateStrategyAddress @@ -630,10 +618,6 @@ contract ProtocolV3TestBase is DiffUtils { strategy.getOptimalUsageRatio(reserve) == expectedStrategyValues.optimalUsageRatio, '_validateInterestRateStrategy() : INVALID_OPTIMAL_RATIO' ); - require( - address(strategy.ADDRESSES_PROVIDER()) == expectedStrategyValues.addressesProvider, - '_validateInterestRateStrategy() : INVALID_ADDRESSES_PROVIDER' - ); require( strategy.getBaseVariableBorrowRate(reserve) == expectedStrategyValues.baseVariableBorrowRate, '_validateInterestRateStrategy() : INVALID_BASE_VARIABLE_BORROW' diff --git a/tests/utils/SigUtils.sol b/tests/utils/SigUtils.sol new file mode 100644 index 00000000..72aed63c --- /dev/null +++ b/tests/utils/SigUtils.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import {IStaticATokenLM} from '../../src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol'; + +library SigUtils { + struct Permit { + address owner; + address spender; + uint256 value; + uint256 nonce; + uint256 deadline; + } + + struct WithdrawPermit { + address owner; + address spender; + uint256 staticAmount; + uint256 dynamicAmount; + bool toUnderlying; + uint256 nonce; + uint256 deadline; + } + + struct DepositPermit { + address owner; + address spender; + uint256 value; + uint16 referralCode; + bool fromUnderlying; + uint256 nonce; + uint256 deadline; + IStaticATokenLM.PermitParams permit; + } + + // computes the hash of a permit + function getStructHash(Permit memory _permit, bytes32 typehash) internal pure returns (bytes32) { + return + keccak256( + abi.encode( + typehash, + _permit.owner, + _permit.spender, + _permit.value, + _permit.nonce, + _permit.deadline + ) + ); + } + + function getWithdrawHash( + WithdrawPermit memory permit, + bytes32 typehash + ) internal pure returns (bytes32) { + return + keccak256( + abi.encode( + typehash, + permit.owner, + permit.spender, + permit.staticAmount, + permit.dynamicAmount, + permit.toUnderlying, + permit.nonce, + permit.deadline + ) + ); + } + + function getDepositHash( + DepositPermit memory permit, + bytes32 typehash + ) internal pure returns (bytes32) { + return + keccak256( + abi.encode( + typehash, + permit.owner, + permit.spender, + permit.value, + permit.referralCode, + permit.fromUnderlying, + permit.nonce, + permit.deadline, + permit.permit + ) + ); + } + + // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer + function getTypedDataHash( + Permit memory permit, + bytes32 typehash, + bytes32 domainSeparator + ) public pure returns (bytes32) { + return + keccak256(abi.encodePacked('\x19\x01', domainSeparator, getStructHash(permit, typehash))); + } + + function getTypedWithdrawHash( + WithdrawPermit memory permit, + bytes32 typehash, + bytes32 domainSeparator + ) public pure returns (bytes32) { + return + keccak256(abi.encodePacked('\x19\x01', domainSeparator, getWithdrawHash(permit, typehash))); + } + + function getTypedDepositHash( + DepositPermit memory permit, + bytes32 typehash, + bytes32 domainSeparator + ) public pure returns (bytes32) { + return + keccak256(abi.encodePacked('\x19\x01', domainSeparator, getDepositHash(permit, typehash))); + } +} diff --git a/tests/utils/TestnetProcedures.sol b/tests/utils/TestnetProcedures.sol index 5d6f39c2..35669294 100644 --- a/tests/utils/TestnetProcedures.sol +++ b/tests/utils/TestnetProcedures.sol @@ -4,23 +4,22 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import '../../src/deployments/interfaces/IMarketReportTypes.sol'; -import {ConfigEngineDeployer} from './ConfigEngineDeployer.sol'; import {DeployUtils} from '../../src/deployments/contracts/utilities/DeployUtils.sol'; import {FfiUtils} from '../../src/deployments/contracts/utilities/FfiUtils.sol'; import {DefaultMarketInput} from '../../src/deployments/inputs/DefaultMarketInput.sol'; import {AaveV3BatchOrchestration} from '../../src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol'; -import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; import {AaveV3TestListing} from '../mocks/AaveV3TestListing.sol'; -import {ACLManager, Errors} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol'; -import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol'; -import {TestnetERC20} from 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {PoolConfigurator} from 'aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol'; -import {DefaultReserveInterestRateStrategyV2} from 'aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategyV2.sol'; -import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {PercentageMath} from 'aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol'; -import {AaveProtocolDataProvider} from 'aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol'; +import {ACLManager, Errors} from '../../src/contracts/protocol/configuration/ACLManager.sol'; +import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; +import {TestnetERC20} from '../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; +import {PoolConfigurator} from '../../src/contracts/protocol/pool/PoolConfigurator.sol'; +import {DefaultReserveInterestRateStrategyV2} from '../../src/contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; +import {ReserveConfiguration} from '../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {PercentageMath} from '../../src/contracts/protocol/libraries/math/PercentageMath.sol'; +import {AaveProtocolDataProvider} from '../../src/contracts/helpers/AaveProtocolDataProvider.sol'; import {MarketReportUtils} from '../../src/deployments/contracts/utilities/MarketReportUtils.sol'; -import {AaveV3ConfigEngine, IAaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol'; +import {AaveV3ConfigEngine, IAaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; struct TestVars { string aTokenName; @@ -111,9 +110,14 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { MarketReport memory deployedContracts ) = _getMarketInput(poolAdmin); roleList = roles; - flags.l2 = l2; + // Etch the create2 factory + vm.etch( + 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, + hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' + ); + (report, tokenList) = deployAaveV3TestnetAssets( poolAdmin, roles, @@ -218,10 +222,8 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { MarketReport memory r = deployAaveV3Testnet(deployer, roles, config, flags, deployedContracts); - address engine = ConfigEngineDeployer.deployEngine(vm, r); - AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(engine), + IAaveV3ConfigEngine(r.configEngine), roles.poolAdmin, assetsList.weth, r @@ -298,7 +300,7 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { t.variableDebtSymbol = _concatStr('varDebtMISC ', x); t.stableDebtName = _concatStr('Stable Debt Misc ', x); t.stableDebtSymbol = _concatStr('stableDebtMISC ', x); - t.rateStrategy = r.defaultInterestRateStrategyV2; + t.rateStrategy = r.defaultInterestRateStrategy; t.interestRateData = abi.encode( IDefaultInterestRateStrategyV2.InterestRateData({ optimalUsageRatio: 80_00, From b77eb7117c1cb9998aa35b037b1652f4aefbe84d Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 29 Apr 2024 14:01:50 +0530 Subject: [PATCH 02/11] fix: lint --- .../misc/DeployAaveV3MarketBatchedBase.sol | 3 +- .../extensions/v3-config-engine/README.md | 3 +- .../procedures/AaveV3HelpersProcedureOne.sol | 8 +- .../procedures/AaveV3HelpersProcedureTwo.sol | 17 +- .../contracts/utilities/MetadataReporter.sol | 18 +- .../batches/AaveV3HelpersBatchTwo.sol | 12 +- tests/deployments/AaveV3BatchTests.t.sol | 8 +- tests/deployments/DeploymentsGasLimits.t.sol | 8 +- .../static-a-token/StataOracle.t.sol | 5 +- .../static-a-token/StaticATokenLM.t.sol | 12 +- .../StaticATokenMetaTransactions.t.sol | 5 +- .../static-a-token/StaticATokenNoLM.t.sol | 1 - tests/extensions/static-a-token/TestBase.sol | 11 +- .../AaveV3ConfigEngineTest.t.sol | 194 ++++++++++-------- .../mocks/AaveV3MockAssetEModeUpdate.sol | 5 +- .../mocks/AaveV3MockListing.sol | 6 +- .../mocks/AaveV3MockListingCustom.sol | 9 +- .../mocks/AaveV3MockPriceFeedUpdate.sol | 11 +- .../PoolConfigurator.reserveRiskConfig.t.sol | 4 +- .../PoolConfigurator.upgradeabilty.t.sol | 12 +- tests/utils/BatchTestProcedures.sol | 19 +- 21 files changed, 192 insertions(+), 179 deletions(-) diff --git a/scripts/misc/DeployAaveV3MarketBatchedBase.sol b/scripts/misc/DeployAaveV3MarketBatchedBase.sol index 961b0f38..25af8793 100644 --- a/scripts/misc/DeployAaveV3MarketBatchedBase.sol +++ b/scripts/misc/DeployAaveV3MarketBatchedBase.sol @@ -46,7 +46,8 @@ abstract contract DeployAaveV3MarketBatchedBase is DeployUtils, MarketInput, Scr } if ( (flags.l2 && - (config.l2SequencerUptimeFeed == address(0) || config.l2PriceOracleSentinelGracePeriod == 0)) + (config.l2SequencerUptimeFeed == address(0) || + config.l2PriceOracleSentinelGracePeriod == 0)) ) { console.log( 'Warning: L2 Sequencer uptime feed wont be set at deployment due missing config.l2SequencerUptimeFeed config.l2PriceOracleSentinelGracePeriod' diff --git a/src/contracts/extensions/v3-config-engine/README.md b/src/contracts/extensions/v3-config-engine/README.md index 7308dde5..62480d8f 100644 --- a/src/contracts/extensions/v3-config-engine/README.md +++ b/src/contracts/extensions/v3-config-engine/README.md @@ -35,7 +35,7 @@ Change eMode category of a particular asset? Same as previous, just define the u ### Internal aspects to consider - Frequently, at the same time that you want to do an update of parameters or listing, you also want to do something extra before or after. -The `Base Aave v3 Payload` defines `_preExecute()` and `_postExecute()` hook functions, that you can redefine on your payload and will the execute before and after all configs changes/listings you define. + The `Base Aave v3 Payload` defines `_preExecute()` and `_postExecute()` hook functions, that you can redefine on your payload and will the execute before and after all configs changes/listings you define. - The payload also allow you to group changes of parameters and listings, just by defining at the same time the aforementioned `newListings()`, `capsUpdate()` and/or `collateralsUpdates()` and so on. For reference, the execution ordering is the following: 1. `_preExecute()` @@ -51,6 +51,7 @@ The `Base Aave v3 Payload` defines `_preExecute()` and `_postExecute()` hook fun 11. `_postExecute()` ## Links to examples + - [Simple mock listing on Aave v3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockListing.sol) - [Simple custom mock listing on Aave V3 with custom token impl](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockListingCustom.sol) - [Mock e-mode category update on Aave V3](../../../../tests/helpers/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol) diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol index 952b02af..7ff449f2 100644 --- a/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol +++ b/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol @@ -50,13 +50,7 @@ contract AaveV3HelpersProcedureOne { configEngineReport.capsEngine = engineLibraries.capsEngine; configEngineReport.configEngine = address( - new AaveV3ConfigEngine( - aTokenImpl, - vTokenImpl, - sTokenImpl, - engineConstants, - engineLibraries - ) + new AaveV3ConfigEngine(aTokenImpl, vTokenImpl, sTokenImpl, engineConstants, engineLibraries) ); return configEngineReport; } diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol index f455b2e9..9a92839a 100644 --- a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol +++ b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol @@ -17,10 +17,7 @@ contract AaveV3HelpersProcedureTwo is IErrors { staticATokenReport.transparentProxyFactory = address(new TransparentProxyFactory()); staticATokenReport.staticATokenImplementation = address( - new StaticATokenLM( - IPool(pool), - IRewardsController(rewardsController) - ) + new StaticATokenLM(IPool(pool), IRewardsController(rewardsController)) ); staticATokenReport.staticATokenFactoryImplementation = address( new StaticATokenFactory( @@ -31,11 +28,13 @@ contract AaveV3HelpersProcedureTwo is IErrors { ) ); - staticATokenReport.staticATokenFactoryProxy = ITransparentProxyFactory(staticATokenReport.transparentProxyFactory).create( - staticATokenReport.staticATokenFactoryImplementation, - proxyAdmin, - abi.encodeWithSelector(StaticATokenFactory.initialize.selector) - ); + staticATokenReport.staticATokenFactoryProxy = ITransparentProxyFactory( + staticATokenReport.transparentProxyFactory + ).create( + staticATokenReport.staticATokenFactoryImplementation, + proxyAdmin, + abi.encodeWithSelector(StaticATokenFactory.initialize.selector) + ); return staticATokenReport; } diff --git a/src/deployments/contracts/utilities/MetadataReporter.sol b/src/deployments/contracts/utilities/MetadataReporter.sol index 7fc3a262..27b5085c 100644 --- a/src/deployments/contracts/utilities/MetadataReporter.sol +++ b/src/deployments/contracts/utilities/MetadataReporter.sol @@ -69,12 +69,24 @@ contract MetadataReporter is IMetadataReporter { report.paraSwapWithdrawSwapAdapter ); vm.serializeAddress(jsonReport, 'aaveParaSwapFeeClaimer', report.aaveParaSwapFeeClaimer); - vm.serializeAddress(jsonReport, 'defaultInterestRateStrategy', report.defaultInterestRateStrategy); + vm.serializeAddress( + jsonReport, + 'defaultInterestRateStrategy', + report.defaultInterestRateStrategy + ); vm.serializeAddress(jsonReport, 'priceOracleSentinel', report.priceOracleSentinel); vm.serializeAddress(jsonReport, 'configEngine', report.configEngine); - vm.serializeAddress(jsonReport, 'staticATokenFactoryImplementation', report.staticATokenFactoryImplementation); + vm.serializeAddress( + jsonReport, + 'staticATokenFactoryImplementation', + report.staticATokenFactoryImplementation + ); vm.serializeAddress(jsonReport, 'staticATokenFactoryProxy', report.staticATokenFactoryProxy); - vm.serializeAddress(jsonReport, 'staticATokenImplementation', report.staticATokenImplementation); + vm.serializeAddress( + jsonReport, + 'staticATokenImplementation', + report.staticATokenImplementation + ); vm.serializeAddress(jsonReport, 'transparentProxyFactory', report.transparentProxyFactory); string memory output = vm.serializeAddress( diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol index b145b257..1db9f7b9 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol @@ -7,16 +7,8 @@ import '../../../interfaces/IMarketReportTypes.sol'; contract AaveV3HelpersBatchTwo is AaveV3HelpersProcedureTwo { StaticATokenReport internal _report; - constructor( - address pool, - address rewardsController, - address proxyAdmin - ) { - _report = _deployStaticAToken( - pool, - rewardsController, - proxyAdmin - ); + constructor(address pool, address rewardsController, address proxyAdmin) { + _report = _deployStaticAToken(pool, rewardsController, proxyAdmin); } function staticATokenReport() external view returns (StaticATokenReport memory) { diff --git a/tests/deployments/AaveV3BatchTests.t.sol b/tests/deployments/AaveV3BatchTests.t.sol index 0727aac6..99a41eac 100644 --- a/tests/deployments/AaveV3BatchTests.t.sol +++ b/tests/deployments/AaveV3BatchTests.t.sol @@ -96,12 +96,8 @@ contract AaveV3BatchTests is BatchTestProcedures { miscReport, tokensReport, paraswapReportOne, - ) = deployAndSetup( - roles, - config, - flags, - deployedContracts - ); + + ) = deployAndSetup(roles, config, flags, deployedContracts); } function testAaveV3FullBatchOrchestration() public { diff --git a/tests/deployments/DeploymentsGasLimits.t.sol b/tests/deployments/DeploymentsGasLimits.t.sol index 6f33f88d..fd42791e 100644 --- a/tests/deployments/DeploymentsGasLimits.t.sol +++ b/tests/deployments/DeploymentsGasLimits.t.sol @@ -93,12 +93,8 @@ contract DeploymentsGasLimits is BatchTestProcedures { miscReport, tokensReport, paraswapReportOne, - ) = deployAndSetup( - roles, - config, - flags, - deployedContracts - ); + + ) = deployAndSetup(roles, config, flags, deployedContracts); } function test0AaveV3SetupDeployment() public { diff --git a/tests/extensions/static-a-token/StataOracle.t.sol b/tests/extensions/static-a-token/StataOracle.t.sol index bef3620f..5e6e4efd 100644 --- a/tests/extensions/static-a-token/StataOracle.t.sol +++ b/tests/extensions/static-a-token/StataOracle.t.sol @@ -35,7 +35,10 @@ contract StataOracleTest is BaseTest { uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(underlying); assertGe(stataPrice, underlyingPrice); - assertEq(stataPrice, (underlyingPrice * StaticATokenLM(staticAToken).convertToAssets(1e18)) / 1e18); + assertEq( + stataPrice, + (underlyingPrice * StaticATokenLM(staticAToken).convertToAssets(1e18)) / 1e18 + ); } } diff --git a/tests/extensions/static-a-token/StaticATokenLM.t.sol b/tests/extensions/static-a-token/StaticATokenLM.t.sol index 6fcdd428..5c84fe55 100644 --- a/tests/extensions/static-a-token/StaticATokenLM.t.sol +++ b/tests/extensions/static-a-token/StaticATokenLM.t.sol @@ -464,13 +464,7 @@ contract StaticATokenLMTest is BaseTest { POOL.deposit(address(wbtc), 2_000e8, borrowUser, 0); // borrow all available - POOL.borrow( - UNDERLYING, - underlyingBalanceBefore - (maxRedeemBefore / 2), - 2, - 0, - borrowUser - ); + POOL.borrow(UNDERLYING, underlyingBalanceBefore - (maxRedeemBefore / 2), 2, 0, borrowUser); uint256 maxRedeemAfter = staticATokenLM.previewRedeem(staticATokenLM.maxRedeem(address(user))); assertApproxEqAbs(maxRedeemAfter, (maxRedeemBefore / 2), 1); @@ -581,7 +575,9 @@ contract StaticATokenLMTest is BaseTest { TestnetERC20(REWARD_TOKEN).mint(EMISSION_ADMIN, 10_000 ether); vm.stopPrank(); - RewardsDataTypes.RewardsConfigInput[] memory config = new RewardsDataTypes.RewardsConfigInput[](1); + RewardsDataTypes.RewardsConfigInput[] memory config = new RewardsDataTypes.RewardsConfigInput[]( + 1 + ); config[0] = RewardsDataTypes.RewardsConfigInput( 0.00385 ether, 10_000 ether, diff --git a/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol b/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol index 748986bb..4cc133e7 100644 --- a/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol +++ b/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol @@ -7,12 +7,13 @@ import {SigUtils} from '../../utils/SigUtils.sol'; import {BaseTest, IAToken, IRewardsController, DataTypes} from './TestBase.sol'; contract StaticATokenMetaTransactions is BaseTest { - function setUp() public override { super.setUp(); // Testing meta transactions with USDX as WETH does not support permit - DataTypes.ReserveDataLegacy memory reserveDataUSDX = contracts.poolProxy.getReserveData(address(usdx)); + DataTypes.ReserveDataLegacy memory reserveDataUSDX = contracts.poolProxy.getReserveData( + address(usdx) + ); UNDERLYING = address(usdx); A_TOKEN = reserveDataUSDX.aTokenAddress; diff --git a/tests/extensions/static-a-token/StaticATokenNoLM.t.sol b/tests/extensions/static-a-token/StaticATokenNoLM.t.sol index f45d197b..84ddbd33 100644 --- a/tests/extensions/static-a-token/StaticATokenNoLM.t.sol +++ b/tests/extensions/static-a-token/StaticATokenNoLM.t.sol @@ -8,7 +8,6 @@ import {BaseTest, IERC20} from './TestBase.sol'; * This is a slightly different assumption than a pool that doesn't have LM enabled any more as incentivesController.rewardTokens() will have length=0 */ contract StaticATokenNoLMTest is BaseTest { - function setUp() public override { super.setUp(); diff --git a/tests/extensions/static-a-token/TestBase.sol b/tests/extensions/static-a-token/TestBase.sol index 7fb215b7..d4b488fa 100644 --- a/tests/extensions/static-a-token/TestBase.sol +++ b/tests/extensions/static-a-token/TestBase.sol @@ -41,15 +41,12 @@ abstract contract BaseTest is TestnetProcedures { spender = vm.addr(spenderPrivateKey); initTestEnvironment(); - DataTypes.ReserveDataLegacy memory reserveDataWETH = contracts.poolProxy.getReserveData(tokenList.weth); + DataTypes.ReserveDataLegacy memory reserveDataWETH = contracts.poolProxy.getReserveData( + tokenList.weth + ); UNDERLYING = address(weth); - REWARD_TOKEN = address(new TestnetERC20( - 'LM Reward ERC20', - 'RWD', - 18, - OWNER - )); + REWARD_TOKEN = address(new TestnetERC20('LM Reward ERC20', 'RWD', 18, OWNER)); A_TOKEN = reserveDataWETH.aTokenAddress; POOL = contracts.poolProxy; diff --git a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol index b9e60567..cf909a86 100644 --- a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol +++ b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol @@ -53,12 +53,7 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { ); function testListings() public { - address asset = address(new TestnetERC20( - '1INCH', - '1INCH', - 18, - address(this) - )); + address asset = address(new TestnetERC20('1INCH', '1INCH', 18, address(this))); address feed = address(new MockAggregator(int256(25e8))); AaveV3MockListing payload = new AaveV3MockListing(asset, feed, configEngine); @@ -133,27 +128,35 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), IDefaultInterestRateStrategyV2.InterestRateDataRay({ optimalUsageRatio: _bpsToRay(payload.newListings()[0].rateStrategyParams.optimalUsageRatio), - baseVariableBorrowRate: _bpsToRay(payload.newListings()[0].rateStrategyParams.baseVariableBorrowRate), - variableRateSlope1: _bpsToRay(payload.newListings()[0].rateStrategyParams.variableRateSlope1), - variableRateSlope2: _bpsToRay(payload.newListings()[0].rateStrategyParams.variableRateSlope2) + baseVariableBorrowRate: _bpsToRay( + payload.newListings()[0].rateStrategyParams.baseVariableBorrowRate + ), + variableRateSlope1: _bpsToRay( + payload.newListings()[0].rateStrategyParams.variableRateSlope1 + ), + variableRateSlope2: _bpsToRay( + payload.newListings()[0].rateStrategyParams.variableRateSlope2 + ) }) ); } function testListingsCustom() public { - address asset = address(new TestnetERC20( - 'PSP', - 'PSP', - 18, - address(this) - )); + address asset = address(new TestnetERC20('PSP', 'PSP', 18, address(this))); address feed = address(new MockAggregator(int256(15e8))); address aTokenImpl = address(new ATokenInstance(contracts.poolProxy)); address vTokenImpl = address(new VariableDebtTokenInstance(contracts.poolProxy)); address sTokenImpl = address(new StableDebtTokenInstance(contracts.poolProxy)); - AaveV3MockListingCustom payload = new AaveV3MockListingCustom(asset, feed, configEngine, aTokenImpl, vTokenImpl, sTokenImpl); + AaveV3MockListingCustom payload = new AaveV3MockListingCustom( + asset, + feed, + configEngine, + aTokenImpl, + vTokenImpl, + sTokenImpl + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -224,10 +227,18 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), IDefaultInterestRateStrategyV2.InterestRateDataRay({ - optimalUsageRatio: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.optimalUsageRatio), - baseVariableBorrowRate: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.baseVariableBorrowRate), - variableRateSlope1: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope1), - variableRateSlope2: _bpsToRay(payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope2) + optimalUsageRatio: _bpsToRay( + payload.newListingsCustom()[0].base.rateStrategyParams.optimalUsageRatio + ), + baseVariableBorrowRate: _bpsToRay( + payload.newListingsCustom()[0].base.rateStrategyParams.baseVariableBorrowRate + ), + variableRateSlope1: _bpsToRay( + payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope1 + ), + variableRateSlope2: _bpsToRay( + payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope2 + ) }) ); } @@ -252,16 +263,14 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { IPool(address(contracts.poolProxy)) ); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); diffReports('preTestEngineCaps', 'postTestEngineCaps'); expectedAssetConfig.supplyCap = 1_000_000; _validateReserveConfig(expectedAssetConfig, allConfigsAfter); } + function testCollateralsUpdates() public { // this asset has been listed before address asset = tokenList.usdx; @@ -282,10 +291,7 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { IPool(address(contracts.poolProxy)) ); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); diffReports('preTestEngineCollateral', 'postTestEngineCollateral'); @@ -305,7 +311,10 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { function testFailCollateralsUpdatesNoChange() public { // this asset has been listed before address asset = tokenList.usdx; - AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange(asset, configEngine); + AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange( + asset, + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -329,7 +338,10 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { function testCollateralsUpdatesNoChange() public { // this asset has been listed before address asset = tokenList.usdx; - AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange(asset, configEngine); + AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange( + asset, + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -348,17 +360,17 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { diffReports('preTestEngineCollateralNoChange', 'postTestEngineCollateralNoChange'); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); _validateReserveConfig(expectedAssetConfig, allConfigsAfter); } function testCollateralUpdateWrongBonus() public { address asset = tokenList.usdx; - AaveV3MockCollateralUpdateWrongBonus payload = new AaveV3MockCollateralUpdateWrongBonus(asset, configEngine); + AaveV3MockCollateralUpdateWrongBonus payload = new AaveV3MockCollateralUpdateWrongBonus( + asset, + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -369,7 +381,10 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { function testCollateralUpdateCorrectBonus() public { address asset = tokenList.usdx; - AaveV3MockCollateralUpdateCorrectBonus payload = new AaveV3MockCollateralUpdateCorrectBonus(asset, configEngine); + AaveV3MockCollateralUpdateCorrectBonus payload = new AaveV3MockCollateralUpdateCorrectBonus( + asset, + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -388,10 +403,7 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { diffReports('preTestEngineCollateralEdgeBonus', 'postTestEngineCollateralEdgeBonus'); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); expectedAssetConfig.ltv = 62_00; expectedAssetConfig.liquidationThreshold = 90_00; expectedAssetConfig.liquidationBonus = 111_00; // 100_00 + 11_00 @@ -420,10 +432,7 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { diffReports('preTestEngineBorrow', 'postTestEngineBorrow'); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); expectedAssetConfig.reserveFactor = 15_00; expectedAssetConfig.borrowingEnabled = true; expectedAssetConfig.isFlashloanable = false; @@ -433,7 +442,10 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { function testBorrowUpdatesNoChange() public { address asset = tokenList.usdx; - AaveV3MockBorrowUpdateNoChange payload = new AaveV3MockBorrowUpdateNoChange(asset, configEngine); + AaveV3MockBorrowUpdateNoChange payload = new AaveV3MockBorrowUpdateNoChange( + asset, + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -452,10 +464,7 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { diffReports('preTestEngineBorrowNoChange', 'postTestEngineBorrowNoChange'); - ReserveConfig memory expectedAssetConfig = _findReserveConfig( - allConfigsBefore, - asset - ); + ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); _validateReserveConfig(expectedAssetConfig, allConfigsAfter); } @@ -467,17 +476,11 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); - createConfigurationSnapshot( - 'preTestEngineRates', - IPool(address(contracts.poolProxy)) - ); + createConfigurationSnapshot('preTestEngineRates', IPool(address(contracts.poolProxy))); payload.execute(); - createConfigurationSnapshot( - 'postTestEngineRates', - IPool(address(contracts.poolProxy)) - ); + createConfigurationSnapshot('postTestEngineRates', IPool(address(contracts.poolProxy))); diffReports('preTestEngineRates', 'postTestEngineRates'); @@ -487,7 +490,9 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), IDefaultInterestRateStrategyV2.InterestRateDataRay({ optimalUsageRatio: _bpsToRay(payload.rateStrategiesUpdates()[0].params.optimalUsageRatio), - baseVariableBorrowRate: _bpsToRay(payload.rateStrategiesUpdates()[0].params.baseVariableBorrowRate), + baseVariableBorrowRate: _bpsToRay( + payload.rateStrategiesUpdates()[0].params.baseVariableBorrowRate + ), variableRateSlope1: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope1), variableRateSlope2: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope2) }) @@ -502,17 +507,11 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); - createConfigurationSnapshot( - 'preTestEnginePriceFeed', - IPool(address(contracts.poolProxy)) - ); + createConfigurationSnapshot('preTestEnginePriceFeed', IPool(address(contracts.poolProxy))); payload.execute(); - createConfigurationSnapshot( - 'postTestEnginePriceFeed', - IPool(address(contracts.poolProxy)) - ); + createConfigurationSnapshot('postTestEnginePriceFeed', IPool(address(contracts.poolProxy))); diffReports('preTestEnginePriceFeed', 'postTestEnginePriceFeed'); @@ -552,11 +551,17 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { prevEmodeCategoryData.priceSource = address(0); prevEmodeCategoryData.label = 'ETH Correlated'; - _validateEmodeCategory(IPoolAddressesProvider(address(contracts.poolAddressesProvider)), 1, prevEmodeCategoryData); + _validateEmodeCategory( + IPoolAddressesProvider(address(contracts.poolAddressesProvider)), + 1, + prevEmodeCategoryData + ); } function testEModeCategoryUpdatesWrongBonus() public { - AaveV3MockEModeCategoryUpdateEdgeBonus payload = new AaveV3MockEModeCategoryUpdateEdgeBonus(configEngine); + AaveV3MockEModeCategoryUpdateEdgeBonus payload = new AaveV3MockEModeCategoryUpdateEdgeBonus( + configEngine + ); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -567,9 +572,13 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { // TODO manage this after testFail* deprecation. function testFailEModeCategoryUpdatesNoChange() public { - AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange(configEngine); + AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange( + configEngine + ); - DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts.poolProxy.getEModeCategoryData(1); + DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts + .poolProxy + .getEModeCategoryData(1); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -588,18 +597,28 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { // Same as testFailEModeCategoryUpdatesNoChange, but this time should work, as we are not expecting any event emitted function testEModeCategoryUpdatesNoChange() public { - AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange(configEngine); + AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange( + configEngine + ); - DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts.poolProxy.getEModeCategoryData(1); + DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts + .poolProxy + .getEModeCategoryData(1); vm.prank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); - createConfigurationSnapshot('preTestEngineEModeCategoryNoChange', IPool(address(contracts.poolProxy))); + createConfigurationSnapshot( + 'preTestEngineEModeCategoryNoChange', + IPool(address(contracts.poolProxy)) + ); payload.execute(); - createConfigurationSnapshot('postTestEngineEModeCategoryNoChange', IPool(address(contracts.poolProxy))); + createConfigurationSnapshot( + 'postTestEngineEModeCategoryNoChange', + IPool(address(contracts.poolProxy)) + ); diffReports('preTestEngineEModeCategoryNoChange', 'postTestEngineEModeCategoryNoChange'); @@ -610,13 +629,19 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { prevEmodeCategoryData.priceSource = eModeCategoryDataBefore.priceSource; prevEmodeCategoryData.label = eModeCategoryDataBefore.label; - _validateEmodeCategory(IPoolAddressesProvider(address(contracts.poolAddressesProvider)), 1, prevEmodeCategoryData); + _validateEmodeCategory( + IPoolAddressesProvider(address(contracts.poolAddressesProvider)), + 1, + prevEmodeCategoryData + ); } function testAssetEModeUpdates() public { address asset = tokenList.usdx; - AaveV3MockEModeCategoryUpdate payloadToAddEMode = new AaveV3MockEModeCategoryUpdate(configEngine); + AaveV3MockEModeCategoryUpdate payloadToAddEMode = new AaveV3MockEModeCategoryUpdate( + configEngine + ); AaveV3MockAssetEModeUpdate payload = new AaveV3MockAssetEModeUpdate(asset, configEngine); vm.startPrank(roleList.marketOwner); @@ -626,19 +651,20 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { payloadToAddEMode.execute(); - createConfigurationSnapshot('preTestEngineAssetEModeUpdate', IPool(address(contracts.poolProxy))); + createConfigurationSnapshot( + 'preTestEngineAssetEModeUpdate', + IPool(address(contracts.poolProxy)) + ); payload.execute(); - createConfigurationSnapshot('postTestEngineAssetEModeUpdate', IPool(address(contracts.poolProxy))); + createConfigurationSnapshot( + 'postTestEngineAssetEModeUpdate', + IPool(address(contracts.poolProxy)) + ); diffReports('preTestEngineAssetEModeUpdate', 'postTestEngineAssetEModeUpdate'); - assertEq( - contracts.protocolDataProvider.getReserveEModeCategory( - asset - ), - 1 - ); + assertEq(contracts.protocolDataProvider.getReserveEModeCategory(asset), 1); } } diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol index 31d67eb0..5e2d45ac 100644 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol @@ -18,10 +18,7 @@ contract AaveV3MockAssetEModeUpdate is AaveV3Payload { function assetsEModeUpdates() public view override returns (IEngine.AssetEModeUpdate[] memory) { IEngine.AssetEModeUpdate[] memory eModeUpdate = new IEngine.AssetEModeUpdate[](1); - eModeUpdate[0] = IEngine.AssetEModeUpdate({ - asset: ASSET_ADDRESS, - eModeCategory: 1 - }); + eModeUpdate[0] = IEngine.AssetEModeUpdate({asset: ASSET_ADDRESS, eModeCategory: 1}); return eModeUpdate; } diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol index 7944629d..825e80ee 100644 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol @@ -13,7 +13,11 @@ contract AaveV3MockListing is AaveV3Payload { address public immutable ASSET_ADDRESS; address public immutable ASSET_FEED; - constructor(address assetAddress, address assetFeed, address customEngine) AaveV3Payload(IEngine(customEngine)) { + constructor( + address assetAddress, + address assetFeed, + address customEngine + ) AaveV3Payload(IEngine(customEngine)) { ASSET_ADDRESS = assetAddress; ASSET_FEED = assetFeed; } diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol index f9a342fd..dc41c531 100644 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol @@ -16,7 +16,14 @@ contract AaveV3MockListingCustom is AaveV3Payload { address public immutable V_TOKEN_IMPL; address public immutable S_TOKEN_IMPL; - constructor(address assetAddress, address assetFeed, address customEngine, address aTokenImpl, address vTokenImpl, address sTokenImpl) AaveV3Payload(IEngine(customEngine)) { + constructor( + address assetAddress, + address assetFeed, + address customEngine, + address aTokenImpl, + address vTokenImpl, + address sTokenImpl + ) AaveV3Payload(IEngine(customEngine)) { ASSET_ADDRESS = assetAddress; ASSET_FEED = assetFeed; A_TOKEN_IMPL = aTokenImpl; diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol index 048c5b9d..0b5bd8b1 100644 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol @@ -13,7 +13,11 @@ contract AaveV3MockPriceFeedUpdate is AaveV3Payload { address public immutable ASSET_ADDRESS; address public immutable ASSET_FEED; - constructor(address assetAddress, address feed, address customEngine) AaveV3Payload(IEngine(customEngine)) { + constructor( + address assetAddress, + address feed, + address customEngine + ) AaveV3Payload(IEngine(customEngine)) { ASSET_ADDRESS = assetAddress; ASSET_FEED = feed; } @@ -21,10 +25,7 @@ contract AaveV3MockPriceFeedUpdate is AaveV3Payload { function priceFeedsUpdates() public view override returns (IEngine.PriceFeedUpdate[] memory) { IEngine.PriceFeedUpdate[] memory priceFeedsUpdate = new IEngine.PriceFeedUpdate[](1); - priceFeedsUpdate[0] = IEngine.PriceFeedUpdate({ - asset: ASSET_ADDRESS, - priceFeed: ASSET_FEED - }); + priceFeedsUpdate[0] = IEngine.PriceFeedUpdate({asset: ASSET_ADDRESS, priceFeed: ASSET_FEED}); return priceFeedsUpdate; } diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol index 97298c12..087ae883 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol @@ -734,9 +734,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { } function test_setLiquidationGracePeriodReserve(uint40 gracePeriod) public { - vm.assume( - gracePeriod < contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD() && gracePeriod != 0 - ); + vm.assume(gracePeriod < contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD() && gracePeriod != 0); address asset = tokenList.usdx; diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol index a85fd89a..586971d9 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.upgradeabilty.t.sol @@ -31,11 +31,7 @@ contract PoolConfiguratorUpgradeabilityTests is TestnetProcedures { address newStrategy ); - event ReserveInterestRateDataChanged( - address indexed asset, - address indexed strategy, - bytes data - ); + event ReserveInterestRateDataChanged(address indexed asset, address indexed strategy, bytes data); event ATokenUpgraded( address indexed asset, @@ -99,7 +95,11 @@ contract PoolConfiguratorUpgradeabilityTests is TestnetProcedures { bytes memory newInterestRateData = _getDefaultInterestRatesStrategyData(); vm.expectEmit(address(contracts.poolConfiguratorProxy)); - emit ReserveInterestRateDataChanged(tokenList.usdx, currentInterestRateStrategy, newInterestRateData); + emit ReserveInterestRateDataChanged( + tokenList.usdx, + currentInterestRateStrategy, + newInterestRateData + ); vm.prank(poolAdmin); contracts.poolConfiguratorProxy.setReserveInterestRateData( diff --git a/tests/utils/BatchTestProcedures.sol b/tests/utils/BatchTestProcedures.sol index d0418972..dfdcd416 100644 --- a/tests/utils/BatchTestProcedures.sol +++ b/tests/utils/BatchTestProcedures.sol @@ -99,14 +99,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput config.l2PriceOracleSentinelGracePeriod ); - return ( - initialReport, - gettersReport1, - poolReport, - peripheryReport, - miscReport, - setupContract - ); + return (initialReport, gettersReport1, poolReport, peripheryReport, miscReport, setupContract); } function deployAndSetup( @@ -189,10 +182,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput assertTrue(r.poolConfiguratorImplementation != address(0), 'r.poolConfiguratorImplementation'); assertTrue(r.protocolDataProvider != address(0), 'report.protocolDataProvider'); assertTrue(r.aaveOracle != address(0), 'report.aaveOracle'); - assertTrue( - r.defaultInterestRateStrategy != address(0), - 'report.defaultInterestRateStrategy' - ); + assertTrue(r.defaultInterestRateStrategy != address(0), 'report.defaultInterestRateStrategy'); assertTrue(r.aclManager != address(0), 'report.aclManager'); assertTrue(r.treasury != address(0), 'report.treasury'); assertTrue(r.proxyAdmin != address(0), 'report.proxyAdmin'); @@ -221,7 +211,10 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput ); assertTrue(r.rewardsControllerProxy != address(0), 'report.rewardsControllerProxy'); assertTrue(r.configEngine != address(0), 'report.configEngine'); - assertTrue(r.staticATokenFactoryImplementation != address(0), 'report.staticATokenFactoryImplementation'); + assertTrue( + r.staticATokenFactoryImplementation != address(0), + 'report.staticATokenFactoryImplementation' + ); assertTrue(r.staticATokenFactoryProxy != address(0), 'report.staticATokenFactoryProxy'); assertTrue(r.staticATokenImplementation != address(0), 'report.staticATokenImplementation'); assertTrue(r.transparentProxyFactory != address(0), 'report.transparentProxyFactory'); From cab9796c5f5bd79f2ee4c7e838ac7df5e5e8032f Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 29 Apr 2024 14:15:30 +0530 Subject: [PATCH 03/11] chore: add reports dir --- reports/.empty | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 reports/.empty diff --git a/reports/.empty b/reports/.empty new file mode 100644 index 00000000..e69de29b From 94f4730930415c5a6fcbfcd3e45b80bb522b1d56 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 2 May 2024 17:15:44 +0530 Subject: [PATCH 04/11] test: test template with deployed contracts --- tests/template/BaseTest.t.sol | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/template/BaseTest.t.sol diff --git a/tests/template/BaseTest.t.sol b/tests/template/BaseTest.t.sol new file mode 100644 index 00000000..8e8de790 --- /dev/null +++ b/tests/template/BaseTest.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {TestnetProcedures, IERC20, IAToken} from '../utils/TestnetProcedures.sol'; + +// Base test to setup the initial config: deploying the protocol contracts and setting them up locally on foundry +contract BaseTest is TestnetProcedures { + function setUp() public { + // this method deploys all the protocol contract and does the inital setup. + // -> the deployed contracts could be accessed via the ContractsReport struct internal variable `contracts`. Ex `contracts.poolProxy` + // -> the assets listed could be accessed via the TokenList struct internal variable `tokenList` + // -> the internal variable `poolAdmin` has the poolAdmin role of the protocol and holds all the admin access. + initTestEnvironment(); + + // initL2TestEnvironment(); -> deploys the protocol contracts as on an L2 (ex. we deploy L2Pool instead of Pool) + // initTestEnvironment(true); -> mints the listed assets to users: alice, bob, carol (can be accessed by the same variable name) + } + + // add your code below + function test_default() public { + uint256 supplyAmount = 0.2e8; + uint256 underlyingBalanceBefore = IERC20(tokenList.wbtc).balanceOf(alice); + (address aWBTC, , ) = contracts.protocolDataProvider.getReserveTokensAddresses(tokenList.wbtc); + + vm.prank(alice); + contracts.poolProxy.supply(tokenList.wbtc, supplyAmount, alice, 0); + + assertEq(IERC20(tokenList.wbtc).balanceOf(alice), underlyingBalanceBefore - supplyAmount); + assertEq(IAToken(aWBTC).scaledBalanceOf(alice), supplyAmount); + } +} From c966e91bac54646909194dace5c336860ce80985 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 2 May 2024 17:54:52 +0530 Subject: [PATCH 05/11] chore: comment to test --- Makefile | 3 ++- tests/template/BaseTest.t.sol | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5d0ee01e..f46c33c3 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ update:; forge update # Build & test test :; forge test -vvv --no-match-contract DeploymentsGasLimits +test-contract :; forge test --match-contract ${filter} -vvv test-watch :; forge test --watch -vvv --no-match-contract DeploymentsGasLimits coverage :; forge coverage --report lcov && \ lcov --remove ./lcov.info -o ./lcov.info.p \ @@ -34,4 +35,4 @@ coverage :; forge coverage --report lcov && \ download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address} git-diff : @mkdir -p diffs - @printf '%s\n%s\n%s\n' "\`\`\`diff" "$$(git diff --no-index --diff-algorithm=patience --ignore-space-at-eol ${before} ${after})" "\`\`\`" > diffs/${out}.md \ No newline at end of file + @printf '%s\n%s\n%s\n' "\`\`\`diff" "$$(git diff --no-index --diff-algorithm=patience --ignore-space-at-eol ${before} ${after})" "\`\`\`" > diffs/${out}.md diff --git a/tests/template/BaseTest.t.sol b/tests/template/BaseTest.t.sol index 8e8de790..62d10faa 100644 --- a/tests/template/BaseTest.t.sol +++ b/tests/template/BaseTest.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {TestnetProcedures, IERC20, IAToken} from '../utils/TestnetProcedures.sol'; // Base test to setup the initial config: deploying the protocol contracts and setting them up locally on foundry +// command to test: make test-contract filter=BaseTest contract BaseTest is TestnetProcedures { function setUp() public { // this method deploys all the protocol contract and does the inital setup. From 87a473d47640d5abb925c1e92e84026bb85ebcc8 Mon Sep 17 00:00:00 2001 From: eboado Date: Thu, 2 May 2024 16:19:12 +0200 Subject: [PATCH 06/11] feat: improved 3.1 features docs --- docs/Aave-v3.1-features.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/Aave-v3.1-features.md b/docs/Aave-v3.1-features.md index 285433c7..f1867b1e 100644 --- a/docs/Aave-v3.1-features.md +++ b/docs/Aave-v3.1-features.md @@ -28,7 +28,11 @@ This new feature doesn’t create any incompatibility with Aave v3 integrations, Given its implications and criticality, virtual accounting can be considered the major feature of Aave 3.1. -_Important_. Virtual balance doesn't fix the imprecision caused by other components of the protocol, its objective is to add stricter validations, reducing any type of vector to the minimum. +**Misc considerations & acknowledged limitations** +- Virtual balance doesn't fix the imprecision caused by other components of the protocol, its objective is to add stricter validations, reducing any type of attack vector to the minimum. +- An extra "soft" protection has been added on borrowing actions (flash loan and borrow): the amount borrowed of underlying should not be higher than the aToken supply. The idea behind is to add more defenses on inflation scenarios, even if we are aware total protection is not achieved (e.g. against certain edge iteration vectors). +Not using `accruedToTreasury` in the calculation is intentional. +- The addition of virtual accounting can create a situation over time that more liquidity will be available in the aToken contract than what the the virtual balance allows to withdraw/borrow. This is intended by design.
From 246a54cc45dfee2d429b209d06d803c414944e58 Mon Sep 17 00:00:00 2001 From: eboado Date: Thu, 2 May 2024 16:27:01 +0200 Subject: [PATCH 07/11] Fixed linting --- docs/Aave-v3.1-features.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Aave-v3.1-features.md b/docs/Aave-v3.1-features.md index f1867b1e..6219dbeb 100644 --- a/docs/Aave-v3.1-features.md +++ b/docs/Aave-v3.1-features.md @@ -29,9 +29,10 @@ This new feature doesn’t create any incompatibility with Aave v3 integrations, Given its implications and criticality, virtual accounting can be considered the major feature of Aave 3.1. **Misc considerations & acknowledged limitations** + - Virtual balance doesn't fix the imprecision caused by other components of the protocol, its objective is to add stricter validations, reducing any type of attack vector to the minimum. - An extra "soft" protection has been added on borrowing actions (flash loan and borrow): the amount borrowed of underlying should not be higher than the aToken supply. The idea behind is to add more defenses on inflation scenarios, even if we are aware total protection is not achieved (e.g. against certain edge iteration vectors). -Not using `accruedToTreasury` in the calculation is intentional. + Not using `accruedToTreasury` in the calculation is intentional. - The addition of virtual accounting can create a situation over time that more liquidity will be available in the aToken contract than what the the virtual balance allows to withdraw/borrow. This is intended by design.
From 03a0f73a252e49f714d9841105b69ab5818d25e6 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 6 May 2024 13:52:48 +0530 Subject: [PATCH 08/11] chore: fix conflicts --- .../PoolConfigurator.ACLModifiers.t.sol | 11 +- .../PoolConfigurator.initReserves.t.sol | 239 ++++-------------- .../PoolConfigurator.reserveRiskConfig.t.sol | 84 +++--- .../tokenization/StableDebtToken.t.sol | 70 ++--- .../tokenization/VariableDebtToken.t.sol | 66 ++--- tests/utils/TestnetProcedures.sol | 114 +++++---- 6 files changed, 231 insertions(+), 353 deletions(-) diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol index a6c86453..dc351d2f 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.ACLModifiers.t.sol @@ -5,15 +5,20 @@ import 'forge-std/Test.sol'; import {Errors} from '../../../../src/contracts/protocol/libraries/helpers/Errors.sol'; import {ConfiguratorInputTypes} from '../../../../src/contracts/protocol/pool/PoolConfigurator.sol'; -import {TestnetProcedures} from '../../../utils/TestnetProcedures.sol'; +import {TestnetProcedures, TestVars} from '../../../utils/TestnetProcedures.sol'; contract PoolConfiguratorACLModifiersTest is TestnetProcedures { function setUp() public { initTestEnvironment(); } - function test_reverts_notAdmin_initReserves(address caller) public { - ConfiguratorInputTypes.InitReserveInput[] memory input; + function test_reverts_notAdmin_initReserves(TestVars memory t, address caller) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, + report, + poolAdmin, + true + ); vm.assume( !contracts.aclManager.isPoolAdmin(caller) && !contracts.aclManager.isAssetListingAdmin(caller) && diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol index c760a736..24a16c0e 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.initReserves.t.sol @@ -23,189 +23,77 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { initTestEnvironment(); } - function test_initReserves_singleAsset(bool isVirtualAccActive) public { - TestnetERC20 newToken = new TestnetERC20('Misc Token', 'MISC', 18, poolAdmin); + function test_initReserves_validNumberOfAssets(TestVars[128] memory t, uint8 length) public { + vm.assume(length > 0 && length < 128); - TestVars memory t; - t.aTokenName = 'Misc AToken'; - t.aTokenSymbol = 'aMISC'; - t.variableDebtName = 'Variable Debt Misc'; - t.variableDebtSymbol = 'varDebtMISC'; - t.stableDebtName = 'Stable Debt Misc'; - t.stableDebtSymbol = 'stableDebtMISC'; - t.rateStrategy = report.defaultInterestRateStrategy; - t.interestRateData = abi.encode( - IDefaultInterestRateStrategyV2.InterestRateData({ - optimalUsageRatio: 80_00, - baseVariableBorrowRate: 1_00, - variableRateSlope1: 4_00, - variableRateSlope2: 60_00 - }) - ); uint256 previousListedAssets = contracts.poolProxy.getReservesList().length; + uint256 maxListings = contracts.poolProxy.MAX_NUMBER_RESERVES() - previousListedAssets + 1; + vm.assume(length < maxListings); ConfiguratorInputTypes.InitReserveInput[] - memory input = new ConfiguratorInputTypes.InitReserveInput[](1); - - input[0] = ConfiguratorInputTypes.InitReserveInput( - report.aToken, - report.stableDebtToken, - report.variableDebtToken, - newToken.decimals(), - isVirtualAccActive, - t.rateStrategy, - address(newToken), - report.treasury, - report.rewardsControllerProxy, - t.aTokenName, - t.aTokenSymbol, - t.variableDebtName, - t.variableDebtSymbol, - t.stableDebtName, - t.stableDebtSymbol, - t.emptyParams, - t.interestRateData - ); - vm.expectEmit(true, false, false, false, address(contracts.poolConfiguratorProxy)); - emit ReserveInitialized( - input[0].underlyingAsset, - address(0), - address(0), - address(0), - input[0].interestRateStrategyAddress - ); - - // Perform action - vm.prank(poolAdmin); - contracts.poolConfiguratorProxy.initReserves(input); - - // Perform assertions - { - (address aTokenProxy, address stableDebtProxy, address variableDebtProxy) = contracts - .protocolDataProvider - .getReserveTokensAddresses(address(newToken)); + memory input = new ConfiguratorInputTypes.InitReserveInput[](length); + for (uint i = 0; i < length; i++) { + input[i] = _generateInitReserveInput(t[i], report, poolAdmin, true); - assertEq(AToken(aTokenProxy).name(), t.aTokenName); - assertEq(AToken(aTokenProxy).symbol(), t.aTokenSymbol); - assertEq(AToken(aTokenProxy).decimals(), newToken.decimals()); - assertEq(AToken(aTokenProxy).RESERVE_TREASURY_ADDRESS(), report.treasury); - assertEq(AToken(aTokenProxy).UNDERLYING_ASSET_ADDRESS(), address(newToken)); - assertEq( - address(AToken(aTokenProxy).getIncentivesController()), - report.rewardsControllerProxy - ); - - assertEq(AToken(stableDebtProxy).name(), t.stableDebtName); - assertEq(AToken(stableDebtProxy).symbol(), t.stableDebtSymbol); - assertEq(AToken(stableDebtProxy).decimals(), newToken.decimals()); - assertEq(AToken(stableDebtProxy).UNDERLYING_ASSET_ADDRESS(), address(newToken)); - assertEq( - address(AToken(stableDebtProxy).getIncentivesController()), - report.rewardsControllerProxy - ); - - assertEq(AToken(variableDebtProxy).name(), t.variableDebtName); - assertEq(AToken(variableDebtProxy).symbol(), t.variableDebtSymbol); - assertEq(AToken(variableDebtProxy).decimals(), newToken.decimals()); - assertEq(AToken(variableDebtProxy).UNDERLYING_ASSET_ADDRESS(), address(newToken)); - assertEq( - address(AToken(variableDebtProxy).getIncentivesController()), - report.rewardsControllerProxy - ); - } - // Perform default asset checks - TestReserveConfig memory c = _getReserveConfig(address(newToken), report.protocolDataProvider); - - assertEq(c.isActive, true); - assertEq(c.isFrozen, false); - assertEq(c.isPaused, false); - assertEq(c.decimals, newToken.decimals()); - - assertEq(c.ltv, 0); - assertEq(c.liquidationThreshold, 0); - assertEq(c.liquidationBonus, 0); - assertEq(c.reserveFactor, 0); - assertEq(c.usageAsCollateralEnabled, false); - assertEq(c.borrowingEnabled, false); - assertEq(c.stableBorrowRateEnabled, false); - assertEq(c.isVirtualAccActive, isVirtualAccActive); - - assertEq(contracts.poolProxy.getReservesList().length, previousListedAssets + 1); - } - - function test_initReserves_multipleAssets() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 4, - report, - poolAdmin - ); - uint256 previousListedAssets = contracts.poolProxy.getReservesList().length; - - for (uint256 y; y < input.length; ++y) { vm.expectEmit(true, false, false, false, address(contracts.poolConfiguratorProxy)); emit ReserveInitialized( - input[y].underlyingAsset, + input[i].underlyingAsset, address(0), address(0), address(0), - input[y].interestRateStrategyAddress + input[i].interestRateStrategyAddress ); } - // Perform action vm.prank(poolAdmin); contracts.poolConfiguratorProxy.initReserves(input); - // Perform assertions - for (uint256 y; y < input.length; ++y) { - ConfiguratorInputTypes.InitReserveInput memory reserveInput = input[y]; - + for (uint i = 0; i < length; i++) { + ConfiguratorInputTypes.InitReserveInput memory initConfig = input[i]; + // Perform assertions { (address aTokenProxy, address stableDebtProxy, address variableDebtProxy) = contracts .protocolDataProvider - .getReserveTokensAddresses(reserveInput.underlyingAsset); + .getReserveTokensAddresses(initConfig.underlyingAsset); - assertEq(AToken(aTokenProxy).name(), reserveInput.aTokenName); - assertEq(AToken(aTokenProxy).symbol(), reserveInput.aTokenSymbol); - assertEq(AToken(aTokenProxy).decimals(), reserveInput.underlyingAssetDecimals); - assertEq(AToken(aTokenProxy).RESERVE_TREASURY_ADDRESS(), reserveInput.treasury); - assertEq(AToken(aTokenProxy).UNDERLYING_ASSET_ADDRESS(), reserveInput.underlyingAsset); + assertEq(AToken(aTokenProxy).name(), initConfig.aTokenName); + assertEq(AToken(aTokenProxy).symbol(), initConfig.aTokenSymbol); + assertEq(AToken(aTokenProxy).decimals(), initConfig.underlyingAssetDecimals); + assertEq(AToken(aTokenProxy).RESERVE_TREASURY_ADDRESS(), initConfig.treasury); + assertEq(AToken(aTokenProxy).UNDERLYING_ASSET_ADDRESS(), initConfig.underlyingAsset); assertEq( address(AToken(aTokenProxy).getIncentivesController()), - reserveInput.incentivesController + initConfig.incentivesController ); - assertEq(AToken(stableDebtProxy).name(), reserveInput.stableDebtTokenName); - assertEq(AToken(stableDebtProxy).symbol(), reserveInput.stableDebtTokenSymbol); - assertEq(AToken(stableDebtProxy).decimals(), reserveInput.underlyingAssetDecimals); - assertEq(AToken(stableDebtProxy).UNDERLYING_ASSET_ADDRESS(), reserveInput.underlyingAsset); + assertEq(AToken(stableDebtProxy).name(), initConfig.stableDebtTokenName); + assertEq(AToken(stableDebtProxy).symbol(), initConfig.stableDebtTokenSymbol); + assertEq(AToken(stableDebtProxy).decimals(), initConfig.underlyingAssetDecimals); + assertEq(AToken(stableDebtProxy).UNDERLYING_ASSET_ADDRESS(), initConfig.underlyingAsset); assertEq( address(AToken(stableDebtProxy).getIncentivesController()), - reserveInput.incentivesController + initConfig.incentivesController ); - assertEq(AToken(variableDebtProxy).name(), reserveInput.variableDebtTokenName); - assertEq(AToken(variableDebtProxy).symbol(), reserveInput.variableDebtTokenSymbol); - assertEq(AToken(variableDebtProxy).decimals(), reserveInput.underlyingAssetDecimals); - assertEq( - AToken(variableDebtProxy).UNDERLYING_ASSET_ADDRESS(), - reserveInput.underlyingAsset - ); + assertEq(AToken(variableDebtProxy).name(), initConfig.variableDebtTokenName); + assertEq(AToken(variableDebtProxy).symbol(), initConfig.variableDebtTokenSymbol); + assertEq(AToken(variableDebtProxy).decimals(), initConfig.underlyingAssetDecimals); + assertEq(AToken(variableDebtProxy).UNDERLYING_ASSET_ADDRESS(), initConfig.underlyingAsset); assertEq( address(AToken(variableDebtProxy).getIncentivesController()), - reserveInput.incentivesController + initConfig.incentivesController ); } // Perform default asset checks TestReserveConfig memory c = _getReserveConfig( - reserveInput.underlyingAsset, + initConfig.underlyingAsset, report.protocolDataProvider ); assertEq(c.isActive, true); assertEq(c.isFrozen, false); assertEq(c.isPaused, false); - assertEq(c.decimals, reserveInput.underlyingAssetDecimals); + assertEq(c.decimals, initConfig.underlyingAssetDecimals); assertEq(c.ltv, 0); assertEq(c.liquidationThreshold, 0); @@ -214,8 +102,9 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { assertEq(c.usageAsCollateralEnabled, false); assertEq(c.borrowingEnabled, false); assertEq(c.stableBorrowRateEnabled, false); + assertEq(c.isVirtualAccActive, initConfig.useVirtualBalance); } - assertEq(contracts.poolProxy.getReservesList().length, previousListedAssets + input.length); + assertEq(contracts.poolProxy.getReservesList().length, previousListedAssets + length); } function test_initReserves_zeroAssets() public { @@ -230,14 +119,16 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { assertEq(contracts.poolProxy.getReservesList().length, previousListedAssets); } - function test_reverts_initReserves_maxAssets() public { + function test_reverts_initReserves_maxAssets(TestVars memory t, uint8 lengthSeed) public { uint256 previousListedAssets = contracts.poolProxy.getReservesList().length; + uint256 maxListings = contracts.poolProxy.MAX_NUMBER_RESERVES() - previousListedAssets + 1; - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - maxListings, - report, - poolAdmin - ); + uint256 length = maxListings + lengthSeed; + + ConfiguratorInputTypes.InitReserveInput[] + memory input = new ConfiguratorInputTypes.InitReserveInput[](length); + for (uint256 i = 0; i < length; i++) + input[i] = _generateInitReserveInput(t, report, poolAdmin, true); vm.expectRevert(bytes(Errors.NO_MORE_RESERVES_ALLOWED)); vm.prank(poolAdmin); @@ -246,48 +137,14 @@ contract PoolConfiguratorInitReservesTest is TestnetProcedures { assertEq(contracts.poolProxy.getReservesList().length, previousListedAssets); } - function test_initReserves_notEnoughDecimal(uint8 decimals) public { - vm.assume(decimals < 6); - TestnetERC20 newToken = new TestnetERC20('Misc Token', 'MISC', decimals, poolAdmin); + function test_initReserves_notEnoughDecimal(TestVars memory t) public { + vm.assume(t.underlyingDecimals < 6); - TestVars memory t; - t.aTokenName = 'Misc AToken'; - t.aTokenSymbol = 'aMISC'; - t.variableDebtName = 'Variable Debt Misc'; - t.variableDebtSymbol = 'varDebtMISC'; - t.stableDebtName = 'Stable Debt Misc'; - t.stableDebtSymbol = 'stableDebtMISC'; - t.rateStrategy = report.defaultInterestRateStrategy; - t.interestRateData = abi.encode( - IDefaultInterestRateStrategyV2.InterestRateData({ - optimalUsageRatio: 80_00, - baseVariableBorrowRate: 1_00, - variableRateSlope1: 4_00, - variableRateSlope2: 60_00 - }) - ); - - ConfiguratorInputTypes.InitReserveInput[] - memory input = new ConfiguratorInputTypes.InitReserveInput[](1); - - input[0] = ConfiguratorInputTypes.InitReserveInput( - report.aToken, - report.stableDebtToken, - report.variableDebtToken, - newToken.decimals(), - true, - t.rateStrategy, - address(newToken), - report.treasury, - report.rewardsControllerProxy, - t.aTokenName, - t.aTokenSymbol, - t.variableDebtName, - t.variableDebtSymbol, - t.stableDebtName, - t.stableDebtSymbol, - t.emptyParams, - t.interestRateData + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, + report, + poolAdmin, + false ); vm.expectRevert(bytes(Errors.INVALID_DECIMALS)); diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol index 087ae883..caa9dd1e 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol @@ -65,11 +65,12 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { contracts.poolProxy.supply(tokenList.wbtc, 100e8, bob, 0); } - function test_enableBorrowing() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + function test_enableBorrowing(TestVars memory t) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -103,11 +104,12 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { assertEq(borrowingConfigAfter, false); } - function test_enableFlashBorrow() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + function test_enableFlashBorrow(TestVars memory t) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -130,15 +132,16 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { assertEq(valueAfter, false); } - function test_setCollateralConfig() public { + function test_setCollateralConfig(TestVars memory t) public { uint256 ltv = 80_00; uint256 liquidationThreshold = 85_00; uint256 liquidationBonus = 105_00; - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -169,11 +172,12 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { assertEq(liqBonus, liquidationBonus); } - function test_reverts_setCollateralConfig_invalidParams() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + function test_reverts_setCollateralConfig_invalidParams(TestVars memory t) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -234,11 +238,12 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { contracts.poolConfiguratorProxy.configureReserveAsCollateral(tokenList.usdx, 0, 0, 0); } - function test_enableStableBorrowing() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + function test_enableStableBorrowing(TestVars memory t) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -276,11 +281,12 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { assertEq(borrowingConfigAfter, false); } - function test_reverts_enableStableBorrowing_borrowNotEnabled() public { - ConfiguratorInputTypes.InitReserveInput[] memory input = _generateListingInput( - 1, + function test_reverts_enableStableBorrowing_borrowNotEnabled(TestVars memory t) public { + ConfiguratorInputTypes.InitReserveInput[] memory input = _generateInitConfig( + t, report, - poolAdmin + poolAdmin, + true ); // Perform action @@ -740,30 +746,14 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { uint40 until = uint40(block.timestamp) + gracePeriod; - vm.startPrank(poolAdmin); - - // reserve unpause -> unpause, liquidationGracePeriod would be set - vm.expectEmit(address(contracts.poolConfiguratorProxy)); - emit LiquidationGracePeriodChanged(asset, until); - contracts.poolConfiguratorProxy.setReservePause(asset, false, gracePeriod); - assertEq(contracts.poolProxy.getLiquidationGracePeriod(asset), until); - - // reserve unpause -> pause, liquidationGracePeriod would not be set - contracts.poolConfiguratorProxy.setReservePause(asset, true, gracePeriod + 1); - assertEq(contracts.poolProxy.getLiquidationGracePeriod(asset), until); - assertTrue(contracts.protocolDataProvider.getPaused(asset)); - - // reserve pause -> pause, liquidationGracePeriod would not be set - contracts.poolConfiguratorProxy.setReservePause(asset, true, gracePeriod + 1); - assertEq(contracts.poolProxy.getLiquidationGracePeriod(asset), until); - - // reserve pause -> unpause, liquidationGracePeriod would be set - vm.expectEmit(address(contracts.poolConfiguratorProxy)); - emit LiquidationGracePeriodChanged(asset, until + 1); - contracts.poolConfiguratorProxy.setReservePause(asset, false, gracePeriod + 1); - assertEq(contracts.poolProxy.getLiquidationGracePeriod(asset), until + 1); + vm.prank(poolAdmin); - vm.stopPrank(); + if (gracePeriod != 0) { + vm.expectEmit(address(contracts.poolConfiguratorProxy)); + emit LiquidationGracePeriodChanged(asset, until); + contracts.poolConfiguratorProxy.setReservePause(asset, false, gracePeriod); + assertEq(contracts.poolProxy.getLiquidationGracePeriod(asset), until); + } } function test_setLiquidationGracePeriodPool(uint40 gracePeriod) public { diff --git a/tests/protocol/tokenization/StableDebtToken.t.sol b/tests/protocol/tokenization/StableDebtToken.t.sol index 06aa317c..f2461065 100644 --- a/tests/protocol/tokenization/StableDebtToken.t.sol +++ b/tests/protocol/tokenization/StableDebtToken.t.sol @@ -9,7 +9,7 @@ import {IAaveIncentivesController} from '../../../src/contracts/interfaces/IAave import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; import {PoolConfigurator, ConfiguratorInputTypes, IPool} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; -import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {TestnetProcedures, TestVars} from '../../utils/TestnetProcedures.sol'; contract StableDebtTokenEventsTests is TestnetProcedures { StableDebtTokenInstance public stableDebtToken; @@ -69,11 +69,14 @@ contract StableDebtTokenEventsTests is TestnetProcedures { return stDebtToken; } - function test_reverts_initialize_twice() public { - StableDebtTokenInstance staDebtToken = test_initialize_StableDebtToken(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + function test_reverts_initialize_twice(TestVars memory t) public { + StableDebtTokenInstance staDebtToken = test_initialize_StableDebtToken(t); + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); uint8 decimals = TestnetERC20(listing.underlyingAsset).decimals(); @@ -90,11 +93,16 @@ contract StableDebtTokenEventsTests is TestnetProcedures { ); } - function test_initialize_StableDebtToken() public returns (StableDebtTokenInstance) { + function test_initialize_StableDebtToken( + TestVars memory t + ) public returns (StableDebtTokenInstance) { StableDebtTokenInstance stDebtToken = test_new_StableDebtToken_implementation(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); vm.expectEmit(address(stDebtToken)); emit Initialized( @@ -128,11 +136,14 @@ contract StableDebtTokenEventsTests is TestnetProcedures { return stDebtToken; } - function test_reverts_initialize_pool_do_not_match() public { + function test_reverts_initialize_pool_do_not_match(TestVars memory t) public { StableDebtTokenInstance stDebtToken = test_new_StableDebtToken_implementation(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); uint8 decimals = TestnetERC20(listing.underlyingAsset).decimals(); @@ -149,8 +160,8 @@ contract StableDebtTokenEventsTests is TestnetProcedures { ); } - function test_mint_stableDebt_caller_alice() public { - StableDebtTokenInstance debtToken = test_initialize_StableDebtToken(); + function test_mint_stableDebt_caller_alice(TestVars memory t) public { + StableDebtTokenInstance debtToken = test_initialize_StableDebtToken(t); vm.expectRevert(bytes(Errors.OPERATION_NOT_SUPPORTED)); @@ -158,8 +169,8 @@ contract StableDebtTokenEventsTests is TestnetProcedures { debtToken.mint(alice, alice, 0, 0); } - function test_mint_stableDebt_caller_bob_onBehalf_alice() public { - StableDebtTokenInstance debtToken = test_initialize_StableDebtToken(); + function test_mint_stableDebt_caller_bob_onBehalf_alice(TestVars memory t) public { + StableDebtTokenInstance debtToken = test_initialize_StableDebtToken(t); TestnetERC20 asset = TestnetERC20(debtToken.UNDERLYING_ASSET_ADDRESS()); uint8 decimals = asset.decimals(); uint256 amount = 1200 * 10 ** decimals; @@ -208,53 +219,48 @@ contract StableDebtTokenEventsTests is TestnetProcedures { stDebtToken.burn(address(0), 0); } - function test_default_revision() public { - StableDebtTokenInstance stDebtToken = new StableDebtTokenInstance(IPool(report.poolProxy)); - assertEq(stDebtToken._getRevision(), stDebtToken.DEBT_TOKEN_REVISION()); - } - - function test_getAverageStableRate() public view { + function test_getAverageStableRate() public { uint256 avgStableRate = stableDebtToken.getAverageStableRate(); assertEq(avgStableRate, 0); } - function test_getUserLastUpdated() public view { + function test_getUserLastUpdated() public { uint256 lastUpdated = stableDebtToken.getUserLastUpdated(alice); assertEq(lastUpdated, 0); } - function test_getUserStableRate() public view { + function test_getUserStableRate() public { uint256 userStableRate = stableDebtToken.getUserStableRate(alice); assertEq(userStableRate, 0); } - function test_balanceOf() public view { + function test_balanceOf() public { uint256 balance = stableDebtToken.balanceOf(alice); assertEq(balance, 0); } - function test_totalSupply() public view { + function test_totalSupply() public { uint256 scaledTotalSupply = stableDebtToken.totalSupply(); assertEq(scaledTotalSupply, 0); } - function test_getTotalSupplyLastUpdated() public view { + function test_getTotalSupplyLastUpdated() public { uint256 totalSupplyLastUpdated = stableDebtToken.getTotalSupplyLastUpdated(); assertEq(totalSupplyLastUpdated, 0); } - function test_principalBalanceOf() public view { + function test_principalBalanceOf() public { uint256 principalBalanceOf = stableDebtToken.principalBalanceOf(alice); assertEq(principalBalanceOf, 0); } - function test_getTotalSupplyAndAvgRate() public view { + function test_getTotalSupplyAndAvgRate() public { (uint256 totalSupply, uint256 avgRate) = stableDebtToken.getTotalSupplyAndAvgRate(); assertEq(totalSupply, 0); assertEq(avgRate, 0); } - function test_getSupplyData() public view { + function test_getSupplyData() public { ( uint256 principal, uint256 totalSupply, diff --git a/tests/protocol/tokenization/VariableDebtToken.t.sol b/tests/protocol/tokenization/VariableDebtToken.t.sol index 0c13902e..5124f253 100644 --- a/tests/protocol/tokenization/VariableDebtToken.t.sol +++ b/tests/protocol/tokenization/VariableDebtToken.t.sol @@ -11,7 +11,7 @@ import {ReserveLogic, DataTypes} from '../../../src/contracts/protocol/libraries import {WadRayMath} from '../../../src/contracts/protocol/libraries/math/WadRayMath.sol'; import {ConfiguratorInputTypes, IPool} from '../../../src/contracts/protocol/pool/PoolConfigurator.sol'; import {EIP712SigUtils} from '../../utils/EIP712SigUtils.sol'; -import {TestnetProcedures} from '../../utils/TestnetProcedures.sol'; +import {TestnetProcedures, TestVars} from '../../utils/TestnetProcedures.sol'; contract VariableDebtTokenEventsTests is TestnetProcedures { using WadRayMath for uint256; @@ -82,18 +82,23 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { return varDebtToken; } - function test_initialize_VariableDebtToken() public returns (VariableDebtTokenInstance) { + function test_initialize_VariableDebtToken( + TestVars memory t + ) public returns (VariableDebtTokenInstance) { VariableDebtTokenInstance varDebtToken = test_new_VariableDebtToken_implementation(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); vm.expectEmit(address(varDebtToken)); emit Initialized( listing.underlyingAsset, report.poolProxy, - report.rewardsControllerProxy, - TestnetERC20(listing.underlyingAsset).decimals(), + listing.incentivesController, + listing.underlyingAssetDecimals, listing.variableDebtTokenName, listing.variableDebtTokenSymbol, listing.params @@ -103,7 +108,7 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { IPool(report.poolProxy), listing.underlyingAsset, IAaveIncentivesController(listing.incentivesController), - TestnetERC20(listing.underlyingAsset).decimals(), + listing.underlyingAssetDecimals, listing.variableDebtTokenName, listing.variableDebtTokenSymbol, listing.params @@ -120,11 +125,14 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { return varDebtToken; } - function test_reverts_initialize_twice() public { - VariableDebtTokenInstance varDebtToken = test_initialize_VariableDebtToken(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + function test_reverts_initialize_twice(TestVars memory t) public { + VariableDebtTokenInstance varDebtToken = test_initialize_VariableDebtToken(t); + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); uint8 decimals = TestnetERC20(listing.underlyingAsset).decimals(); @@ -141,11 +149,14 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { ); } - function test_reverts_initialize_pool_do_not_match() public { + function test_reverts_initialize_pool_do_not_match(TestVars memory t) public { VariableDebtTokenInstance varDebtToken = test_new_VariableDebtToken_implementation(); - ConfiguratorInputTypes.InitReserveInput memory listing = ( - _generateListingInput(1, report, poolAdmin) - )[0]; + ConfiguratorInputTypes.InitReserveInput memory listing = _generateInitReserveInput( + t, + report, + poolAdmin, + true + ); uint8 decimals = TestnetERC20(listing.underlyingAsset).decimals(); @@ -162,13 +173,8 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { ); } - function test_default_revision() public { - VariableDebtTokenInstance varDebtToken = new VariableDebtTokenInstance(IPool(report.poolProxy)); - assertEq(varDebtToken._getRevision(), varDebtToken.DEBT_TOKEN_REVISION()); - } - - function test_mint_variableDebt_caller_alice() public { - VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(); + function test_mint_variableDebt_caller_alice(TestVars memory t) public { + VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(t); TestnetERC20 asset = TestnetERC20(debtToken.UNDERLYING_ASSET_ADDRESS()); uint8 decimals = asset.decimals(); uint256 amount = 1200 * 10 ** decimals; @@ -182,8 +188,8 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { assertEq(debtToken.scaledBalanceOf(alice), amount); } - function test_mint_variableDebt_caller_bob_onBehalf_alice() public { - VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(); + function test_mint_variableDebt_caller_bob_onBehalf_alice(TestVars memory t) public { + VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(t); TestnetERC20 asset = TestnetERC20(debtToken.UNDERLYING_ASSET_ADDRESS()); uint8 decimals = asset.decimals(); uint256 amount = 1200 * 10 ** decimals; @@ -203,8 +209,8 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { assertEq(debtToken.scaledBalanceOf(alice), amount); } - function test_partial_burn_variableDebt() public { - VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(); + function test_partial_burn_variableDebt(TestVars memory t) public { + VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(t); TestnetERC20 asset = TestnetERC20(debtToken.UNDERLYING_ASSET_ADDRESS()); uint8 decimals = asset.decimals(); uint256 amount = 1200 * 10 ** decimals; @@ -229,8 +235,8 @@ contract VariableDebtTokenEventsTests is TestnetProcedures { assertEq(debtToken.scaledBalanceOf(alice), balanceScaled - repaymentScaled); } - function test_total_burn_variableDebt() public { - VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(); + function test_total_burn_variableDebt(TestVars memory t) public { + VariableDebtTokenInstance debtToken = test_initialize_VariableDebtToken(t); TestnetERC20 asset = TestnetERC20(debtToken.UNDERLYING_ASSET_ADDRESS()); uint8 decimals = asset.decimals(); uint256 amount = 1200 * 10 ** decimals; diff --git a/tests/utils/TestnetProcedures.sol b/tests/utils/TestnetProcedures.sol index 35669294..5d74854a 100644 --- a/tests/utils/TestnetProcedures.sol +++ b/tests/utils/TestnetProcedures.sol @@ -22,6 +22,7 @@ import {MarketReportUtils} from '../../src/deployments/contracts/utilities/Marke import {AaveV3ConfigEngine, IAaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; struct TestVars { + uint8 underlyingDecimals; string aTokenName; string aTokenSymbol; string variableDebtName; @@ -29,10 +30,11 @@ struct TestVars { string stableDebtName; string stableDebtSymbol; address rateStrategy; - bytes interestRateData; - bytes emptyParams; - uint256 previousReservesLength; + address incentivesController; + address treasury; + bool useVirtualBalance; } + struct TestReserveConfig { uint256 decimals; uint256 ltv; @@ -278,59 +280,71 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { return string(abi.encodePacked(a, vm.toString(b))); } - function _generateListingInput( - uint256 listings, + function _generateInitConfig( + TestVars memory t, + MarketReport memory r, + address poolAdminUser, + bool isValidDecimals + ) internal returns (ConfiguratorInputTypes.InitReserveInput[] memory) { + TestVars[] memory tArray = new TestVars[](1); + tArray[0] = t; + return _generateInitConfig(tArray, r, poolAdminUser, isValidDecimals); + } + + function _generateInitConfig( + TestVars[] memory t, MarketReport memory r, - address poolAdminUser + address poolAdminUser, + bool isValidDecimals ) internal returns (ConfiguratorInputTypes.InitReserveInput[] memory) { ConfiguratorInputTypes.InitReserveInput[] - memory input = new ConfiguratorInputTypes.InitReserveInput[](listings); - - for (uint256 x; x < listings; ++x) { - TestnetERC20 listingToken = new TestnetERC20( - _concatStr('Token', x), - _concatStr('T', x), - uint8(10 + x), - poolAdminUser - ); - TestVars memory t; - t.aTokenName = _concatStr('AToken ', x); - t.aTokenName = _concatStr('a ', x); - t.variableDebtName = _concatStr('Variable Debt Misc', x); - t.variableDebtSymbol = _concatStr('varDebtMISC ', x); - t.stableDebtName = _concatStr('Stable Debt Misc ', x); - t.stableDebtSymbol = _concatStr('stableDebtMISC ', x); - t.rateStrategy = r.defaultInterestRateStrategy; - t.interestRateData = abi.encode( - IDefaultInterestRateStrategyV2.InterestRateData({ - optimalUsageRatio: 80_00, - baseVariableBorrowRate: 1_00, - variableRateSlope1: 4_00, - variableRateSlope2: 60_00 - }) - ); + memory configurations = new ConfiguratorInputTypes.InitReserveInput[](t.length); + for (uint256 i = 0; i < t.length; i++) { + configurations[i] = _generateInitReserveInput(t[i], r, poolAdminUser, isValidDecimals); + } + return configurations; + } - input[x] = ConfiguratorInputTypes.InitReserveInput( - r.aToken, - r.stableDebtToken, - r.variableDebtToken, - listingToken.decimals(), - true, - t.rateStrategy, - address(listingToken), - r.treasury, - r.rewardsControllerProxy, - t.aTokenName, - t.aTokenSymbol, - t.variableDebtName, - t.variableDebtSymbol, - t.stableDebtName, - t.stableDebtSymbol, - t.emptyParams, - t.interestRateData - ); + function _generateInitReserveInput( + TestVars memory t, + MarketReport memory r, + address poolAdminUser, + bool isValidDecimals + ) internal returns (ConfiguratorInputTypes.InitReserveInput memory) { + if (isValidDecimals) { + t.underlyingDecimals = uint8(bound(t.underlyingDecimals, 6, 25)); + } else { + t.underlyingDecimals = uint8(bound(t.underlyingDecimals, 0, 5)); } + ConfiguratorInputTypes.InitReserveInput memory input; + input.aTokenImpl = r.aToken; + input.underlyingAsset = address( + new TestnetERC20('Misc Token', 'MISC', t.underlyingDecimals, poolAdminUser) + ); + input.stableDebtTokenImpl = r.stableDebtToken; + input.variableDebtTokenImpl = r.variableDebtToken; + input.underlyingAssetDecimals = t.underlyingDecimals; + input.useVirtualBalance = t.useVirtualBalance; + input.interestRateStrategyAddress = r.defaultInterestRateStrategy; + input.treasury = t.treasury; + input.incentivesController = r.rewardsControllerProxy; + input.aTokenName = t.aTokenName; + input.aTokenSymbol = t.aTokenSymbol; + input.variableDebtTokenName = t.variableDebtName; + input.variableDebtTokenSymbol = t.variableDebtSymbol; + input.stableDebtTokenName = t.stableDebtName; + input.stableDebtTokenSymbol = t.stableDebtSymbol; + input.params = bytes(''); + input.interestRateData = abi.encode( + IDefaultInterestRateStrategyV2.InterestRateData({ + optimalUsageRatio: 80_00, + baseVariableBorrowRate: 1_00, + variableRateSlope1: 4_00, + variableRateSlope2: 60_00 + }) + ); + return input; } From 9d80072d95a426e4c19584110411ddf25ea60e65 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 6 May 2024 17:05:03 +0530 Subject: [PATCH 09/11] fix: remove static-a-token, config engine tests and the deployments --- .../misc/DeployAaveV3MarketBatchedBase.sol | 13 +- .../openzeppelin/contracts/ECDSA.sol | 180 ----- src/contracts/dependencies/solmate/ERC20.sol | 207 ----- .../extensions/static-a-token/README.md | 38 - .../extensions/static-a-token/StataOracle.sol | 41 - .../static-a-token/StaticATokenErrors.sol | 14 - .../static-a-token/StaticATokenFactory.sol | 86 --- .../static-a-token/StaticATokenLM.sol | 712 ------------------ .../static-a-token/interfaces/IAToken.sol | 16 - .../static-a-token/interfaces/IERC4626.sol | 241 ------ .../IInitializableStaticATokenLM.sol | 32 - .../interfaces/IStataOracle.sol | 31 - .../interfaces/IStaticATokenFactory.sol | 24 - .../interfaces/IStaticATokenLM.sol | 214 ------ .../libraries/RayMathExplicitRounding.sol | 42 -- .../procedures/AaveV3HelpersProcedureOne.sol | 57 -- .../procedures/AaveV3HelpersProcedureTwo.sol | 41 - .../procedures/AaveV3MiscProcedure.sol | 34 - .../procedures/AaveV3SetupProcedure.sol | 13 +- .../contracts/utilities/MetadataReporter.sol | 24 +- .../interfaces/IMarketReportTypes.sol | 32 +- .../AaveV3BatchOrchestration.sol | 95 +-- .../batches/AaveV3HelpersBatchOne.sol | 37 - .../batches/AaveV3HelpersBatchTwo.sol | 17 - .../batches/AaveV3MiscBatch.sol | 29 - .../batches/AaveV3PeripheryBatch.sol | 6 +- .../batches/AaveV3SetupBatch.sol | 6 +- tests/deployments/AaveV3BatchDeployment.t.sol | 16 +- tests/deployments/AaveV3BatchTests.t.sol | 80 +- tests/deployments/DeploymentsGasLimits.t.sol | 94 +-- .../static-a-token/StataOracle.t.sol | 57 -- .../static-a-token/StaticATokenLM.t.sol | 609 --------------- .../StaticATokenMetaTransactions.t.sol | 252 ------- .../static-a-token/StaticATokenNoLM.t.sol | 50 -- tests/extensions/static-a-token/TestBase.sol | 91 --- .../AaveV3ConfigEngineTest.t.sol | 670 ---------------- .../mocks/AaveV3MockAssetEModeUpdate.sol | 29 - .../mocks/AaveV3MockBorrowUpdate.sol | 38 - .../mocks/AaveV3MockBorrowUpdateNoChange.sol | 36 - .../mocks/AaveV3MockCapUpdate.sol | 33 - .../mocks/AaveV3MockCollateralUpdate.sol | 36 - .../AaveV3MockCollateralUpdateNoChange.sol | 36 - .../AaveV3MockCollateralUpdateWrongBonus.sol | 68 -- .../mocks/AaveV3MockEModeCategoryUpdate.sol | 72 -- .../AaveV3MockEModeCategoryUpdateNoChange.sol | 37 - .../mocks/AaveV3MockListing.sol | 60 -- .../mocks/AaveV3MockListingCustom.sol | 81 -- .../mocks/AaveV3MockPriceFeedUpdate.sol | 36 - .../mocks/AaveV3MockRatesUpdate.sol | 42 -- tests/utils/BatchTestProcedures.sol | 57 +- tests/utils/ConfigEngineDeployer.sol | 60 ++ tests/utils/SigUtils.sol | 117 --- tests/utils/TestnetProcedures.sol | 12 +- 53 files changed, 141 insertions(+), 4910 deletions(-) delete mode 100644 src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol delete mode 100644 src/contracts/dependencies/solmate/ERC20.sol delete mode 100644 src/contracts/extensions/static-a-token/README.md delete mode 100644 src/contracts/extensions/static-a-token/StataOracle.sol delete mode 100644 src/contracts/extensions/static-a-token/StaticATokenErrors.sol delete mode 100644 src/contracts/extensions/static-a-token/StaticATokenFactory.sol delete mode 100644 src/contracts/extensions/static-a-token/StaticATokenLM.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IAToken.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IERC4626.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol delete mode 100644 src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol delete mode 100644 src/contracts/misc/libraries/RayMathExplicitRounding.sol delete mode 100644 src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol delete mode 100644 src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol delete mode 100644 src/deployments/contracts/procedures/AaveV3MiscProcedure.sol delete mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol delete mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol delete mode 100644 src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol delete mode 100644 tests/extensions/static-a-token/StataOracle.t.sol delete mode 100644 tests/extensions/static-a-token/StaticATokenLM.t.sol delete mode 100644 tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol delete mode 100644 tests/extensions/static-a-token/StaticATokenNoLM.t.sol delete mode 100644 tests/extensions/static-a-token/TestBase.sol delete mode 100644 tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol delete mode 100644 tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol create mode 100644 tests/utils/ConfigEngineDeployer.sol delete mode 100644 tests/utils/SigUtils.sol diff --git a/scripts/misc/DeployAaveV3MarketBatchedBase.sol b/scripts/misc/DeployAaveV3MarketBatchedBase.sol index 25af8793..e6fddd33 100644 --- a/scripts/misc/DeployAaveV3MarketBatchedBase.sol +++ b/scripts/misc/DeployAaveV3MarketBatchedBase.sol @@ -25,7 +25,7 @@ abstract contract DeployAaveV3MarketBatchedBase is DeployUtils, MarketInput, Scr (roles, config, flags, report) = _getMarketInput(msg.sender); - _loadWarnings(config, flags); + _loadWarnings(config); vm.startBroadcast(); report = AaveV3BatchOrchestration.deployAaveV3(msg.sender, roles, config, flags, report); @@ -38,21 +38,12 @@ abstract contract DeployAaveV3MarketBatchedBase is DeployUtils, MarketInput, Scr metadataReporter.writeJsonReportMarket(report); } - function _loadWarnings(MarketConfig memory config, DeployFlags memory flags) internal view { + function _loadWarnings(MarketConfig memory config) internal view { if (config.paraswapAugustusRegistry == address(0)) { console.log( 'Warning: Paraswap Adapters will be skipped at deployment due missing config.paraswapAugustusRegistry' ); } - if ( - (flags.l2 && - (config.l2SequencerUptimeFeed == address(0) || - config.l2PriceOracleSentinelGracePeriod == 0)) - ) { - console.log( - 'Warning: L2 Sequencer uptime feed wont be set at deployment due missing config.l2SequencerUptimeFeed config.l2PriceOracleSentinelGracePeriod' - ); - } if ( config.networkBaseTokenPriceInUsdProxyAggregator == address(0) || config.marketReferenceCurrencyPriceInUsdProxyAggregator == address(0) diff --git a/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol b/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol deleted file mode 100644 index e58805c6..00000000 --- a/src/contracts/dependencies/openzeppelin/contracts/ECDSA.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) -pragma solidity ^0.8.0; - -/** - * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. - * - * These functions can be used to verify that a message was signed by the holder - * of the private keys of a given address. - */ -library ECDSA { - enum RecoverError { - NoError, - InvalidSignature, - InvalidSignatureLength, - InvalidSignatureS - } - - /** - * @dev The signature derives the `address(0)`. - */ - error ECDSAInvalidSignature(); - - /** - * @dev The signature has an invalid length. - */ - error ECDSAInvalidSignatureLength(uint256 length); - - /** - * @dev The signature has an S value that is in the upper half order. - */ - error ECDSAInvalidSignatureS(bytes32 s); - - /** - * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not - * return address(0) without also returning an error description. Errors are documented using an enum (error type) - * and a bytes32 providing additional information about the error. - * - * If no error is returned, then the address can be used for verification purposes. - * - * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. - * - * Documentation for signature generation: - * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] - * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] - */ - function tryRecover( - bytes32 hash, - bytes memory signature - ) internal pure returns (address, RecoverError, bytes32) { - if (signature.length == 65) { - bytes32 r; - bytes32 s; - uint8 v; - // ecrecover takes the signature parameters, and the only way to get them - // currently is to use assembly. - /// @solidity memory-safe-assembly - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - } - return tryRecover(hash, v, r, s); - } else { - return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature`. This address can then be used for verification purposes. - * - * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. - */ - function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { - (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); - _throwError(error, errorArg); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. - * - * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] - */ - function tryRecover( - bytes32 hash, - bytes32 r, - bytes32 vs - ) internal pure returns (address, RecoverError, bytes32) { - unchecked { - bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - // We do not check for an overflow here since the shift operation results in 0 or 1. - uint8 v = uint8((uint256(vs) >> 255) + 27); - return tryRecover(hash, v, r, s); - } - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. - */ - function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { - (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); - _throwError(error, errorArg); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `v`, - * `r` and `s` signature fields separately. - */ - function tryRecover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address, RecoverError, bytes32) { - // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature - // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines - // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most - // signatures from current libraries generate a unique signature with an s-value in the lower half order. - // - // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value - // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or - // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept - // these malleable signatures as well. - if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - return (address(0), RecoverError.InvalidSignatureS, s); - } - - // If the signature is valid (and not malleable), return the signer address - address signer = ecrecover(hash, v, r, s); - if (signer == address(0)) { - return (address(0), RecoverError.InvalidSignature, bytes32(0)); - } - - return (signer, RecoverError.NoError, bytes32(0)); - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `v`, - * `r` and `s` signature fields separately. - */ - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { - (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); - _throwError(error, errorArg); - return recovered; - } - - /** - * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. - */ - function _throwError(RecoverError error, bytes32 errorArg) private pure { - if (error == RecoverError.NoError) { - return; // no error: do nothing - } else if (error == RecoverError.InvalidSignature) { - revert ECDSAInvalidSignature(); - } else if (error == RecoverError.InvalidSignatureLength) { - revert ECDSAInvalidSignatureLength(uint256(errorArg)); - } else if (error == RecoverError.InvalidSignatureS) { - revert ECDSAInvalidSignatureS(errorArg); - } - } -} diff --git a/src/contracts/dependencies/solmate/ERC20.sol b/src/contracts/dependencies/solmate/ERC20.sol deleted file mode 100644 index 47d7b549..00000000 --- a/src/contracts/dependencies/solmate/ERC20.sol +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ECDSA} from '../openzeppelin/contracts/ECDSA.sol'; - -/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) -/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) -/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. -abstract contract ERC20 { - bytes32 public constant PERMIT_TYPEHASH = - keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); - - /* ////////////////////////////////////////////////////////////// - EVENTS - ////////////////////////////////////////////////////////////// */ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /* ////////////////////////////////////////////////////////////// - METADATA STORAGE - ////////////////////////////////////////////////////////////// */ - - string public name; - - string public symbol; - - uint8 public decimals; - - /* ////////////////////////////////////////////////////////////// - ERC20 STORAGE - ////////////////////////////////////////////////////////////// */ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /* ////////////////////////////////////////////////////////////// - EIP-2612 STORAGE - ////////////////////////////////////////////////////////////// */ - - mapping(address => uint256) public nonces; - - /* ////////////////////////////////////////////////////////////// - CONSTRUCTOR - ////////////////////////////////////////////////////////////// */ - - constructor(string memory _name, string memory _symbol, uint8 _decimals) { - name = _name; - symbol = _symbol; - decimals = _decimals; - } - - /* ////////////////////////////////////////////////////////////// - ERC20 LOGIC - ////////////////////////////////////////////////////////////// */ - - function approve(address spender, uint256 amount) public virtual returns (bool) { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - return true; - } - - function transfer(address to, uint256 amount) public virtual returns (bool) { - _beforeTokenTransfer(msg.sender, to, amount); - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - return true; - } - - function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) { - _beforeTokenTransfer(from, to, amount); - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - return true; - } - - /* ////////////////////////////////////////////////////////////// - EIP-2612 LOGIC - ////////////////////////////////////////////////////////////// */ - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - require(deadline >= block.timestamp, 'PERMIT_DEADLINE_EXPIRED'); - - // Unchecked because the only math done is incrementing - // the owner's nonce which cannot realistically overflow. - unchecked { - address signer = ECDSA.recover( - keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) - ) - ), - v, - r, - s - ); - - require(signer == owner, 'INVALID_SIGNER'); - - allowance[signer][spender] = value; - } - - emit Approval(owner, spender, value); - } - - function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { - return computeDomainSeparator(); - } - - function computeDomainSeparator() internal view virtual returns (bytes32) { - return - keccak256( - abi.encode( - keccak256( - 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' - ), - keccak256(bytes(name)), - keccak256('1'), - block.chainid, - address(this) - ) - ); - } - - /* ////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - ////////////////////////////////////////////////////////////// */ - - function _mint(address to, uint256 amount) internal virtual { - _beforeTokenTransfer(address(0), to, amount); - totalSupply += amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(address(0), to, amount); - } - - function _burn(address from, uint256 amount) internal virtual { - _beforeTokenTransfer(from, address(0), amount); - balanceOf[from] -= amount; - - // Cannot underflow because a user's balance - // will never be larger than the total supply. - unchecked { - totalSupply -= amount; - } - - emit Transfer(from, address(0), amount); - } - - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} -} diff --git a/src/contracts/extensions/static-a-token/README.md b/src/contracts/extensions/static-a-token/README.md deleted file mode 100644 index 9ced57a6..00000000 --- a/src/contracts/extensions/static-a-token/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# stataToken - Static aToken vault/wrapper - -

- -

- -## About - -The static-a-token contains an [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) generic token vault/wrapper for all Aave v3 pools. - -## Features - -- **Full [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) compatibility.** -- **Accounting for any potential liquidity mining rewards.** Let’s say some team of the Aave ecosystem (or the Aave community itself) decides to incentivize deposits of USDC on Aave v3 Ethereum. By holding `stataUSDC`, the user will still be eligible for those incentives. - It is important to highlight that while currently the wrapper supports infinite reward tokens by design (e.g. AAVE incentivizing stETH & Lido incentivizing stETH as well), each reward needs to be permissionlessly registered which bears some [⁽¹⁾](#limitations). -- **Meta-transactions support.** To enable interfaces to offer gas-less transactions to deposit/withdraw on the wrapper/Aave protocol (also supported on Aave v3). Including permit() for transfers of the `stataAToken` itself. -- **Upgradable by the Aave governance.** Similar to other contracts of the Aave ecosystem, the Level 1 executor (short executor) will be able to add new features to the deployed instances of the `stataTokens`. -- **Powered by a stataToken Factory.** Whenever a token will be listed on Aave v3, anybody will be able to call the stataToken Factory to deploy an instance for the new asset, permissionless, but still assuring the code used and permissions are properly configured without any extra headache. - -See [IStaticATokenLM.sol](./interfaces/IStaticATokenLM.sol) for detailed method documentation. - -## Deployed Addresses - -The staticATokenFactory is deployed for all major Aave v3 pools. -An up to date address can be fetched from the respective [address-book pool library](https://github.com/bgd-labs/aave-address-book/blob/main/src/AaveV3Ethereum.sol). - -## Limitations - -The `stataToken` is not natively integrated into the aave protocol and therefore cannot hook into the emissionManager. -This means a `reward` added **after** `statToken` creation needs to be registered manually on the token via the permissionless `refreshRewardTokens()` method. -As this process is not currently automated users might be missing out on rewards until the method is called. - -## Security procedures - -For this project, the security procedures applied/being finished are: - -- The test suite of the codebase itself. -- Certora audit/property checking for all the dynamics of the `stataToken`, including respecting all the specs of [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626). diff --git a/src/contracts/extensions/static-a-token/StataOracle.sol b/src/contracts/extensions/static-a-token/StataOracle.sol deleted file mode 100644 index 50715593..00000000 --- a/src/contracts/extensions/static-a-token/StataOracle.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IPool} from '../../interfaces/IPool.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IAaveOracle} from '../../interfaces/IAaveOracle.sol'; -import {IStataOracle} from './interfaces/IStataOracle.sol'; -import {IERC4626} from './interfaces/IERC4626.sol'; - -/** - * @title StataOracle - * @author BGD Labs - * @notice Contract to get asset prices of stata tokens - */ -contract StataOracle is IStataOracle { - /// @inheritdoc IStataOracle - IPool public immutable POOL; - /// @inheritdoc IStataOracle - IAaveOracle public immutable AAVE_ORACLE; - - constructor(IPoolAddressesProvider provider) { - POOL = IPool(provider.getPool()); - AAVE_ORACLE = IAaveOracle(provider.getPriceOracle()); - } - - /// @inheritdoc IStataOracle - function getAssetPrice(address asset) public view returns (uint256) { - address underlying = IERC4626(asset).asset(); - return - (AAVE_ORACLE.getAssetPrice(underlying) * POOL.getReserveNormalizedIncome(underlying)) / 1e27; - } - - /// @inheritdoc IStataOracle - function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory) { - uint256[] memory prices = new uint256[](assets.length); - for (uint256 i = 0; i < assets.length; i++) { - prices[i] = getAssetPrice(assets[i]); - } - return prices; - } -} diff --git a/src/contracts/extensions/static-a-token/StaticATokenErrors.sol b/src/contracts/extensions/static-a-token/StaticATokenErrors.sol deleted file mode 100644 index bec417df..00000000 --- a/src/contracts/extensions/static-a-token/StaticATokenErrors.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -library StaticATokenErrors { - string public constant INVALID_OWNER = '1'; - string public constant INVALID_EXPIRATION = '2'; - string public constant INVALID_SIGNATURE = '3'; - string public constant INVALID_DEPOSITOR = '4'; - string public constant INVALID_RECIPIENT = '5'; - string public constant INVALID_CLAIMER = '6'; - string public constant ONLY_ONE_AMOUNT_FORMAT_ALLOWED = '7'; - string public constant INVALID_ZERO_AMOUNT = '8'; - string public constant REWARD_NOT_INITIALIZED = '9'; -} diff --git a/src/contracts/extensions/static-a-token/StaticATokenFactory.sol b/src/contracts/extensions/static-a-token/StaticATokenFactory.sol deleted file mode 100644 index bf307197..00000000 --- a/src/contracts/extensions/static-a-token/StaticATokenFactory.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IPool, DataTypes} from '../../interfaces/IPool.sol'; -import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; -import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; -import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol'; -import {StaticATokenLM} from './StaticATokenLM.sol'; -import {IStaticATokenFactory} from './interfaces/IStaticATokenFactory.sol'; - -/** - * @title StaticATokenFactory - * @notice Factory contract that keeps track of all deployed static aToken wrappers for a specified pool. - * This registry also acts as a factory, allowing to deploy new static aTokens on demand. - * There can only be one static aToken per underlying on the registry at a time. - * @author BGD labs - */ -contract StaticATokenFactory is Initializable, IStaticATokenFactory { - IPool public immutable POOL; - address public immutable ADMIN; - ITransparentProxyFactory public immutable TRANSPARENT_PROXY_FACTORY; - address public immutable STATIC_A_TOKEN_IMPL; - - mapping(address => address) internal _underlyingToStaticAToken; - address[] internal _staticATokens; - - event StaticTokenCreated(address indexed staticAToken, address indexed underlying); - - constructor( - IPool pool, - address proxyAdmin, - ITransparentProxyFactory transparentProxyFactory, - address staticATokenImpl - ) { - POOL = pool; - ADMIN = proxyAdmin; - TRANSPARENT_PROXY_FACTORY = transparentProxyFactory; - STATIC_A_TOKEN_IMPL = staticATokenImpl; - } - - function initialize() external initializer {} - - ///@inheritdoc IStaticATokenFactory - function createStaticATokens(address[] memory underlyings) external returns (address[] memory) { - address[] memory staticATokens = new address[](underlyings.length); - for (uint256 i = 0; i < underlyings.length; i++) { - address cachedStaticAToken = _underlyingToStaticAToken[underlyings[i]]; - if (cachedStaticAToken == address(0)) { - DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(underlyings[i]); - require(reserveData.aTokenAddress != address(0), 'UNDERLYING_NOT_LISTED'); - bytes memory symbol = abi.encodePacked( - 'stat', - IERC20Metadata(reserveData.aTokenAddress).symbol() - ); - address staticAToken = TRANSPARENT_PROXY_FACTORY.createDeterministic( - STATIC_A_TOKEN_IMPL, - ADMIN, - abi.encodeWithSelector( - StaticATokenLM.initialize.selector, - reserveData.aTokenAddress, - string(abi.encodePacked('Static ', IERC20Metadata(reserveData.aTokenAddress).name())), - string(symbol) - ), - bytes32(uint256(uint160(underlyings[i]))) - ); - _underlyingToStaticAToken[underlyings[i]] = staticAToken; - staticATokens[i] = staticAToken; - _staticATokens.push(staticAToken); - emit StaticTokenCreated(staticAToken, underlyings[i]); - } else { - staticATokens[i] = cachedStaticAToken; - } - } - return staticATokens; - } - - ///@inheritdoc IStaticATokenFactory - function getStaticATokens() external view returns (address[] memory) { - return _staticATokens; - } - - ///@inheritdoc IStaticATokenFactory - function getStaticAToken(address underlying) external view returns (address) { - return _underlyingToStaticAToken[underlying]; - } -} diff --git a/src/contracts/extensions/static-a-token/StaticATokenLM.sol b/src/contracts/extensions/static-a-token/StaticATokenLM.sol deleted file mode 100644 index cb74ee88..00000000 --- a/src/contracts/extensions/static-a-token/StaticATokenLM.sol +++ /dev/null @@ -1,712 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IPool} from '../../interfaces/IPool.sol'; -import {DataTypes, ReserveConfiguration} from '../../protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IRewardsController} from '../../rewards/interfaces/IRewardsController.sol'; -import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; -import {MathUtils} from '../../protocol/libraries/math/MathUtils.sol'; -import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; -import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol'; -import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; -import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {IERC20WithPermit} from 'solidity-utils/contracts/oz-common/interfaces/IERC20WithPermit.sol'; - -import {IStaticATokenLM} from './interfaces/IStaticATokenLM.sol'; -import {IAToken} from './interfaces/IAToken.sol'; -import {ERC20} from '../../dependencies/solmate/ERC20.sol'; -import {IInitializableStaticATokenLM} from './interfaces/IInitializableStaticATokenLM.sol'; -import {StaticATokenErrors} from './StaticATokenErrors.sol'; -import {RayMathExplicitRounding, Rounding} from '../../misc/libraries/RayMathExplicitRounding.sol'; -import {IERC4626} from './interfaces/IERC4626.sol'; - -/** - * @title StaticATokenLM - * @notice Wrapper smart contract that allows to deposit tokens on the Aave protocol and receive - * a token which balance doesn't increase automatically, but uses an ever-increasing exchange rate. - * It supports claiming liquidity mining rewards from the Aave system. - * @author BGD labs - */ -contract StaticATokenLM is - Initializable, - ERC20('STATIC__aToken_IMPL', 'STATIC__aToken_IMPL', 18), - IStaticATokenLM, - IERC4626 -{ - using SafeERC20 for IERC20; - using SafeCast for uint256; - using WadRayMath for uint256; - using RayMathExplicitRounding for uint256; - - bytes32 public constant METADEPOSIT_TYPEHASH = - keccak256( - 'Deposit(address depositor,address receiver,uint256 assets,uint16 referralCode,bool depositToAave,uint256 nonce,uint256 deadline,PermitParams permit)' - ); - bytes32 public constant METAWITHDRAWAL_TYPEHASH = - keccak256( - 'Withdraw(address owner,address receiver,uint256 shares,uint256 assets,bool withdrawFromAave,uint256 nonce,uint256 deadline)' - ); - - uint256 public constant STATIC__ATOKEN_LM_REVISION = 2; - - IPool public immutable POOL; - IRewardsController public immutable INCENTIVES_CONTROLLER; - - IERC20 internal _aToken; - address internal _aTokenUnderlying; - address[] internal _rewardTokens; - mapping(address => RewardIndexCache) internal _startIndex; - mapping(address => mapping(address => UserRewardsData)) internal _userRewardsData; - - constructor(IPool pool, IRewardsController rewardsController) { - POOL = pool; - INCENTIVES_CONTROLLER = rewardsController; - } - - ///@inheritdoc IInitializableStaticATokenLM - function initialize( - address newAToken, - string calldata staticATokenName, - string calldata staticATokenSymbol - ) external initializer { - require(IAToken(newAToken).POOL() == address(POOL)); - _aToken = IERC20(newAToken); - - name = staticATokenName; - symbol = staticATokenSymbol; - decimals = IERC20Metadata(newAToken).decimals(); - - _aTokenUnderlying = IAToken(newAToken).UNDERLYING_ASSET_ADDRESS(); - IERC20(_aTokenUnderlying).forceApprove(address(POOL), type(uint256).max); - - if (INCENTIVES_CONTROLLER != IRewardsController(address(0))) { - refreshRewardTokens(); - } - - emit Initialized(newAToken, staticATokenName, staticATokenSymbol); - } - - ///@inheritdoc IStaticATokenLM - function refreshRewardTokens() public override { - address[] memory rewards = INCENTIVES_CONTROLLER.getRewardsByAsset(address(_aToken)); - for (uint256 i = 0; i < rewards.length; i++) { - _registerRewardToken(rewards[i]); - } - } - - ///@inheritdoc IStaticATokenLM - function isRegisteredRewardToken(address reward) public view override returns (bool) { - return _startIndex[reward].isRegistered; - } - - ///@inheritdoc IStaticATokenLM - function deposit( - uint256 assets, - address receiver, - uint16 referralCode, - bool depositToAave - ) external returns (uint256) { - (uint256 shares, ) = _deposit(msg.sender, receiver, 0, assets, referralCode, depositToAave); - return shares; - } - - ///@inheritdoc IStaticATokenLM - function metaDeposit( - address depositor, - address receiver, - uint256 assets, - uint16 referralCode, - bool depositToAave, - uint256 deadline, - PermitParams calldata permit, - SignatureParams calldata sigParams - ) external returns (uint256) { - require(depositor != address(0), StaticATokenErrors.INVALID_DEPOSITOR); - //solium-disable-next-line - require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); - uint256 nonce = nonces[depositor]; - - // Unchecked because the only math done is incrementing - // the owner's nonce which cannot realistically overflow. - unchecked { - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256( - abi.encode( - METADEPOSIT_TYPEHASH, - depositor, - receiver, - assets, - referralCode, - depositToAave, - nonce, - deadline, - permit - ) - ) - ) - ); - nonces[depositor] = nonce + 1; - require( - depositor == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), - StaticATokenErrors.INVALID_SIGNATURE - ); - } - // assume if deadline 0 no permit was supplied - if (permit.deadline != 0) { - try - IERC20WithPermit(depositToAave ? address(_aTokenUnderlying) : address(_aToken)).permit( - depositor, - address(this), - permit.value, - permit.deadline, - permit.v, - permit.r, - permit.s - ) - {} catch {} - } - (uint256 shares, ) = _deposit(depositor, receiver, 0, assets, referralCode, depositToAave); - return shares; - } - - ///@inheritdoc IStaticATokenLM - function metaWithdraw( - address owner, - address receiver, - uint256 shares, - uint256 assets, - bool withdrawFromAave, - uint256 deadline, - SignatureParams calldata sigParams - ) external returns (uint256, uint256) { - require(owner != address(0), StaticATokenErrors.INVALID_OWNER); - //solium-disable-next-line - require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); - uint256 nonce = nonces[owner]; - // Unchecked because the only math done is incrementing - // the owner's nonce which cannot realistically overflow. - unchecked { - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256( - abi.encode( - METAWITHDRAWAL_TYPEHASH, - owner, - receiver, - shares, - assets, - withdrawFromAave, - nonce, - deadline - ) - ) - ) - ); - nonces[owner] = nonce + 1; - require( - owner == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), - StaticATokenErrors.INVALID_SIGNATURE - ); - } - return _withdraw(owner, receiver, shares, assets, withdrawFromAave); - } - - ///@inheritdoc IERC4626 - function previewRedeem(uint256 shares) public view virtual returns (uint256) { - return _convertToAssets(shares, Rounding.DOWN); - } - - ///@inheritdoc IERC4626 - function previewMint(uint256 shares) public view virtual returns (uint256) { - return _convertToAssets(shares, Rounding.UP); - } - - ///@inheritdoc IERC4626 - function previewWithdraw(uint256 assets) public view virtual returns (uint256) { - return _convertToShares(assets, Rounding.UP); - } - - ///@inheritdoc IERC4626 - function previewDeposit(uint256 assets) public view virtual returns (uint256) { - return _convertToShares(assets, Rounding.DOWN); - } - - ///@inheritdoc IStaticATokenLM - function rate() public view returns (uint256) { - return POOL.getReserveNormalizedIncome(_aTokenUnderlying); - } - - ///@inheritdoc IStaticATokenLM - function collectAndUpdateRewards(address reward) public returns (uint256) { - if (reward == address(0)) { - return 0; - } - - address[] memory assets = new address[](1); - assets[0] = address(_aToken); - - return INCENTIVES_CONTROLLER.claimRewards(assets, type(uint256).max, address(this), reward); - } - - ///@inheritdoc IStaticATokenLM - function claimRewardsOnBehalf( - address onBehalfOf, - address receiver, - address[] memory rewards - ) external { - require( - msg.sender == onBehalfOf || msg.sender == INCENTIVES_CONTROLLER.getClaimer(onBehalfOf), - StaticATokenErrors.INVALID_CLAIMER - ); - _claimRewardsOnBehalf(onBehalfOf, receiver, rewards); - } - - ///@inheritdoc IStaticATokenLM - function claimRewards(address receiver, address[] memory rewards) external { - _claimRewardsOnBehalf(msg.sender, receiver, rewards); - } - - ///@inheritdoc IStaticATokenLM - function claimRewardsToSelf(address[] memory rewards) external { - _claimRewardsOnBehalf(msg.sender, msg.sender, rewards); - } - - ///@inheritdoc IStaticATokenLM - function getCurrentRewardsIndex(address reward) public view returns (uint256) { - if (address(reward) == address(0)) { - return 0; - } - (, uint256 nextIndex) = INCENTIVES_CONTROLLER.getAssetIndex(address(_aToken), reward); - return nextIndex; - } - - ///@inheritdoc IStaticATokenLM - function getTotalClaimableRewards(address reward) external view returns (uint256) { - if (reward == address(0)) { - return 0; - } - - address[] memory assets = new address[](1); - assets[0] = address(_aToken); - uint256 freshRewards = INCENTIVES_CONTROLLER.getUserRewards(assets, address(this), reward); - return IERC20(reward).balanceOf(address(this)) + freshRewards; - } - - ///@inheritdoc IStaticATokenLM - function getClaimableRewards(address user, address reward) external view returns (uint256) { - return _getClaimableRewards(user, reward, balanceOf[user], getCurrentRewardsIndex(reward)); - } - - ///@inheritdoc IStaticATokenLM - function getUnclaimedRewards(address user, address reward) external view returns (uint256) { - return _userRewardsData[user][reward].unclaimedRewards; - } - - ///@inheritdoc IERC4626 - function asset() external view returns (address) { - return address(_aTokenUnderlying); - } - - ///@inheritdoc IStaticATokenLM - function aToken() external view returns (IERC20) { - return _aToken; - } - - ///@inheritdoc IStaticATokenLM - function rewardTokens() external view returns (address[] memory) { - return _rewardTokens; - } - - ///@inheritdoc IERC4626 - function totalAssets() external view returns (uint256) { - return _aToken.balanceOf(address(this)); - } - - ///@inheritdoc IERC4626 - function convertToShares(uint256 assets) external view returns (uint256) { - return _convertToShares(assets, Rounding.DOWN); - } - - ///@inheritdoc IERC4626 - function convertToAssets(uint256 shares) external view returns (uint256) { - return _convertToAssets(shares, Rounding.DOWN); - } - - ///@inheritdoc IERC4626 - function maxMint(address) public view virtual returns (uint256) { - uint256 assets = maxDeposit(address(0)); - if (assets == type(uint256).max) return type(uint256).max; - return _convertToShares(assets, Rounding.DOWN); - } - - ///@inheritdoc IERC4626 - function maxWithdraw(address owner) public view virtual returns (uint256) { - uint256 shares = maxRedeem(owner); - return _convertToAssets(shares, Rounding.DOWN); - } - - ///@inheritdoc IERC4626 - function maxRedeem(address owner) public view virtual returns (uint256) { - address cachedATokenUnderlying = _aTokenUnderlying; - DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(cachedATokenUnderlying); - - // if paused or inactive users cannot withdraw underlying - if ( - !ReserveConfiguration.getActive(reserveData.configuration) || - ReserveConfiguration.getPaused(reserveData.configuration) - ) { - return 0; - } - - // otherwise users can withdraw up to the available amount - uint256 underlyingTokenBalanceInShares = _convertToShares( - IERC20(cachedATokenUnderlying).balanceOf(reserveData.aTokenAddress), - Rounding.DOWN - ); - uint256 cachedUserBalance = balanceOf[owner]; - return - underlyingTokenBalanceInShares >= cachedUserBalance - ? cachedUserBalance - : underlyingTokenBalanceInShares; - } - - ///@inheritdoc IERC4626 - function maxDeposit(address) public view virtual returns (uint256) { - DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(_aTokenUnderlying); - - // if inactive, paused or frozen users cannot deposit underlying - if ( - !ReserveConfiguration.getActive(reserveData.configuration) || - ReserveConfiguration.getPaused(reserveData.configuration) || - ReserveConfiguration.getFrozen(reserveData.configuration) - ) { - return 0; - } - - uint256 supplyCap = ReserveConfiguration.getSupplyCap(reserveData.configuration) * - (10 ** ReserveConfiguration.getDecimals(reserveData.configuration)); - // if no supply cap deposit is unlimited - if (supplyCap == 0) return type(uint256).max; - // return remaining supply cap margin - uint256 currentSupply = (IAToken(reserveData.aTokenAddress).scaledTotalSupply() + - reserveData.accruedToTreasury).rayMulRoundUp(_getNormalizedIncome(reserveData)); - return currentSupply > supplyCap ? 0 : supplyCap - currentSupply; - } - - ///@inheritdoc IERC4626 - function deposit(uint256 assets, address receiver) external virtual returns (uint256) { - (uint256 shares, ) = _deposit(msg.sender, receiver, 0, assets, 0, true); - return shares; - } - - ///@inheritdoc IERC4626 - function mint(uint256 shares, address receiver) external virtual returns (uint256) { - (, uint256 assets) = _deposit(msg.sender, receiver, shares, 0, 0, true); - - return assets; - } - - ///@inheritdoc IERC4626 - function withdraw( - uint256 assets, - address receiver, - address owner - ) external virtual returns (uint256) { - (uint256 shares, ) = _withdraw(owner, receiver, 0, assets, true); - - return shares; - } - - ///@inheritdoc IERC4626 - function redeem( - uint256 shares, - address receiver, - address owner - ) external virtual returns (uint256) { - (, uint256 assets) = _withdraw(owner, receiver, shares, 0, true); - - return assets; - } - - ///@inheritdoc IStaticATokenLM - function redeem( - uint256 shares, - address receiver, - address owner, - bool withdrawFromAave - ) external virtual returns (uint256, uint256) { - return _withdraw(owner, receiver, shares, 0, withdrawFromAave); - } - - function _deposit( - address depositor, - address receiver, - uint256 _shares, - uint256 _assets, - uint16 referralCode, - bool depositToAave - ) internal returns (uint256, uint256) { - require(receiver != address(0), StaticATokenErrors.INVALID_RECIPIENT); - require(_shares == 0 || _assets == 0, StaticATokenErrors.ONLY_ONE_AMOUNT_FORMAT_ALLOWED); - - uint256 assets = _assets; - uint256 shares = _shares; - if (shares > 0) { - if (depositToAave) { - require(shares <= maxMint(receiver), 'ERC4626: mint more than max'); - } - assets = previewMint(shares); - } else { - if (depositToAave) { - require(assets <= maxDeposit(receiver), 'ERC4626: deposit more than max'); - } - shares = previewDeposit(assets); - } - require(shares != 0, StaticATokenErrors.INVALID_ZERO_AMOUNT); - - if (depositToAave) { - address cachedATokenUnderlying = _aTokenUnderlying; - IERC20(cachedATokenUnderlying).safeTransferFrom(depositor, address(this), assets); - POOL.deposit(cachedATokenUnderlying, assets, address(this), referralCode); - } else { - _aToken.safeTransferFrom(depositor, address(this), assets); - } - - _mint(receiver, shares); - - emit Deposit(depositor, receiver, assets, shares); - - return (shares, assets); - } - - function _withdraw( - address owner, - address receiver, - uint256 _shares, - uint256 _assets, - bool withdrawFromAave - ) internal returns (uint256, uint256) { - require(receiver != address(0), StaticATokenErrors.INVALID_RECIPIENT); - require(_shares == 0 || _assets == 0, StaticATokenErrors.ONLY_ONE_AMOUNT_FORMAT_ALLOWED); - require(_shares != _assets, StaticATokenErrors.INVALID_ZERO_AMOUNT); - - uint256 assets = _assets; - uint256 shares = _shares; - - if (shares > 0) { - if (withdrawFromAave) { - require(shares <= maxRedeem(owner), 'ERC4626: redeem more than max'); - } - assets = previewRedeem(shares); - } else { - if (withdrawFromAave) { - require(assets <= maxWithdraw(owner), 'ERC4626: withdraw more than max'); - } - shares = previewWithdraw(assets); - } - - if (msg.sender != owner) { - uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; - } - - _burn(owner, shares); - - emit Withdraw(msg.sender, receiver, owner, assets, shares); - - if (withdrawFromAave) { - POOL.withdraw(_aTokenUnderlying, assets, receiver); - } else { - _aToken.safeTransfer(receiver, assets); - } - - return (shares, assets); - } - - /** - * @notice Updates rewards for senders and receiver in a transfer (not updating rewards for address(0)) - * @param from The address of the sender of tokens - * @param to The address of the receiver of tokens - */ - function _beforeTokenTransfer(address from, address to, uint256) internal override { - for (uint256 i = 0; i < _rewardTokens.length; i++) { - address rewardToken = address(_rewardTokens[i]); - uint256 rewardsIndex = getCurrentRewardsIndex(rewardToken); - if (from != address(0)) { - _updateUser(from, rewardsIndex, rewardToken); - } - if (to != address(0) && from != to) { - _updateUser(to, rewardsIndex, rewardToken); - } - } - } - - /** - * @notice Adding the pending rewards to the unclaimed for specific user and updating user index - * @param user The address of the user to update - * @param currentRewardsIndex The current rewardIndex - * @param rewardToken The address of the reward token - */ - function _updateUser(address user, uint256 currentRewardsIndex, address rewardToken) internal { - uint256 balance = balanceOf[user]; - if (balance > 0) { - _userRewardsData[user][rewardToken].unclaimedRewards = _getClaimableRewards( - user, - rewardToken, - balance, - currentRewardsIndex - ).toUint128(); - } - _userRewardsData[user][rewardToken].rewardsIndexOnLastInteraction = currentRewardsIndex - .toUint128(); - } - - /** - * @notice Compute the pending in WAD. Pending is the amount to add (not yet unclaimed) rewards in WAD. - * @param balance The balance of the user - * @param rewardsIndexOnLastInteraction The index which was on the last interaction of the user - * @param currentRewardsIndex The current rewards index in the system - * @param assetUnit One unit of asset (10**decimals) - * @return The amount of pending rewards in WAD - */ - function _getPendingRewards( - uint256 balance, - uint256 rewardsIndexOnLastInteraction, - uint256 currentRewardsIndex, - uint256 assetUnit - ) internal pure returns (uint256) { - if (balance == 0) { - return 0; - } - return (balance * (currentRewardsIndex - rewardsIndexOnLastInteraction)) / assetUnit; - } - - /** - * @notice Compute the claimable rewards for a user - * @param user The address of the user - * @param reward The address of the reward - * @param balance The balance of the user in WAD - * @param currentRewardsIndex The current rewards index - * @return The total rewards that can be claimed by the user (if `fresh` flag true, after updating rewards) - */ - function _getClaimableRewards( - address user, - address reward, - uint256 balance, - uint256 currentRewardsIndex - ) internal view returns (uint256) { - RewardIndexCache memory rewardsIndexCache = _startIndex[reward]; - require(rewardsIndexCache.isRegistered == true, StaticATokenErrors.REWARD_NOT_INITIALIZED); - UserRewardsData memory currentUserRewardsData = _userRewardsData[user][reward]; - uint256 assetUnit = 10 ** decimals; - return - currentUserRewardsData.unclaimedRewards + - _getPendingRewards( - balance, - currentUserRewardsData.rewardsIndexOnLastInteraction == 0 - ? rewardsIndexCache.lastUpdatedIndex - : currentUserRewardsData.rewardsIndexOnLastInteraction, - currentRewardsIndex, - assetUnit - ); - } - - /** - * @notice Claim rewards on behalf of a user and send them to a receiver - * @param onBehalfOf The address to claim on behalf of - * @param rewards The addresses of the rewards - * @param receiver The address to receive the rewards - */ - function _claimRewardsOnBehalf( - address onBehalfOf, - address receiver, - address[] memory rewards - ) internal { - for (uint256 i = 0; i < rewards.length; i++) { - if (address(rewards[i]) == address(0)) { - continue; - } - uint256 currentRewardsIndex = getCurrentRewardsIndex(rewards[i]); - uint256 balance = balanceOf[onBehalfOf]; - uint256 userReward = _getClaimableRewards( - onBehalfOf, - rewards[i], - balance, - currentRewardsIndex - ); - uint256 totalRewardTokenBalance = IERC20(rewards[i]).balanceOf(address(this)); - uint256 unclaimedReward = 0; - - if (userReward > totalRewardTokenBalance) { - totalRewardTokenBalance += collectAndUpdateRewards(address(rewards[i])); - } - - if (userReward > totalRewardTokenBalance) { - unclaimedReward = userReward - totalRewardTokenBalance; - userReward = totalRewardTokenBalance; - } - if (userReward > 0) { - _userRewardsData[onBehalfOf][rewards[i]].unclaimedRewards = unclaimedReward.toUint128(); - _userRewardsData[onBehalfOf][rewards[i]].rewardsIndexOnLastInteraction = currentRewardsIndex - .toUint128(); - IERC20(rewards[i]).safeTransfer(receiver, userReward); - } - } - } - - function _convertToShares(uint256 assets, Rounding rounding) internal view returns (uint256) { - if (rounding == Rounding.UP) return assets.rayDivRoundUp(rate()); - return assets.rayDivRoundDown(rate()); - } - - function _convertToAssets(uint256 shares, Rounding rounding) internal view returns (uint256) { - if (rounding == Rounding.UP) return shares.rayMulRoundUp(rate()); - return shares.rayMulRoundDown(rate()); - } - - /** - * @notice Initializes a new rewardToken - * @param reward The reward token to be registered - */ - function _registerRewardToken(address reward) internal { - if (isRegisteredRewardToken(reward)) return; - uint256 startIndex = getCurrentRewardsIndex(reward); - - _rewardTokens.push(reward); - _startIndex[reward] = RewardIndexCache(true, startIndex.toUint240()); - - emit RewardTokenRegistered(reward, startIndex); - } - - /** - * Copy of https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ReserveLogic.sol#L47 with memory instead of calldata - * @notice Returns the ongoing normalized income for the reserve. - * @dev A value of 1e27 means there is no income. As time passes, the income is accrued - * @dev A value of 2*1e27 means for each unit of asset one unit of income has been accrued - * @param reserve The reserve object - * @return The normalized income, expressed in ray - */ - function _getNormalizedIncome( - DataTypes.ReserveDataLegacy memory reserve - ) internal view returns (uint256) { - uint40 timestamp = reserve.lastUpdateTimestamp; - - //solium-disable-next-line - if (timestamp == block.timestamp) { - //if the index was updated in the same block, no need to perform any calculation - return reserve.liquidityIndex; - } else { - return - MathUtils.calculateLinearInterest(reserve.currentLiquidityRate, timestamp).rayMul( - reserve.liquidityIndex - ); - } - } -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IAToken.sol b/src/contracts/extensions/static-a-token/interfaces/IAToken.sol deleted file mode 100644 index 31e9a805..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IAToken.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -interface IAToken { - function POOL() external view returns (address); - - function getIncentivesController() external view returns (address); - - function UNDERLYING_ASSET_ADDRESS() external view returns (address); - - /** - * @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); -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol b/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol deleted file mode 100644 index 08f14f90..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IERC4626.sol +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) - -pragma solidity ^0.8.10; - -/** - * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in - * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. - * - * _Available since v4.7._ - */ -interface IERC4626 { - 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 unless due to integer overflow caused by an unreasonably large input. - * - * 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. - * While deposit of aToken is not affected by aave pool configrations, deposit of the aTokenUnderlying will need to deposit to aave - * so it is affected by current aave pool configuration. - * Reference: https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ValidationLogic.sol#L57 - * - 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 unless due to integer overflow caused by an unreasonably large input. - */ - 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 to the aToken underlying. - * While redeem of aToken is not affected by aave pool configrations, redeeming of the aTokenUnderlying will need to redeem from aave - * so it is affected by current aave pool configuration. - * Reference: https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/ValidationLogic.sol#L87 - * - 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); -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol b/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol deleted file mode 100644 index 586a935a..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IInitializableStaticATokenLM.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import {IPool} from '../../../interfaces/IPool.sol'; -import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; - -/** - * @title IInitializableStaticATokenLM - * @notice Interface for the initialize function on StaticATokenLM - * @author Aave - **/ -interface IInitializableStaticATokenLM { - /** - * @dev Emitted when a StaticATokenLM is initialized - * @param aToken The address of the underlying aToken (aWETH) - * @param staticATokenName The name of the Static aToken - * @param staticATokenSymbol The symbol of the Static aToken - **/ - event Initialized(address indexed aToken, string staticATokenName, string staticATokenSymbol); - - /** - * @dev Initializes the StaticATokenLM - * @param aToken The address of the underlying aToken (aWETH) - * @param staticATokenName The name of the Static aToken - * @param staticATokenSymbol The symbol of the Static aToken - */ - function initialize( - address aToken, - string calldata staticATokenName, - string calldata staticATokenSymbol - ) external; -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol b/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol deleted file mode 100644 index d08f2a29..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IStataOracle.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import {IPool} from '../../../interfaces/IPool.sol'; -import {IAaveOracle} from '../../../interfaces/IAaveOracle.sol'; - -interface IStataOracle { - /** - * @return The pool used for fetching the rate on the aggregator oracle - */ - function POOL() external view returns (IPool); - - /** - * @return The aave oracle used for fetching the price of the underlying - */ - function AAVE_ORACLE() external view returns (IAaveOracle); - - /** - * @notice Returns the prices of an asset address - * @param asset The asset address - * @return The prices of the given asset - */ - function getAssetPrice(address asset) external view returns (uint256); - - /** - * @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); -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol deleted file mode 100644 index 7532e92c..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenFactory.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -interface IStaticATokenFactory { - /** - * @notice Creates new staticATokens - * @param underlyings the addresses of the underlyings to create. - * @return address[] addresses of the new staticATokens. - */ - function createStaticATokens(address[] memory underlyings) external returns (address[] memory); - - /** - * @notice Returns all tokens deployed via this registry. - * @return address[] list of tokens - */ - function getStaticATokens() external view returns (address[] memory); - - /** - * @notice Returns the staticAToken for a given underlying. - * @param underlying the address of the underlying. - * @return address the staticAToken address. - */ - function getStaticAToken(address underlying) external view returns (address); -} diff --git a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol b/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol deleted file mode 100644 index eed469f3..00000000 --- a/src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {IInitializableStaticATokenLM} from './IInitializableStaticATokenLM.sol'; - -interface IStaticATokenLM is IInitializableStaticATokenLM { - struct SignatureParams { - uint8 v; - bytes32 r; - bytes32 s; - } - - struct PermitParams { - address owner; - address spender; - uint256 value; - uint256 deadline; - uint8 v; - bytes32 r; - bytes32 s; - } - - struct UserRewardsData { - uint128 rewardsIndexOnLastInteraction; // (in RAYs) - uint128 unclaimedRewards; // (in RAYs) - } - - struct RewardIndexCache { - bool isRegistered; - uint248 lastUpdatedIndex; - } - - event RewardTokenRegistered(address indexed reward, uint256 startIndex); - - /** - * @notice Burns `amount` of static aToken, with receiver receiving the corresponding amount of `ASSET` - * @param shares The amount to withdraw, in static balance of StaticAToken - * @param receiver The address that will receive the amount of `ASSET` withdrawn from the Aave protocol - * @param withdrawFromAave bool - * - `true` for the receiver to get underlying tokens (e.g. USDC) - * - `false` for the receiver to get aTokens (e.g. aUSDC) - * @return amountToBurn: StaticATokens burnt, static balance - * @return amountToWithdraw: underlying/aToken send to `receiver`, dynamic balance - **/ - function redeem( - uint256 shares, - address receiver, - address owner, - bool withdrawFromAave - ) external returns (uint256, uint256); - - /** - * @notice Deposits `ASSET` in the Aave protocol and mints static aTokens to msg.sender - * @param assets The amount of underlying `ASSET` to deposit (e.g. deposit of 100 USDC) - * @param receiver The address that will receive the static 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 - * @param depositToAave bool - * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) - * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) - * @return uint256 The amount of StaticAToken minted, static balance - **/ - function deposit( - uint256 assets, - address receiver, - uint16 referralCode, - bool depositToAave - ) external returns (uint256); - - /** - * @notice Allows to deposit on Aave via meta-transaction - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param depositor Address from which the funds to deposit are going to be pulled - * @param receiver Address that will receive the staticATokens, in the average case, same as the `depositor` - * @param assets The amount to deposit - * @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 depositToAave bool - * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) - * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param sigParams Signature params: v,r,s - * @return uint256 The amount of StaticAToken minted, static balance - */ - function metaDeposit( - address depositor, - address receiver, - uint256 assets, - uint16 referralCode, - bool depositToAave, - uint256 deadline, - PermitParams calldata permit, - SignatureParams calldata sigParams - ) external returns (uint256); - - /** - * @notice Allows to withdraw from Aave via meta-transaction - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param owner Address owning the staticATokens - * @param receiver Address that will receive the underlying withdrawn from Aave - * @param shares The amount of staticAToken to withdraw. If > 0, `assets` needs to be 0 - * @param assets The amount of underlying/aToken to withdraw. If > 0, `shares` needs to be 0 - * @param withdrawFromAave bool - * - `true` for the receiver to get underlying tokens (e.g. USDC) - * - `false` for the receiver to get aTokens (e.g. aUSDC) - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param sigParams Signature params: v,r,s - * @return amountToBurn: StaticATokens burnt, static balance - * @return amountToWithdraw: underlying/aToken send to `receiver`, dynamic balance - */ - function metaWithdraw( - address owner, - address receiver, - uint256 shares, - uint256 assets, - bool withdrawFromAave, - uint256 deadline, - SignatureParams calldata sigParams - ) external returns (uint256, uint256); - - /** - * @notice Returns the Aave liquidity index of the underlying aToken, denominated rate here - * as it can be considered as an ever-increasing exchange rate - * @return The liquidity index - **/ - function rate() external view returns (uint256); - - /** - * @notice Claims rewards from `INCENTIVES_CONTROLLER` and updates internal accounting of rewards. - * @param reward The reward to claim - * @return uint256 Amount collected - */ - function collectAndUpdateRewards(address reward) external returns (uint256); - - /** - * @notice Claim rewards on behalf of a user and send them to a receiver - * @dev Only callable by if sender is onBehalfOf or sender is approved claimer - * @param onBehalfOf The address to claim on behalf of - * @param receiver The address to receive the rewards - * @param rewards The rewards to claim - */ - function claimRewardsOnBehalf( - address onBehalfOf, - address receiver, - address[] memory rewards - ) external; - - /** - * @notice Claim rewards and send them to a receiver - * @param receiver The address to receive the rewards - * @param rewards The rewards to claim - */ - function claimRewards(address receiver, address[] memory rewards) external; - - /** - * @notice Claim rewards - * @param rewards The rewards to claim - */ - function claimRewardsToSelf(address[] memory rewards) external; - - /** - * @notice Get the total claimable rewards of the contract. - * @param reward The reward to claim - * @return uint256 The current balance + pending rewards from the `_incentivesController` - */ - function getTotalClaimableRewards(address reward) external view returns (uint256); - - /** - * @notice Get the total claimable rewards for a user in WAD - * @param user The address of the user - * @param reward The reward to claim - * @return uint256 The claimable amount of rewards in WAD - */ - function getClaimableRewards(address user, address reward) external view returns (uint256); - - /** - * @notice The unclaimed rewards for a user in WAD - * @param user The address of the user - * @param reward The reward to claim - * @return uint256 The unclaimed amount of rewards in WAD - */ - function getUnclaimedRewards(address user, address reward) external view returns (uint256); - - /** - * @notice The underlying asset reward index in RAY - * @param reward The reward to claim - * @return uint256 The underlying asset reward index in RAY - */ - function getCurrentRewardsIndex(address reward) external view returns (uint256); - - /** - * @notice The aToken used inside the 4626 vault. - * @return IERC20 The aToken IERC20. - */ - function aToken() external view returns (IERC20); - - /** - * @notice The IERC20s that are currently rewarded to addresses of the vault via LM on incentivescontroller. - * @return IERC20 The IERC20s of the rewards. - */ - function rewardTokens() external view returns (address[] memory); - - /** - * @notice Fetches all rewardTokens from the incentivecontroller and registers the missing ones. - */ - function refreshRewardTokens() external; - - /** - * @notice Checks if the passed token is a registered reward. - * @return bool signaling if token is a registered reward. - */ - function isRegisteredRewardToken(address reward) external view returns (bool); -} diff --git a/src/contracts/misc/libraries/RayMathExplicitRounding.sol b/src/contracts/misc/libraries/RayMathExplicitRounding.sol deleted file mode 100644 index 8d3f3dcb..00000000 --- a/src/contracts/misc/libraries/RayMathExplicitRounding.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity ^0.8.10; - -enum Rounding { - UP, - DOWN -} - -/** - * Simplified version of RayMath that instead of half-up rounding does explicit rounding in a specified direction. - * This is needed to have a 4626 complient implementation, that always predictable rounds in favor of the vault / static a token. - */ -library RayMathExplicitRounding { - uint256 internal constant RAY = 1e27; - uint256 internal constant WAD_RAY_RATIO = 1e9; - - function rayMulRoundDown(uint256 a, uint256 b) internal pure returns (uint256) { - if (a == 0 || b == 0) { - return 0; - } - return (a * b) / RAY; - } - - function rayMulRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { - if (a == 0 || b == 0) { - return 0; - } - return ((a * b) + RAY - 1) / RAY; - } - - function rayDivRoundDown(uint256 a, uint256 b) internal pure returns (uint256) { - return (a * RAY) / b; - } - - function rayDivRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { - return ((a * RAY) + b - 1) / b; - } - - function rayToWadRoundDown(uint256 a) internal pure returns (uint256) { - return a / WAD_RAY_RATIO; - } -} diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol deleted file mode 100644 index 7ff449f2..00000000 --- a/src/deployments/contracts/procedures/AaveV3HelpersProcedureOne.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import {Create2Utils} from '../utilities/Create2Utils.sol'; -import {ConfigEngineReport} from '../../interfaces/IMarketReportTypes.sol'; -import {AaveV3ConfigEngine, IAaveV3ConfigEngine, CapsEngine, BorrowEngine, CollateralEngine, RateEngine, PriceFeedEngine, EModeEngine, ListingEngine} from '../../../contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; -import {IPool} from '../../../contracts/interfaces/IPool.sol'; -import {IPoolConfigurator} from '../../../contracts/interfaces/IPoolConfigurator.sol'; -import {IAaveOracle} from '../../../contracts/interfaces/IAaveOracle.sol'; - -contract AaveV3HelpersProcedureOne { - function _deployConfigEngine( - address pool, - address poolConfigurator, - address defaultInterestRateStrategy, - address aaveOracle, - address rewardsController, - address collector, - address aTokenImpl, - address vTokenImpl, - address sTokenImpl - ) internal returns (ConfigEngineReport memory configEngineReport) { - IAaveV3ConfigEngine.EngineLibraries memory engineLibraries = IAaveV3ConfigEngine - .EngineLibraries({ - listingEngine: Create2Utils._create2Deploy('v1', type(ListingEngine).creationCode), - eModeEngine: Create2Utils._create2Deploy('v1', type(EModeEngine).creationCode), - borrowEngine: Create2Utils._create2Deploy('v1', type(BorrowEngine).creationCode), - collateralEngine: Create2Utils._create2Deploy('v1', type(CollateralEngine).creationCode), - priceFeedEngine: Create2Utils._create2Deploy('v1', type(PriceFeedEngine).creationCode), - rateEngine: Create2Utils._create2Deploy('v1', type(RateEngine).creationCode), - capsEngine: Create2Utils._create2Deploy('v1', type(CapsEngine).creationCode) - }); - - IAaveV3ConfigEngine.EngineConstants memory engineConstants = IAaveV3ConfigEngine - .EngineConstants({ - pool: IPool(pool), - poolConfigurator: IPoolConfigurator(poolConfigurator), - defaultInterestRateStrategy: defaultInterestRateStrategy, - oracle: IAaveOracle(aaveOracle), - rewardsController: rewardsController, - collector: collector - }); - - configEngineReport.listingEngine = engineLibraries.listingEngine; - configEngineReport.eModeEngine = engineLibraries.eModeEngine; - configEngineReport.borrowEngine = engineLibraries.borrowEngine; - configEngineReport.collateralEngine = engineLibraries.collateralEngine; - configEngineReport.priceFeedEngine = engineLibraries.priceFeedEngine; - configEngineReport.rateEngine = engineLibraries.rateEngine; - configEngineReport.capsEngine = engineLibraries.capsEngine; - - configEngineReport.configEngine = address( - new AaveV3ConfigEngine(aTokenImpl, vTokenImpl, sTokenImpl, engineConstants, engineLibraries) - ); - return configEngineReport; - } -} diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol deleted file mode 100644 index 9a92839a..00000000 --- a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../interfaces/IMarketReportTypes.sol'; -import {TransparentProxyFactory, ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; -import {StaticATokenLM} from '../../../contracts/extensions/static-a-token/StaticATokenLM.sol'; -import {StaticATokenFactory} from '../../../contracts/extensions/static-a-token/StaticATokenFactory.sol'; -import {IErrors} from '../../interfaces/IErrors.sol'; - -contract AaveV3HelpersProcedureTwo is IErrors { - function _deployStaticAToken( - address pool, - address rewardsController, - address proxyAdmin - ) internal returns (StaticATokenReport memory staticATokenReport) { - if (proxyAdmin == address(0)) revert ProxyAdminNotFound(); - - staticATokenReport.transparentProxyFactory = address(new TransparentProxyFactory()); - staticATokenReport.staticATokenImplementation = address( - new StaticATokenLM(IPool(pool), IRewardsController(rewardsController)) - ); - staticATokenReport.staticATokenFactoryImplementation = address( - new StaticATokenFactory( - IPool(pool), - proxyAdmin, - ITransparentProxyFactory(staticATokenReport.transparentProxyFactory), - staticATokenReport.staticATokenImplementation - ) - ); - - staticATokenReport.staticATokenFactoryProxy = ITransparentProxyFactory( - staticATokenReport.transparentProxyFactory - ).create( - staticATokenReport.staticATokenFactoryImplementation, - proxyAdmin, - abi.encodeWithSelector(StaticATokenFactory.initialize.selector) - ); - - return staticATokenReport; - } -} diff --git a/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol b/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol deleted file mode 100644 index bd6bac8b..00000000 --- a/src/deployments/contracts/procedures/AaveV3MiscProcedure.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../interfaces/IMarketReportTypes.sol'; -import {PriceOracleSentinel, ISequencerOracle} from '../../../contracts/misc/PriceOracleSentinel.sol'; -import {DefaultReserveInterestRateStrategyV2} from '../../../contracts/misc/DefaultReserveInterestRateStrategyV2.sol'; -import {IErrors} from '../../interfaces/IErrors.sol'; - -contract AaveV3MiscProcedure is IErrors { - function _deploySentinelAndDefaultIR( - bool l2Flag, - address poolAddressesProvider, - address sequencerUptimeOracle, - uint256 gracePeriod - ) internal returns (MiscReport memory miscReport) { - if (poolAddressesProvider == address(0)) revert ProviderNotFound(); - - if (l2Flag && sequencerUptimeOracle != address(0) && gracePeriod != 0) { - miscReport.priceOracleSentinel = address( - new PriceOracleSentinel( - IPoolAddressesProvider(poolAddressesProvider), - ISequencerOracle(sequencerUptimeOracle), - gracePeriod - ) - ); - } - - miscReport.defaultInterestRateStrategy = address( - new DefaultReserveInterestRateStrategyV2(poolAddressesProvider) - ); - - return miscReport; - } -} diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index 9d85884b..7f48b649 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -38,8 +38,7 @@ contract AaveV3SetupProcedure { address poolConfiguratorImplementation, address protocolDataProvider, address aaveOracle, - address rewardsControllerImplementation, - address priceOracleSentinel + address rewardsControllerImplementation ) internal returns (SetupReport memory) { _validateMarketSetup(roles); @@ -50,8 +49,7 @@ contract AaveV3SetupProcedure { protocolDataProvider, roles.poolAdmin, aaveOracle, - rewardsControllerImplementation, - priceOracleSentinel + rewardsControllerImplementation ); report.aclManager = _setupACL( @@ -96,8 +94,7 @@ contract AaveV3SetupProcedure { address protocolDataProvider, address poolAdmin, address aaveOracle, - address rewardsControllerImplementation, - address priceOracleSentinel + address rewardsControllerImplementation ) internal returns (SetupReport memory) { SetupReport memory report; @@ -110,10 +107,6 @@ contract AaveV3SetupProcedure { report.poolProxy = address(provider.getPool()); report.poolConfiguratorProxy = address(provider.getPoolConfigurator()); - if (priceOracleSentinel != address(0)) { - provider.setPriceOracleSentinel(priceOracleSentinel); - } - bytes32 controllerId = keccak256('INCENTIVES_CONTROLLER'); provider.setAddressAsProxy(controllerId, rewardsControllerImplementation); report.rewardsControllerProxy = provider.getAddress(controllerId); diff --git a/src/deployments/contracts/utilities/MetadataReporter.sol b/src/deployments/contracts/utilities/MetadataReporter.sol index 27b5085c..a4dfb787 100644 --- a/src/deployments/contracts/utilities/MetadataReporter.sol +++ b/src/deployments/contracts/utilities/MetadataReporter.sol @@ -57,6 +57,11 @@ contract MetadataReporter is IMetadataReporter { vm.serializeAddress(jsonReport, 'rewardsControllerProxy', report.rewardsControllerProxy); vm.serializeAddress(jsonReport, 'aclManager', report.aclManager); vm.serializeAddress(jsonReport, 'protocolDataProvider', report.protocolDataProvider); + vm.serializeAddress( + jsonReport, + 'defaultInterestRateStrategy', + report.defaultInterestRateStrategy + ); vm.serializeAddress( jsonReport, @@ -69,25 +74,6 @@ contract MetadataReporter is IMetadataReporter { report.paraSwapWithdrawSwapAdapter ); vm.serializeAddress(jsonReport, 'aaveParaSwapFeeClaimer', report.aaveParaSwapFeeClaimer); - vm.serializeAddress( - jsonReport, - 'defaultInterestRateStrategy', - report.defaultInterestRateStrategy - ); - vm.serializeAddress(jsonReport, 'priceOracleSentinel', report.priceOracleSentinel); - vm.serializeAddress(jsonReport, 'configEngine', report.configEngine); - vm.serializeAddress( - jsonReport, - 'staticATokenFactoryImplementation', - report.staticATokenFactoryImplementation - ); - vm.serializeAddress(jsonReport, 'staticATokenFactoryProxy', report.staticATokenFactoryProxy); - vm.serializeAddress( - jsonReport, - 'staticATokenImplementation', - report.staticATokenImplementation - ); - vm.serializeAddress(jsonReport, 'transparentProxyFactory', report.transparentProxyFactory); string memory output = vm.serializeAddress( jsonReport, diff --git a/src/deployments/interfaces/IMarketReportTypes.sol b/src/deployments/interfaces/IMarketReportTypes.sol index b838a0db..4d0d3967 100644 --- a/src/deployments/interfaces/IMarketReportTypes.sol +++ b/src/deployments/interfaces/IMarketReportTypes.sol @@ -65,7 +65,6 @@ struct MarketReport { address protocolDataProvider; address aaveOracle; address defaultInterestRateStrategy; - address priceOracleSentinel; address aclManager; address treasury; address proxyAdmin; @@ -85,11 +84,6 @@ struct MarketReport { address emissionManager; address rewardsControllerImplementation; address rewardsControllerProxy; - address configEngine; - address transparentProxyFactory; - address staticATokenFactoryImplementation; - address staticATokenFactoryProxy; - address staticATokenImplementation; } struct LibrariesReport { @@ -116,8 +110,6 @@ struct MarketConfig { uint8 oracleDecimals; address paraswapAugustusRegistry; address paraswapFeeClaimer; - address l2SequencerUptimeFeed; - uint256 l2PriceOracleSentinelGracePeriod; uint256 providerId; bytes32 salt; address wrappedNativeToken; @@ -135,29 +127,6 @@ struct PoolReport { address poolConfiguratorImplementation; } -struct MiscReport { - address priceOracleSentinel; - address defaultInterestRateStrategy; -} - -struct ConfigEngineReport { - address configEngine; - address listingEngine; - address eModeEngine; - address borrowEngine; - address collateralEngine; - address priceFeedEngine; - address rateEngine; - address capsEngine; -} - -struct StaticATokenReport { - address transparentProxyFactory; - address staticATokenImplementation; - address staticATokenFactoryImplementation; - address staticATokenFactoryProxy; -} - struct InitialReport { address poolAddressesProvider; address poolAddressesProviderRegistry; @@ -177,6 +146,7 @@ struct PeripheryReport { address treasuryImplementation; address emissionManager; address rewardsControllerImplementation; + address defaultInterestRateStrategy; } struct ParaswapReport { diff --git a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol index ec93fc80..39b50d94 100644 --- a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol +++ b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol @@ -10,9 +10,6 @@ import {AaveV3GettersProcedureTwo} from '../../contracts/procedures/AaveV3Getter import {AaveV3PeripheryBatch} from './batches/AaveV3PeripheryBatch.sol'; import {AaveV3ParaswapBatch} from './batches/AaveV3ParaswapBatch.sol'; import {AaveV3SetupBatch} from './batches/AaveV3SetupBatch.sol'; -import {AaveV3HelpersBatchOne} from './batches/AaveV3HelpersBatchOne.sol'; -import {AaveV3HelpersBatchTwo} from './batches/AaveV3HelpersBatchTwo.sol'; -import {AaveV3MiscBatch} from './batches/AaveV3MiscBatch.sol'; import '../../interfaces/IMarketReportTypes.sol'; import {IMarketReportStorage} from '../../interfaces/IMarketReportStorage.sol'; import {IPoolReport} from '../../interfaces/IPoolReport.sol'; @@ -55,13 +52,6 @@ library AaveV3BatchOrchestration { address(setupBatch) ); - MiscReport memory miscReport = _deployMisc( - flags.l2, - initialReport.poolAddressesProvider, - config.l2SequencerUptimeFeed, - config.l2PriceOracleSentinelGracePeriod - ); - SetupReport memory setupReport = setupBatch.setupAaveV3Market( roles, config, @@ -69,8 +59,7 @@ library AaveV3BatchOrchestration { poolReport.poolConfiguratorImplementation, gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, - peripheryReport.rewardsControllerImplementation, - miscReport.priceOracleSentinel + peripheryReport.rewardsControllerImplementation ); ParaswapReport memory paraswapReport = _deployParaswapAdapters( @@ -89,19 +78,6 @@ library AaveV3BatchOrchestration { AaveV3TokensBatch.TokensReport memory tokensReport = _deployTokens(setupReport.poolProxy); - ConfigEngineReport memory configEngineReport = _deployHelpersBatch1( - setupReport, - miscReport, - peripheryReport, - tokensReport - ); - - StaticATokenReport memory staticATokenReport = _deployHelpersBatch2( - setupReport.poolProxy, - setupReport.rewardsControllerProxy, - peripheryReport.proxyAdmin - ); - // Save final report at AaveV3SetupBatch contract MarketReport memory report = _generateMarketReport( initialReport, @@ -109,12 +85,9 @@ library AaveV3BatchOrchestration { gettersReport2, poolReport, peripheryReport, - miscReport, paraswapReport, setupReport, - tokensReport, - configEngineReport, - staticATokenReport + tokensReport ); setupBatch.setMarketReport(report); @@ -164,57 +137,6 @@ library AaveV3BatchOrchestration { }); } - function _deployHelpersBatch1( - SetupReport memory setupReport, - MiscReport memory miscReport, - PeripheryReport memory peripheryReport, - AaveV3TokensBatch.TokensReport memory tokensReport - ) internal returns (ConfigEngineReport memory) { - AaveV3HelpersBatchOne helpersBatchOne = new AaveV3HelpersBatchOne( - setupReport.poolProxy, - setupReport.poolConfiguratorProxy, - miscReport.defaultInterestRateStrategy, - peripheryReport.aaveOracle, - setupReport.rewardsControllerProxy, - peripheryReport.treasury, - tokensReport.aToken, - tokensReport.variableDebtToken, - tokensReport.stableDebtToken - ); - - return helpersBatchOne.getConfigEngineReport(); - } - - function _deployHelpersBatch2( - address pool, - address rewardsController, - address proxyAdmin - ) internal returns (StaticATokenReport memory) { - AaveV3HelpersBatchTwo helpersBatchTwo = new AaveV3HelpersBatchTwo( - pool, - rewardsController, - proxyAdmin - ); - - return helpersBatchTwo.staticATokenReport(); - } - - function _deployMisc( - bool l2Flag, - address poolAddressesProvider, - address sequencerUptimeOracle, - uint256 gracePeriod - ) internal returns (MiscReport memory) { - AaveV3MiscBatch miscBatch = new AaveV3MiscBatch( - l2Flag, - poolAddressesProvider, - sequencerUptimeOracle, - gracePeriod - ); - - return miscBatch.getMiscReport(); - } - function _deployPoolImplementations( address poolAddressesProvider, DeployFlags memory flags @@ -285,12 +207,9 @@ library AaveV3BatchOrchestration { AaveV3GettersBatchTwo.GettersReportBatchTwo memory gettersReportTwo, PoolReport memory poolReport, PeripheryReport memory peripheryReport, - MiscReport memory miscReport, ParaswapReport memory paraswapReport, SetupReport memory setupReport, - AaveV3TokensBatch.TokensReport memory tokensReport, - ConfigEngineReport memory configEngineReport, - StaticATokenReport memory staticATokenReport + AaveV3TokensBatch.TokensReport memory tokensReport ) internal pure returns (MarketReport memory) { MarketReport memory report; @@ -321,13 +240,7 @@ library AaveV3BatchOrchestration { report.aToken = tokensReport.aToken; report.variableDebtToken = tokensReport.variableDebtToken; report.stableDebtToken = tokensReport.stableDebtToken; - report.priceOracleSentinel = miscReport.priceOracleSentinel; - report.defaultInterestRateStrategy = miscReport.defaultInterestRateStrategy; - report.configEngine = configEngineReport.configEngine; - report.staticATokenFactoryImplementation = staticATokenReport.staticATokenFactoryImplementation; - report.staticATokenFactoryProxy = staticATokenReport.staticATokenFactoryProxy; - report.staticATokenImplementation = staticATokenReport.staticATokenImplementation; - report.transparentProxyFactory = staticATokenReport.transparentProxyFactory; + report.defaultInterestRateStrategy = peripheryReport.defaultInterestRateStrategy; return report; } diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol deleted file mode 100644 index f841b657..00000000 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import {AaveV3HelpersProcedureOne} from '../../../contracts/procedures/AaveV3HelpersProcedureOne.sol'; -import '../../../interfaces/IMarketReportTypes.sol'; - -contract AaveV3HelpersBatchOne is AaveV3HelpersProcedureOne { - ConfigEngineReport internal _report; - - constructor( - address poolProxy, - address poolConfiguratorProxy, - address defaultInterestRateStrategy, - address aaveOracle, - address rewardsController, - address collector, - address aTokenImpl, - address vTokenImpl, - address sTokenImpl - ) { - _report = _deployConfigEngine( - poolProxy, - poolConfiguratorProxy, - defaultInterestRateStrategy, - aaveOracle, - rewardsController, - collector, - aTokenImpl, - vTokenImpl, - sTokenImpl - ); - } - - function getConfigEngineReport() external view returns (ConfigEngineReport memory) { - return _report; - } -} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol deleted file mode 100644 index 1db9f7b9..00000000 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import {AaveV3HelpersProcedureTwo} from '../../../contracts/procedures/AaveV3HelpersProcedureTwo.sol'; -import '../../../interfaces/IMarketReportTypes.sol'; - -contract AaveV3HelpersBatchTwo is AaveV3HelpersProcedureTwo { - StaticATokenReport internal _report; - - constructor(address pool, address rewardsController, address proxyAdmin) { - _report = _deployStaticAToken(pool, rewardsController, proxyAdmin); - } - - function staticATokenReport() external view returns (StaticATokenReport memory) { - return _report; - } -} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol deleted file mode 100644 index a841d76a..00000000 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import {AaveV3MiscProcedure} from '../../../contracts/procedures/AaveV3MiscProcedure.sol'; -import '../../../interfaces/IMarketReportTypes.sol'; - -contract AaveV3MiscBatch is AaveV3MiscProcedure { - MiscReport internal _report; - - constructor( - bool l2Flag, - address poolAddressesProvider, - address sequencerUptimeOracle, - uint256 gracePeriod - ) { - MiscReport memory miscReport = _deploySentinelAndDefaultIR( - l2Flag, - poolAddressesProvider, - sequencerUptimeOracle, - gracePeriod - ); - _report.priceOracleSentinel = miscReport.priceOracleSentinel; - _report.defaultInterestRateStrategy = miscReport.defaultInterestRateStrategy; - } - - function getMiscReport() external view returns (MiscReport memory) { - return _report; - } -} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index f2a3ec54..8ec0c136 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -4,12 +4,14 @@ pragma solidity ^0.8.0; import {AaveV3TreasuryProcedure} from '../../../contracts/procedures/AaveV3TreasuryProcedure.sol'; import {AaveV3OracleProcedure} from '../../../contracts/procedures/AaveV3OracleProcedure.sol'; import {AaveV3IncentiveProcedure} from '../../../contracts/procedures/AaveV3IncentiveProcedure.sol'; +import {AaveV3DefaultRateStrategyProcedure} from '../../../contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol'; import '../../../interfaces/IMarketReportTypes.sol'; contract AaveV3PeripheryBatch is AaveV3TreasuryProcedure, AaveV3OracleProcedure, - AaveV3IncentiveProcedure + AaveV3IncentiveProcedure, + AaveV3DefaultRateStrategyProcedure { PeripheryReport internal _report; @@ -32,6 +34,8 @@ contract AaveV3PeripheryBatch is (_report.emissionManager, _report.rewardsControllerImplementation) = _deployIncentives( setupBatch ); + + _report.defaultInterestRateStrategy = _deployDefaultRateStrategyV2(poolAddressesProvider); } function getPeripheryReport() external view returns (PeripheryReport memory) { diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol index abed9a61..f62bcd4f 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol @@ -32,8 +32,7 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable address poolConfiguratorImplementation, address protocolDataProvider, address aaveOracle, - address rewardsControllerImplementation, - address priceOracleSentinel + address rewardsControllerImplementation ) external onlyOwner returns (SetupReport memory) { _setupReport = _setupAaveV3Market( roles, @@ -43,8 +42,7 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable poolConfiguratorImplementation, protocolDataProvider, aaveOracle, - rewardsControllerImplementation, - priceOracleSentinel + rewardsControllerImplementation ); return _setupReport; diff --git a/tests/deployments/AaveV3BatchDeployment.t.sol b/tests/deployments/AaveV3BatchDeployment.t.sol index aa0cf2d2..55c5a81d 100644 --- a/tests/deployments/AaveV3BatchDeployment.t.sol +++ b/tests/deployments/AaveV3BatchDeployment.t.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {ConfigEngineDeployer} from '../utils/ConfigEngineDeployer.sol'; + import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; import {MockParaSwapFeeClaimer} from '../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; import {BatchTestProcedures} from '../utils/BatchTestProcedures.sol'; @@ -20,12 +22,14 @@ contract AaveV3BatchDeployment is BatchTestProcedures { address public emergencyAdmin; Roles public roles; + MarketConfig public config; DeployFlags public flags; - MarketConfig config; MarketReport deployedContracts; address public weth9; + event ReportLog(MarketReport report); + function setUp() public { bytes32 emptySalt; weth9 = address(new WETH9()); @@ -41,8 +45,6 @@ contract AaveV3BatchDeployment is BatchTestProcedures { 8, address(new AugustusRegistryMock()), address(new MockParaSwapFeeClaimer()), - address(0), // l2SequencerUptimeFeed - 0, // l2PriceOracleSentinelGracePeriod 8080, emptySalt, weth9, @@ -62,8 +64,9 @@ contract AaveV3BatchDeployment is BatchTestProcedures { ); checkFullReport(flags, fullReport); + address engine = ConfigEngineDeployer.deployEngine(vm, fullReport); AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(fullReport.configEngine), + IAaveV3ConfigEngine(engine), marketOwner, weth9, fullReport @@ -79,8 +82,6 @@ contract AaveV3BatchDeployment is BatchTestProcedures { function testAaveV3L2BatchDeploymentCheck() public { flags.l2 = true; - config.l2SequencerUptimeFeed = address(new SequencerOracle(poolAdmin)); - config.l2PriceOracleSentinelGracePeriod = 2 hours; MarketReport memory fullReport = deployAaveV3Testnet( marketOwner, @@ -92,8 +93,9 @@ contract AaveV3BatchDeployment is BatchTestProcedures { checkFullReport(flags, fullReport); + address engine = ConfigEngineDeployer.deployEngine(vm, fullReport); AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(fullReport.configEngine), + IAaveV3ConfigEngine(engine), marketOwner, weth9, fullReport diff --git a/tests/deployments/AaveV3BatchTests.t.sol b/tests/deployments/AaveV3BatchTests.t.sol index 99a41eac..254db0d1 100644 --- a/tests/deployments/AaveV3BatchTests.t.sol +++ b/tests/deployments/AaveV3BatchTests.t.sol @@ -10,9 +10,6 @@ import {AaveV3GettersBatchTwo} from '../../src/deployments/projects/aave-v3-batc import {AaveV3PeripheryBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; import {AaveV3ParaswapBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; import {AaveV3SetupBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; -import {AaveV3MiscBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol'; -import {AaveV3HelpersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol'; -import {AaveV3HelpersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol'; import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; import {MockParaSwapFeeClaimer} from 'src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; @@ -37,15 +34,13 @@ contract AaveV3BatchTests is BatchTestProcedures { PeripheryReport peripheryReportOne; ParaswapReport paraswapReportOne; - MiscReport miscReport; - ConfigEngineReport configEngineReport; - StaticATokenReport staticATokenReport; - AaveV3TokensBatch.TokensReport tokensReport; SetupReport setupReportTwo; AaveV3SetupBatch aaveV3SetupOne; + event ReportLog(MarketReport report); + function setUp() public { deployer = makeAddr('deployer'); marketOwner = makeAddr('marketOwner'); @@ -60,8 +55,6 @@ contract AaveV3BatchTests is BatchTestProcedures { 8, address(new AugustusRegistryMock()), address(new MockParaSwapFeeClaimer()), - address(0), // l2SequencerUptimeFeed - 0, // l2PriceOracleSentinelGracePeriod 8080, emptySalt, address(new WETH9()), @@ -71,33 +64,20 @@ contract AaveV3BatchTests is BatchTestProcedures { ); flags = DeployFlags(false); - // Etch the create2 factory - vm.etch( - 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, - hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' - ); - ( marketReportOne, gettersReportOne, poolReportOne, peripheryReportOne, - miscReport, + paraswapReportOne, aaveV3SetupOne ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); - - ( - , - , - gettersReportTwo, - , - setupReportTwo, - , - miscReport, - tokensReport, - paraswapReportOne, - - ) = deployAndSetup(roles, config, flags, deployedContracts); + (, , gettersReportTwo, , setupReportTwo, , , ) = deployAndSetup( + roles, + config, + flags, + deployedContracts + ); } function testAaveV3FullBatchOrchestration() public { @@ -136,7 +116,7 @@ contract AaveV3BatchTests is BatchTestProcedures { new AaveV3PoolBatch(marketReportOne.poolAddressesProvider); } - function test3AaveV3L2PoolDeployment() public { + function test2AaveV3L2PoolDeployment() public { new AaveV3L2PoolBatch(marketReportOne.poolAddressesProvider); } @@ -149,16 +129,7 @@ contract AaveV3BatchTests is BatchTestProcedures { ); } - function test5MiscDeployment() public { - new AaveV3MiscBatch( - flags.l2, - marketReportOne.poolAddressesProvider, - config.l2SequencerUptimeFeed, - config.l2PriceOracleSentinelGracePeriod - ); - } - - function test6ParaswapRelease() public { + function test5PeripheralsRelease() public { new AaveV3ParaswapBatch( roles.poolAdmin, config, @@ -167,7 +138,7 @@ contract AaveV3BatchTests is BatchTestProcedures { ); } - function test7SetupMarket() public { + function test6SetupMarket() public { vm.prank(roles.marketOwner); aaveV3SetupOne.setupAaveV3Market( roles, @@ -176,34 +147,11 @@ contract AaveV3BatchTests is BatchTestProcedures { poolReportOne.poolConfiguratorImplementation, gettersReportOne.protocolDataProvider, peripheryReportOne.aaveOracle, - peripheryReportOne.rewardsControllerImplementation, - miscReport.priceOracleSentinel + peripheryReportOne.rewardsControllerImplementation ); } - function test8TokensMarket() public { + function test7TokensMarket() public { new AaveV3TokensBatch(setupReportTwo.poolProxy); } - - function test9ConfigEngineDeployment() public { - new AaveV3HelpersBatchOne( - setupReportTwo.poolProxy, - setupReportTwo.poolConfiguratorProxy, - miscReport.defaultInterestRateStrategy, - peripheryReportOne.aaveOracle, - setupReportTwo.rewardsControllerProxy, - peripheryReportOne.treasury, - tokensReport.aToken, - tokensReport.variableDebtToken, - tokensReport.stableDebtToken - ); - } - - function test10StaticATokenDeployment() public { - new AaveV3HelpersBatchTwo( - setupReportTwo.poolProxy, - setupReportTwo.rewardsControllerProxy, - peripheryReportOne.proxyAdmin - ); - } } diff --git a/tests/deployments/DeploymentsGasLimits.t.sol b/tests/deployments/DeploymentsGasLimits.t.sol index fd42791e..ae3865f0 100644 --- a/tests/deployments/DeploymentsGasLimits.t.sol +++ b/tests/deployments/DeploymentsGasLimits.t.sol @@ -11,9 +11,6 @@ import {AaveV3GettersBatchTwo} from '../../src/deployments/projects/aave-v3-batc import {AaveV3PeripheryBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol'; import {AaveV3ParaswapBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3ParaswapBatch.sol'; import {AaveV3SetupBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol'; -import {AaveV3MiscBatch} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3MiscBatch.sol'; -import {AaveV3HelpersBatchOne} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchOne.sol'; -import {AaveV3HelpersBatchTwo} from '../../src/deployments/projects/aave-v3-batched/batches/AaveV3HelpersBatchTwo.sol'; import {WETH9} from '../../src/contracts/dependencies/weth/WETH9.sol'; import {AugustusRegistryMock} from '../mocks/AugustusRegistryMock.sol'; import {MockParaSwapFeeClaimer} from '../../src/contracts/mocks/swap/MockParaSwapFeeClaimer.sol'; @@ -34,8 +31,6 @@ contract DeploymentsGasLimits is BatchTestProcedures { PeripheryReport peripheryReportOne; ParaswapReport paraswapReportOne; - MiscReport miscReport; - AaveV3TokensBatch.TokensReport tokensReport; SetupReport setupReportTwo; @@ -57,8 +52,6 @@ contract DeploymentsGasLimits is BatchTestProcedures { 8, address(new AugustusRegistryMock()), // replace with mock of augustus registry address(new MockParaSwapFeeClaimer()), - address(new SequencerOracle(poolAdmin)), - 2 hours, // l2PriceOracleSentinelGracePeriod 8080, empty, address(new WETH9()), @@ -66,35 +59,22 @@ contract DeploymentsGasLimits is BatchTestProcedures { 0.0005e4, 0.0004e4 ); - flags = DeployFlags(true); - - // Etch the create2 factory - vm.etch( - 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, - hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' - ); + flags = DeployFlags(false); ( marketReportOne, gettersReportOne, poolReportOne, peripheryReportOne, - miscReport, + paraswapReportOne, aaveV3SetupOne ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); - - ( - , - , - gettersReportTwo, - , - setupReportTwo, - , - miscReport, - tokensReport, - paraswapReportOne, - - ) = deployAndSetup(roles, config, flags, deployedContracts); + (, , gettersReportTwo, , setupReportTwo, , , ) = deployAndSetup( + roles, + config, + flags, + deployedContracts + ); } function test0AaveV3SetupDeployment() public { @@ -135,16 +115,7 @@ contract DeploymentsGasLimits is BatchTestProcedures { ); } - function test6MiscDeployment() public { - new AaveV3MiscBatch( - flags.l2, - marketReportOne.poolAddressesProvider, - config.l2SequencerUptimeFeed, - config.l2PriceOracleSentinelGracePeriod - ); - } - - function test7ParaswapDeployment() public { + function test6ParaswapDeployment() public { new AaveV3ParaswapBatch( roles.poolAdmin, config, @@ -153,7 +124,7 @@ contract DeploymentsGasLimits is BatchTestProcedures { ); } - function test8SetupMarket() public { + function test7SetupMarket() public { vm.prank(roles.marketOwner); aaveV3SetupOne.setupAaveV3Market( roles, @@ -162,37 +133,14 @@ contract DeploymentsGasLimits is BatchTestProcedures { poolReportOne.poolConfiguratorImplementation, gettersReportOne.protocolDataProvider, peripheryReportOne.aaveOracle, - peripheryReportOne.rewardsControllerImplementation, - miscReport.priceOracleSentinel + peripheryReportOne.rewardsControllerImplementation ); } - function test9TokensMarket() public { + function test8TokensMarket() public { new AaveV3TokensBatch(setupReportTwo.poolProxy); } - function test10ConfigEngineDeployment() public { - new AaveV3HelpersBatchOne( - setupReportTwo.poolProxy, - setupReportTwo.poolConfiguratorProxy, - miscReport.defaultInterestRateStrategy, - peripheryReportOne.aaveOracle, - setupReportTwo.rewardsControllerProxy, - peripheryReportOne.treasury, - tokensReport.aToken, - tokensReport.variableDebtToken, - tokensReport.stableDebtToken - ); - } - - function test11StaticATokenDeployment() public { - new AaveV3HelpersBatchTwo( - setupReportTwo.poolProxy, - setupReportTwo.rewardsControllerProxy, - peripheryReportOne.proxyAdmin - ); - } - function testCheckInitCodeSizeBatchs() public view { uint16 maxInitCodeSize = 49152; @@ -200,13 +148,10 @@ contract DeploymentsGasLimits is BatchTestProcedures { console.log('AaveV3L2PoolBatch', type(AaveV3L2PoolBatch).creationCode.length); console.log('AaveV3PoolBatch', type(AaveV3PoolBatch).creationCode.length); console.log('AaveV3PeripheryBatch', type(AaveV3PeripheryBatch).creationCode.length); - console.log('AaveV3MiscBatch', type(AaveV3MiscBatch).creationCode.length); console.log('AaveV3ParaswapBatch', type(AaveV3ParaswapBatch).creationCode.length); console.log('AaveV3GettersBatchOne', type(AaveV3GettersBatchOne).creationCode.length); console.log('AaveV3GettersBatchTwo', type(AaveV3GettersBatchTwo).creationCode.length); console.log('AaveV3TokensBatch', type(AaveV3TokensBatch).creationCode.length); - console.log('AaveV3HelpersBatchOne', type(AaveV3HelpersBatchOne).creationCode.length); - console.log('AaveV3HelpersBatchTwo', type(AaveV3HelpersBatchTwo).creationCode.length); assertLe( type(AaveV3SetupBatch).creationCode.length, @@ -228,11 +173,6 @@ contract DeploymentsGasLimits is BatchTestProcedures { maxInitCodeSize, 'AaveV3PeripheryBatch max init code size' ); - assertLe( - type(AaveV3MiscBatch).creationCode.length, - maxInitCodeSize, - 'AaveV3MiscBatch max init code size' - ); assertLe( type(AaveV3ParaswapBatch).creationCode.length, maxInitCodeSize, @@ -253,15 +193,5 @@ contract DeploymentsGasLimits is BatchTestProcedures { maxInitCodeSize, 'AaveV3TokensBatch max init code size' ); - assertLe( - type(AaveV3HelpersBatchOne).creationCode.length, - maxInitCodeSize, - 'AaveV3HelpersBatchOne max init code size' - ); - assertLe( - type(AaveV3HelpersBatchTwo).creationCode.length, - maxInitCodeSize, - 'AaveV3HelpersBatchTwo max init code size' - ); } } diff --git a/tests/extensions/static-a-token/StataOracle.t.sol b/tests/extensions/static-a-token/StataOracle.t.sol deleted file mode 100644 index 5e6e4efd..00000000 --- a/tests/extensions/static-a-token/StataOracle.t.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {StataOracle} from '../../../src/contracts/extensions/static-a-token/StataOracle.sol'; -import {StaticATokenLM} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; -import {BaseTest} from './TestBase.sol'; - -contract StataOracleTest is BaseTest { - StataOracle public oracle; - - function setUp() public override { - super.setUp(); - oracle = new StataOracle(contracts.poolAddressesProvider); - - vm.prank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 1_000_000); - } - - function test_assetPrice() public view { - uint256 stataPrice = oracle.getAssetPrice(address(staticATokenLM)); - uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); - assertGe(stataPrice, underlyingPrice); - assertEq(stataPrice, (underlyingPrice * staticATokenLM.convertToAssets(1e18)) / 1e18); - } - - function test_assetsPrices() public view { - address[] memory staticATokens = factory.getStaticATokens(); - uint256[] memory stataPrices = oracle.getAssetsPrices(staticATokens); - - for (uint256 i = 0; i < staticATokens.length; i++) { - address staticAToken = staticATokens[i]; - uint256 stataPrice = stataPrices[i]; - - address underlying = StaticATokenLM(staticAToken).asset(); - uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(underlying); - - assertGe(stataPrice, underlyingPrice); - assertEq( - stataPrice, - (underlyingPrice * StaticATokenLM(staticAToken).convertToAssets(1e18)) / 1e18 - ); - } - } - - function test_error(uint256 shares) public view { - vm.assume(shares <= staticATokenLM.maxMint(address(0))); - uint256 pricePerShare = oracle.getAssetPrice(address(staticATokenLM)); - uint256 pricePerAsset = contracts.aaveOracle.getAssetPrice(UNDERLYING); - uint256 assets = staticATokenLM.convertToAssets(shares); - - assertApproxEqAbs( - (pricePerShare * shares) / 1e18, - (pricePerAsset * assets) / 1e18, - (assets / 1e18) + 1 // there can be imprecision of 1 wei, which will accumulate for each asset - ); - } -} diff --git a/tests/extensions/static-a-token/StaticATokenLM.t.sol b/tests/extensions/static-a-token/StaticATokenLM.t.sol deleted file mode 100644 index 5c84fe55..00000000 --- a/tests/extensions/static-a-token/StaticATokenLM.t.sol +++ /dev/null @@ -1,609 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {AToken} from '../../../src/contracts/protocol/tokenization/AToken.sol'; -import {DataTypes} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IERC20, IERC20Metadata} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; -import {RayMathExplicitRounding} from '../../../src/contracts/misc/libraries/RayMathExplicitRounding.sol'; -import {PullRewardsTransferStrategy} from '../../../src/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; -import {RewardsDataTypes} from '../../../src/contracts/rewards/libraries/RewardsDataTypes.sol'; -import {ITransferStrategyBase} from '../../../src/contracts/rewards/interfaces/ITransferStrategyBase.sol'; -import {IEACAggregatorProxy} from '../../../src/contracts/helpers/interfaces/IEACAggregatorProxy.sol'; -import {IStaticATokenLM} from '../../../src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol'; -import {SigUtils} from '../../utils/SigUtils.sol'; -import {BaseTest, TestnetERC20} from './TestBase.sol'; - -contract StaticATokenLMTest is BaseTest { - using RayMathExplicitRounding for uint256; - - address public constant EMISSION_ADMIN = address(25); - - function setUp() public override { - super.setUp(); - - _configureLM(); - _openSupplyAndBorrowPositions(); - - vm.startPrank(user); - } - - function test_initializeShouldRevert() public { - address impl = factory.STATIC_A_TOKEN_IMPL(); - vm.expectRevert(); - IStaticATokenLM(impl).initialize(0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8, 'hey', 'ho'); - } - - function test_getters() public view { - assertEq(staticATokenLM.name(), 'Static Aave Local WETH'); - assertEq(staticATokenLM.symbol(), 'stataLocWETH'); - - IERC20 aToken = staticATokenLM.aToken(); - assertEq(address(aToken), A_TOKEN); - - address underlyingAddress = address(staticATokenLM.asset()); - assertEq(underlyingAddress, UNDERLYING); - - IERC20Metadata underlying = IERC20Metadata(underlyingAddress); - assertEq(staticATokenLM.decimals(), underlying.decimals()); - - assertEq( - address(staticATokenLM.INCENTIVES_CONTROLLER()), - address(AToken(A_TOKEN).getIncentivesController()) - ); - } - - function test_convertersAndPreviews() public view { - uint128 amount = 5 ether; - uint256 shares = staticATokenLM.convertToShares(amount); - assertLe(shares, amount, 'SHARES LOWER'); - assertEq(shares, staticATokenLM.previewDeposit(amount), 'PREVIEW_DEPOSIT'); - assertLe(shares, staticATokenLM.previewWithdraw(amount), 'PREVIEW_WITHDRAW'); - uint256 assets = staticATokenLM.convertToAssets(amount); - assertGe(assets, shares, 'ASSETS GREATER'); - assertLe(assets, staticATokenLM.previewMint(amount), 'PREVIEW_MINT'); - assertEq(assets, staticATokenLM.previewRedeem(amount), 'PREVIEW_REDEEM'); - } - - // Redeem tests - function test_redeem() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - assertEq(staticATokenLM.maxRedeem(user), staticATokenLM.balanceOf(user)); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); - assertEq(staticATokenLM.balanceOf(user), 0); - assertLe(IERC20(UNDERLYING).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user), amountToDeposit, 1); - } - - function test_redeemAToken() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - assertEq(staticATokenLM.maxRedeem(user), staticATokenLM.balanceOf(user)); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user, false); - assertEq(staticATokenLM.balanceOf(user), 0); - assertLe(IERC20(A_TOKEN).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(A_TOKEN).balanceOf(user), amountToDeposit, 1); - } - - function test_redeemAllowance() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - staticATokenLM.approve(user1, staticATokenLM.maxRedeem(user)); - vm.stopPrank(); - vm.startPrank(user1); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user1, user); - assertEq(staticATokenLM.balanceOf(user), 0); - assertLe(IERC20(UNDERLYING).balanceOf(user1), amountToDeposit); - assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user1), amountToDeposit, 1); - } - - function testFail_redeemOverflowAllowance() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - staticATokenLM.approve(user1, staticATokenLM.maxRedeem(user) / 2); - vm.stopPrank(); - vm.startPrank(user1); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user1, user); - assertEq(staticATokenLM.balanceOf(user), 0); - assertEq(IERC20(A_TOKEN).balanceOf(user1), amountToDeposit); - } - - function testFail_redeemAboveBalance() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user) + 1, user, user); - } - - // Withdraw tests - function test_withdraw() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - assertLe(staticATokenLM.maxWithdraw(user), amountToDeposit); - staticATokenLM.withdraw(staticATokenLM.maxWithdraw(user), user, user); - assertEq(staticATokenLM.balanceOf(user), 0); - assertLe(IERC20(UNDERLYING).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(UNDERLYING).balanceOf(user), amountToDeposit, 1); - } - - function testFail_withdrawAboveBalance() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - _fundUser(amountToDeposit, user1); - - _depositAToken(amountToDeposit, user); - _depositAToken(amountToDeposit, user1); - - assertEq(staticATokenLM.maxWithdraw(user), amountToDeposit); - staticATokenLM.withdraw(staticATokenLM.maxWithdraw(user) + 1, user, user); - } - - // mint - function test_mint() public { - vm.stopPrank(); - - // set supply cap to non-zero - vm.startPrank(poolAdmin); - contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 15_000); - vm.stopPrank(); - - vm.startPrank(user); - - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - IERC20(UNDERLYING).approve(address(staticATokenLM), amountToDeposit); - uint256 shares = 1 ether; - staticATokenLM.mint(shares, user); - assertEq(shares, staticATokenLM.balanceOf(user)); - } - - function testFail_mintAboveBalance() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _underlyingToAToken(amountToDeposit, user); - IERC20(A_TOKEN).approve(address(staticATokenLM), amountToDeposit); - staticATokenLM.mint(amountToDeposit, user); - } - - // test rewards - function test_collectAndUpdateRewards() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); - uint256 claimable = staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN); - staticATokenLM.collectAndUpdateRewards(REWARD_TOKEN); - assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), claimable); - } - - function test_claimRewardsToSelf() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - - uint256 claimable = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - } - - function test_claimRewards() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - - uint256 claimable = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - staticATokenLM.claimRewards(user, rewardTokens); - assertEq(claimable, IERC20(REWARD_TOKEN).balanceOf(user)); - assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - } - - // should fail as user1 is not a valid claimer - function testFail_claimRewardsOnBehalfOf() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - - vm.stopPrank(); - vm.startPrank(user1); - - staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - staticATokenLM.claimRewardsOnBehalf(user, user1, rewardTokens); - } - - function test_depositATokenClaimWithdrawClaim() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - // deposit aweth - _depositAToken(amountToDeposit, user); - - // forward time - _skipBlocks(60); - - // claim - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); - uint256 claimable0 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable0); - assertGt(claimable0, 0); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable0); - - // forward time - _skipBlocks(60); - - // redeem - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); - uint256 claimable1 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable1); - assertGt(claimable1, 0); - - // claim on behalf of other user - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable1 + claimable0); - assertEq(staticATokenLM.balanceOf(user), 0); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); - assertGt(AToken(UNDERLYING).balanceOf(user), 5 ether); - } - - function test_depositWETHClaimWithdrawClaim() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - // forward time - _skipBlocks(60); - - // claim - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); - uint256 claimable0 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable0); - assertGt(claimable0, 0); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable0); - - // forward time - _skipBlocks(60); - - // redeem - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); - uint256 claimable1 = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), claimable1); - assertGt(claimable1, 0); - - // claim on behalf of other user - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimable1 + claimable0); - assertEq(staticATokenLM.balanceOf(user), 0); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); - assertGt(AToken(UNDERLYING).balanceOf(user), 5 ether); - } - - function test_transfer() public { - uint128 amountToDeposit = 10 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - // transfer to 2nd user - staticATokenLM.transfer(user1, amountToDeposit / 2); - assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); - - // forward time - _skipBlocks(60); - - // redeem for both - uint256 claimableUser = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimableUser); - vm.stopPrank(); - vm.startPrank(user1); - uint256 claimableUser1 = staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user1), user1, user1); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user1), claimableUser1); - assertGt(claimableUser1, 0); - - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); - } - - // getUnclaimedRewards - function test_getUnclaimedRewards() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - uint256 shares = _depositAToken(amountToDeposit, user); - assertEq(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); - _skipBlocks(1000); - staticATokenLM.redeem(shares, user, user); - assertGt(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); - } - - /** - * maxDeposit test - */ - function test_maxDeposit_freeze() public { - vm.stopPrank(); - vm.startPrank(roleList.marketOwner); - contracts.poolConfiguratorProxy.setReserveFreeze(UNDERLYING, true); - - uint256 max = staticATokenLM.maxDeposit(address(0)); - - assertEq(max, 0); - } - - function test_maxDeposit_paused() public { - vm.stopPrank(); - vm.startPrank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setReservePause(UNDERLYING, true); - - uint256 max = staticATokenLM.maxDeposit(address(0)); - - assertEq(max, 0); - } - - function test_maxDeposit_noCap() public { - vm.stopPrank(); - vm.startPrank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 0); - - uint256 maxDeposit = staticATokenLM.maxDeposit(address(0)); - uint256 maxMint = staticATokenLM.maxMint(address(0)); - - assertEq(maxDeposit, type(uint256).max); - assertEq(maxMint, type(uint256).max); - } - - // should be 0 as supply is ~5k - function test_maxDeposit_5kCap() public { - vm.stopPrank(); - vm.startPrank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 5_000); - - uint256 max = staticATokenLM.maxDeposit(address(0)); - assertEq(max, 0); - } - - function test_maxDeposit_50kCap() public { - vm.stopPrank(); - vm.startPrank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 50_000); - - uint256 max = staticATokenLM.maxDeposit(address(0)); - DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(UNDERLYING); - assertEq( - max, - 50_000 * - (10 ** IERC20Metadata(UNDERLYING).decimals()) - - (IERC20Metadata(A_TOKEN).totalSupply() + - uint256(reserveData.accruedToTreasury).rayMulRoundUp(staticATokenLM.rate())) - ); - } - - /** - * maxRedeem test - */ - function test_maxRedeem_paused() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - vm.stopPrank(); - vm.startPrank(address(roleList.marketOwner)); - contracts.poolConfiguratorProxy.setReservePause(UNDERLYING, true); - - uint256 max = staticATokenLM.maxRedeem(address(user)); - - assertEq(max, 0); - } - - function test_maxRedeem_allAvailable() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - uint256 max = staticATokenLM.maxRedeem(address(user)); - - assertEq(max, staticATokenLM.balanceOf(user)); - } - - function test_maxRedeem_partAvailable() public { - uint128 amountToDeposit = 50 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - vm.stopPrank(); - - uint256 maxRedeemBefore = staticATokenLM.previewRedeem(staticATokenLM.maxRedeem(address(user))); - uint256 underlyingBalanceBefore = IERC20Metadata(UNDERLYING).balanceOf(A_TOKEN); - - // create rich user - address borrowUser = address(99); - vm.startPrank(borrowUser); - deal(address(wbtc), borrowUser, 2_000e8); - wbtc.approve(address(POOL), 2_000e8); - POOL.deposit(address(wbtc), 2_000e8, borrowUser, 0); - - // borrow all available - POOL.borrow(UNDERLYING, underlyingBalanceBefore - (maxRedeemBefore / 2), 2, 0, borrowUser); - - uint256 maxRedeemAfter = staticATokenLM.previewRedeem(staticATokenLM.maxRedeem(address(user))); - assertApproxEqAbs(maxRedeemAfter, (maxRedeemBefore / 2), 1); - } - - function test_maxRedeem_nonAvailable() public { - uint128 amountToDeposit = 50 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - vm.stopPrank(); - - uint256 underlyingBalanceBefore = IERC20Metadata(UNDERLYING).balanceOf(A_TOKEN); - // create rich user - address borrowUser = address(99); - vm.startPrank(borrowUser); - deal(address(wbtc), borrowUser, 2_000e8); - wbtc.approve(address(POOL), 2_000e8); - POOL.deposit(address(wbtc), 2_000e8, borrowUser, 0); - - // borrow all available - contracts.poolProxy.borrow(UNDERLYING, underlyingBalanceBefore, 2, 0, borrowUser); - - uint256 maxRedeemAfter = staticATokenLM.maxRedeem(address(user)); - assertEq(maxRedeemAfter, 0); - } - - function test_permit() public { - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: spender, - value: 1 ether, - nonce: staticATokenLM.nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - staticATokenLM.PERMIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); - - assertEq(staticATokenLM.allowance(permit.owner, spender), permit.value); - } - - function test_permit_expired() public { - // as the default timestamp is 0, we move ahead in time a bit - vm.warp(10 days); - - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: spender, - value: 1 ether, - nonce: staticATokenLM.nonces(user), - deadline: block.timestamp - 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - staticATokenLM.PERMIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - vm.expectRevert('PERMIT_DEADLINE_EXPIRED'); - staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); - } - - function test_permit_invalidSigner() public { - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: address(424242), - spender: spender, - value: 1 ether, - nonce: staticATokenLM.nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - staticATokenLM.PERMIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - vm.expectRevert('INVALID_SIGNER'); - staticATokenLM.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); - } - - function _configureLM() internal { - PullRewardsTransferStrategy strat = new PullRewardsTransferStrategy( - report.rewardsControllerProxy, - EMISSION_ADMIN, - EMISSION_ADMIN - ); - - vm.startPrank(poolAdmin); - contracts.emissionManager.setEmissionAdmin(REWARD_TOKEN, EMISSION_ADMIN); - vm.stopPrank(); - - vm.startPrank(EMISSION_ADMIN); - IERC20(REWARD_TOKEN).approve(address(strat), 10_000 ether); - vm.stopPrank(); - - vm.startPrank(OWNER); - TestnetERC20(REWARD_TOKEN).mint(EMISSION_ADMIN, 10_000 ether); - vm.stopPrank(); - - RewardsDataTypes.RewardsConfigInput[] memory config = new RewardsDataTypes.RewardsConfigInput[]( - 1 - ); - config[0] = RewardsDataTypes.RewardsConfigInput( - 0.00385 ether, - 10_000 ether, - uint32(block.timestamp + 30 days), - A_TOKEN, - REWARD_TOKEN, - ITransferStrategyBase(strat), - IEACAggregatorProxy(address(2)) - ); - - vm.prank(EMISSION_ADMIN); - contracts.emissionManager.configureAssets(config); - - staticATokenLM.refreshRewardTokens(); - } - - function _openSupplyAndBorrowPositions() internal { - // this is to open borrow positions so that the aToken balance increases - address whale = address(79); - vm.startPrank(whale); - _fundUser(5_000 ether, whale); - - weth.approve(address(POOL), 5_000 ether); - POOL.deposit(address(weth), 5_000 ether, whale, 0); - - POOL.borrow(address(weth), 1_000 ether, 2, 0, whale); - vm.stopPrank(); - } -} diff --git a/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol b/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol deleted file mode 100644 index 4cc133e7..00000000 --- a/tests/extensions/static-a-token/StaticATokenMetaTransactions.t.sol +++ /dev/null @@ -1,252 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IERC20WithPermit} from 'solidity-utils/contracts/oz-common/interfaces/IERC20WithPermit.sol'; -import {StaticATokenLM, IStaticATokenLM, IERC20} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; -import {SigUtils} from '../../utils/SigUtils.sol'; -import {BaseTest, IAToken, IRewardsController, DataTypes} from './TestBase.sol'; - -contract StaticATokenMetaTransactions is BaseTest { - function setUp() public override { - super.setUp(); - - // Testing meta transactions with USDX as WETH does not support permit - DataTypes.ReserveDataLegacy memory reserveDataUSDX = contracts.poolProxy.getReserveData( - address(usdx) - ); - UNDERLYING = address(usdx); - A_TOKEN = reserveDataUSDX.aTokenAddress; - - staticATokenLM = StaticATokenLM(factory.getStaticAToken(UNDERLYING)); - - vm.startPrank(user); - } - - function test_validateDomainSeparator() public view { - address[] memory staticATokens = factory.getStaticATokens(); - - for (uint256 i = 0; i < staticATokens.length; i++) { - bytes32 separator1 = StaticATokenLM(staticATokens[i]).DOMAIN_SEPARATOR(); - for (uint256 j = 0; j < staticATokens.length; j++) { - if (i != j) { - bytes32 separator2 = StaticATokenLM(staticATokens[j]).DOMAIN_SEPARATOR(); - assertNotEq(separator1, separator2, 'DOMAIN_SEPARATOR_MUST_BE_UNIQUE'); - } - } - } - } - - function test_metaDepositATokenUnderlyingNoPermit() public { - uint128 amountToDeposit = 5e6; - deal(UNDERLYING, user, amountToDeposit); - IERC20(UNDERLYING).approve(address(staticATokenLM), 1e6); - IStaticATokenLM.PermitParams memory permitParams; - - // generate combined permit - SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ - owner: user, - spender: spender, - value: 1e6, - referralCode: 0, - fromUnderlying: true, - nonce: staticATokenLM.nonces(user), - deadline: block.timestamp + 1 days, - permit: permitParams - }); - bytes32 digest = SigUtils.getTypedDepositHash( - depositPermit, - staticATokenLM.METADEPOSIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - - IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - - uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); - staticATokenLM.metaDeposit( - depositPermit.owner, - depositPermit.spender, - depositPermit.value, - depositPermit.referralCode, - depositPermit.fromUnderlying, - depositPermit.deadline, - permitParams, - sigParams - ); - - assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); - } - - function test_metaDepositATokenUnderlying() public { - uint128 amountToDeposit = 5e6; - deal(UNDERLYING, user, amountToDeposit); - - // permit for aToken deposit - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: address(staticATokenLM), - value: 1e6, - nonce: IERC20WithPermit(UNDERLYING).nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - staticATokenLM.PERMIT_TYPEHASH(), - IERC20WithPermit(UNDERLYING).DOMAIN_SEPARATOR() - ); - - (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); - - IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( - permit.owner, - permit.spender, - permit.value, - permit.deadline, - pV, - pR, - pS - ); - - // generate combined permit - SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ - owner: user, - spender: spender, - value: permit.value, - referralCode: 0, - fromUnderlying: true, - nonce: staticATokenLM.nonces(user), - deadline: permit.deadline, - permit: permitParams - }); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - userPrivateKey, - SigUtils.getTypedDepositHash( - depositPermit, - staticATokenLM.METADEPOSIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ) - ); - - IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - - uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); - uint256 shares = staticATokenLM.metaDeposit( - depositPermit.owner, - depositPermit.spender, - depositPermit.value, - depositPermit.referralCode, - depositPermit.fromUnderlying, - depositPermit.deadline, - permitParams, - sigParams - ); - assertEq(shares, previewDeposit); - assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); - } - - function test_metaDepositAToken() public { - uint128 amountToDeposit = 5e6; - _fundUser(amountToDeposit, user); - _underlyingToAToken(amountToDeposit, user); - - // permit for aToken deposit - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: address(staticATokenLM), - value: 1e6, - nonce: IERC20WithPermit(A_TOKEN).nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - staticATokenLM.PERMIT_TYPEHASH(), - IERC20WithPermit(A_TOKEN).DOMAIN_SEPARATOR() - ); - - (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); - - IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( - permit.owner, - permit.spender, - permit.value, - permit.deadline, - pV, - pR, - pS - ); - - // generate combined permit - SigUtils.DepositPermit memory depositPermit = SigUtils.DepositPermit({ - owner: user, - spender: spender, - value: permit.value, - referralCode: 0, - fromUnderlying: false, - nonce: staticATokenLM.nonces(user), - deadline: permit.deadline, - permit: permitParams - }); - bytes32 digest = SigUtils.getTypedDepositHash( - depositPermit, - staticATokenLM.METADEPOSIT_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - - IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - - uint256 previewDeposit = staticATokenLM.previewDeposit(depositPermit.value); - - staticATokenLM.metaDeposit( - depositPermit.owner, - depositPermit.spender, - depositPermit.value, - depositPermit.referralCode, - depositPermit.fromUnderlying, - depositPermit.deadline, - permitParams, - sigParams - ); - - assertEq(staticATokenLM.balanceOf(depositPermit.spender), previewDeposit); - } - - function test_metaWithdraw() public { - uint128 amountToDeposit = 5e6; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - SigUtils.WithdrawPermit memory permit = SigUtils.WithdrawPermit({ - owner: user, - spender: spender, - staticAmount: 0, - dynamicAmount: 1e6, - toUnderlying: false, - nonce: staticATokenLM.nonces(user), - deadline: block.timestamp + 1 days - }); - bytes32 digest = SigUtils.getTypedWithdrawHash( - permit, - staticATokenLM.METAWITHDRAWAL_TYPEHASH(), - staticATokenLM.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - - IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - - staticATokenLM.metaWithdraw( - permit.owner, - permit.spender, - permit.staticAmount, - permit.dynamicAmount, - permit.toUnderlying, - permit.deadline, - sigParams - ); - - assertEq(IERC20(A_TOKEN).balanceOf(permit.spender), permit.dynamicAmount); - } -} diff --git a/tests/extensions/static-a-token/StaticATokenNoLM.t.sol b/tests/extensions/static-a-token/StaticATokenNoLM.t.sol deleted file mode 100644 index 84ddbd33..00000000 --- a/tests/extensions/static-a-token/StaticATokenNoLM.t.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {BaseTest, IERC20} from './TestBase.sol'; - -/** - * Testing the static token wrapper on a pool that never had LM enabled - * This is a slightly different assumption than a pool that doesn't have LM enabled any more as incentivesController.rewardTokens() will have length=0 - */ -contract StaticATokenNoLMTest is BaseTest { - function setUp() public override { - super.setUp(); - - vm.startPrank(user); - } - - // test rewards - function test_collectAndUpdateRewardsWithLMDisabled() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); - assertEq(staticATokenLM.collectAndUpdateRewards(REWARD_TOKEN), 0); - assertEq(IERC20(REWARD_TOKEN).balanceOf(address(staticATokenLM)), 0); - } - - function test_claimRewardsToSelfWithLMDisabled() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - _skipBlocks(60); - - try staticATokenLM.getClaimableRewards(user, REWARD_TOKEN) {} catch Error( - string memory reason - ) { - require(keccak256(bytes(reason)) == keccak256(bytes('9'))); - } - - try staticATokenLM.claimRewardsToSelf(rewardTokens) {} catch Error(string memory reason) { - require(keccak256(bytes(reason)) == keccak256(bytes('9'))); - } - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); - } -} diff --git a/tests/extensions/static-a-token/TestBase.sol b/tests/extensions/static-a-token/TestBase.sol deleted file mode 100644 index d4b488fa..00000000 --- a/tests/extensions/static-a-token/TestBase.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IRewardsController} from 'src/contracts/rewards/interfaces/IRewardsController.sol'; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; -import {IPool} from '../../../src/contracts/interfaces/IPool.sol'; -import {StaticATokenFactory} from '../../../src/contracts/extensions/static-a-token/StaticATokenFactory.sol'; -import {StaticATokenLM, IStaticATokenLM, IERC20, IERC20Metadata, ERC20} from '../../../src/contracts/extensions/static-a-token/StaticATokenLM.sol'; -import {IAToken} from '../../../src/contracts/extensions/static-a-token/interfaces/IAToken.sol'; -import {TestnetProcedures, TestnetERC20} from '../../utils/TestnetProcedures.sol'; -import {DataTypes} from '../../../src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; - -abstract contract BaseTest is TestnetProcedures { - address constant OWNER = address(1234); - - address public user; - address public user1; - address internal spender; - - uint256 internal userPrivateKey; - uint256 internal spenderPrivateKey; - - StaticATokenLM public staticATokenLM; - address public proxyAdmin; - ITransparentProxyFactory public proxyFactory; - StaticATokenFactory public factory; - - address[] rewardTokens; - - address public UNDERLYING; - address public A_TOKEN; - address public REWARD_TOKEN; - IPool public POOL; - - function setUp() public virtual { - userPrivateKey = 0xA11CE; - spenderPrivateKey = 0xB0B0; - user = address(vm.addr(userPrivateKey)); - user1 = address(vm.addr(2)); - spender = vm.addr(spenderPrivateKey); - - initTestEnvironment(); - DataTypes.ReserveDataLegacy memory reserveDataWETH = contracts.poolProxy.getReserveData( - tokenList.weth - ); - - UNDERLYING = address(weth); - REWARD_TOKEN = address(new TestnetERC20('LM Reward ERC20', 'RWD', 18, OWNER)); - A_TOKEN = reserveDataWETH.aTokenAddress; - POOL = contracts.poolProxy; - - rewardTokens.push(REWARD_TOKEN); - - proxyFactory = ITransparentProxyFactory(report.transparentProxyFactory); - proxyAdmin = report.proxyAdmin; - - factory = StaticATokenFactory(report.staticATokenFactoryProxy); - factory.createStaticATokens(POOL.getReservesList()); - - staticATokenLM = StaticATokenLM(factory.getStaticAToken(UNDERLYING)); - } - - function _fundUser(uint128 amountToDeposit, address targetUser) internal { - deal(UNDERLYING, targetUser, amountToDeposit); - } - - function _skipBlocks(uint128 blocks) internal { - vm.roll(block.number + blocks); - vm.warp(block.timestamp + blocks * 12); // assuming a block is around 12seconds - } - - function _underlyingToAToken(uint256 amountToDeposit, address targetUser) internal { - IERC20(UNDERLYING).approve(address(POOL), amountToDeposit); - POOL.deposit(UNDERLYING, amountToDeposit, targetUser, 0); - } - - function _depositAToken(uint256 amountToDeposit, address targetUser) internal returns (uint256) { - _underlyingToAToken(amountToDeposit, targetUser); - IERC20(A_TOKEN).approve(address(staticATokenLM), amountToDeposit); - return staticATokenLM.deposit(amountToDeposit, targetUser, 10, false); - } - - function testAdmin() public { - vm.stopPrank(); - vm.startPrank(proxyAdmin); - assertEq(TransparentUpgradeableProxy(payable(address(staticATokenLM))).admin(), proxyAdmin); - assertEq(TransparentUpgradeableProxy(payable(address(factory))).admin(), proxyAdmin); - vm.stopPrank(); - } -} diff --git a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol deleted file mode 100644 index cf909a86..00000000 --- a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol +++ /dev/null @@ -1,670 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import 'forge-std/Test.sol'; -import {IAaveV3ConfigEngine} from '../../../src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {AaveV3MockListing} from './mocks/AaveV3MockListing.sol'; -import {AaveV3MockListingCustom} from './mocks/AaveV3MockListingCustom.sol'; -import {AaveV3MockCapUpdate} from './mocks/AaveV3MockCapUpdate.sol'; -import {AaveV3MockCollateralUpdate} from './mocks/AaveV3MockCollateralUpdate.sol'; -import {AaveV3MockCollateralUpdateNoChange} from './mocks/AaveV3MockCollateralUpdateNoChange.sol'; -import {AaveV3MockCollateralUpdateWrongBonus, AaveV3MockCollateralUpdateCorrectBonus} from './mocks/AaveV3MockCollateralUpdateWrongBonus.sol'; -import {AaveV3MockBorrowUpdate} from './mocks/AaveV3MockBorrowUpdate.sol'; -import {AaveV3MockBorrowUpdateNoChange} from './mocks/AaveV3MockBorrowUpdateNoChange.sol'; -import {AaveV3MockRatesUpdate} from './mocks/AaveV3MockRatesUpdate.sol'; -import {AaveV3MockPriceFeedUpdate} from './mocks/AaveV3MockPriceFeedUpdate.sol'; -import {AaveV3MockEModeCategoryUpdate, AaveV3MockEModeCategoryUpdateEdgeBonus} from './mocks/AaveV3MockEModeCategoryUpdate.sol'; -import {AaveV3MockEModeCategoryUpdateNoChange} from './mocks/AaveV3MockEModeCategoryUpdateNoChange.sol'; -import {AaveV3MockAssetEModeUpdate} from './mocks/AaveV3MockAssetEModeUpdate.sol'; - -import {ATokenInstance} from '../../../src/contracts/instances/ATokenInstance.sol'; -import {StableDebtTokenInstance} from '../../../src/contracts/instances/StableDebtTokenInstance.sol'; -import {VariableDebtTokenInstance} from '../../../src/contracts/instances/VariableDebtTokenInstance.sol'; -import {TestnetProcedures, AaveV3ConfigEngine} from '../../utils/TestnetProcedures.sol'; -import {TestnetERC20} from '../../../src/contracts/mocks/testnet-helpers/TestnetERC20.sol'; -import {MockAggregator} from '../../../src/contracts/mocks/oracle/CLAggregators/MockAggregator.sol'; -import {IPool, IPoolAddressesProvider} from '../../utils/ProtocolV3TestBase.sol'; -import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol'; -import {ProtocolV3TestBase, IDefaultInterestRateStrategyV2, ReserveConfig, ReserveTokens, DataTypes as DataTypeOld} from '../../utils/ProtocolV3TestBase.sol'; - -contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { - using stdStorage for StdStorage; - address configEngine; - - function setUp() public { - initTestEnvironment(); - configEngine = report.configEngine; - } - - event CollateralConfigurationChanged( - address indexed asset, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus - ); - - event EModeCategoryAdded( - uint8 indexed categoryId, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - address oracle, - string label - ); - - function testListings() public { - address asset = address(new TestnetERC20('1INCH', '1INCH', 18, address(this))); - - address feed = address(new MockAggregator(int256(25e8))); - AaveV3MockListing payload = new AaveV3MockListing(asset, feed, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineListing', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineListing', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineListing', 'postTestEngineListing'); - - ReserveConfig memory expectedAssetConfig = ReserveConfig({ - symbol: '1INCH', - underlying: asset, - aToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - variableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - stableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - decimals: 18, - ltv: 82_50, - liquidationThreshold: 86_00, - liquidationBonus: 105_00, - liquidationProtocolFee: 10_00, - reserveFactor: 10_00, - usageAsCollateralEnabled: true, - borrowingEnabled: true, - interestRateStrategy: AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), - stableBorrowRateEnabled: false, - isPaused: false, - isActive: true, - isFrozen: false, - isSiloed: false, - isBorrowableInIsolation: false, - isFlashloanable: false, - supplyCap: 85_000, - borrowCap: 60_000, - debtCeiling: 0, - eModeCategory: 0 - }); - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - - _noReservesConfigsChangesApartNewListings(allConfigsBefore, allConfigsAfter); - - _validateReserveTokensImpls( - _findReserveConfigBySymbol(allConfigsAfter, '1INCH'), - ReserveTokens({ - aToken: address(contracts.aToken), - stableDebtToken: address(contracts.stableDebtToken), - variableDebtToken: address(contracts.variableDebtToken) - }) - ); - - _validateAssetSourceOnOracle( - IPoolAddressesProvider(address(contracts.poolAddressesProvider)), - asset, - feed - ); - - _validateInterestRateStrategy( - asset, - contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), - AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), - IDefaultInterestRateStrategyV2.InterestRateDataRay({ - optimalUsageRatio: _bpsToRay(payload.newListings()[0].rateStrategyParams.optimalUsageRatio), - baseVariableBorrowRate: _bpsToRay( - payload.newListings()[0].rateStrategyParams.baseVariableBorrowRate - ), - variableRateSlope1: _bpsToRay( - payload.newListings()[0].rateStrategyParams.variableRateSlope1 - ), - variableRateSlope2: _bpsToRay( - payload.newListings()[0].rateStrategyParams.variableRateSlope2 - ) - }) - ); - } - - function testListingsCustom() public { - address asset = address(new TestnetERC20('PSP', 'PSP', 18, address(this))); - - address feed = address(new MockAggregator(int256(15e8))); - address aTokenImpl = address(new ATokenInstance(contracts.poolProxy)); - address vTokenImpl = address(new VariableDebtTokenInstance(contracts.poolProxy)); - address sTokenImpl = address(new StableDebtTokenInstance(contracts.poolProxy)); - - AaveV3MockListingCustom payload = new AaveV3MockListingCustom( - asset, - feed, - configEngine, - aTokenImpl, - vTokenImpl, - sTokenImpl - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineListingCustom', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineListingCustom', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineListingCustom', 'postTestEngineListingCustom'); - - ReserveConfig memory expectedAssetConfig = ReserveConfig({ - symbol: 'PSP', - underlying: asset, - aToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - variableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - stableDebtToken: address(0), // Mock, as they don't get validated, because of the "dynamic" deployment on proposal execution - decimals: 18, - ltv: 82_50, - liquidationThreshold: 86_00, - liquidationBonus: 105_00, - liquidationProtocolFee: 10_00, - reserveFactor: 10_00, - usageAsCollateralEnabled: true, - borrowingEnabled: true, - interestRateStrategy: AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), - stableBorrowRateEnabled: false, - isPaused: false, - isActive: true, - isFrozen: false, - isSiloed: false, - isBorrowableInIsolation: false, - isFlashloanable: false, - supplyCap: 85_000, - borrowCap: 60_000, - debtCeiling: 0, - eModeCategory: 0 - }); - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - - _noReservesConfigsChangesApartNewListings(allConfigsBefore, allConfigsAfter); - - _validateReserveTokensImpls( - _findReserveConfigBySymbol(allConfigsAfter, 'PSP'), - ReserveTokens({ - aToken: aTokenImpl, - stableDebtToken: sTokenImpl, - variableDebtToken: vTokenImpl - }) - ); - - _validateAssetSourceOnOracle( - IPoolAddressesProvider(address(contracts.poolAddressesProvider)), - asset, - feed - ); - - _validateInterestRateStrategy( - asset, - contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), - AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), - IDefaultInterestRateStrategyV2.InterestRateDataRay({ - optimalUsageRatio: _bpsToRay( - payload.newListingsCustom()[0].base.rateStrategyParams.optimalUsageRatio - ), - baseVariableBorrowRate: _bpsToRay( - payload.newListingsCustom()[0].base.rateStrategyParams.baseVariableBorrowRate - ), - variableRateSlope1: _bpsToRay( - payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope1 - ), - variableRateSlope2: _bpsToRay( - payload.newListingsCustom()[0].base.rateStrategyParams.variableRateSlope2 - ) - }) - ); - } - - function testCapsUpdate() public { - // this asset has been listed before - address asset = tokenList.usdx; - AaveV3MockCapUpdate payload = new AaveV3MockCapUpdate(asset, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineCaps', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineCaps', - IPool(address(contracts.poolProxy)) - ); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - - diffReports('preTestEngineCaps', 'postTestEngineCaps'); - - expectedAssetConfig.supplyCap = 1_000_000; - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - function testCollateralsUpdates() public { - // this asset has been listed before - address asset = tokenList.usdx; - AaveV3MockCollateralUpdate payload = new AaveV3MockCollateralUpdate(asset, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineCollateral', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineCollateral', - IPool(address(contracts.poolProxy)) - ); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - - diffReports('preTestEngineCollateral', 'postTestEngineCollateral'); - - expectedAssetConfig.ltv = 62_00; - expectedAssetConfig.liquidationThreshold = 72_00; - expectedAssetConfig.liquidationBonus = 106_00; // 100_00 + 6_00 - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - // TODO manage this after testFail* deprecation. - // This should not be necessary, but there seems there is no other way - // of validating that when all collateral params are KEEP_CURRENT, the config - // engine doesn't call the POOL_CONFIGURATOR. - // So the solution is expecting the event emitted on the POOL_CONFIGURATOR, - // and as this doesn't happen, expect the failure of the test - function testFailCollateralsUpdatesNoChange() public { - // this asset has been listed before - address asset = tokenList.usdx; - AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange( - asset, - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineCollateralNoChange', - IPool(address(contracts.poolProxy)) - ); - - vm.expectEmit(); - emit CollateralConfigurationChanged( - allConfigsBefore[0].underlying, - allConfigsBefore[0].ltv, - allConfigsBefore[0].liquidationThreshold, - allConfigsBefore[0].liquidationBonus - ); - payload.execute(); - } - - // Same as testFailCollateralsUpdatesNoChange, but this time should work, as we are not expecting any event emitted - function testCollateralsUpdatesNoChange() public { - // this asset has been listed before - address asset = tokenList.usdx; - AaveV3MockCollateralUpdateNoChange payload = new AaveV3MockCollateralUpdateNoChange( - asset, - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineCollateralNoChange', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineCollateralNoChange', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineCollateralNoChange', 'postTestEngineCollateralNoChange'); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - function testCollateralUpdateWrongBonus() public { - address asset = tokenList.usdx; - AaveV3MockCollateralUpdateWrongBonus payload = new AaveV3MockCollateralUpdateWrongBonus( - asset, - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - vm.expectRevert(bytes('INVALID_LT_LB_RATIO')); - payload.execute(); - } - - function testCollateralUpdateCorrectBonus() public { - address asset = tokenList.usdx; - AaveV3MockCollateralUpdateCorrectBonus payload = new AaveV3MockCollateralUpdateCorrectBonus( - asset, - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineCollateralEdgeBonus', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineCollateralEdgeBonus', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineCollateralEdgeBonus', 'postTestEngineCollateralEdgeBonus'); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - expectedAssetConfig.ltv = 62_00; - expectedAssetConfig.liquidationThreshold = 90_00; - expectedAssetConfig.liquidationBonus = 111_00; // 100_00 + 11_00 - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - function testBorrowsUpdates() public { - address asset = tokenList.usdx; - AaveV3MockBorrowUpdate payload = new AaveV3MockBorrowUpdate(asset, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineBorrow', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineBorrow', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineBorrow', 'postTestEngineBorrow'); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - expectedAssetConfig.reserveFactor = 15_00; - expectedAssetConfig.borrowingEnabled = true; - expectedAssetConfig.isFlashloanable = false; - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - function testBorrowUpdatesNoChange() public { - address asset = tokenList.usdx; - AaveV3MockBorrowUpdateNoChange payload = new AaveV3MockBorrowUpdateNoChange( - asset, - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot( - 'preTestEngineBorrowNoChange', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot( - 'postTestEngineBorrowNoChange', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineBorrowNoChange', 'postTestEngineBorrowNoChange'); - - ReserveConfig memory expectedAssetConfig = _findReserveConfig(allConfigsBefore, asset); - - _validateReserveConfig(expectedAssetConfig, allConfigsAfter); - } - - function testRateStrategiesUpdates() public { - address asset = tokenList.usdx; - AaveV3MockRatesUpdate payload = new AaveV3MockRatesUpdate(asset, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - createConfigurationSnapshot('preTestEngineRates', IPool(address(contracts.poolProxy))); - - payload.execute(); - - createConfigurationSnapshot('postTestEngineRates', IPool(address(contracts.poolProxy))); - - diffReports('preTestEngineRates', 'postTestEngineRates'); - - _validateInterestRateStrategy( - asset, - contracts.protocolDataProvider.getInterestRateStrategyAddress(asset), - AaveV3ConfigEngine(configEngine).DEFAULT_INTEREST_RATE_STRATEGY(), - IDefaultInterestRateStrategyV2.InterestRateDataRay({ - optimalUsageRatio: _bpsToRay(payload.rateStrategiesUpdates()[0].params.optimalUsageRatio), - baseVariableBorrowRate: _bpsToRay( - payload.rateStrategiesUpdates()[0].params.baseVariableBorrowRate - ), - variableRateSlope1: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope1), - variableRateSlope2: _bpsToRay(payload.rateStrategiesUpdates()[0].params.variableRateSlope2) - }) - ); - } - - function testPriceFeedsUpdates() public { - address asset = tokenList.usdx; - address newFeed = address(new MockAggregator(int256(1.05e8))); - AaveV3MockPriceFeedUpdate payload = new AaveV3MockPriceFeedUpdate(asset, newFeed, configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - createConfigurationSnapshot('preTestEnginePriceFeed', IPool(address(contracts.poolProxy))); - - payload.execute(); - - createConfigurationSnapshot('postTestEnginePriceFeed', IPool(address(contracts.poolProxy))); - - diffReports('preTestEnginePriceFeed', 'postTestEnginePriceFeed'); - - _validateAssetSourceOnOracle( - IPoolAddressesProvider(address(contracts.poolAddressesProvider)), - asset, - newFeed - ); - } - - function testEModeCategoryUpdates() public { - AaveV3MockEModeCategoryUpdate payload = new AaveV3MockEModeCategoryUpdate(configEngine); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - contracts.poolProxy.getEModeCategoryData(1); - - createConfigurationSnapshot( - 'preTestEngineEModeCategoryUpdate', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - createConfigurationSnapshot( - 'postTestEngineEModeCategoryUpdate', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineEModeCategoryUpdate', 'postTestEngineEModeCategoryUpdate'); - - DataTypeOld.EModeCategory memory prevEmodeCategoryData; - prevEmodeCategoryData.ltv = 97_40; - prevEmodeCategoryData.liquidationThreshold = 97_60; - prevEmodeCategoryData.liquidationBonus = 101_50; // 100_00 + 1_50 - prevEmodeCategoryData.priceSource = address(0); - prevEmodeCategoryData.label = 'ETH Correlated'; - - _validateEmodeCategory( - IPoolAddressesProvider(address(contracts.poolAddressesProvider)), - 1, - prevEmodeCategoryData - ); - } - - function testEModeCategoryUpdatesWrongBonus() public { - AaveV3MockEModeCategoryUpdateEdgeBonus payload = new AaveV3MockEModeCategoryUpdateEdgeBonus( - configEngine - ); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - vm.expectRevert(bytes('INVALID_LT_LB_RATIO')); - payload.execute(); - } - - // TODO manage this after testFail* deprecation. - function testFailEModeCategoryUpdatesNoChange() public { - AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange( - configEngine - ); - - DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts - .poolProxy - .getEModeCategoryData(1); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - vm.expectEmit(true, true, true, true); - emit EModeCategoryAdded( - 1, - eModeCategoryDataBefore.ltv, - eModeCategoryDataBefore.liquidationThreshold, - eModeCategoryDataBefore.liquidationBonus, - eModeCategoryDataBefore.priceSource, - eModeCategoryDataBefore.label - ); - payload.execute(); - } - - // Same as testFailEModeCategoryUpdatesNoChange, but this time should work, as we are not expecting any event emitted - function testEModeCategoryUpdatesNoChange() public { - AaveV3MockEModeCategoryUpdateNoChange payload = new AaveV3MockEModeCategoryUpdateNoChange( - configEngine - ); - - DataTypes.EModeCategory memory eModeCategoryDataBefore = contracts - .poolProxy - .getEModeCategoryData(1); - - vm.prank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - - createConfigurationSnapshot( - 'preTestEngineEModeCategoryNoChange', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - createConfigurationSnapshot( - 'postTestEngineEModeCategoryNoChange', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineEModeCategoryNoChange', 'postTestEngineEModeCategoryNoChange'); - - DataTypeOld.EModeCategory memory prevEmodeCategoryData; - prevEmodeCategoryData.ltv = eModeCategoryDataBefore.ltv; - prevEmodeCategoryData.liquidationThreshold = eModeCategoryDataBefore.liquidationThreshold; - prevEmodeCategoryData.liquidationBonus = eModeCategoryDataBefore.liquidationBonus; - prevEmodeCategoryData.priceSource = eModeCategoryDataBefore.priceSource; - prevEmodeCategoryData.label = eModeCategoryDataBefore.label; - - _validateEmodeCategory( - IPoolAddressesProvider(address(contracts.poolAddressesProvider)), - 1, - prevEmodeCategoryData - ); - } - - function testAssetEModeUpdates() public { - address asset = tokenList.usdx; - - AaveV3MockEModeCategoryUpdate payloadToAddEMode = new AaveV3MockEModeCategoryUpdate( - configEngine - ); - AaveV3MockAssetEModeUpdate payload = new AaveV3MockAssetEModeUpdate(asset, configEngine); - - vm.startPrank(roleList.marketOwner); - contracts.aclManager.addPoolAdmin(address(payload)); - contracts.aclManager.addPoolAdmin(address(payloadToAddEMode)); - vm.stopPrank(); - - payloadToAddEMode.execute(); - - createConfigurationSnapshot( - 'preTestEngineAssetEModeUpdate', - IPool(address(contracts.poolProxy)) - ); - - payload.execute(); - - createConfigurationSnapshot( - 'postTestEngineAssetEModeUpdate', - IPool(address(contracts.poolProxy)) - ); - - diffReports('preTestEngineAssetEModeUpdate', 'postTestEngineAssetEModeUpdate'); - - assertEq(contracts.protocolDataProvider.getReserveEModeCategory(asset), 1); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol deleted file mode 100644 index 5e2d45ac..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock asset e-mode update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockAssetEModeUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function assetsEModeUpdates() public view override returns (IEngine.AssetEModeUpdate[] memory) { - IEngine.AssetEModeUpdate[] memory eModeUpdate = new IEngine.AssetEModeUpdate[](1); - - eModeUpdate[0] = IEngine.AssetEModeUpdate({asset: ASSET_ADDRESS, eModeCategory: 1}); - - return eModeUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol deleted file mode 100644 index d397e9f1..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdate.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock borrow update, to be able to test - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3MockBorrowUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function borrowsUpdates() public view override returns (IEngine.BorrowUpdate[] memory) { - IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); - - borrowsUpdate[0] = IEngine.BorrowUpdate({ - asset: ASSET_ADDRESS, - enabledToBorrow: EngineFlags.ENABLED, - flashloanable: EngineFlags.DISABLED, - stableRateModeEnabled: EngineFlags.KEEP_CURRENT, - borrowableInIsolation: EngineFlags.KEEP_CURRENT, - withSiloedBorrowing: EngineFlags.KEEP_CURRENT, - reserveFactor: 15_00 - }); - - return borrowsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol deleted file mode 100644 index b7176035..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockBorrowUpdateNoChange.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock borrow update with no change, to be able to test - * @author BGD Labs - */ -contract AaveV3MockBorrowUpdateNoChange is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function borrowsUpdates() public view override returns (IEngine.BorrowUpdate[] memory) { - IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); - - borrowsUpdate[0] = IEngine.BorrowUpdate({ - asset: ASSET_ADDRESS, - enabledToBorrow: EngineFlags.KEEP_CURRENT, - flashloanable: EngineFlags.KEEP_CURRENT, - stableRateModeEnabled: EngineFlags.KEEP_CURRENT, - borrowableInIsolation: EngineFlags.KEEP_CURRENT, - withSiloedBorrowing: EngineFlags.KEEP_CURRENT, - reserveFactor: EngineFlags.KEEP_CURRENT - }); - - return borrowsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol deleted file mode 100644 index 7575fa20..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockCapUpdate.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock caps update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockCapUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function capsUpdates() public view override returns (IEngine.CapsUpdate[] memory) { - IEngine.CapsUpdate[] memory capsUpdate = new IEngine.CapsUpdate[](1); - - capsUpdate[0] = IEngine.CapsUpdate({ - asset: ASSET_ADDRESS, - supplyCap: 1_000_000, - borrowCap: EngineFlags.KEEP_CURRENT - }); - - return capsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol deleted file mode 100644 index 70e38f1e..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdate.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock collateral update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockCollateralUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: ASSET_ADDRESS, - ltv: 62_00, - liqThreshold: 72_00, - liqBonus: 6_00, - debtCeiling: EngineFlags.KEEP_CURRENT, - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); - - return collateralsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol deleted file mode 100644 index 12c9221f..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateNoChange.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock collateral update with no changes, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockCollateralUpdateNoChange is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: ASSET_ADDRESS, - ltv: EngineFlags.KEEP_CURRENT, - liqThreshold: EngineFlags.KEEP_CURRENT, - liqBonus: EngineFlags.KEEP_CURRENT, - debtCeiling: EngineFlags.KEEP_CURRENT, - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); - - return collateralsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol deleted file mode 100644 index b41f26d5..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockCollateralUpdateWrongBonus.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contracts for a mock collateral update, with wrong LT/LB ratio - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockCollateralUpdateWrongBonus is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: ASSET_ADDRESS, - ltv: 62_00, - liqThreshold: 90_00, - liqBonus: 12_00, - debtCeiling: EngineFlags.KEEP_CURRENT, - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); - - return collateralsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} - -/** - * @dev Smart contracts for a mock collateral update, with correct (but edge) LT/LB ratio - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockCollateralUpdateCorrectBonus is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function collateralsUpdates() public view override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: ASSET_ADDRESS, - ltv: 62_00, - liqThreshold: 90_00, - liqBonus: 11_00, - debtCeiling: EngineFlags.KEEP_CURRENT, - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); - - return collateralsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol deleted file mode 100644 index 796b4009..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdate.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock emode category update, to be able to test - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3MockEModeCategoryUpdate is AaveV3Payload { - constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} - - function eModeCategoriesUpdates() - public - pure - override - returns (IEngine.EModeCategoryUpdate[] memory) - { - IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); - - eModeUpdates[0] = IEngine.EModeCategoryUpdate({ - eModeCategory: 1, - ltv: 97_40, - liqThreshold: 97_60, - liqBonus: 1_50, - priceSource: address(0), - label: 'ETH Correlated' - }); - - return eModeUpdates; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Polygon', networkAbbreviation: 'Pol'}); - } -} - -/** - * @dev Smart contract for a mock emode category update, to be able to test - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3MockEModeCategoryUpdateEdgeBonus is AaveV3Payload { - constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} - - function eModeCategoriesUpdates() - public - pure - override - returns (IEngine.EModeCategoryUpdate[] memory) - { - IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); - - eModeUpdates[0] = IEngine.EModeCategoryUpdate({ - eModeCategory: 1, - ltv: 97_40, - liqThreshold: 97_60, - liqBonus: 2_50, - priceSource: EngineFlags.KEEP_CURRENT_ADDRESS, - label: EngineFlags.KEEP_CURRENT_STRING - }); - - return eModeUpdates; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol deleted file mode 100644 index b36ce80c..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockEModeCategoryUpdateNoChange.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock e-mode category update with no changes, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockEModeCategoryUpdateNoChange is AaveV3Payload { - constructor(address customEngine) AaveV3Payload(IEngine(customEngine)) {} - - function eModeCategoriesUpdates() - public - pure - override - returns (IEngine.EModeCategoryUpdate[] memory) - { - IEngine.EModeCategoryUpdate[] memory eModeUpdates = new IEngine.EModeCategoryUpdate[](1); - - eModeUpdates[0] = IEngine.EModeCategoryUpdate({ - eModeCategory: 1, - ltv: EngineFlags.KEEP_CURRENT, - liqThreshold: EngineFlags.KEEP_CURRENT, - liqBonus: EngineFlags.KEEP_CURRENT, - priceSource: EngineFlags.KEEP_CURRENT_ADDRESS, - label: EngineFlags.KEEP_CURRENT_STRING - }); - - return eModeUpdates; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol deleted file mode 100644 index 825e80ee..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockListing.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock listing, to be able to test without having a v3 instance on Local - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3MockListing is AaveV3Payload { - address public immutable ASSET_ADDRESS; - address public immutable ASSET_FEED; - - constructor( - address assetAddress, - address assetFeed, - address customEngine - ) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - ASSET_FEED = assetFeed; - } - - function newListings() public view override returns (IEngine.Listing[] memory) { - IEngine.Listing[] memory listings = new IEngine.Listing[](1); - - listings[0] = IEngine.Listing({ - asset: ASSET_ADDRESS, - assetSymbol: '1INCH', - priceFeed: ASSET_FEED, - rateStrategyParams: IEngine.InterestRateInputData({ - optimalUsageRatio: 80_00, - baseVariableBorrowRate: 25, // 0.25% - variableRateSlope1: 3_00, - variableRateSlope2: 75_00 - }), - enabledToBorrow: EngineFlags.ENABLED, - stableRateModeEnabled: EngineFlags.DISABLED, - borrowableInIsolation: EngineFlags.DISABLED, - withSiloedBorrowing: EngineFlags.DISABLED, - flashloanable: EngineFlags.DISABLED, - ltv: 82_50, - liqThreshold: 86_00, - liqBonus: 5_00, - reserveFactor: 10_00, - supplyCap: 85_000, - borrowCap: 60_000, - debtCeiling: 0, - liqProtocolFee: 10_00, - eModeCategory: 0 - }); - - return listings; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol deleted file mode 100644 index dc41c531..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockListingCustom.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock custom listing update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockListingCustom is AaveV3Payload { - address public immutable ASSET_ADDRESS; - address public immutable ASSET_FEED; - - address public immutable A_TOKEN_IMPL; - address public immutable V_TOKEN_IMPL; - address public immutable S_TOKEN_IMPL; - - constructor( - address assetAddress, - address assetFeed, - address customEngine, - address aTokenImpl, - address vTokenImpl, - address sTokenImpl - ) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - ASSET_FEED = assetFeed; - A_TOKEN_IMPL = aTokenImpl; - V_TOKEN_IMPL = vTokenImpl; - S_TOKEN_IMPL = sTokenImpl; - } - - function newListingsCustom() - public - view - override - returns (IEngine.ListingWithCustomImpl[] memory) - { - IEngine.ListingWithCustomImpl[] memory listingsCustom = new IEngine.ListingWithCustomImpl[](1); - - listingsCustom[0] = IEngine.ListingWithCustomImpl( - IEngine.Listing({ - asset: ASSET_ADDRESS, - assetSymbol: 'PSP', - priceFeed: ASSET_FEED, - rateStrategyParams: IEngine.InterestRateInputData({ - optimalUsageRatio: 80_00, - baseVariableBorrowRate: 25, // 0.25% - variableRateSlope1: 3_00, - variableRateSlope2: 75_00 - }), - enabledToBorrow: EngineFlags.ENABLED, - stableRateModeEnabled: EngineFlags.DISABLED, - borrowableInIsolation: EngineFlags.DISABLED, - withSiloedBorrowing: EngineFlags.DISABLED, - flashloanable: EngineFlags.DISABLED, - ltv: 82_50, - liqThreshold: 86_00, - liqBonus: 5_00, - reserveFactor: 10_00, - supplyCap: 85_000, - borrowCap: 60_000, - debtCeiling: 0, - liqProtocolFee: 10_00, - eModeCategory: 0 - }), - IEngine.TokenImplementations({ - aToken: A_TOKEN_IMPL, - vToken: V_TOKEN_IMPL, - sToken: S_TOKEN_IMPL - }) - ); - - return listingsCustom; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol deleted file mode 100644 index 0b5bd8b1..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockPriceFeedUpdate.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock price feed update, to be able to test - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3MockPriceFeedUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - address public immutable ASSET_FEED; - - constructor( - address assetAddress, - address feed, - address customEngine - ) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - ASSET_FEED = feed; - } - - function priceFeedsUpdates() public view override returns (IEngine.PriceFeedUpdate[] memory) { - IEngine.PriceFeedUpdate[] memory priceFeedsUpdate = new IEngine.PriceFeedUpdate[](1); - - priceFeedsUpdate[0] = IEngine.PriceFeedUpdate({asset: ASSET_ADDRESS, priceFeed: ASSET_FEED}); - - return priceFeedsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol deleted file mode 100644 index 42214ccc..00000000 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockRatesUpdate.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock rate strategy params update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV3MockRatesUpdate is AaveV3Payload { - address public immutable ASSET_ADDRESS; - - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { - ASSET_ADDRESS = assetAddress; - } - - function rateStrategiesUpdates() - public - view - override - returns (IEngine.RateStrategyUpdate[] memory) - { - IEngine.RateStrategyUpdate[] memory ratesUpdate = new IEngine.RateStrategyUpdate[](1); - - ratesUpdate[0] = IEngine.RateStrategyUpdate({ - asset: ASSET_ADDRESS, - params: IEngine.InterestRateInputData({ - optimalUsageRatio: 50_00, - baseVariableBorrowRate: 30, // 0.30% - variableRateSlope1: 4_00, - variableRateSlope2: 76_00 - }) - }); - - return ratesUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Local', networkAbbreviation: 'Loc'}); - } -} diff --git a/tests/utils/BatchTestProcedures.sol b/tests/utils/BatchTestProcedures.sol index dfdcd416..ea6dd5b0 100644 --- a/tests/utils/BatchTestProcedures.sol +++ b/tests/utils/BatchTestProcedures.sol @@ -63,7 +63,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput AaveV3GettersBatchOne.GettersReportBatchOne memory gettersReport1, PoolReport memory poolReport, PeripheryReport memory peripheryReport, - MiscReport memory miscReport, + ParaswapReport memory paraswapReport, AaveV3SetupBatch setupContract ) { @@ -92,14 +92,21 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput address(setupContract) ); - miscReport = AaveV3BatchOrchestration._deployMisc( - flags.l2, + paraswapReport = AaveV3BatchOrchestration._deployParaswapAdapters( + roles, + config, initialReport.poolAddressesProvider, - config.l2SequencerUptimeFeed, - config.l2PriceOracleSentinelGracePeriod + peripheryReport.treasury ); - return (initialReport, gettersReport1, poolReport, peripheryReport, miscReport, setupContract); + return ( + initialReport, + gettersReport1, + poolReport, + peripheryReport, + paraswapReport, + setupContract + ); } function deployAndSetup( @@ -116,8 +123,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput PoolReport memory poolReport, SetupReport memory setupReport, PeripheryReport memory peripheryReport, - MiscReport memory miscReport, - AaveV3TokensBatch.TokensReport memory tokensReport, ParaswapReport memory paraswapReport, AaveV3SetupBatch setupContract ) @@ -127,7 +132,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput gettersReport1, poolReport, peripheryReport, - miscReport, + paraswapReport, setupContract ) = deployCoreAndPeriphery(roles, config, flags, deployedContracts); @@ -139,15 +144,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput poolReport.poolConfiguratorImplementation, gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, - peripheryReport.rewardsControllerImplementation, - miscReport.priceOracleSentinel - ); - - paraswapReport = AaveV3BatchOrchestration._deployParaswapAdapters( - roles, - config, - initialReport.poolAddressesProvider, - peripheryReport.treasury + peripheryReport.rewardsControllerImplementation ); gettersReport2 = AaveV3BatchOrchestration._deployGettersBatch2( @@ -157,8 +154,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput flags.l2 ); - tokensReport = AaveV3BatchOrchestration._deployTokens(setupReport.poolProxy); - return ( initialReport, gettersReport1, @@ -166,8 +161,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput poolReport, setupReport, peripheryReport, - miscReport, - tokensReport, paraswapReport, setupContract ); @@ -182,7 +175,10 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput assertTrue(r.poolConfiguratorImplementation != address(0), 'r.poolConfiguratorImplementation'); assertTrue(r.protocolDataProvider != address(0), 'report.protocolDataProvider'); assertTrue(r.aaveOracle != address(0), 'report.aaveOracle'); - assertTrue(r.defaultInterestRateStrategy != address(0), 'report.defaultInterestRateStrategy'); + assertTrue( + r.defaultInterestRateStrategy != address(0), + 'report.defaultInterestRateStrategy' + ); assertTrue(r.aclManager != address(0), 'report.aclManager'); assertTrue(r.treasury != address(0), 'report.treasury'); assertTrue(r.proxyAdmin != address(0), 'report.proxyAdmin'); @@ -198,7 +194,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput if (flags.l2) { assertTrue(r.l2Encoder != address(0), 'report.l2Encoder'); - assertTrue(r.priceOracleSentinel != address(0), 'report.priceOracleSentinel'); } assertTrue(r.aToken != address(0), 'report.aToken'); @@ -210,14 +205,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput 'r.rewardsControllerImplementation' ); assertTrue(r.rewardsControllerProxy != address(0), 'report.rewardsControllerProxy'); - assertTrue(r.configEngine != address(0), 'report.configEngine'); - assertTrue( - r.staticATokenFactoryImplementation != address(0), - 'report.staticATokenFactoryImplementation' - ); - assertTrue(r.staticATokenFactoryProxy != address(0), 'report.staticATokenFactoryProxy'); - assertTrue(r.staticATokenImplementation != address(0), 'report.staticATokenImplementation'); - assertTrue(r.transparentProxyFactory != address(0), 'report.transparentProxyFactory'); } function deployAaveV3Testnet( @@ -229,12 +216,6 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput ) internal returns (MarketReport memory testReport) { detectFoundryLibrariesAndDelete(); - // Etch the create2 factory - vm.etch( - 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, - hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' - ); - vm.startPrank(deployer); MarketReport memory deployReport = AaveV3BatchOrchestration.deployAaveV3( deployer, diff --git a/tests/utils/ConfigEngineDeployer.sol b/tests/utils/ConfigEngineDeployer.sol new file mode 100644 index 00000000..5f3e3bb3 --- /dev/null +++ b/tests/utils/ConfigEngineDeployer.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {Vm} from 'forge-std/Vm.sol'; +import {Create2Utils} from '../../src/deployments/contracts/utilities/Create2Utils.sol'; +import {AaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; +import {IAaveV3ConfigEngine} from '../../src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol'; +import {IPoolAddressesProvider} from '../../src/contracts/interfaces/IPoolAddressesProvider.sol'; +import {IPool} from '../../src/contracts/interfaces/IPool.sol'; +import {IPoolConfigurator} from '../../src/contracts/interfaces/IPoolConfigurator.sol'; +import {IAaveOracle} from '../../src/contracts/interfaces/IAaveOracle.sol'; +import {CapsEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/CapsEngine.sol'; +import {BorrowEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/BorrowEngine.sol'; +import {CollateralEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/CollateralEngine.sol'; +import {RateEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/RateEngine.sol'; +import {PriceFeedEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/PriceFeedEngine.sol'; +import {EModeEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol'; +import {ListingEngine} from '../../src/contracts/extensions/v3-config-engine/libraries/ListingEngine.sol'; + +library ConfigEngineDeployer { + function deployEngine(Vm vm, MarketReport memory report) internal returns (address) { + // Etch the create2 factory in the local env + vm.etch( + 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, + hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' + ); + IAaveV3ConfigEngine.EngineLibraries memory engineLibraries = IAaveV3ConfigEngine + .EngineLibraries({ + listingEngine: Create2Utils._create2Deploy('v1', type(ListingEngine).creationCode), + eModeEngine: Create2Utils._create2Deploy('v1', type(EModeEngine).creationCode), + borrowEngine: Create2Utils._create2Deploy('v1', type(BorrowEngine).creationCode), + collateralEngine: Create2Utils._create2Deploy('v1', type(CollateralEngine).creationCode), + priceFeedEngine: Create2Utils._create2Deploy('v1', type(PriceFeedEngine).creationCode), + rateEngine: Create2Utils._create2Deploy('v1', type(RateEngine).creationCode), + capsEngine: Create2Utils._create2Deploy('v1', type(CapsEngine).creationCode) + }); + + IAaveV3ConfigEngine.EngineConstants memory engineConstants = IAaveV3ConfigEngine + .EngineConstants({ + pool: IPool(report.poolProxy), + poolConfigurator: IPoolConfigurator(report.poolConfiguratorProxy), + defaultInterestRateStrategy: report.defaultInterestRateStrategy, + oracle: IAaveOracle(report.aaveOracle), + rewardsController: report.rewardsControllerProxy, + collector: report.treasury + }); + + return + address( + new AaveV3ConfigEngine( + report.aToken, + report.variableDebtToken, + report.stableDebtToken, + engineConstants, + engineLibraries + ) + ); + } +} diff --git a/tests/utils/SigUtils.sol b/tests/utils/SigUtils.sol deleted file mode 100644 index 72aed63c..00000000 --- a/tests/utils/SigUtils.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.10; - -import {IStaticATokenLM} from '../../src/contracts/extensions/static-a-token/interfaces/IStaticATokenLM.sol'; - -library SigUtils { - struct Permit { - address owner; - address spender; - uint256 value; - uint256 nonce; - uint256 deadline; - } - - struct WithdrawPermit { - address owner; - address spender; - uint256 staticAmount; - uint256 dynamicAmount; - bool toUnderlying; - uint256 nonce; - uint256 deadline; - } - - struct DepositPermit { - address owner; - address spender; - uint256 value; - uint16 referralCode; - bool fromUnderlying; - uint256 nonce; - uint256 deadline; - IStaticATokenLM.PermitParams permit; - } - - // computes the hash of a permit - function getStructHash(Permit memory _permit, bytes32 typehash) internal pure returns (bytes32) { - return - keccak256( - abi.encode( - typehash, - _permit.owner, - _permit.spender, - _permit.value, - _permit.nonce, - _permit.deadline - ) - ); - } - - function getWithdrawHash( - WithdrawPermit memory permit, - bytes32 typehash - ) internal pure returns (bytes32) { - return - keccak256( - abi.encode( - typehash, - permit.owner, - permit.spender, - permit.staticAmount, - permit.dynamicAmount, - permit.toUnderlying, - permit.nonce, - permit.deadline - ) - ); - } - - function getDepositHash( - DepositPermit memory permit, - bytes32 typehash - ) internal pure returns (bytes32) { - return - keccak256( - abi.encode( - typehash, - permit.owner, - permit.spender, - permit.value, - permit.referralCode, - permit.fromUnderlying, - permit.nonce, - permit.deadline, - permit.permit - ) - ); - } - - // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer - function getTypedDataHash( - Permit memory permit, - bytes32 typehash, - bytes32 domainSeparator - ) public pure returns (bytes32) { - return - keccak256(abi.encodePacked('\x19\x01', domainSeparator, getStructHash(permit, typehash))); - } - - function getTypedWithdrawHash( - WithdrawPermit memory permit, - bytes32 typehash, - bytes32 domainSeparator - ) public pure returns (bytes32) { - return - keccak256(abi.encodePacked('\x19\x01', domainSeparator, getWithdrawHash(permit, typehash))); - } - - function getTypedDepositHash( - DepositPermit memory permit, - bytes32 typehash, - bytes32 domainSeparator - ) public pure returns (bytes32) { - return - keccak256(abi.encodePacked('\x19\x01', domainSeparator, getDepositHash(permit, typehash))); - } -} diff --git a/tests/utils/TestnetProcedures.sol b/tests/utils/TestnetProcedures.sol index 5d74854a..480c091b 100644 --- a/tests/utils/TestnetProcedures.sol +++ b/tests/utils/TestnetProcedures.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import '../../src/deployments/interfaces/IMarketReportTypes.sol'; +import {ConfigEngineDeployer} from './ConfigEngineDeployer.sol'; import {DeployUtils} from '../../src/deployments/contracts/utilities/DeployUtils.sol'; import {FfiUtils} from '../../src/deployments/contracts/utilities/FfiUtils.sol'; import {DefaultMarketInput} from '../../src/deployments/inputs/DefaultMarketInput.sol'; @@ -112,13 +113,8 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { MarketReport memory deployedContracts ) = _getMarketInput(poolAdmin); roleList = roles; - flags.l2 = l2; - // Etch the create2 factory - vm.etch( - 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7, - hex'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3' - ); + flags.l2 = l2; (report, tokenList) = deployAaveV3TestnetAssets( poolAdmin, @@ -224,8 +220,10 @@ contract TestnetProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput { MarketReport memory r = deployAaveV3Testnet(deployer, roles, config, flags, deployedContracts); + address engine = ConfigEngineDeployer.deployEngine(vm, r); + AaveV3TestListing testnetListingPayload = new AaveV3TestListing( - IAaveV3ConfigEngine(r.configEngine), + IAaveV3ConfigEngine(engine), roles.poolAdmin, assetsList.weth, r From 4d2b0700ca4260a6e198a8daf0d99c439909d0cb Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 6 May 2024 17:28:14 +0530 Subject: [PATCH 10/11] fix: tests --- .../PoolConfigurator.reserveRiskConfig.t.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol index caa9dd1e..ab2c00cf 100644 --- a/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol +++ b/tests/protocol/pool/pool-configurator/PoolConfigurator.reserveRiskConfig.t.sol @@ -581,7 +581,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { emit ReservePaused(reserves[x], true); } vm.prank(poolAdmin); - contracts.poolConfiguratorProxy.setPoolPause(true); + contracts.poolConfiguratorProxy.setPoolPause(true, 0); for (uint16 x; x < reserves.length; ++x) { bool isPaused = contracts.protocolDataProvider.getPaused(reserves[x]); @@ -597,7 +597,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { emit ReservePaused(reserves[x], false); } vm.prank(poolAdmin); - contracts.poolConfiguratorProxy.setPoolPause(false); + contracts.poolConfiguratorProxy.setPoolPause(false, 0); for (uint16 x; x < reserves.length; ++x) { bool isPaused = contracts.protocolDataProvider.getPaused(reserves[x]); @@ -740,7 +740,7 @@ contract PoolConfiguratorReserveRiskConfigs is TestnetProcedures { } function test_setLiquidationGracePeriodReserve(uint40 gracePeriod) public { - vm.assume(gracePeriod < contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD() && gracePeriod != 0); + vm.assume(gracePeriod <= contracts.poolConfiguratorProxy.MAX_GRACE_PERIOD()); address asset = tokenList.usdx; From 3244a5b1971a02cb8cf7730ecfeb3a98cb1793e9 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 6 May 2024 17:31:33 +0530 Subject: [PATCH 11/11] fix: lint --- tests/utils/BatchTestProcedures.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/utils/BatchTestProcedures.sol b/tests/utils/BatchTestProcedures.sol index ea6dd5b0..9a2e0984 100644 --- a/tests/utils/BatchTestProcedures.sol +++ b/tests/utils/BatchTestProcedures.sol @@ -175,10 +175,7 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput assertTrue(r.poolConfiguratorImplementation != address(0), 'r.poolConfiguratorImplementation'); assertTrue(r.protocolDataProvider != address(0), 'report.protocolDataProvider'); assertTrue(r.aaveOracle != address(0), 'report.aaveOracle'); - assertTrue( - r.defaultInterestRateStrategy != address(0), - 'report.defaultInterestRateStrategy' - ); + assertTrue(r.defaultInterestRateStrategy != address(0), 'report.defaultInterestRateStrategy'); assertTrue(r.aclManager != address(0), 'report.aclManager'); assertTrue(r.treasury != address(0), 'report.treasury'); assertTrue(r.proxyAdmin != address(0), 'report.proxyAdmin');