diff --git a/.github/workflows/merge-main.yml b/.github/workflows/merge-main.yml index 34d6739be..6b6006545 100644 --- a/.github/workflows/merge-main.yml +++ b/.github/workflows/merge-main.yml @@ -12,8 +12,42 @@ on: jobs: test: - uses: bgd-labs/github-workflows/.github/workflows/foundry-test.yml@main - secrets: inherit - release: - needs: [test] - uses: bgd-labs/github-workflows/.github/workflows/release.yml@main + name: zkSync Foundry build and test + runs-on: ubuntu-latest + env: + FOUNDRY_PROFILE: ci + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + ref: ${{ inputs.ref }} + fetch-depth: 0 + - name: Setup env + uses: bgd-labs/github-workflows/.github/actions/env@main + with: + RPC_MAINNET: ${{secrets.RPC_MAINNET}} + RPC_POLYGON: ${{secrets.RPC_POLYGON}} + RPC_AVALANCHE: ${{secrets.RPC_AVALANCHE}} + RPC_OPTIMISM: ${{secrets.RPC_OPTIMISM}} + RPC_ARBITRUM: ${{secrets.RPC_ARBITRUM}} + RPC_METIS: ${{secrets.RPC_METIS}} + RPC_BASE: ${{secrets.RPC_BASE}} + RPC_GNOSIS: ${{secrets.RPC_GNOSIS}} + RPC_BNB: ${{secrets.RPC_BNB}} + RPC_ZKEVM: ${{secrets.RPC_ZKEVM}} + RPC_SCROLL: ${{secrets.RPC_SCROLL}} + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: nightly-2024-02-06 + - name: Clone Foundry ZkSync + run: git clone https://github.com/matter-labs/foundry-zksync --depth=1 -b dev + - name: Build forge binary + run: | + cd foundry-zksync + cargo build --release --bin forge + - name: Run tests using built binary + run: | + cd .. + forge test --zksync + diff --git a/.gitignore b/.gitignore index 7c0385634..bd687477a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ package-lock.json .DS_Store yarn-error.log +zkout/ # snapshot artifacts reports/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 837cb4ae2..4e1a9a6d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,10 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std -[submodule "lib/solidity-utils"] - path = lib/solidity-utils - url = https://github.com/bgd-labs/solidity-utils [submodule "lib/aave-address-book"] path = lib/aave-address-book url = https://github.com/bgd-labs/aave-address-book + branch = feat/zksync-lib +[submodule "lib/solidity-utils"] + path = lib/solidity-utils + url = https://github.com/bgd-labs/solidity-utils diff --git a/foundry.toml b/foundry.toml index e6ca27298..16e9c87ae 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,7 +8,11 @@ remappings = [] fs_permissions = [{ access = "read-write", path = "./reports" }] ffi = true solc = '0.8.18' -evm_version = 'shanghai' + +[profile.default.zksync] +compile = true +fallback_oz = true +mode = '3' [rpc_endpoints] mainnet = "${RPC_MAINNET}" diff --git a/lib/aave-address-book b/lib/aave-address-book index 63edff27c..dd68e468f 160000 --- a/lib/aave-address-book +++ b/lib/aave-address-book @@ -1 +1 @@ -Subproject commit 63edff27c017c3b5f10e02055d6959aba0d2275e +Subproject commit dd68e468f06c21e3b183d22c9b9db94672ac9739 diff --git a/lib/solidity-utils b/lib/solidity-utils index 17a826c5c..9e1215692 160000 --- a/lib/solidity-utils +++ b/lib/solidity-utils @@ -1 +1 @@ -Subproject commit 17a826c5c7e691f8938043ea72b4040def416015 +Subproject commit 9e1215692ff2db31197b281a1083c52f928a0217 diff --git a/remappings.txt b/remappings.txt index 706bff1af..3de9c02ec 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,6 +1,6 @@ aave-address-book/=lib/aave-address-book/src/ -aave-v3-origin/=lib/aave-address-book/lib/aave-v3-origin/src/ -aave-v3-core/=lib/aave-address-book/lib/aave-v3-origin/src/core -aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-origin/src/periphery +aave-v3-origin/=lib/aave-address-book/lib/aave-v3-origin-private/src/ +aave-v3-core/=lib/aave-address-book/lib/aave-v3-origin-private/src/core +aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-origin-private/src/periphery forge-std/=lib/forge-std/src/ solidity-utils/=lib/solidity-utils/src/ diff --git a/src/AaveHelpers.sol b/src/AaveHelpers.sol index a41e99ef9..77180147a 100644 --- a/src/AaveHelpers.sol +++ b/src/AaveHelpers.sol @@ -2,5 +2,5 @@ pragma solidity >=0.7.5 <0.9.0; import {GovHelpers, AaveGovernanceV2} from './GovHelpers.sol'; -import {ProxyHelpers} from './ProxyHelpers.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; import {ProtocolV3TestBase} from './ProtocolV3TestBase.sol'; diff --git a/src/ChainIds.sol b/src/ChainIds.sol index 02e05397c..4e36654c4 100644 --- a/src/ChainIds.sol +++ b/src/ChainIds.sol @@ -37,6 +37,7 @@ library TestNetChainIds { uint256 internal constant CELO_ALFAJORES = 44787; uint256 internal constant OPTIMISM_SEPOLIA = 11155420; uint256 internal constant ARBITRUM_SEPOLIA = 421614; + uint256 internal constant ZK_SYNC_SEPOLIA = 300; } library ChainHelpers { @@ -76,6 +77,8 @@ library ChainHelpers { newFork = vm.createSelectFork(vm.rpcUrl('sepolia')); } else if (chainId == ChainIds.HARMONY) { newFork = vm.createSelectFork(vm.rpcUrl('harmony')); + } else if (chainId == ChainIds.ZK_SYNC) { + newFork = vm.createSelectFork(vm.rpcUrl('zksync')); } else { revert UnknownChainId(); } @@ -108,6 +111,8 @@ library ChainHelpers { networkName = 'scroll'; } else if (chainId == ChainIds.CELO) { networkName = 'celo'; + } else if (chainId == ChainIds.ZK_SYNC) { + networkName = 'zksync'; } // testnets else if (chainId == TestNetChainIds.ETHEREUM_SEPOLIA) { @@ -132,6 +137,8 @@ library ChainHelpers { networkName = 'scroll_sepolia'; } else if (chainId == TestNetChainIds.CELO_ALFAJORES) { networkName = 'celo_alfajores'; + } else if (chainId == TestNetChainIds.ZK_SYNC_SEPOLIA) { + networkName = 'zksync_sepolia'; } else { revert('chain id is not supported'); } diff --git a/src/GovHelpers.sol b/src/GovHelpers.sol index b443505fa..d47b654bd 100644 --- a/src/GovHelpers.sol +++ b/src/GovHelpers.sol @@ -10,7 +10,7 @@ import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {AaveV3Harmony} from 'aave-address-book/AaveV3Harmony.sol'; import {AaveV3Fantom} from 'aave-address-book/AaveV3Fantom.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {ProxyHelpers} from './ProxyHelpers.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; import {ChainIds} from './ChainIds.sol'; import {StorageHelpers} from './StorageHelpers.sol'; diff --git a/src/GovV3Helpers.sol b/src/GovV3Helpers.sol index 90a5beb39..8d148ca18 100644 --- a/src/GovV3Helpers.sol +++ b/src/GovV3Helpers.sol @@ -22,7 +22,7 @@ import {GovernanceV3PolygonZkEvm} from 'aave-address-book/GovernanceV3PolygonZkE import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {Address} from 'solidity-utils/contracts/oz-common/Address.sol'; import {StorageHelpers} from './StorageHelpers.sol'; -import {ProxyHelpers} from './ProxyHelpers.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; import {Create2Utils} from './ScriptUtils.sol'; interface IGovernance_V2_5 { @@ -695,7 +695,7 @@ library GovV3Helpers { PayloadsControllerUtils.Payload[] memory payloads, bytes32 ipfsHash, address votingPortal - ) public pure { + ) internal pure { string memory payloadsStr; for (uint256 i = 0; i < payloads.length; i++) { string memory payloadBase = string.concat('&payload[', vm.toString(i), '].'); diff --git a/src/ProtocolV2TestBase.sol b/src/ProtocolV2TestBase.sol index 34b3f2083..0edd57bf1 100644 --- a/src/ProtocolV2TestBase.sol +++ b/src/ProtocolV2TestBase.sol @@ -12,8 +12,9 @@ import {DiffUtils} from 'aave-v3-origin/../tests/utils/DiffUtils.sol'; import {IInitializableAdminUpgradeabilityProxy} from './interfaces/IInitializableAdminUpgradeabilityProxy.sol'; import {ExtendedAggregatorV2V3Interface} from './interfaces/ExtendedAggregatorV2V3Interface.sol'; import {CommonTestBase, ReserveTokens} from './CommonTestBase.sol'; -import {ProxyHelpers} from './ProxyHelpers.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; import {ChainIds} from './ChainIds.sol'; +import {SnapshotHelpersV2} from './SnapshotHelpersV2.sol'; struct ReserveConfig { string symbol; @@ -52,6 +53,12 @@ struct InterestStrategyValues { contract ProtocolV2TestBase is CommonTestBase, DiffUtils { using SafeERC20 for IERC20; + SnapshotHelpersV2 public snapshotHelper; + + function setUp() virtual public { + snapshotHelper = new SnapshotHelpersV2(); + } + /** * @dev runs the default test suite that should run on any proposal touching the aave protocol which includes: * - diffing the config @@ -95,19 +102,7 @@ contract ProtocolV2TestBase is CommonTestBase, DiffUtils { string memory reportName, ILendingPool pool ) public returns (ReserveConfig[] memory) { - string memory path = string(abi.encodePacked('./reports/', reportName, '.json')); - vm.writeFile(path, '{ "reserves": {}, "strategies": {}, "poolConfiguration": {} }'); - vm.serializeUint('root', 'chainId', block.chainid); - ReserveConfig[] memory configs = _getReservesConfigs(pool); - ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( - pool.getAddressesProvider() - ); - ILendingRateOracle oracle = ILendingRateOracle(addressesProvider.getLendingRateOracle()); - _writeReserveConfigs(path, configs, pool, oracle); - _writeStrategyConfigs(path, configs); - _writePoolConfiguration(path, pool); - - return configs; + return snapshotHelper.createConfigurationSnapshot(reportName, pool); } /** @@ -328,94 +323,11 @@ contract ProtocolV2TestBase is CommonTestBase, DiffUtils { } function _writeStrategyConfigs(string memory path, ReserveConfig[] memory configs) internal { - // keys for json stringification - string memory strategiesKey = 'stategies'; - string memory content = '{}'; - vm.serializeJson(strategiesKey, '{}'); - - for (uint256 i = 0; i < configs.length; i++) { - IDefaultInterestRateStrategy strategy = IDefaultInterestRateStrategy( - configs[i].interestRateStrategy - ); - string memory key = vm.toString(configs[i].underlying); - vm.serializeJson(key, '{}'); - vm.serializeString(key, 'address', vm.toString(address(strategy))); - vm.serializeString(key, 'stableRateSlope1', vm.toString(strategy.stableRateSlope1())); - vm.serializeString(key, 'stableRateSlope2', vm.toString(strategy.stableRateSlope2())); - vm.serializeString( - key, - 'baseVariableBorrowRate', - vm.toString(strategy.baseVariableBorrowRate()) - ); - vm.serializeString(key, 'variableRateSlope1', vm.toString(strategy.variableRateSlope1())); - vm.serializeString(key, 'variableRateSlope2', vm.toString(strategy.variableRateSlope2())); - vm.serializeString( - key, - 'optimalUsageRatio', - vm.toString(strategy.OPTIMAL_UTILIZATION_RATE()) - ); - string memory object = vm.serializeString( - key, - 'maxExcessUsageRatio', - vm.toString(strategy.EXCESS_UTILIZATION_RATE()) - ); - content = vm.serializeString(strategiesKey, key, object); - } - string memory output = vm.serializeString('root', 'strategies', content); - vm.writeJson(output, path); + return snapshotHelper.writeStrategyConfigs(path, configs); } function _writePoolConfiguration(string memory path, ILendingPool pool) internal { - // keys for json stringification - string memory poolConfigKey = 'poolConfig'; - - // addresses provider - ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( - pool.getAddressesProvider() - ); - vm.serializeAddress(poolConfigKey, 'poolAddressesProvider', address(addressesProvider)); - - // oracle - IAaveOracle oracle = IAaveOracle(addressesProvider.getPriceOracle()); - vm.serializeAddress(poolConfigKey, 'oracle', address(oracle)); - - // pool configurator - ILendingPoolConfigurator configurator = ILendingPoolConfigurator( - addressesProvider.getLendingPoolConfigurator() - ); - vm.serializeAddress(poolConfigKey, 'poolConfigurator', address(configurator)); - vm.serializeAddress( - poolConfigKey, - 'poolConfiguratorImpl', - ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(configurator)) - ); - address lendingPoolCollateralManager = addressesProvider.getLendingPoolCollateralManager(); - vm.serializeAddress( - poolConfigKey, - 'lendingPoolCollateralManager', - address(lendingPoolCollateralManager) - ); - - // PoolDataProvider - IAaveProtocolDataProvider pdp = IAaveProtocolDataProvider( - addressesProvider.getAddress( - pool == AaveV2EthereumAMM.POOL - ? bytes32(0x1000000000000000000000000000000000000000000000000000000000000000) - : bytes32(0x0100000000000000000000000000000000000000000000000000000000000000) - ) - ); - vm.serializeAddress(poolConfigKey, 'protocolDataProvider', address(pdp)); - - // pool - vm.serializeAddress( - poolConfigKey, - 'poolImpl', - ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(pool)) - ); - string memory content = vm.serializeAddress(poolConfigKey, 'pool', address(pool)); - - string memory output = vm.serializeString('root', 'poolConfig', content); - vm.writeJson(output, path); + return snapshotHelper.writePoolConfiguration(path, pool); } function _writeReserveConfigs( @@ -424,152 +336,18 @@ contract ProtocolV2TestBase is CommonTestBase, DiffUtils { ILendingPool pool, ILendingRateOracle rateOracle ) internal { - // keys for json stringification - string memory reservesKey = 'reserves'; - string memory content = '{}'; - vm.serializeJson(reservesKey, '{}'); - - ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( - pool.getAddressesProvider() - ); - IAaveOracle oracle = IAaveOracle(addressesProvider.getPriceOracle()); - - for (uint256 i = 0; i < configs.length; i++) { - ReserveConfig memory config = configs[i]; - ExtendedAggregatorV2V3Interface assetOracle = ExtendedAggregatorV2V3Interface( - oracle.getSourceOfAsset(config.underlying) - ); - - string memory key = vm.toString(config.underlying); - vm.serializeJson(key, '{}'); - vm.serializeString(key, 'symbol', config.symbol); - vm.serializeString( - key, - 'baseStableBorrowRate', - vm.toString(rateOracle.getMarketBorrowRate(config.underlying)) - ); - vm.serializeUint(key, 'ltv', config.ltv); - vm.serializeUint(key, 'liquidationThreshold', config.liquidationThreshold); - vm.serializeUint(key, 'liquidationBonus', config.liquidationBonus); - vm.serializeUint(key, 'reserveFactor', config.reserveFactor); - vm.serializeUint(key, 'decimals', config.decimals); - vm.serializeBool(key, 'usageAsCollateralEnabled', config.usageAsCollateralEnabled); - vm.serializeBool(key, 'borrowingEnabled', config.borrowingEnabled); - vm.serializeBool(key, 'stableBorrowRateEnabled', config.stableBorrowRateEnabled); - vm.serializeBool(key, 'isActive', config.isActive); - vm.serializeBool(key, 'isFrozen', config.isFrozen); - vm.serializeAddress(key, 'interestRateStrategy', config.interestRateStrategy); - vm.serializeAddress(key, 'underlying', config.underlying); - vm.serializeAddress(key, 'aToken', config.aToken); - vm.serializeAddress(key, 'stableDebtToken', config.stableDebtToken); - vm.serializeAddress(key, 'variableDebtToken', config.variableDebtToken); - vm.serializeAddress( - key, - 'aTokenImpl', - ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, config.aToken) - ); - vm.serializeString(key, 'aTokenSymbol', IERC20Metadata(config.aToken).symbol()); - vm.serializeString(key, 'aTokenName', IERC20Metadata(config.aToken).name()); - vm.serializeAddress( - key, - 'stableDebtTokenImpl', - ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( - vm, - config.stableDebtToken - ) - ); - vm.serializeString( - key, - 'stableDebtTokenSymbol', - IERC20Metadata(config.stableDebtToken).symbol() - ); - vm.serializeString(key, 'stableDebtTokenName', IERC20Metadata(config.stableDebtToken).name()); - vm.serializeAddress( - key, - 'variableDebtTokenImpl', - ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( - vm, - config.variableDebtToken - ) - ); - vm.serializeString( - key, - 'variableDebtTokenSymbol', - IERC20Metadata(config.variableDebtToken).symbol() - ); - vm.serializeString( - key, - 'variableDebtTokenName', - IERC20Metadata(config.variableDebtToken).name() - ); - vm.serializeAddress(key, 'oracle', address(assetOracle)); - if (address(assetOracle) != address(0)) { - try assetOracle.description() returns (string memory name) { - vm.serializeString(key, 'oracleDescription', name); - } catch { - try assetOracle.name() returns (string memory name) { - vm.serializeString(key, 'oracleName', name); - } catch {} - } - try assetOracle.decimals() returns (uint8 decimals) { - vm.serializeUint(key, 'oracleDecimals', decimals); - } catch { - try assetOracle.DECIMALS() returns (uint8 decimals) { - vm.serializeUint(key, 'oracleDecimals', decimals); - } catch {} - } - } - string memory out = vm.serializeUint( - key, - 'oracleLatestAnswer', - uint256(oracle.getAssetPrice(config.underlying)) - ); - content = vm.serializeString(reservesKey, key, out); - } - string memory output = vm.serializeString('root', 'reserves', content); - vm.writeJson(output, path); + return snapshotHelper.writeReserveConfigs(path, configs, pool, rateOracle); } function _getReservesConfigs(ILendingPool pool) internal view returns (ReserveConfig[] memory) { - ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( - pool.getAddressesProvider() - ); - IAaveProtocolDataProvider poolDataProvider = IAaveProtocolDataProvider( - addressesProvider.getAddress( - pool == AaveV2EthereumAMM.POOL - ? bytes32(0x1000000000000000000000000000000000000000000000000000000000000000) - : bytes32(0x0100000000000000000000000000000000000000000000000000000000000000) - ) - ); - LocalVars memory vars; - - vars.reserves = poolDataProvider.getAllReservesTokens(); - - vars.configs = new ReserveConfig[](vars.reserves.length); - - for (uint256 i = 0; i < vars.reserves.length; i++) { - vars.configs[i] = _getStructReserveConfig(pool, poolDataProvider, vars.reserves[i]); - ReserveTokens memory reserveTokens = _getStructReserveTokens( - poolDataProvider, - vars.configs[i].underlying - ); - vars.configs[i].aToken = reserveTokens.aToken; - vars.configs[i].variableDebtToken = reserveTokens.variableDebtToken; - vars.configs[i].stableDebtToken = reserveTokens.stableDebtToken; - } - - return vars.configs; + return snapshotHelper.getReservesConfigs(pool); } function _getStructReserveTokens( IAaveProtocolDataProvider pdp, address underlyingAddress ) internal view returns (ReserveTokens memory) { - ReserveTokens memory reserveTokens; - (reserveTokens.aToken, reserveTokens.stableDebtToken, reserveTokens.variableDebtToken) = pdp - .getReserveTokensAddresses(underlyingAddress); - - return reserveTokens; + return snapshotHelper.getStructReserveTokens(pdp, underlyingAddress); } function _getStructReserveConfig( @@ -577,36 +355,7 @@ contract ProtocolV2TestBase is CommonTestBase, DiffUtils { IAaveProtocolDataProvider pdp, TokenData memory reserve ) internal view virtual returns (ReserveConfig memory) { - ReserveConfig memory localConfig; - ( - uint256 decimals, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - uint256 reserveFactor, - bool usageAsCollateralEnabled, - bool borrowingEnabled, - bool stableBorrowRateEnabled, - bool isActive, - bool isFrozen - ) = pdp.getReserveConfigurationData(reserve.tokenAddress); - localConfig.symbol = reserve.symbol; - localConfig.underlying = reserve.tokenAddress; - localConfig.decimals = decimals; - localConfig.ltv = ltv; - localConfig.liquidationThreshold = liquidationThreshold; - localConfig.liquidationBonus = liquidationBonus; - localConfig.reserveFactor = reserveFactor; - localConfig.usageAsCollateralEnabled = usageAsCollateralEnabled; - localConfig.borrowingEnabled = borrowingEnabled; - localConfig.stableBorrowRateEnabled = stableBorrowRateEnabled; - localConfig.interestRateStrategy = pool - .getReserveData(reserve.tokenAddress) - .interestRateStrategyAddress; - localConfig.isActive = isActive; - localConfig.isFrozen = isFrozen; - - return localConfig; + return snapshotHelper.getStructReserveConfig(pool, pdp, reserve); } // TODO This should probably be simplified with assembly, too much boilerplate diff --git a/src/ProtocolV3TestBase.sol b/src/ProtocolV3TestBase.sol index 603c7fac4..e43933483 100644 --- a/src/ProtocolV3TestBase.sol +++ b/src/ProtocolV3TestBase.sol @@ -7,14 +7,14 @@ import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; import {ReserveConfiguration} from 'aave-v3-origin/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; import {DiffUtils} from 'aave-v3-origin/../tests/utils/DiffUtils.sol'; -import {ProtocolV3TestBase as RawProtocolV3TestBase, ReserveConfig} from 'aave-v3-origin/../tests/utils/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase as RawProtocolV3TestBase, ReserveConfig, ReserveTokens} from 'aave-v3-origin/../tests/utils/ProtocolV3TestBase.sol'; import {IInitializableAdminUpgradeabilityProxy} from './interfaces/IInitializableAdminUpgradeabilityProxy.sol'; import {ExtendedAggregatorV2V3Interface} from './interfaces/ExtendedAggregatorV2V3Interface.sol'; -import {ProxyHelpers} from './ProxyHelpers.sol'; -import {CommonTestBase, ReserveTokens} from './CommonTestBase.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; +import {CommonTestBase} from './CommonTestBase.sol'; +import {SnapshotHelpersV3} from './SnapshotHelpersV3.sol'; import {ILegacyDefaultInterestRateStrategy} from './dependencies/ILegacyDefaultInterestRateStrategy.sol'; struct LocalVars { @@ -41,6 +41,12 @@ contract ProtocolV3TestBase is RawProtocolV3TestBase, CommonTestBase { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using SafeERC20 for IERC20; + SnapshotHelpersV3 public snapshotHelper; + + function setUp() virtual public { + snapshotHelper = new SnapshotHelpersV3(); + } + /** * @dev runs the default test suite that should run on any proposal touching the aave protocol which includes: * - diffing the config @@ -118,6 +124,37 @@ contract ProtocolV3TestBase is RawProtocolV3TestBase, CommonTestBase { } } + /** + * @dev Generates a markdown compatible snapshot of the whole pool configuration into `/reports`. + * @param reportName filename suffix for the generated reports. + * @param pool the pool to be snapshot + * @return ReserveConfig[] list of configs + */ + function createConfigurationSnapshot( + string memory reportName, + IPool pool + ) public override returns (ReserveConfig[] memory) { + return createConfigurationSnapshot(reportName, pool, true, true, true, true); + } + + function createConfigurationSnapshot( + string memory reportName, + IPool pool, + bool reserveConfigs, + bool strategyConfigs, + bool eModeConigs, + bool poolConfigs + ) public override returns (ReserveConfig[] memory) { + return snapshotHelper.createConfigurationSnapshot( + reportName, + pool, + reserveConfigs, + strategyConfigs, + eModeConigs, + poolConfigs + ); + } + /** * @dev Makes a e2e test including withdrawals/borrows and supplies to various reserves. * @param pool the pool that should be tested @@ -345,10 +382,113 @@ contract ProtocolV3TestBase is RawProtocolV3TestBase, CommonTestBase { vm.stopPrank(); } - function getIsVirtualAccActive( - DataTypes.ReserveConfigurationMap memory configuration - ) external pure returns (bool) { - return configuration.getIsVirtualAccActive(); + function _writeEModeConfigs( + string memory path, + ReserveConfig[] memory configs, + IPool pool + ) internal override { + return snapshotHelper.writeEModeConfigs( + path, + configs, + pool + ); + } + + function _writeStrategyConfigs(string memory path, ReserveConfig[] memory configs) internal override { + return snapshotHelper.writeStrategyConfigs(path, configs); + } + + function _writeReserveConfigs( + string memory path, + ReserveConfig[] memory configs, + IPool pool + ) internal override { + return snapshotHelper.writeReserveConfigs(path, configs, pool); + } + + function _writePoolConfiguration(string memory path, IPool pool) internal override { + return snapshotHelper.writePoolConfiguration(path, pool); + } + + function _getReservesConfigs(IPool pool) internal view override returns (ReserveConfig[] memory) { + return snapshotHelper.getReservesConfigs(pool); + } + + function _getStructReserveTokens( + IPoolDataProvider pdp, + address underlyingAddress + ) internal view override returns (ReserveTokens memory) { + return snapshotHelper.getStructReserveTokens(pdp, underlyingAddress); + } + + function _getStructReserveConfig( + IPool pool, + IPoolDataProvider.TokenData memory reserve + ) internal view virtual returns (ReserveConfig memory) { + return snapshotHelper.getStructReserveConfig(pool, reserve); + } + + // TODO This should probably be simplified with assembly, too much boilerplate + function _clone(ReserveConfig memory config) internal pure override returns (ReserveConfig memory) { + return + ReserveConfig({ + symbol: config.symbol, + underlying: config.underlying, + aToken: config.aToken, + stableDebtToken: config.stableDebtToken, + variableDebtToken: config.variableDebtToken, + decimals: config.decimals, + ltv: config.ltv, + liquidationThreshold: config.liquidationThreshold, + liquidationBonus: config.liquidationBonus, + liquidationProtocolFee: config.liquidationProtocolFee, + reserveFactor: config.reserveFactor, + usageAsCollateralEnabled: config.usageAsCollateralEnabled, + borrowingEnabled: config.borrowingEnabled, + interestRateStrategy: config.interestRateStrategy, + stableBorrowRateEnabled: config.stableBorrowRateEnabled, + isPaused: config.isPaused, + isActive: config.isActive, + isFrozen: config.isFrozen, + isSiloed: config.isSiloed, + isBorrowableInIsolation: config.isBorrowableInIsolation, + isFlashloanable: config.isFlashloanable, + supplyCap: config.supplyCap, + borrowCap: config.borrowCap, + debtCeiling: config.debtCeiling, + eModeCategory: config.eModeCategory, + virtualAccActive: config.virtualAccActive, + virtualBalance: config.virtualBalance, + aTokenUnderlyingBalance: config.aTokenUnderlyingBalance + }); + } + + function _findReserveConfig( + ReserveConfig[] memory configs, + address underlying + ) internal pure override returns (ReserveConfig memory) { + for (uint256 i = 0; i < configs.length; i++) { + if (configs[i].underlying == underlying) { + // Important to clone the struct, to avoid unexpected side effect if modifying the returned config + return _clone(configs[i]); + } + } + revert('RESERVE_CONFIG_NOT_FOUND'); + } + + function _findReserveConfigBySymbol( + ReserveConfig[] memory configs, + string memory symbolOfUnderlying + ) internal pure override returns (ReserveConfig memory) { + for (uint256 i = 0; i < configs.length; i++) { + if ( + keccak256(abi.encodePacked(configs[i].symbol)) == + keccak256(abi.encodePacked(symbolOfUnderlying)) + ) { + return _clone(configs[i]); + } + } + revert('RESERVE_CONFIG_NOT_FOUND'); } function _logReserveConfig(ReserveConfig memory config) internal view { @@ -382,97 +522,10 @@ contract ProtocolV3TestBase is RawProtocolV3TestBase, CommonTestBase { console.log('-----'); } - function _writeStrategyConfigs( - string memory path, - ReserveConfig[] memory configs - ) internal override { - // keys for json stringification - string memory strategiesKey = 'stategies'; - string memory content = '{}'; - vm.serializeJson(strategiesKey, '{}'); - - for (uint256 i = 0; i < configs.length; i++) { - IDefaultInterestRateStrategyV2 strategyV2 = IDefaultInterestRateStrategyV2( - configs[i].interestRateStrategy - ); - ILegacyDefaultInterestRateStrategy strategyV1 = ILegacyDefaultInterestRateStrategy( - configs[i].interestRateStrategy - ); - address asset = configs[i].underlying; - string memory key = vm.toString(asset); - vm.serializeJson(key, '{}'); - vm.serializeString(key, 'address', vm.toString(configs[i].interestRateStrategy)); - string memory object; - try strategyV1.getVariableRateSlope1() { - vm.serializeString( - key, - 'baseStableBorrowRate', - vm.toString(strategyV1.getBaseStableBorrowRate()) - ); - vm.serializeString(key, 'stableRateSlope1', vm.toString(strategyV1.getStableRateSlope1())); - vm.serializeString(key, 'stableRateSlope2', vm.toString(strategyV1.getStableRateSlope2())); - vm.serializeString( - key, - 'baseVariableBorrowRate', - vm.toString(strategyV1.getBaseVariableBorrowRate()) - ); - vm.serializeString( - key, - 'variableRateSlope1', - vm.toString(strategyV1.getVariableRateSlope1()) - ); - vm.serializeString( - key, - 'variableRateSlope2', - vm.toString(strategyV1.getVariableRateSlope2()) - ); - vm.serializeString( - key, - 'optimalStableToTotalDebtRatio', - vm.toString(strategyV1.OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO()) - ); - vm.serializeString( - key, - 'maxExcessStableToTotalDebtRatio', - vm.toString(strategyV1.MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO()) - ); - vm.serializeString(key, 'optimalUsageRatio', vm.toString(strategyV1.OPTIMAL_USAGE_RATIO())); - object = vm.serializeString( - key, - 'maxExcessUsageRatio', - vm.toString(strategyV1.MAX_EXCESS_USAGE_RATIO()) - ); - } catch { - vm.serializeString( - key, - 'baseVariableBorrowRate', - vm.toString(strategyV2.getBaseVariableBorrowRate(asset)) - ); - vm.serializeString( - key, - 'variableRateSlope1', - vm.toString(strategyV2.getVariableRateSlope1(asset)) - ); - vm.serializeString( - key, - 'variableRateSlope2', - vm.toString(strategyV2.getVariableRateSlope2(asset)) - ); - vm.serializeString( - key, - 'maxVariableBorrowRate', - vm.toString(strategyV2.getMaxVariableBorrowRate(asset)) - ); - object = vm.serializeString( - key, - 'optimalUsageRatio', - vm.toString(strategyV2.getOptimalUsageRatio(asset)) - ); - } - content = vm.serializeString(strategiesKey, key, object); - } - string memory output = vm.serializeString('root', 'strategies', content); - vm.writeJson(output, path); + function getIsVirtualAccActive( + DataTypes.ReserveConfigurationMap memory configuration + ) external pure returns (bool) { + return configuration.getIsVirtualAccActive(); } // TODO: deprecated, remove it later diff --git a/src/SnapshotHelpersV2.sol b/src/SnapshotHelpersV2.sol new file mode 100644 index 000000000..855d3309e --- /dev/null +++ b/src/SnapshotHelpersV2.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {Test} from 'forge-std/Test.sol'; +import {IAaveOracle, ILendingPool, ILendingPoolAddressesProvider, ILendingPoolConfigurator, IAaveProtocolDataProvider, TokenData, ILendingRateOracle, IDefaultInterestRateStrategy} from 'aave-address-book/AaveV2.sol'; +import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; +import {AaveV2EthereumAMM} from 'aave-address-book/AaveV2EthereumAMM.sol'; +import {ExtendedAggregatorV2V3Interface} from './interfaces/ExtendedAggregatorV2V3Interface.sol'; +import {ReserveTokens} from './CommonTestBase.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; +import {ReserveConfig, LocalVars} from './ProtocolV2TestBase.sol'; + +contract SnapshotHelpersV2 is Test { + /** + * @dev Generates a markdown compatible snapshot of the whole pool configuration into `/reports`. + * @param reportName filename suffix for the generated reports. + * @param pool the pool to be snapshotted + * @return ReserveConfig[] list of configs + */ + function createConfigurationSnapshot( + string memory reportName, + ILendingPool pool + ) public returns (ReserveConfig[] memory) { + string memory path = string(abi.encodePacked('./reports/', reportName, '.json')); + vm.writeFile(path, '{ "reserves": {}, "strategies": {}, "poolConfiguration": {} }'); + vm.serializeUint('root', 'chainId', block.chainid); + ReserveConfig[] memory configs = getReservesConfigs(pool); + ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( + pool.getAddressesProvider() + ); + ILendingRateOracle oracle = ILendingRateOracle(addressesProvider.getLendingRateOracle()); + writeReserveConfigs(path, configs, pool, oracle); + writeStrategyConfigs(path, configs); + writePoolConfiguration(path, pool); + + return configs; + } + + function writeStrategyConfigs(string memory path, ReserveConfig[] memory configs) public { + // keys for json stringification + string memory strategiesKey = 'stategies'; + string memory content = '{}'; + vm.serializeJson(strategiesKey, '{}'); + + for (uint256 i = 0; i < configs.length; i++) { + IDefaultInterestRateStrategy strategy = IDefaultInterestRateStrategy( + configs[i].interestRateStrategy + ); + string memory key = vm.toString(configs[i].underlying); + vm.serializeJson(key, '{}'); + vm.serializeString(key, 'address', vm.toString(address(strategy))); + vm.serializeString(key, 'stableRateSlope1', vm.toString(strategy.stableRateSlope1())); + vm.serializeString(key, 'stableRateSlope2', vm.toString(strategy.stableRateSlope2())); + vm.serializeString( + key, + 'baseVariableBorrowRate', + vm.toString(strategy.baseVariableBorrowRate()) + ); + vm.serializeString(key, 'variableRateSlope1', vm.toString(strategy.variableRateSlope1())); + vm.serializeString(key, 'variableRateSlope2', vm.toString(strategy.variableRateSlope2())); + vm.serializeString( + key, + 'optimalUsageRatio', + vm.toString(strategy.OPTIMAL_UTILIZATION_RATE()) + ); + string memory object = vm.serializeString( + key, + 'maxExcessUsageRatio', + vm.toString(strategy.EXCESS_UTILIZATION_RATE()) + ); + content = vm.serializeString(strategiesKey, key, object); + } + string memory output = vm.serializeString('root', 'strategies', content); + vm.writeJson(output, path); + } + + function writePoolConfiguration(string memory path, ILendingPool pool) public { + // keys for json stringification + string memory poolConfigKey = 'poolConfig'; + + // addresses provider + ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( + pool.getAddressesProvider() + ); + vm.serializeAddress(poolConfigKey, 'poolAddressesProvider', address(addressesProvider)); + + // oracle + IAaveOracle oracle = IAaveOracle(addressesProvider.getPriceOracle()); + vm.serializeAddress(poolConfigKey, 'oracle', address(oracle)); + + // pool configurator + ILendingPoolConfigurator configurator = ILendingPoolConfigurator( + addressesProvider.getLendingPoolConfigurator() + ); + vm.serializeAddress(poolConfigKey, 'poolConfigurator', address(configurator)); + vm.serializeAddress( + poolConfigKey, + 'poolConfiguratorImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(configurator)) + ); + address lendingPoolCollateralManager = addressesProvider.getLendingPoolCollateralManager(); + vm.serializeAddress( + poolConfigKey, + 'lendingPoolCollateralManager', + address(lendingPoolCollateralManager) + ); + + // PoolDataProvider + IAaveProtocolDataProvider pdp = IAaveProtocolDataProvider( + addressesProvider.getAddress( + pool == AaveV2EthereumAMM.POOL + ? bytes32(0x1000000000000000000000000000000000000000000000000000000000000000) + : bytes32(0x0100000000000000000000000000000000000000000000000000000000000000) + ) + ); + vm.serializeAddress(poolConfigKey, 'protocolDataProvider', address(pdp)); + + // pool + vm.serializeAddress( + poolConfigKey, + 'poolImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(pool)) + ); + string memory content = vm.serializeAddress(poolConfigKey, 'pool', address(pool)); + + string memory output = vm.serializeString('root', 'poolConfig', content); + vm.writeJson(output, path); + } + + function writeReserveConfigs( + string memory path, + ReserveConfig[] memory configs, + ILendingPool pool, + ILendingRateOracle rateOracle + ) public { + // keys for json stringification + string memory reservesKey = 'reserves'; + string memory content = '{}'; + vm.serializeJson(reservesKey, '{}'); + + ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( + pool.getAddressesProvider() + ); + IAaveOracle oracle = IAaveOracle(addressesProvider.getPriceOracle()); + + for (uint256 i = 0; i < configs.length; i++) { + ReserveConfig memory config = configs[i]; + ExtendedAggregatorV2V3Interface assetOracle = ExtendedAggregatorV2V3Interface( + oracle.getSourceOfAsset(config.underlying) + ); + + string memory key = vm.toString(config.underlying); + vm.serializeJson(key, '{}'); + vm.serializeString(key, 'symbol', config.symbol); + vm.serializeString( + key, + 'baseStableBorrowRate', + vm.toString(rateOracle.getMarketBorrowRate(config.underlying)) + ); + vm.serializeUint(key, 'ltv', config.ltv); + vm.serializeUint(key, 'liquidationThreshold', config.liquidationThreshold); + vm.serializeUint(key, 'liquidationBonus', config.liquidationBonus); + vm.serializeUint(key, 'reserveFactor', config.reserveFactor); + vm.serializeUint(key, 'decimals', config.decimals); + vm.serializeBool(key, 'usageAsCollateralEnabled', config.usageAsCollateralEnabled); + vm.serializeBool(key, 'borrowingEnabled', config.borrowingEnabled); + vm.serializeBool(key, 'stableBorrowRateEnabled', config.stableBorrowRateEnabled); + vm.serializeBool(key, 'isActive', config.isActive); + vm.serializeBool(key, 'isFrozen', config.isFrozen); + vm.serializeAddress(key, 'interestRateStrategy', config.interestRateStrategy); + vm.serializeAddress(key, 'underlying', config.underlying); + vm.serializeAddress(key, 'aToken', config.aToken); + vm.serializeAddress(key, 'stableDebtToken', config.stableDebtToken); + vm.serializeAddress(key, 'variableDebtToken', config.variableDebtToken); + vm.serializeAddress( + key, + 'aTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, config.aToken) + ); + vm.serializeString(key, 'aTokenSymbol', IERC20Metadata(config.aToken).symbol()); + vm.serializeString(key, 'aTokenName', IERC20Metadata(config.aToken).name()); + vm.serializeAddress( + key, + 'stableDebtTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( + vm, + config.stableDebtToken + ) + ); + vm.serializeString( + key, + 'stableDebtTokenSymbol', + IERC20Metadata(config.stableDebtToken).symbol() + ); + vm.serializeString(key, 'stableDebtTokenName', IERC20Metadata(config.stableDebtToken).name()); + vm.serializeAddress( + key, + 'variableDebtTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( + vm, + config.variableDebtToken + ) + ); + vm.serializeString( + key, + 'variableDebtTokenSymbol', + IERC20Metadata(config.variableDebtToken).symbol() + ); + vm.serializeString( + key, + 'variableDebtTokenName', + IERC20Metadata(config.variableDebtToken).name() + ); + vm.serializeAddress(key, 'oracle', address(assetOracle)); + if (address(assetOracle) != address(0)) { + try assetOracle.description() returns (string memory name) { + vm.serializeString(key, 'oracleDescription', name); + } catch { + try assetOracle.name() returns (string memory name) { + vm.serializeString(key, 'oracleName', name); + } catch {} + } + try assetOracle.decimals() returns (uint8 decimals) { + vm.serializeUint(key, 'oracleDecimals', decimals); + } catch { + try assetOracle.DECIMALS() returns (uint8 decimals) { + vm.serializeUint(key, 'oracleDecimals', decimals); + } catch {} + } + } + string memory out = vm.serializeUint( + key, + 'oracleLatestAnswer', + uint256(oracle.getAssetPrice(config.underlying)) + ); + content = vm.serializeString(reservesKey, key, out); + } + string memory output = vm.serializeString('root', 'reserves', content); + vm.writeJson(output, path); + } + + function getReservesConfigs(ILendingPool pool) public view returns (ReserveConfig[] memory) { + ILendingPoolAddressesProvider addressesProvider = ILendingPoolAddressesProvider( + pool.getAddressesProvider() + ); + IAaveProtocolDataProvider poolDataProvider = IAaveProtocolDataProvider( + addressesProvider.getAddress( + pool == AaveV2EthereumAMM.POOL + ? bytes32(0x1000000000000000000000000000000000000000000000000000000000000000) + : bytes32(0x0100000000000000000000000000000000000000000000000000000000000000) + ) + ); + LocalVars memory vars; + + vars.reserves = poolDataProvider.getAllReservesTokens(); + + vars.configs = new ReserveConfig[](vars.reserves.length); + + for (uint256 i = 0; i < vars.reserves.length; i++) { + vars.configs[i] = getStructReserveConfig(pool, poolDataProvider, vars.reserves[i]); + ReserveTokens memory reserveTokens = getStructReserveTokens( + poolDataProvider, + vars.configs[i].underlying + ); + vars.configs[i].aToken = reserveTokens.aToken; + vars.configs[i].variableDebtToken = reserveTokens.variableDebtToken; + vars.configs[i].stableDebtToken = reserveTokens.stableDebtToken; + } + + return vars.configs; + } + + function getStructReserveConfig( + ILendingPool pool, + IAaveProtocolDataProvider pdp, + TokenData memory reserve + ) public view virtual returns (ReserveConfig memory) { + ReserveConfig memory localConfig; + ( + uint256 decimals, + uint256 ltv, + uint256 liquidationThreshold, + uint256 liquidationBonus, + uint256 reserveFactor, + bool usageAsCollateralEnabled, + bool borrowingEnabled, + bool stableBorrowRateEnabled, + bool isActive, + bool isFrozen + ) = pdp.getReserveConfigurationData(reserve.tokenAddress); + localConfig.symbol = reserve.symbol; + localConfig.underlying = reserve.tokenAddress; + localConfig.decimals = decimals; + localConfig.ltv = ltv; + localConfig.liquidationThreshold = liquidationThreshold; + localConfig.liquidationBonus = liquidationBonus; + localConfig.reserveFactor = reserveFactor; + localConfig.usageAsCollateralEnabled = usageAsCollateralEnabled; + localConfig.borrowingEnabled = borrowingEnabled; + localConfig.stableBorrowRateEnabled = stableBorrowRateEnabled; + localConfig.interestRateStrategy = pool + .getReserveData(reserve.tokenAddress) + .interestRateStrategyAddress; + localConfig.isActive = isActive; + localConfig.isFrozen = isFrozen; + + return localConfig; + } + + function getStructReserveTokens( + IAaveProtocolDataProvider pdp, + address underlyingAddress + ) public view returns (ReserveTokens memory) { + ReserveTokens memory reserveTokens; + (reserveTokens.aToken, reserveTokens.stableDebtToken, reserveTokens.variableDebtToken) = pdp + .getReserveTokensAddresses(underlyingAddress); + + return reserveTokens; + } +} diff --git a/src/SnapshotHelpersV3.sol b/src/SnapshotHelpersV3.sol new file mode 100644 index 000000000..73adbc1a1 --- /dev/null +++ b/src/SnapshotHelpersV3.sol @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {IERC20Detailed} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.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 {IPoolConfigurator} from 'aave-v3-core/contracts/interfaces/IPoolConfigurator.sol'; +import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; +import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {ExtendedAggregatorV2V3Interface} from './interfaces/ExtendedAggregatorV2V3Interface.sol'; +import {ProxyHelpers} from 'aave-v3-origin/../tests/utils/ProxyHelpers.sol'; +import {CommonTestBase} from './CommonTestBase.sol'; +import {IDefaultInterestRateStrategyV2} from 'aave-v3-core/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; +import {ReserveConfig, ReserveTokens, DataTypes} from 'aave-v3-origin/../tests/utils/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase as TestBase, LocalVars} from './ProtocolV3TestBase.sol'; +import {ILegacyDefaultInterestRateStrategy} from './dependencies/ILegacyDefaultInterestRateStrategy.sol'; + +contract SnapshotHelpersV3 is CommonTestBase { + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + + function createConfigurationSnapshot( + string memory reportName, + IPool pool, + bool reserveConfigs, + bool strategyConfigs, + bool eModeConigs, + bool poolConfigs + ) public returns (ReserveConfig[] memory) { + string memory path = string(abi.encodePacked('./reports/', reportName, '.json')); + // overwrite with empty json to later be extended + vm.writeFile( + path, + '{ "eModes": {}, "reserves": {}, "strategies": {}, "poolConfiguration": {} }' + ); + vm.serializeUint('root', 'chainId', block.chainid); + ReserveConfig[] memory configs = getReservesConfigs(pool); + if (reserveConfigs) writeReserveConfigs(path, configs, pool); + if (strategyConfigs) writeStrategyConfigs(path, configs); + if (eModeConigs) writeEModeConfigs(path, configs, pool); + if (poolConfigs) writePoolConfiguration(path, pool); + + return configs; + } + + function writeEModeConfigs( + string memory path, + ReserveConfig[] memory configs, + IPool pool + ) public { + // keys for json stringification + string memory eModesKey = 'emodes'; + string memory content = '{}'; + vm.serializeJson(eModesKey, '{}'); + + uint256[] memory usedCategories = new uint256[](configs.length); + for (uint256 i = 0; i < configs.length; i++) { + if (!_isInUint256Array(usedCategories, configs[i].eModeCategory)) { + usedCategories[i] = configs[i].eModeCategory; + DataTypes.EModeCategory memory category = pool.getEModeCategoryData( + uint8(configs[i].eModeCategory) + ); + string memory key = vm.toString(configs[i].eModeCategory); + vm.serializeJson(key, '{}'); + vm.serializeUint(key, 'eModeCategory', configs[i].eModeCategory); + vm.serializeString(key, 'label', category.label); + vm.serializeUint(key, 'ltv', category.ltv); + vm.serializeUint(key, 'liquidationThreshold', category.liquidationThreshold); + vm.serializeUint(key, 'liquidationBonus', category.liquidationBonus); + string memory object = vm.serializeAddress(key, 'priceSource', category.priceSource); + content = vm.serializeString(eModesKey, key, object); + } + } + string memory output = vm.serializeString('root', 'eModes', content); + vm.writeJson(output, path); + } + + function writeStrategyConfigs(string memory path, ReserveConfig[] memory configs) public { + // keys for json stringification + string memory strategiesKey = 'stategies'; + string memory content = '{}'; + vm.serializeJson(strategiesKey, '{}'); + + for (uint256 i = 0; i < configs.length; i++) { + IDefaultInterestRateStrategyV2 strategyV2 = IDefaultInterestRateStrategyV2( + configs[i].interestRateStrategy + ); + ILegacyDefaultInterestRateStrategy strategyV1 = ILegacyDefaultInterestRateStrategy( + configs[i].interestRateStrategy + ); + address asset = configs[i].underlying; + string memory key = vm.toString(asset); + vm.serializeJson(key, '{}'); + vm.serializeString(key, 'address', vm.toString(configs[i].interestRateStrategy)); + string memory object; + try strategyV1.getVariableRateSlope1() { + vm.serializeString( + key, + 'baseStableBorrowRate', + vm.toString(strategyV1.getBaseStableBorrowRate()) + ); + vm.serializeString(key, 'stableRateSlope1', vm.toString(strategyV1.getStableRateSlope1())); + vm.serializeString(key, 'stableRateSlope2', vm.toString(strategyV1.getStableRateSlope2())); + vm.serializeString( + key, + 'baseVariableBorrowRate', + vm.toString(strategyV1.getBaseVariableBorrowRate()) + ); + vm.serializeString( + key, + 'variableRateSlope1', + vm.toString(strategyV1.getVariableRateSlope1()) + ); + vm.serializeString( + key, + 'variableRateSlope2', + vm.toString(strategyV1.getVariableRateSlope2()) + ); + vm.serializeString( + key, + 'optimalStableToTotalDebtRatio', + vm.toString(strategyV1.OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO()) + ); + vm.serializeString( + key, + 'maxExcessStableToTotalDebtRatio', + vm.toString(strategyV1.MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO()) + ); + vm.serializeString(key, 'optimalUsageRatio', vm.toString(strategyV1.OPTIMAL_USAGE_RATIO())); + object = vm.serializeString( + key, + 'maxExcessUsageRatio', + vm.toString(strategyV1.MAX_EXCESS_USAGE_RATIO()) + ); + } catch { + vm.serializeString( + key, + 'baseVariableBorrowRate', + vm.toString(strategyV2.getBaseVariableBorrowRate(asset)) + ); + vm.serializeString( + key, + 'variableRateSlope1', + vm.toString(strategyV2.getVariableRateSlope1(asset)) + ); + vm.serializeString( + key, + 'variableRateSlope2', + vm.toString(strategyV2.getVariableRateSlope2(asset)) + ); + vm.serializeString( + key, + 'maxVariableBorrowRate', + vm.toString(strategyV2.getMaxVariableBorrowRate(asset)) + ); + object = vm.serializeString( + key, + 'optimalUsageRatio', + vm.toString(strategyV2.getOptimalUsageRatio(asset)) + ); + } + content = vm.serializeString(strategiesKey, key, object); + } + string memory output = vm.serializeString('root', 'strategies', content); + vm.writeJson(output, path); + } + + function writeReserveConfigs( + string memory path, + ReserveConfig[] memory configs, + IPool pool + ) public { + // keys for json stringification + string memory reservesKey = 'reserves'; + string memory content = '{}'; + + IPoolAddressesProvider addressesProvider = IPoolAddressesProvider(pool.ADDRESSES_PROVIDER()); + IAaveOracle oracle = IAaveOracle(addressesProvider.getPriceOracle()); + for (uint256 i = 0; i < configs.length; i++) { + ReserveConfig memory config = configs[i]; + ExtendedAggregatorV2V3Interface assetOracle = ExtendedAggregatorV2V3Interface( + oracle.getSourceOfAsset(config.underlying) + ); + + string memory key = vm.toString(config.underlying); + vm.serializeString(key, 'symbol', config.symbol); + vm.serializeUint(key, 'ltv', config.ltv); + vm.serializeUint(key, 'liquidationThreshold', config.liquidationThreshold); + vm.serializeUint(key, 'liquidationBonus', config.liquidationBonus); + vm.serializeUint(key, 'liquidationProtocolFee', config.liquidationProtocolFee); + vm.serializeUint(key, 'reserveFactor', config.reserveFactor); + vm.serializeUint(key, 'decimals', config.decimals); + vm.serializeUint(key, 'borrowCap', config.borrowCap); + vm.serializeUint(key, 'supplyCap', config.supplyCap); + vm.serializeUint(key, 'debtCeiling', config.debtCeiling); + vm.serializeUint(key, 'eModeCategory', config.eModeCategory); + vm.serializeBool(key, 'usageAsCollateralEnabled', config.usageAsCollateralEnabled); + vm.serializeBool(key, 'borrowingEnabled', config.borrowingEnabled); + vm.serializeBool(key, 'stableBorrowRateEnabled', config.stableBorrowRateEnabled); + vm.serializeBool(key, 'isPaused', config.isPaused); + vm.serializeBool(key, 'isActive', config.isActive); + vm.serializeBool(key, 'isFrozen', config.isFrozen); + vm.serializeBool(key, 'isSiloed', config.isSiloed); + vm.serializeBool(key, 'isBorrowableInIsolation', config.isBorrowableInIsolation); + vm.serializeBool(key, 'isFlashloanable', config.isFlashloanable); + vm.serializeAddress(key, 'interestRateStrategy', config.interestRateStrategy); + vm.serializeAddress(key, 'underlying', config.underlying); + vm.serializeAddress(key, 'aToken', config.aToken); + vm.serializeAddress(key, 'stableDebtToken', config.stableDebtToken); + vm.serializeAddress(key, 'variableDebtToken', config.variableDebtToken); + vm.serializeAddress( + key, + 'aTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, config.aToken) + ); + vm.serializeString(key, 'aTokenSymbol', IERC20Detailed(config.aToken).symbol()); + vm.serializeString(key, 'aTokenName', IERC20Detailed(config.aToken).name()); + vm.serializeAddress( + key, + 'stableDebtTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( + vm, + config.stableDebtToken + ) + ); + vm.serializeString( + key, + 'stableDebtTokenSymbol', + IERC20Detailed(config.stableDebtToken).symbol() + ); + vm.serializeString(key, 'stableDebtTokenName', IERC20Detailed(config.stableDebtToken).name()); + vm.serializeAddress( + key, + 'variableDebtTokenImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation( + vm, + config.variableDebtToken + ) + ); + vm.serializeString( + key, + 'variableDebtTokenSymbol', + IERC20Detailed(config.variableDebtToken).symbol() + ); + vm.serializeString( + key, + 'variableDebtTokenName', + IERC20Detailed(config.variableDebtToken).name() + ); + vm.serializeAddress(key, 'oracle', address(assetOracle)); + if (address(assetOracle) != address(0)) { + try assetOracle.description() returns (string memory name) { + vm.serializeString(key, 'oracleDescription', name); + } catch { + try assetOracle.name() returns (string memory name) { + vm.serializeString(key, 'oracleName', name); + } catch {} + } + try assetOracle.decimals() returns (uint8 decimals) { + vm.serializeUint(key, 'oracleDecimals', decimals); + } catch { + try assetOracle.DECIMALS() returns (uint8 decimals) { + vm.serializeUint(key, 'oracleDecimals', decimals); + } catch {} + } + } + + vm.serializeBool(key, 'virtualAccountingActive', config.virtualAccActive); + vm.serializeUint(key, 'virtualBalance', config.virtualBalance); + vm.serializeUint(key, 'aTokenUnderlyingBalance', config.aTokenUnderlyingBalance); + + string memory out = vm.serializeUint( + key, + 'oracleLatestAnswer', + uint256(oracle.getAssetPrice(config.underlying)) + ); + content = vm.serializeString(reservesKey, key, out); + } + string memory output = vm.serializeString('root', 'reserves', content); + vm.writeJson(output, path); + } + + function writePoolConfiguration(string memory path, IPool pool) public { + // keys for json stringification + string memory poolConfigKey = 'poolConfig'; + + // addresses provider + IPoolAddressesProvider addressesProvider = IPoolAddressesProvider(pool.ADDRESSES_PROVIDER()); + vm.serializeAddress(poolConfigKey, 'poolAddressesProvider', address(addressesProvider)); + + // oracles + vm.serializeAddress(poolConfigKey, 'oracle', addressesProvider.getPriceOracle()); + vm.serializeAddress( + poolConfigKey, + 'priceOracleSentinel', + addressesProvider.getPriceOracleSentinel() + ); + + // pool configurator + IPoolConfigurator configurator = IPoolConfigurator(addressesProvider.getPoolConfigurator()); + vm.serializeAddress(poolConfigKey, 'poolConfigurator', address(configurator)); + vm.serializeAddress( + poolConfigKey, + 'poolConfiguratorImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(configurator)) + ); + + // PoolDataProvider + IPoolDataProvider pdp = IPoolDataProvider(addressesProvider.getPoolDataProvider()); + vm.serializeAddress(poolConfigKey, 'protocolDataProvider', address(pdp)); + + // pool + vm.serializeAddress( + poolConfigKey, + 'poolImpl', + ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, address(pool)) + ); + string memory content = vm.serializeAddress(poolConfigKey, 'pool', address(pool)); + + string memory output = vm.serializeString('root', 'poolConfig', content); + vm.writeJson(output, path); + } + + function getReservesConfigs(IPool pool) public view returns (ReserveConfig[] memory) { + IPoolAddressesProvider addressesProvider = IPoolAddressesProvider(pool.ADDRESSES_PROVIDER()); + IPoolDataProvider poolDataProvider = IPoolDataProvider(addressesProvider.getPoolDataProvider()); + LocalVars memory vars; + + vars.reserves = poolDataProvider.getAllReservesTokens(); + + vars.configs = new ReserveConfig[](vars.reserves.length); + + for (uint256 i = 0; i < vars.reserves.length; i++) { + vars.configs[i] = getStructReserveConfig(pool, vars.reserves[i]); + ReserveTokens memory reserveTokens = getStructReserveTokens( + poolDataProvider, + vars.configs[i].underlying + ); + vars.configs[i].aToken = reserveTokens.aToken; + vars.configs[i].variableDebtToken = reserveTokens.variableDebtToken; + vars.configs[i].stableDebtToken = reserveTokens.stableDebtToken; + } + + return vars.configs; + } + + function getStructReserveTokens( + IPoolDataProvider pdp, + address underlyingAddress + ) public view returns (ReserveTokens memory) { + ReserveTokens memory reserveTokens; + (reserveTokens.aToken, reserveTokens.stableDebtToken, reserveTokens.variableDebtToken) = pdp + .getReserveTokensAddresses(underlyingAddress); + + return reserveTokens; + } + + function getStructReserveConfig( + IPool pool, + IPoolDataProvider.TokenData memory reserve + ) public view returns (ReserveConfig memory) { + ReserveConfig memory localConfig; + DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration( + reserve.tokenAddress + ); + localConfig.interestRateStrategy = pool + .getReserveData(reserve.tokenAddress) + .interestRateStrategyAddress; + ( + localConfig.ltv, + localConfig.liquidationThreshold, + localConfig.liquidationBonus, + localConfig.decimals, + localConfig.reserveFactor, + localConfig.eModeCategory + ) = configuration.getParams(); + ( + localConfig.isActive, + localConfig.isFrozen, + localConfig.borrowingEnabled, + localConfig.stableBorrowRateEnabled, + localConfig.isPaused + ) = configuration.getFlags(); + localConfig.symbol = reserve.symbol; + localConfig.underlying = reserve.tokenAddress; + localConfig.usageAsCollateralEnabled = localConfig.liquidationThreshold != 0; + localConfig.isSiloed = configuration.getSiloedBorrowing(); + (localConfig.borrowCap, localConfig.supplyCap) = configuration.getCaps(); + localConfig.debtCeiling = configuration.getDebtCeiling(); + localConfig.liquidationProtocolFee = configuration.getLiquidationProtocolFee(); + localConfig.isBorrowableInIsolation = configuration.getBorrowableInIsolation(); + + localConfig.isFlashloanable = configuration.getFlashLoanEnabled(); + + return localConfig; + } + + function _isInUint256Array( + uint256[] memory haystack, + uint256 needle + ) internal pure returns (bool) { + for (uint256 i = 0; i < haystack.length; i++) { + if (haystack[i] == needle) return true; + } + return false; + } +} diff --git a/src/adi/BaseADIPayloadUpdate.sol b/src/adi/BaseADIPayloadUpdate.sol deleted file mode 100644 index ebfb65453..000000000 --- a/src/adi/BaseADIPayloadUpdate.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; - -import {IProposalGenericExecutor} from '../interfaces/IProposalGenericExecutor.sol'; - -abstract contract BaseADIPayloadUpdate is IProposalGenericExecutor { - address public immutable CROSS_CHAIN_CONTROLLER; - - /** - * @param crossChainController address of the CCC of the network where payload will be deployed - */ - constructor(address crossChainController) { - CROSS_CHAIN_CONTROLLER = crossChainController; - } -} diff --git a/src/adi/BaseAdaptersUpdate.sol b/src/adi/BaseAdaptersUpdate.sol deleted file mode 100644 index a2fd0ffe0..000000000 --- a/src/adi/BaseAdaptersUpdate.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import './BaseReceiverAdaptersUpdate.sol'; -import './BaseForwarderAdaptersUpdate.sol'; -import './BaseADIPayloadUpdate.sol'; - -/** - * @title Base payload aDI and bridge adapters update - * @author BGD Labs @bgdlabs - */ -abstract contract BaseAdaptersUpdate is - BaseReceiverAdaptersUpdate, - BaseForwarderAdaptersUpdate, - BaseADIPayloadUpdate -{ - /** - * @param crossChainController address of the CCC of the network where payload will be deployed - */ - constructor(address crossChainController) BaseADIPayloadUpdate(crossChainController) {} - - function execute() public virtual { - executeReceiversUpdate(CROSS_CHAIN_CONTROLLER); - - executeForwardersUpdate(CROSS_CHAIN_CONTROLLER); - } -} diff --git a/src/adi/BaseCCCUpdate.sol b/src/adi/BaseCCCUpdate.sol deleted file mode 100644 index 3529bc60d..000000000 --- a/src/adi/BaseCCCUpdate.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; - -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {TransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; -import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; -import './BaseADIPayloadUpdate.sol'; - -/** - * @param crossChainController address of the CCC of the network where payload will be deployed - * @param newCCCImpl address of the new ccc implementation - * @param proxyAdmin address of the proxy admin owner of ccc - */ -struct CCCUpdateArgs { - address crossChainController; - address crossChainControllerImpl; - address proxyAdmin; -} - -/** - * @title Base payload to update CCC - * @author BGD Labs @bgdlabs - */ -abstract contract BaseCCCUpdate is BaseADIPayloadUpdate { - address public immutable NEW_CCC_IMPL; - address public immutable PROXY_ADMIN; - - /* - * @param cccUpdateArgs arguments necessary to update ccc implementation - */ - constructor( - CCCUpdateArgs memory cccUpdateArgs - ) BaseADIPayloadUpdate(cccUpdateArgs.crossChainController) { - NEW_CCC_IMPL = cccUpdateArgs.crossChainControllerImpl; - PROXY_ADMIN = cccUpdateArgs.proxyAdmin; - } - - function getInitializeSignature() public virtual returns (bytes memory); - - /// @inheritdoc IProposalGenericExecutor - function execute() external virtual override { - ProxyAdmin(PROXY_ADMIN).upgradeAndCall( - TransparentUpgradeableProxy(payable(CROSS_CHAIN_CONTROLLER)), - NEW_CCC_IMPL, - getInitializeSignature() - ); - } -} diff --git a/src/adi/BaseForwarderAdaptersUpdate.sol b/src/adi/BaseForwarderAdaptersUpdate.sol deleted file mode 100644 index a28b12dee..000000000 --- a/src/adi/BaseForwarderAdaptersUpdate.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IBaseForwarderAdaptersUpdate, ICrossChainForwarder} from './interfaces/IBaseForwarderAdaptersUpdate.sol'; - -/** - * @title Base forwarder payload. It has the methods to update the forwarder bridge adapters. - * @author BGD Labs @bgdlabs - */ -abstract contract BaseForwarderAdaptersUpdate is IBaseForwarderAdaptersUpdate { - /// @inheritdoc IBaseForwarderAdaptersUpdate - function getForwarderBridgeAdaptersToRemove() - public - view - virtual - returns (ICrossChainForwarder.BridgeAdapterToDisable[] memory) - { - return new ICrossChainForwarder.BridgeAdapterToDisable[](0); - } - - /// @inheritdoc IBaseForwarderAdaptersUpdate - function getForwarderBridgeAdaptersToEnable() - public - view - virtual - returns (ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory) - { - return new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[](0); - } - - /// @inheritdoc IBaseForwarderAdaptersUpdate - function executeForwardersUpdate(address crossChainController) public virtual { - // remove forwarding adapters - ICrossChainForwarder.BridgeAdapterToDisable[] - memory forwardersToRemove = getForwarderBridgeAdaptersToRemove(); - if (forwardersToRemove.length != 0) { - ICrossChainForwarder(crossChainController).disableBridgeAdapters(forwardersToRemove); - } - - // add forwarding adapters - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] - memory forwardersToEnable = getForwarderBridgeAdaptersToEnable(); - if (forwardersToEnable.length != 0) { - ICrossChainForwarder(crossChainController).enableBridgeAdapters(forwardersToEnable); - } - } -} diff --git a/src/adi/BaseReceiverAdaptersUpdate.sol b/src/adi/BaseReceiverAdaptersUpdate.sol deleted file mode 100644 index 1b5ee2648..000000000 --- a/src/adi/BaseReceiverAdaptersUpdate.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IBaseReceiverAdaptersUpdate, ICrossChainReceiver} from './interfaces/IBaseReceiverAdaptersUpdate.sol'; - -/** - * @title Base receiver payload. It has the methods to update the receiver bridge adapters. - * @author BGD Labs @bgdlabs - */ -abstract contract BaseReceiverAdaptersUpdate is IBaseReceiverAdaptersUpdate { - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToRemove() - public - view - virtual - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - // remove old Receiver bridge adapter - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToAllow() - public - view - virtual - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function executeReceiversUpdate(address crossChainController) public virtual { - // remove old Receiver bridge adapter - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory receiversToRemove = getReceiverBridgeAdaptersToRemove(); - if (receiversToRemove.length != 0) { - ICrossChainReceiver(crossChainController).disallowReceiverBridgeAdapters(receiversToRemove); - } - - // add receiver adapters - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory receiversToAllow = getReceiverBridgeAdaptersToAllow(); - if (receiversToAllow.length != 0) { - ICrossChainReceiver(crossChainController).allowReceiverBridgeAdapters(receiversToAllow); - } - } -} diff --git a/src/adi/SimpleAddForwarderAdapter.sol b/src/adi/SimpleAddForwarderAdapter.sol deleted file mode 100644 index 2e3cb5b42..000000000 --- a/src/adi/SimpleAddForwarderAdapter.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import './BaseAdaptersUpdate.sol'; - -struct AddForwarderAdapterArgs { - address crossChainController; - address currentChainBridgeAdapter; - address destinationChainBridgeAdapter; - uint256 destinationChainId; -} - -/** - * @title SimpleAddForwarderAdapter - * @author BGD Labs @bgdlabs - * @dev this payload should be used when adding a new bridging path to adi - */ -contract SimpleAddForwarderAdapter is BaseAdaptersUpdate { - address public immutable CURRENT_CHAIN_BRIDGE_ADAPTER; - address public immutable DESTINATION_CHAIN_BRIDGE_ADAPTER; - uint256 public immutable DESTINATION_CHAIN_ID; - - constructor( - AddForwarderAdapterArgs memory forwarderArgs - ) BaseAdaptersUpdate(forwarderArgs.crossChainController) { - CURRENT_CHAIN_BRIDGE_ADAPTER = forwarderArgs.currentChainBridgeAdapter; - DESTINATION_CHAIN_BRIDGE_ADAPTER = forwarderArgs.destinationChainBridgeAdapter; - DESTINATION_CHAIN_ID = forwarderArgs.destinationChainId; - } - - function getForwarderBridgeAdaptersToEnable() - public - view - override - returns (ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory) - { - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] - memory newForwarders = new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[](1); - - newForwarders[0] = ICrossChainForwarder.ForwarderBridgeAdapterConfigInput({ - currentChainBridgeAdapter: CURRENT_CHAIN_BRIDGE_ADAPTER, - destinationBridgeAdapter: DESTINATION_CHAIN_BRIDGE_ADAPTER, - destinationChainId: DESTINATION_CHAIN_ID - }); - - return newForwarders; - } -} diff --git a/src/adi/SimpleOneToManyAdapterUpdate.sol b/src/adi/SimpleOneToManyAdapterUpdate.sol deleted file mode 100644 index a76db7238..000000000 --- a/src/adi/SimpleOneToManyAdapterUpdate.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import './BaseAdaptersUpdate.sol'; - -/** - * @title Base payload aDI and bridge adapters update - * @author BGD Labs @bgdlabs - * @dev This payload should be used when wanting to substitute an adapter that receives and also forwards - */ -abstract contract SimpleOneToManyAdapterUpdate is BaseAdaptersUpdate { - struct ConstructorInput { - address ccc; - address adapterToRemove; - address newAdapter; - } - - struct DestinationAdaptersInput { - address adapter; - uint256 chainId; - } - - address public immutable ADAPTER_TO_REMOVE; - address public immutable NEW_ADAPTER; - - constructor(ConstructorInput memory constructorInput) BaseAdaptersUpdate(constructorInput.ccc) { - ADAPTER_TO_REMOVE = constructorInput.adapterToRemove; - NEW_ADAPTER = constructorInput.newAdapter; - } - - /** - * @notice method used to get the adapters for the destination chain ids - * @return array of adapter - destination chain pairs - */ - function getDestinationAdapters() - public - pure - virtual - returns (DestinationAdaptersInput[] memory) - { - return new DestinationAdaptersInput[](0); - } - - /** - * @notice method to get the chains that a new adapter will receive messages from - * @return an array of chain ids - */ - function getChainsToReceive() public pure virtual returns (uint256[] memory); - - /** - * @notice method to get a list of chain ids that the new adapter will use to send messages to - * @return an array of chain ids - */ - function getChainsToSend() public pure virtual returns (uint256[] memory) { - DestinationAdaptersInput[] memory destinationAdapters = getDestinationAdapters(); - uint256[] memory chainsToSend = new uint256[](destinationAdapters.length); - for (uint256 i = 0; i < destinationAdapters.length; i++) { - chainsToSend[i] = destinationAdapters[i].chainId; - } - return chainsToSend; - } - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToRemove() - public - view - virtual - override - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - if (ADAPTER_TO_REMOVE != address(0)) { - // remove old Receiver bridge adapter - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory bridgeAdaptersToRemove = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( - 1 - ); - - bridgeAdaptersToRemove[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ - bridgeAdapter: ADAPTER_TO_REMOVE, - chainIds: getChainsToReceive() - }); - - return bridgeAdaptersToRemove; - } else { - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - } - - /// @inheritdoc IBaseForwarderAdaptersUpdate - function getForwarderBridgeAdaptersToRemove() - public - view - virtual - override - returns (ICrossChainForwarder.BridgeAdapterToDisable[] memory) - { - if (ADAPTER_TO_REMOVE != address(0)) { - ICrossChainForwarder.BridgeAdapterToDisable[] - memory forwarderAdaptersToRemove = new ICrossChainForwarder.BridgeAdapterToDisable[](1); - - forwarderAdaptersToRemove[0] = ICrossChainForwarder.BridgeAdapterToDisable({ - bridgeAdapter: ADAPTER_TO_REMOVE, - chainIds: getChainsToSend() - }); - - return forwarderAdaptersToRemove; - } else { - return new ICrossChainForwarder.BridgeAdapterToDisable[](0); - } - } - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToAllow() - public - view - virtual - override - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - if (NEW_ADAPTER != address(0)) { - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory bridgeAdapterConfig = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](1); - - bridgeAdapterConfig[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ - bridgeAdapter: NEW_ADAPTER, - chainIds: getChainsToReceive() - }); - - return bridgeAdapterConfig; - } else { - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - } - - /// @inheritdoc IBaseForwarderAdaptersUpdate - function getForwarderBridgeAdaptersToEnable() - public - view - virtual - override - returns (ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory) - { - DestinationAdaptersInput[] memory destinationAdapters = getDestinationAdapters(); - - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] - memory bridgeAdaptersToEnable = new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[]( - destinationAdapters.length - ); - - for (uint256 i = 0; i < destinationAdapters.length; i++) { - bridgeAdaptersToEnable[i] = ICrossChainForwarder.ForwarderBridgeAdapterConfigInput({ - currentChainBridgeAdapter: NEW_ADAPTER, - destinationBridgeAdapter: destinationAdapters[i].adapter, - destinationChainId: destinationAdapters[i].chainId - }); - } - - return bridgeAdaptersToEnable; - } -} diff --git a/src/adi/SimpleReceiverAdapterUpdate.sol b/src/adi/SimpleReceiverAdapterUpdate.sol deleted file mode 100644 index f87624986..000000000 --- a/src/adi/SimpleReceiverAdapterUpdate.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import './BaseAdaptersUpdate.sol'; - -/** - * @title Base payload aDI and bridge adapters update - * @author BGD Labs @bgdlabs - * @dev This payload should be used when wanting to add or remove (or both) a receiver adapter. If one of the - addresses is left as 0, the addition or removal will not be done - */ -abstract contract SimpleReceiverAdapterUpdate is BaseAdaptersUpdate { - struct ConstructorInput { - address ccc; - address adapterToRemove; - address newAdapter; - } - - struct DestinationAdaptersInput { - address adapter; - uint256 chainId; - } - - address public immutable ADAPTER_TO_REMOVE; - address public immutable NEW_ADAPTER; - - constructor(ConstructorInput memory constructorInput) BaseAdaptersUpdate(constructorInput.ccc) { - ADAPTER_TO_REMOVE = constructorInput.adapterToRemove; - NEW_ADAPTER = constructorInput.newAdapter; - } - - /** - * @notice method to get the chains that a new adapter will receive messages from - * @return an array of chain ids - */ - function getChainsToReceive() public pure virtual returns (uint256[] memory); - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToRemove() - public - view - virtual - override - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - if (ADAPTER_TO_REMOVE != address(0)) { - // remove old Receiver bridge adapter - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory bridgeAdaptersToRemove = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( - 1 - ); - - bridgeAdaptersToRemove[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ - bridgeAdapter: ADAPTER_TO_REMOVE, - chainIds: getChainsToReceive() - }); - - return bridgeAdaptersToRemove; - } else { - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - } - - /// @inheritdoc IBaseReceiverAdaptersUpdate - function getReceiverBridgeAdaptersToAllow() - public - view - virtual - override - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) - { - if (NEW_ADAPTER != address(0)) { - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory bridgeAdapterConfig = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](1); - - bridgeAdapterConfig[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ - bridgeAdapter: NEW_ADAPTER, - chainIds: getChainsToReceive() - }); - - return bridgeAdapterConfig; - } else { - return new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); - } - } -} diff --git a/src/adi/interfaces/IBaseAdaptersUpdate.sol b/src/adi/interfaces/IBaseAdaptersUpdate.sol deleted file mode 100644 index 1074ba26c..000000000 --- a/src/adi/interfaces/IBaseAdaptersUpdate.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IBaseReceiverAdaptersUpdate} from './IBaseReceiverAdaptersUpdate.sol'; -import {IBaseForwarderAdaptersUpdate} from './IBaseForwarderAdaptersUpdate.sol'; - -/** - * @title Interface of the base payload aDI and bridge adapters update - * @author BGD Labs @bgdlabs - */ -interface IBaseAdaptersUpdate is IBaseReceiverAdaptersUpdate, IBaseForwarderAdaptersUpdate { - -} diff --git a/src/adi/interfaces/IBaseForwarderAdaptersUpdate.sol b/src/adi/interfaces/IBaseForwarderAdaptersUpdate.sol deleted file mode 100644 index 615a1b27c..000000000 --- a/src/adi/interfaces/IBaseForwarderAdaptersUpdate.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {ICrossChainForwarder} from 'aave-address-book/common/ICrossChainController.sol'; - -/** - * @title Interface for base forwarder payload. - * @author BGD Labs @bgdlabs - */ -interface IBaseForwarderAdaptersUpdate { - /** - * @notice method to get the forwarder adapters to remove - * @return object array with the adapter to remove and an array of chain ids to remove it from - */ - function getForwarderBridgeAdaptersToRemove() - external - view - returns (ICrossChainForwarder.BridgeAdapterToDisable[] memory); - - /** - * @notice method to get the forwarder adapters to enable - * @return object array with the current and destination pair of adapters to enable and the chainId - to communicate with - */ - function getForwarderBridgeAdaptersToEnable() - external - view - returns (ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory); - - /** - * @notice method to add and remove forwarder adapters - * @param crossChainController address of the CCC on the networks where the adapters are going to be updated - */ - function executeForwardersUpdate(address crossChainController) external; -} diff --git a/src/adi/interfaces/IBaseReceiverAdaptersUpdate.sol b/src/adi/interfaces/IBaseReceiverAdaptersUpdate.sol deleted file mode 100644 index 77cccb1b0..000000000 --- a/src/adi/interfaces/IBaseReceiverAdaptersUpdate.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {ICrossChainReceiver} from 'aave-address-book/common/ICrossChainController.sol'; - -/** - * @title Interface of the base payload aDI and bridge adapters update - * @author BGD Labs @bgdlabs - */ -interface IBaseReceiverAdaptersUpdate { - /** - * @notice method to get the receiver adapters to remove - * @return object array with the adapter to remove and an array of chain ids to remove it from - */ - function getReceiverBridgeAdaptersToRemove() - external - view - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory); - - /** - * @notice method to get the receiver adapters to allow - * @return object array with the adapter to allow and an array of chain ids to allow it to receive messages from - */ - function getReceiverBridgeAdaptersToAllow() - external - view - returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory); - - /** - * @notice method to add and remove receiver adapters - * @param crossChainController address of the CCC on the networks where the adapters are going to be updated - */ - function executeReceiversUpdate(address crossChainController) external; -} diff --git a/src/adi/test/ADITestBase.sol b/src/adi/test/ADITestBase.sol deleted file mode 100644 index a5b761d30..000000000 --- a/src/adi/test/ADITestBase.sol +++ /dev/null @@ -1,678 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; - -import 'forge-std/StdJson.sol'; -import 'forge-std/Test.sol'; -import {ICrossChainReceiver, ICrossChainForwarder} from 'aave-address-book/common/ICrossChainController.sol'; -import {ChainIds, ChainHelpers} from '../../ChainIds.sol'; -import {GovV3Helpers} from '../../GovV3Helpers.sol'; -import {IBaseAdaptersUpdate} from '../interfaces/IBaseAdaptersUpdate.sol'; -import {ProxyHelpers} from '../../ProxyHelpers.sol'; - -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {GovernanceV3Polygon} from 'aave-address-book/GovernanceV3Polygon.sol'; -import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; -import {GovernanceV3Optimism} from 'aave-address-book/GovernanceV3Optimism.sol'; -import {GovernanceV3BNB} from 'aave-address-book/GovernanceV3BNB.sol'; -import {GovernanceV3Metis} from 'aave-address-book/GovernanceV3Metis.sol'; -import {GovernanceV3Base} from 'aave-address-book/GovernanceV3Base.sol'; -import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; -import {GovernanceV3Gnosis} from 'aave-address-book/GovernanceV3Gnosis.sol'; -import {GovernanceV3Scroll} from 'aave-address-book/GovernanceV3Scroll.sol'; -import {IBaseAdapter} from 'aave-address-book/common/IBaseAdapter.sol'; - -contract ADITestBase is Test { - using stdJson for string; - - struct ReceiverConfigByChain { - uint8 requiredConfirmations; - uint256 chainId; - uint256 validityTimestamp; - } - - struct ReceiverAdaptersByChain { - uint256 chainId; - address[] receiverAdapters; - } - - struct ForwarderAdaptersByChain { - uint256 chainId; - ICrossChainForwarder.ChainIdBridgeConfig[] forwarders; - } - - struct CCCConfig { - address crossChainControllerImpl; - ReceiverConfigByChain[] receiverConfigs; - ReceiverAdaptersByChain[] receiverAdaptersConfig; - ForwarderAdaptersByChain[] forwarderAdaptersConfig; - } - - struct ForwarderAdapters { - ICrossChainForwarder.ChainIdBridgeConfig[] adapters; - uint256 chainId; - } - - struct AdaptersByChain { - address[] adapters; - uint256 chainId; - } - - struct DestinationPayload { - uint256 chainId; - bytes payloadCode; - } - - struct SnapshotParams { - address crossChainController; - bool receiverConfigs; - bool receiverAdapterConfigs; - bool forwarderAdapterConfigs; - bool cccImplUpdate; - string reportName; - } - - function executePayload(Vm vm, address payload) internal { - GovV3Helpers.executePayload(vm, payload); - } - - /** - * @dev generates the diff between two reports - */ - function diffReports(string memory reportBefore, string memory reportAfter) internal { - string memory outPath = string( - abi.encodePacked('./diffs/', reportBefore, '_', reportAfter, '.md') - ); - string memory beforePath = string(abi.encodePacked('./reports/', reportBefore, '.json')); - string memory afterPath = string(abi.encodePacked('./reports/', reportAfter, '.json')); - - string[] memory inputs = new string[](7); - inputs[0] = 'npx'; - inputs[1] = '@bgd-labs/aave-cli@^0.16.2'; - inputs[2] = 'adi-diff-snapshots'; - inputs[3] = beforePath; - inputs[4] = afterPath; - inputs[5] = '-o'; - inputs[6] = outPath; - vm.ffi(inputs); - } - - function defaultTest( - string memory reportName, - address crossChainController, - address payload, - bool runE2E, - Vm vm - ) public returns (CCCConfig memory, CCCConfig memory) { - string memory beforeString = string(abi.encodePacked('adi_', reportName, '_before')); - CCCConfig memory configBefore = createConfigurationSnapshot(beforeString, crossChainController); - - uint256 snapshotId = vm.snapshot(); - - executePayload(vm, payload); - - string memory afterString = string(abi.encodePacked('adi_', reportName, '_after')); - CCCConfig memory configAfter = createConfigurationSnapshot(afterString, crossChainController); - - diffReports(beforeString, afterString); - - vm.revertTo(snapshotId); - if (runE2E) e2eTest(payload, crossChainController); - - return (configBefore, configAfter); - } - - function e2eTest(address payload, address crossChainController) public { - // test receivers - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory receiversToAllow = IBaseAdaptersUpdate(payload).getReceiverBridgeAdaptersToAllow(); - if (receiversToAllow.length != 0) { - _testCorrectReceiverAdaptersConfiguration(payload, receiversToAllow, crossChainController); - _testCorrectTrustedRemotes(receiversToAllow); - } - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - memory receiversToRemove = IBaseAdaptersUpdate(payload).getReceiverBridgeAdaptersToRemove(); - if (receiversToRemove.length != 0) { - _testOnlyRemovedSpecifiedReceiverAdapters(payload, receiversToRemove, crossChainController); - } - - // test forwarders - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] - memory forwardersToEnable = IBaseAdaptersUpdate(payload).getForwarderBridgeAdaptersToEnable(); - if (forwardersToEnable.length != 0) { - _testCorrectForwarderAdaptersConfiguration(payload, crossChainController, forwardersToEnable); - _testDestinationAdapterIsRegistered(forwardersToEnable); - } - ICrossChainForwarder.BridgeAdapterToDisable[] memory forwardersToRemove = IBaseAdaptersUpdate( - payload - ).getForwarderBridgeAdaptersToRemove(); - if (forwardersToRemove.length != 0) { - _testOnlyRemovedSpecificForwarderAdapters(payload, crossChainController, forwardersToRemove); - } - } - - function getDestinationPayloadsByChain() - public - view - virtual - returns (DestinationPayload[] memory) - { - return new DestinationPayload[](0); - } - - function _testDestinationAdapterIsRegistered( - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwardersToEnable - ) internal { - DestinationPayload[] memory destinationPayloads = getDestinationPayloadsByChain(); - bytes memory empty; - - for (uint256 i = 0; i < forwardersToEnable.length; i++) { - uint256 currentChainId = block.chainid; - // change fork to destination network - (uint256 previousFork, ) = ChainHelpers.selectChain( - vm, - forwardersToEnable[i].destinationChainId - ); - address destinationCCC = getCCCByChainId(block.chainid); - if (destinationPayloads.length > 0) { - for (uint256 j = 0; j < destinationPayloads.length; j++) { - if (destinationPayloads[j].chainId == forwardersToEnable[i].destinationChainId) { - if (keccak256(destinationPayloads[j].payloadCode) != keccak256(empty)) { - address destinationPayload = GovV3Helpers.deployDeterministic( - destinationPayloads[j].payloadCode - ); - - executePayload(vm, destinationPayload); - // check that adapter is registered - assertEq( - ICrossChainReceiver(destinationCCC).isReceiverBridgeAdapterAllowed( - forwardersToEnable[i].destinationBridgeAdapter, - currentChainId - ), - true - ); - break; - } - } - } - } else { - assertEq( - ICrossChainReceiver(destinationCCC).isReceiverBridgeAdapterAllowed( - forwardersToEnable[i].destinationBridgeAdapter, - currentChainId - ), - true - ); - } - vm.selectFork(previousFork); - } - } - - function _testOnlyRemovedSpecificForwarderAdapters( - address payload, - address crossChainController, - ICrossChainForwarder.BridgeAdapterToDisable[] memory adaptersToRemove - ) internal { - ForwarderAdapters[] - memory forwardersBridgeAdaptersByChainBefore = _getCurrentForwarderAdaptersByChain( - crossChainController, - block.chainid - ); - - executePayload(vm, payload); - - ForwarderAdapters[] - memory forwardersBridgeAdaptersByChainAfter = _getCurrentForwarderAdaptersByChain( - crossChainController, - block.chainid - ); - - for (uint256 l = 0; l < forwardersBridgeAdaptersByChainBefore.length; l++) { - for (uint256 j = 0; j < forwardersBridgeAdaptersByChainAfter.length; j++) { - if ( - forwardersBridgeAdaptersByChainBefore[l].chainId == - forwardersBridgeAdaptersByChainAfter[j].chainId - ) { - for (uint256 i = 0; i < forwardersBridgeAdaptersByChainBefore[l].adapters.length; i++) { - bool forwarderFound; - for (uint256 m = 0; m < forwardersBridgeAdaptersByChainAfter[j].adapters.length; m++) { - if ( - forwardersBridgeAdaptersByChainBefore[l].adapters[i].destinationBridgeAdapter == - forwardersBridgeAdaptersByChainAfter[j].adapters[m].destinationBridgeAdapter && - forwardersBridgeAdaptersByChainBefore[l].adapters[i].currentChainBridgeAdapter == - forwardersBridgeAdaptersByChainAfter[j].adapters[m].currentChainBridgeAdapter - ) { - forwarderFound = true; - break; - } - } - if (!forwarderFound) { - bool isAdapterToBeRemoved; - for (uint256 k = 0; k < adaptersToRemove.length; k++) { - if ( - forwardersBridgeAdaptersByChainBefore[l].adapters[i].currentChainBridgeAdapter == - adaptersToRemove[k].bridgeAdapter - ) { - for (uint256 n = 0; n < adaptersToRemove[k].chainIds.length; n++) { - if ( - forwardersBridgeAdaptersByChainBefore[l].chainId == - adaptersToRemove[k].chainIds[n] - ) { - isAdapterToBeRemoved = true; - break; - } - } - } - } - assertEq(isAdapterToBeRemoved, true); - } - } - } - } - } - } - - function _testCorrectForwarderAdaptersConfiguration( - address payload, - address crossChainController, - ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwardersToEnable - ) internal { - executePayload(vm, payload); - - for (uint256 i = 0; i < forwardersToEnable.length; i++) { - ICrossChainForwarder.ChainIdBridgeConfig[] - memory forwardersBridgeAdaptersByChain = ICrossChainForwarder(crossChainController) - .getForwarderBridgeAdaptersByChain(forwardersToEnable[i].destinationChainId); - bool newAdapterFound; - for (uint256 j = 0; j < forwardersBridgeAdaptersByChain.length; j++) { - if ( - forwardersBridgeAdaptersByChain[j].destinationBridgeAdapter == - forwardersToEnable[i].destinationBridgeAdapter && - forwardersBridgeAdaptersByChain[j].currentChainBridgeAdapter == - forwardersToEnable[i].currentChainBridgeAdapter - ) { - newAdapterFound = true; - break; - } - } - assertEq(newAdapterFound, true); - } - } - - function _testCorrectTrustedRemotes( - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiversToAllow - ) internal { - for (uint256 i = 0; i < receiversToAllow.length; i++) { - for (uint256 j = 0; j < receiversToAllow[i].chainIds.length; j++) { - address trustedRemote = IBaseAdapter(receiversToAllow[i].bridgeAdapter) - .getTrustedRemoteByChainId(receiversToAllow[i].chainIds[j]); - assertEq(trustedRemote, getCCCByChainId(receiversToAllow[i].chainIds[j])); - } - } - } - - function _testOnlyRemovedSpecifiedReceiverAdapters( - address payload, - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory adaptersToRemove, - address crossChainController - ) internal { - AdaptersByChain[] memory adaptersBefore = _getCurrentReceiverAdaptersByChain( - crossChainController - ); - - executePayload(vm, payload); - - for (uint256 i = 0; i < adaptersBefore.length; i++) { - for (uint256 j = 0; j < adaptersToRemove.length; j++) { - for (uint256 x = 0; x < adaptersToRemove[j].chainIds.length; x++) { - if (adaptersToRemove[j].chainIds[x] == adaptersBefore[i].chainId) { - for (uint256 k = 0; k < adaptersBefore[i].adapters.length; k++) { - if (adaptersBefore[i].adapters[k] == adaptersToRemove[j].bridgeAdapter) { - assertEq( - ICrossChainReceiver(crossChainController).isReceiverBridgeAdapterAllowed( - adaptersToRemove[j].bridgeAdapter, - adaptersBefore[i].chainId - ), - false - ); - } else { - assertEq( - ICrossChainReceiver(crossChainController).isReceiverBridgeAdapterAllowed( - adaptersBefore[i].adapters[k], - adaptersBefore[i].chainId - ), - true - ); - } - } - } - } - } - } - } - - function _testCorrectReceiverAdaptersConfiguration( - address payload, - ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiversToAllow, - address crossChainController - ) internal { - for (uint256 i = 0; i < receiversToAllow.length; i++) { - for (uint256 j = 0; j < receiversToAllow[i].chainIds.length; j++) { - assertEq( - ICrossChainReceiver(crossChainController).isReceiverBridgeAdapterAllowed( - receiversToAllow[i].bridgeAdapter, - receiversToAllow[i].chainIds[j] - ), - false - ); - } - } - - executePayload(vm, payload); - - for (uint256 i = 0; i < receiversToAllow.length; i++) { - for (uint256 j = 0; j < receiversToAllow[i].chainIds.length; j++) { - assertEq( - ICrossChainReceiver(crossChainController).isReceiverBridgeAdapterAllowed( - receiversToAllow[i].bridgeAdapter, - receiversToAllow[i].chainIds[j] - ), - true - ); - } - } - } - - /** - * @dev Generates a markdown compatible snapshot of the whole CrossChainController configuration into `/reports`. - * @param reportName filename suffix for the generated reports. - * @param crossChainController the ccc to be snapshot - * @return ReserveConfig[] list of configs - */ - function createConfigurationSnapshot( - string memory reportName, - address crossChainController - ) public returns (CCCConfig memory) { - return - createConfigurationSnapshot( - SnapshotParams({ - crossChainController: crossChainController, - receiverConfigs: true, - receiverAdapterConfigs: true, - forwarderAdapterConfigs: true, - cccImplUpdate: true, - reportName: reportName - }) - ); - } - - function createConfigurationSnapshot( - SnapshotParams memory snapshotParams - ) public returns (CCCConfig memory) { - string memory path = string(abi.encodePacked('./reports/', snapshotParams.reportName, '.json')); - // overwrite with empty json to later be extended - vm.writeFile( - path, - '{ "cccImplementation": {}, "receiverConfigsByChain": {}, "receiverAdaptersByChain": {}, "forwarderAdaptersByChain": {}}' - ); - vm.serializeUint('root', 'chainId', block.chainid); - CCCConfig memory config = _getCCCConfig(snapshotParams.crossChainController); - if (snapshotParams.receiverConfigs) _writeReceiverConfigs(path, config); - if (snapshotParams.receiverAdapterConfigs) _writeReceiverAdapters(path, config); - if (snapshotParams.forwarderAdapterConfigs) _writeForwarderAdapters(path, config); - if (snapshotParams.cccImplUpdate) _writeCCCImplUpdate(path, config); - - return config; - } - - function _writeCCCImplUpdate(string memory path, CCCConfig memory config) internal { - string memory output = vm.serializeAddress( - 'root', - 'crossChainControllerImpl', - config.crossChainControllerImpl - ); - vm.writeJson(output, path); - } - - function _writeForwarderAdapters(string memory path, CCCConfig memory config) internal { - // keys for json stringification - string memory forwarderAdaptersKey = 'forwarderAdapters'; - string memory content = '{}'; - vm.serializeJson(forwarderAdaptersKey, '{}'); - ForwarderAdaptersByChain[] memory forwarderConfig = config.forwarderAdaptersConfig; - - for (uint256 i = 0; i < forwarderConfig.length; i++) { - uint256 chainId = forwarderConfig[i].chainId; - string memory key = vm.toString(chainId); - vm.serializeJson(key, '{}'); - string memory object; - - ICrossChainForwarder.ChainIdBridgeConfig[] memory forwarders = forwarderConfig[i].forwarders; - for (uint256 j = 0; j < forwarders.length; j++) { - if (j == forwarders.length - 1) { - object = vm.serializeString( - key, - vm.toString(forwarders[j].currentChainBridgeAdapter), - vm.toString(forwarders[j].destinationBridgeAdapter) - ); - } else { - vm.serializeString( - key, - vm.toString(forwarders[j].currentChainBridgeAdapter), - vm.toString(forwarders[j].destinationBridgeAdapter) - ); - } - } - content = vm.serializeString(forwarderAdaptersKey, key, object); - } - string memory output = vm.serializeString('root', 'forwarderAdaptersByChain', content); - vm.writeJson(output, path); - } - - function _writeReceiverAdapters(string memory path, CCCConfig memory config) internal { - // keys for json stringification - string memory receiverAdaptersKey = 'receiverAdapters'; - string memory content = '{}'; - vm.serializeJson(receiverAdaptersKey, '{}'); - ReceiverAdaptersByChain[] memory receiverConfig = config.receiverAdaptersConfig; - - for (uint256 i = 0; i < receiverConfig.length; i++) { - uint256 chainId = receiverConfig[i].chainId; - string memory key = vm.toString(chainId); - vm.serializeJson(key, '{}'); - string memory object; - - for (uint256 j = 0; j < receiverConfig[i].receiverAdapters.length; j++) { - if (j == receiverConfig[i].receiverAdapters.length - 1) { - object = vm.serializeString( - key, - vm.toString(receiverConfig[i].receiverAdapters[j]), - vm.toString(true) - ); - } else { - vm.serializeString( - key, - vm.toString(receiverConfig[i].receiverAdapters[j]), - vm.toString(true) - ); - } - } - content = vm.serializeString(receiverAdaptersKey, key, object); - } - string memory output = vm.serializeString('root', 'receiverAdaptersByChain', content); - vm.writeJson(output, path); - } - - function _writeReceiverConfigs(string memory path, CCCConfig memory configs) internal { - // keys for json stringification - string memory receiverConfigsKey = 'receiverConfigs'; - string memory content = '{}'; - vm.serializeJson(receiverConfigsKey, '{}'); - ReceiverConfigByChain[] memory receiverConfig = configs.receiverConfigs; - for (uint256 i = 0; i < receiverConfig.length; i++) { - uint256 chainId = receiverConfig[i].chainId; - string memory key = vm.toString(chainId); - vm.serializeJson(key, '{}'); - string memory object; - vm.serializeString( - key, - 'requiredConfirmations', - vm.toString(receiverConfig[i].requiredConfirmations) - ); - object = vm.serializeString( - key, - 'validityTimestamp', - vm.toString(receiverConfig[i].validityTimestamp) - ); - - content = vm.serializeString(receiverConfigsKey, key, object); - } - string memory output = vm.serializeString('root', 'receiverConfigs', content); - vm.writeJson(output, path); - } - - function _getCCCConfig(address ccc) internal view returns (CCCConfig memory) { - CCCConfig memory config; - - // get crossChainController implementation - config.crossChainControllerImpl = ProxyHelpers - .getInitializableAdminUpgradeabilityProxyImplementation(vm, ccc); - // get supported networks - uint256[] memory receiverSupportedChains = ICrossChainReceiver(ccc).getSupportedChains(); - ReceiverConfigByChain[] memory receiverConfigs = new ReceiverConfigByChain[]( - receiverSupportedChains.length - ); - ReceiverAdaptersByChain[] memory receiverAdaptersConfig = new ReceiverAdaptersByChain[]( - receiverSupportedChains.length - ); - for (uint256 i = 0; i < receiverSupportedChains.length; i++) { - uint256 chainId = receiverSupportedChains[i]; - ICrossChainReceiver.ReceiverConfiguration memory receiverConfig = ICrossChainReceiver(ccc) - .getConfigurationByChain(chainId); - receiverConfigs[i] = ReceiverConfigByChain({ - chainId: chainId, - requiredConfirmations: receiverConfig.requiredConfirmation, - validityTimestamp: receiverConfig.validityTimestamp - }); - receiverAdaptersConfig[i] = ReceiverAdaptersByChain({ - chainId: chainId, - receiverAdapters: ICrossChainReceiver(ccc).getReceiverBridgeAdaptersByChain(chainId) - }); - } - - config.receiverAdaptersConfig = receiverAdaptersConfig; - config.receiverConfigs = receiverConfigs; - - // get receiver configs by network - uint256[] memory supportedForwardingNetworks = _getForwarderSupportedChainsByChainId( - block.chainid - ); - ForwarderAdaptersByChain[] memory forwardersByChain = new ForwarderAdaptersByChain[]( - supportedForwardingNetworks.length - ); - for (uint256 i = 0; i < supportedForwardingNetworks.length; i++) { - uint256 chainId = supportedForwardingNetworks[i]; - forwardersByChain[i] = ForwarderAdaptersByChain({ - chainId: chainId, - forwarders: ICrossChainForwarder(ccc).getForwarderBridgeAdaptersByChain(chainId) - }); - } - config.forwarderAdaptersConfig = forwardersByChain; - - return config; - } - - /// @dev Update when supporting new forwarding networks - function _getForwarderSupportedChainsByChainId( - uint256 chainId - ) internal pure returns (uint256[] memory) { - if (chainId == ChainIds.MAINNET) { - uint256[] memory chainIds = new uint256[](10); - chainIds[0] = ChainIds.MAINNET; - chainIds[1] = ChainIds.POLYGON; - chainIds[2] = ChainIds.AVALANCHE; - chainIds[3] = ChainIds.BNB; - chainIds[4] = ChainIds.GNOSIS; - chainIds[5] = ChainIds.ARBITRUM; - chainIds[6] = ChainIds.OPTIMISM; - chainIds[7] = ChainIds.METIS; - chainIds[8] = ChainIds.BASE; - chainIds[9] = ChainIds.SCROLL; - - return chainIds; - } else if (chainId == ChainIds.POLYGON) { - uint256[] memory chainIds = new uint256[](1); - chainIds[0] = ChainIds.MAINNET; - - return chainIds; - } else if (chainId == ChainIds.AVALANCHE) { - uint256[] memory chainIds = new uint256[](1); - chainIds[0] = ChainIds.MAINNET; - - return chainIds; - } else { - return new uint256[](0); - } - } - - function _getCurrentForwarderAdaptersByChain( - address crossChainController, - uint256 chainId - ) internal view returns (ForwarderAdapters[] memory) { - uint256[] memory supportedChains = _getForwarderSupportedChainsByChainId(chainId); - - ForwarderAdapters[] memory forwarderAdapters = new ForwarderAdapters[](supportedChains.length); - - for (uint256 i = 0; i < supportedChains.length; i++) { - ICrossChainForwarder.ChainIdBridgeConfig[] memory forwarders = ICrossChainForwarder( - crossChainController - ).getForwarderBridgeAdaptersByChain(supportedChains[i]); - - forwarderAdapters[i] = ForwarderAdapters({adapters: forwarders, chainId: supportedChains[i]}); - } - return forwarderAdapters; - } - - function _getCurrentReceiverAdaptersByChain( - address crossChainController - ) internal view returns (AdaptersByChain[] memory) { - uint256[] memory supportedChains = ICrossChainReceiver(crossChainController) - .getSupportedChains(); - - AdaptersByChain[] memory receiverAdapters = new AdaptersByChain[](supportedChains.length); - - for (uint256 i = 0; i < supportedChains.length; i++) { - address[] memory receivers = ICrossChainReceiver(crossChainController) - .getReceiverBridgeAdaptersByChain(supportedChains[i]); - - receiverAdapters[i] = AdaptersByChain({adapters: receivers, chainId: supportedChains[i]}); - } - - return receiverAdapters; - } - - /// @dev add new chains t - function getCCCByChainId(uint256 chainId) public pure returns (address) { - if (chainId == ChainIds.MAINNET) { - return GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.POLYGON) { - return GovernanceV3Polygon.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.AVALANCHE) { - return GovernanceV3Avalanche.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.OPTIMISM) { - return GovernanceV3Optimism.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.BNB) { - return GovernanceV3BNB.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.METIS) { - return GovernanceV3Metis.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.BASE) { - return GovernanceV3Base.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.ARBITRUM) { - return GovernanceV3Arbitrum.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.GNOSIS) { - return GovernanceV3Gnosis.CROSS_CHAIN_CONTROLLER; - } else if (chainId == ChainIds.SCROLL) { - return GovernanceV3Scroll.CROSS_CHAIN_CONTROLLER; - } - revert(); - } -} diff --git a/tests/GovV3Test.t.sol b/tests/GovV3Test.t.sol index 8fe13c89e..0c479b0bc 100644 --- a/tests/GovV3Test.t.sol +++ b/tests/GovV3Test.t.sol @@ -24,7 +24,7 @@ contract GovernanceV3Test is ProtocolV3TestBase { uint256 public constant BLOCK_NUMBER = 20381808; - function setUp() public { + function setUp() public override { vm.createSelectFork('mainnet', BLOCK_NUMBER); payload = new PayloadWithEmit(); } diff --git a/tests/ProtocolV2TestBase.t.sol b/tests/ProtocolV2TestBase.t.sol index d983175a8..da279a0dd 100644 --- a/tests/ProtocolV2TestBase.t.sol +++ b/tests/ProtocolV2TestBase.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import 'forge-std/Test.sol'; import {ProtocolV2TestBase, ReserveConfig} from '../src/ProtocolV2TestBase.sol'; import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; import {AaveV2EthereumAMM} from 'aave-address-book/AaveV2EthereumAMM.sol'; @@ -9,8 +8,9 @@ import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {PayloadWithEmit} from './mocks/PayloadWithEmit.sol'; contract ProtocolV2TestBaseTest is ProtocolV2TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('mainnet', 17627440); + super.setUp(); } // function testSnpashot() public { @@ -23,8 +23,9 @@ contract ProtocolV2TestBaseTest is ProtocolV2TestBase { } contract ProtocolV2TestE2ETestAsset is ProtocolV2TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('mainnet', 18572478); + super.setUp(); } function test_e2eTestAssetUSDT() public { diff --git a/tests/ProtocolV3TestBase.t.sol b/tests/ProtocolV3TestBase.t.sol index b7c15b611..bdf50536a 100644 --- a/tests/ProtocolV3TestBase.t.sol +++ b/tests/ProtocolV3TestBase.t.sol @@ -13,8 +13,9 @@ import {AaveV3Fantom} from 'aave-address-book/AaveV3Fantom.sol'; import {PayloadWithEmit} from './mocks/PayloadWithEmit.sol'; contract ProtocolV3TestBaseTest is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('polygon', 47135218); + super.setUp(); } function test_e2eTestDPI() public { @@ -39,8 +40,9 @@ contract ProtocolV3TestBaseTest is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestAsset is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('optimism', 105565839); + super.setUp(); } function test_e2eTestAssetMAI() public { @@ -63,7 +65,7 @@ contract ProtocolV3TestE2ETestAsset is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestOptimismAll is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('optimism', 123145540); } @@ -73,8 +75,9 @@ contract ProtocolV3TestE2ETestOptimismAll is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestMetisAll is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('metis', 10115177); + super.setUp(); } function test_e2e() public { @@ -83,8 +86,9 @@ contract ProtocolV3TestE2ETestMetisAll is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestAvalancheAll is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('avalanche', 38700698); + super.setUp(); } function test_e2e() public { @@ -97,8 +101,9 @@ contract ProtocolV3TestE2ETestAvalancheAll is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestArbitrumAll is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('arbitrum', 164285417); + super.setUp(); } function test_e2e() public { @@ -111,8 +116,9 @@ contract ProtocolV3TestE2ETestArbitrumAll is ProtocolV3TestBase { } contract ProtocolV3TestE2ETestAllMainnet is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('mainnet', 19477376); + super.setUp(); } function test_e2e() public { @@ -121,8 +127,9 @@ contract ProtocolV3TestE2ETestAllMainnet is ProtocolV3TestBase { } contract ProtocolV3TestOptimismSnapshot is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('optimism', 117408311); + super.setUp(); } function test_snapshot() public { @@ -132,7 +139,7 @@ contract ProtocolV3TestOptimismSnapshot is ProtocolV3TestBase { contract ProtocolV3TestFantomSnapshot is ProtocolV3TestBase { - function setUp() public { + function setUp() public override { vm.createSelectFork('fantom', 86731015); } diff --git a/tests/adi/SimpleOneToManyAdapterUpdatePayloadTest.t.sol b/tests/adi/SimpleOneToManyAdapterUpdatePayloadTest.t.sol deleted file mode 100644 index 149fdff43..000000000 --- a/tests/adi/SimpleOneToManyAdapterUpdatePayloadTest.t.sol +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {SimpleOneToManyAdapterUpdate} from '../../src/adi/SimpleOneToManyAdapterUpdate.sol'; -import {GovernanceV3Polygon} from 'aave-address-book/GovernanceV3Polygon.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import 'forge-std/Test.sol'; -import '../../src/adi/test/ADITestBase.sol'; -import {MockAdapterDeploymentHelper} from './mocks/AdaptersByteCode.sol'; - -contract SimpleOneToManyAdapterUpdatePayload is SimpleOneToManyAdapterUpdate { - constructor( - address crossChainController, - address newAdapter - ) - SimpleOneToManyAdapterUpdate( - SimpleOneToManyAdapterUpdate.ConstructorInput({ - ccc: crossChainController, - adapterToRemove: address(0), - newAdapter: newAdapter - }) - ) - {} - - function getChainsToReceive() public pure override returns (uint256[] memory) { - uint256[] memory chains = new uint256[](1); - chains[0] = ChainIds.MAINNET; - return chains; - } - - function getDestinationAdapters() - public - pure - override - returns (DestinationAdaptersInput[] memory) - { - DestinationAdaptersInput[] memory destinationAdapters = new DestinationAdaptersInput[](1); - - destinationAdapters[0].adapter = 0x8410d9BD353b420ebA8C48ff1B0518426C280FCC; - destinationAdapters[0].chainId = ChainIds.MAINNET; - - return destinationAdapters; - } -} - -contract SimpleOneToManyAdapterUpdateEthereumPayload is SimpleOneToManyAdapterUpdate { - constructor( - address crossChainController, - address newAdapter - ) - SimpleOneToManyAdapterUpdate( - SimpleOneToManyAdapterUpdate.ConstructorInput({ - ccc: crossChainController, - adapterToRemove: address(0), - newAdapter: newAdapter - }) - ) - {} - - function getChainsToReceive() public pure override returns (uint256[] memory) { - uint256[] memory chains = new uint256[](2); - chains[0] = ChainIds.POLYGON; - chains[1] = ChainIds.AVALANCHE; - return chains; - } -} - -// provably here we should just define the blockNumber and network. And use base test that in theory could generate diffs -contract SimpleOneToManyAdapterUpdatePayloadTest is ADITestBase { - SimpleOneToManyAdapterUpdatePayload public payload; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('polygon'), 56680671); - // create payload constructor args - IBaseAdapter.TrustedRemotesConfig[] - memory trustedRemotes = new IBaseAdapter.TrustedRemotesConfig[](1); - trustedRemotes[0] = IBaseAdapter.TrustedRemotesConfig({ - originChainId: ChainIds.MAINNET, - originForwarder: GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER - }); - - MockAdapterDeploymentHelper.MockAdapterArgs memory args = MockAdapterDeploymentHelper - .MockAdapterArgs({ - baseArgs: MockAdapterDeploymentHelper.BaseAdapterArgs({ - crossChainController: GovernanceV3Polygon.CROSS_CHAIN_CONTROLLER, - providerGasLimit: 0, - trustedRemotes: trustedRemotes, - isTestnet: false - }), - mockEndpoint: 0x1a44076050125825900e736c501f859c50fE728c - }); - - // deploy adapter - address newAdapter = GovV3Helpers.deployDeterministic( - MockAdapterDeploymentHelper.getAdapterCode(args) - ); - // deploy payload - payload = new SimpleOneToManyAdapterUpdatePayload( - GovernanceV3Polygon.CROSS_CHAIN_CONTROLLER, - newAdapter - ); - } - - function getDestinationPayloadsByChain() - public - pure - override - returns (DestinationPayload[] memory) - { - DestinationPayload[] memory destinationPayload = new DestinationPayload[](1); - - IBaseAdapter.TrustedRemotesConfig[] - memory trustedRemotes = new IBaseAdapter.TrustedRemotesConfig[](2); - trustedRemotes[0] = IBaseAdapter.TrustedRemotesConfig({ - originChainId: ChainIds.POLYGON, - originForwarder: GovernanceV3Polygon.CROSS_CHAIN_CONTROLLER - }); - trustedRemotes[1] = IBaseAdapter.TrustedRemotesConfig({ - originChainId: ChainIds.AVALANCHE, - originForwarder: GovernanceV3Avalanche.CROSS_CHAIN_CONTROLLER - }); - - MockAdapterDeploymentHelper.MockAdapterArgs memory args = MockAdapterDeploymentHelper - .MockAdapterArgs({ - baseArgs: MockAdapterDeploymentHelper.BaseAdapterArgs({ - crossChainController: GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER, - providerGasLimit: 0, - trustedRemotes: trustedRemotes, - isTestnet: false - }), - mockEndpoint: 0x1a44076050125825900e736c501f859c50fE728c - }); - - bytes memory adapterCode = MockAdapterDeploymentHelper.getAdapterCode(args); - - address newAdapter = GovV3Helpers.predictDeterministicAddress(adapterCode); - - destinationPayload[0] = DestinationPayload({ - chainId: ChainIds.MAINNET, - payloadCode: abi.encodePacked( - type(SimpleOneToManyAdapterUpdateEthereumPayload).creationCode, - abi.encode(GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER, newAdapter) - ) - }); - - return destinationPayload; - } - - function test_defaultTest() public { - defaultTest( - 'test_adi_diffs', - GovernanceV3Polygon.CROSS_CHAIN_CONTROLLER, - address(payload), - true, - vm - ); - } -} diff --git a/tests/bridges/arbitrum/AaveArbEthERC20BridgeTest.t.sol b/tests/bridges/arbitrum/AaveArbEthERC20BridgeTest.t.sol deleted file mode 100644 index bb220e079..000000000 --- a/tests/bridges/arbitrum/AaveArbEthERC20BridgeTest.t.sol +++ /dev/null @@ -1,276 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; - -import {AaveArbEthERC20Bridge} from '../../../src/bridges/arbitrum/AaveArbEthERC20Bridge.sol'; -import {IAaveArbEthERC20Bridge} from '../../../src/bridges/arbitrum/IAaveArbEthERC20Bridge.sol'; -import {ArbSysMock} from './ArbSysMock.sol'; - -/** - * @dev Tests for AaveArbEthERC20Bridge - */ -contract AaveArbEthERC20BridgeTest is Test { - event Bridge(address indexed token, uint256 amount); - event Exit( - address l2sender, - address to, - uint256 l2block, - uint256 l1block, - uint256 value, - bytes data - ); - - AaveArbEthERC20Bridge bridgeMainnet; - AaveArbEthERC20Bridge bridgeArbitrum; - uint256 mainnetFork; - uint256 arbitrumFork; - - address USDC_WHALE = 0xb874005cbEa25C357b31C62145b3AEF219d105CF; - address USDC_WHALE_MAINNET = 0xcEe284F754E854890e311e3280b767F80797180d; - - function setUp() public { - bytes32 salt = keccak256(abi.encode(tx.origin, uint256(0))); - - mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 18531022); - bridgeMainnet = new AaveArbEthERC20Bridge{salt: salt}(address(this)); - - arbitrumFork = vm.createSelectFork(vm.rpcUrl('arbitrum'), 148530087); - bridgeArbitrum = new AaveArbEthERC20Bridge{salt: salt}(address(this)); - } -} - -contract BridgeTest is AaveArbEthERC20BridgeTest { - address public constant USDC_GATEWAY = 0x096760F208390250649E3e8763348E783AEF5562; - address public constant ARB_SYS = 0x0000000000000000000000000000000000000064; // pre-compiled - - function test_revertsIf_invalidChain() public { - vm.selectFork(mainnetFork); - - vm.expectRevert(IAaveArbEthERC20Bridge.InvalidChain.selector); - bridgeArbitrum.bridge( - AaveV3ArbitrumAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - USDC_GATEWAY, - 1_000e6 - ); - } - - function test_revertsIf_notOwner() public { - vm.selectFork(arbitrumFork); - - uint256 amount = 1_000e6; - - vm.startPrank(USDC_WHALE); - IERC20(AaveV3ArbitrumAssets.USDC_UNDERLYING).transfer(address(bridgeArbitrum), amount); - vm.stopPrank(); - - bridgeArbitrum.transferOwnership(GovernanceV3Arbitrum.EXECUTOR_LVL_1); - - vm.expectRevert('Ownable: caller is not the owner'); - bridgeArbitrum.bridge( - AaveV3ArbitrumAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - USDC_GATEWAY, - amount - ); - } - - function test_successful_arbitrumBridge() public { - vm.selectFork(arbitrumFork); - - uint256 amount = 1_000e6; - - vm.startPrank(USDC_WHALE); - IERC20(AaveV3ArbitrumAssets.USDC_UNDERLYING).transfer(address(bridgeArbitrum), amount); - vm.stopPrank(); - - bridgeArbitrum.transferOwnership(GovernanceV3Arbitrum.EXECUTOR_LVL_1); - - vm.startPrank(GovernanceV3Arbitrum.EXECUTOR_LVL_1); - - - ArbSysMock arbsys = new ArbSysMock(); - vm.etch(address(0x0000000000000000000000000000000000000064), address(arbsys).code); - - vm.expectEmit(); - emit Bridge(AaveV3ArbitrumAssets.USDC_UNDERLYING, amount); - - bridgeArbitrum.bridge( - AaveV3ArbitrumAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - USDC_GATEWAY, - amount - ); - vm.stopPrank(); - } -} - -contract EmergencyTokenTransfer is AaveArbEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - vm.startPrank(makeAddr('random-caller')); - bridgeArbitrum.emergencyTokenTransfer( - AaveV3ArbitrumAssets.LINK_UNDERLYING, - address(AaveV3Arbitrum.COLLECTOR), - 1_000e6 - ); - vm.stopPrank(); - } - - function test_successful_governanceCaller() public { - address LINK_WHALE = 0x191c10Aa4AF7C30e871E70C95dB0E4eb77237530; - - assertEq(IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(bridgeArbitrum)), 0); - - uint256 balAmount = 1_000e18; - - vm.startPrank(LINK_WHALE); - IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).transfer(address(bridgeArbitrum), balAmount); - vm.stopPrank(); - - assertEq( - IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(bridgeArbitrum)), - balAmount - ); - - uint256 initialCollectorBalBalance = IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf( - address(AaveV3Arbitrum.COLLECTOR) - ); - - bridgeArbitrum.emergencyTokenTransfer( - AaveV3ArbitrumAssets.LINK_UNDERLYING, - address(AaveV3Arbitrum.COLLECTOR), - balAmount - ); - - assertEq( - IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(AaveV3Arbitrum.COLLECTOR)), - initialCollectorBalBalance + balAmount - ); - assertEq(IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(bridgeArbitrum)), 0); - } -} - -/* - * No good way of testing the full flow as proof is generated via API ~7 days after the - * bridge() function is called on Arbitrum. - */ -contract ExitTest is AaveArbEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(arbitrumFork); - - bytes32[] memory proof = new bytes32[](17); - proof[0] = bytes32(0x8f2413401b9e655775aad826103c53ff5ca1ee7ad724eb8c79e9c6daa53a42c1); - proof[1] = bytes32(0x28d6fb477c18b08c0fecd8ffbcd6c866388eeebf2cd2c09eb2a6d8a4400b643b); - proof[2] = bytes32(0xb1435f7e1cb4a5953e89746da1288a039ffb4f24cacccf315732838e53d6f060); - proof[3] = bytes32(0x61db0210d82c6a3a982db41752ab66966ef66f4587bd093dbcc86c79d571f2e2); - proof[4] = bytes32(0x89e093bdddd365d65e23655f220d5d106445b3ae37e6371f4d666f3101228c56); - proof[5] = bytes32(0x09796038b06aa218c3a098a19c2fe62db5ae65150180256775126c6cc0a7944b); - proof[6] = bytes32(0x09e8d829b211a96087ec9e1553d962c7095ea2a516ac5e3d3fc9dfb0883437df); - proof[7] = bytes32(0xeb8a59e232457e7992da6dada364130ac0355abd6a3e2de11994cc87dd48e2fd); - proof[8] = bytes32(0x7f895c7d5e604507e11dcef280b63fbb176470934d655b9774850e7b4e8a2437); - proof[9] = bytes32(0xaa028b33592259e6362db13faf07aad33f79b39ec93c86798e374c1306c622f3); - proof[10] = bytes32(0xb6fa41cd3de57f0ba7f178fa0ce164c9f3fd14d9af481bcdee844f1a48b083ed); - proof[11] = bytes32(0x5e293ff63182ef6620cdd6aa4f35a1a3fe0d8da195a674f11dafc06043d06719); - proof[12] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[13] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[14] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[15] = bytes32(0xc0425084107ea9f7a4118f5ed1e3566cda4e90b550363fc804df1e52ed5f2386); - proof[16] = bytes32(0xb43a6b28077d49f37d58c87aec0b51f7bce13b648143f3295385f3b3d5ac3b9b); - - vm.expectRevert(IAaveArbEthERC20Bridge.InvalidChain.selector); - bridgeMainnet.exit( - proof, - 101373, - 0x09e9222E96E7B4AE2a407B98d48e330053351EEe, - 0xa3A7B6F88361F48403514059F1F16C8E78d60EeC, - 162707774, - 18843894, - 1703278527, - 0, - hex'2e567b36000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000e6bb71856c5c821d1b83f2c6a9a59a78d5e0712000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c0000000000000000000000000000000000000000000000000031f025da53473500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000003c7300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000' - ); - } - - function test_successful_exitsLink() public { - // This test uses a valid proof utilized in a test which can be found here: - // https://etherscan.io/tx/0xa34c3725cc95773eedf96b03e9672ad77940b27fc5b1b94441e6587dec014ecd - // Setting block number to one prior to the real exit TX - vm.createSelectFork(vm.rpcUrl('mainnet'), 18894550); - bridgeMainnet = new AaveArbEthERC20Bridge{salt: keccak256(abi.encode(tx.origin, uint256(0)))}( - address(this) - ); - - uint256 balanceBefore = IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).balanceOf( - address(AaveV3Ethereum.COLLECTOR) - ); - - bytes32[] memory proof = new bytes32[](17); - proof[0] = bytes32(0x8f2413401b9e655775aad826103c53ff5ca1ee7ad724eb8c79e9c6daa53a42c1); - proof[1] = bytes32(0x28d6fb477c18b08c0fecd8ffbcd6c866388eeebf2cd2c09eb2a6d8a4400b643b); - proof[2] = bytes32(0xb1435f7e1cb4a5953e89746da1288a039ffb4f24cacccf315732838e53d6f060); - proof[3] = bytes32(0x61db0210d82c6a3a982db41752ab66966ef66f4587bd093dbcc86c79d571f2e2); - proof[4] = bytes32(0x89e093bdddd365d65e23655f220d5d106445b3ae37e6371f4d666f3101228c56); - proof[5] = bytes32(0x09796038b06aa218c3a098a19c2fe62db5ae65150180256775126c6cc0a7944b); - proof[6] = bytes32(0x09e8d829b211a96087ec9e1553d962c7095ea2a516ac5e3d3fc9dfb0883437df); - proof[7] = bytes32(0xeb8a59e232457e7992da6dada364130ac0355abd6a3e2de11994cc87dd48e2fd); - proof[8] = bytes32(0x7f895c7d5e604507e11dcef280b63fbb176470934d655b9774850e7b4e8a2437); - proof[9] = bytes32(0xaa028b33592259e6362db13faf07aad33f79b39ec93c86798e374c1306c622f3); - proof[10] = bytes32(0xb6fa41cd3de57f0ba7f178fa0ce164c9f3fd14d9af481bcdee844f1a48b083ed); - proof[11] = bytes32(0x5e293ff63182ef6620cdd6aa4f35a1a3fe0d8da195a674f11dafc06043d06719); - proof[12] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[13] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[14] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); - proof[15] = bytes32(0xc0425084107ea9f7a4118f5ed1e3566cda4e90b550363fc804df1e52ed5f2386); - proof[16] = bytes32(0xb43a6b28077d49f37d58c87aec0b51f7bce13b648143f3295385f3b3d5ac3b9b); - - vm.expectEmit(); - emit Exit( - 0x09e9222E96E7B4AE2a407B98d48e330053351EEe, - 0xa3A7B6F88361F48403514059F1F16C8E78d60EeC, - 162707774, - 18843894, - 0, - hex'2e567b36000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000e6bb71856c5c821d1b83f2c6a9a59a78d5e0712000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c0000000000000000000000000000000000000000000000000031f025da53473500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000003c7300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000' - ); - - bridgeMainnet.exit( - proof, - 101373, - 0x09e9222E96E7B4AE2a407B98d48e330053351EEe, - 0xa3A7B6F88361F48403514059F1F16C8E78d60EeC, - 162707774, - 18843894, - 1703278527, - 0, - hex'2e567b36000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000e6bb71856c5c821d1b83f2c6a9a59a78d5e0712000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c0000000000000000000000000000000000000000000000000031f025da53473500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000003c7300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000' - ); - - assertGt( - IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).balanceOf(address(AaveV3Ethereum.COLLECTOR)), - balanceBefore - ); - } -} - -contract TransferOwnership is AaveArbEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.startPrank(makeAddr('random-caller')); - vm.expectRevert('Ownable: caller is not the owner'); - bridgeMainnet.transferOwnership(makeAddr('new-admin')); - vm.stopPrank(); - } - - function test_successful() public { - address newAdmin = GovernanceV3Ethereum.EXECUTOR_LVL_1; - bridgeMainnet.transferOwnership(newAdmin); - - assertEq(newAdmin, bridgeMainnet.owner()); - } -} diff --git a/tests/bridges/arbitrum/ArbSysMock.sol b/tests/bridges/arbitrum/ArbSysMock.sol deleted file mode 100644 index 9566a0b04..000000000 --- a/tests/bridges/arbitrum/ArbSysMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -/// @title ArbSysMock -/// @notice a mocked version of the Arbitrum system contract, add additional methods as needed -contract ArbSysMock { - uint256 ticketId; - - function sendTxToL1(address _l1Target, bytes memory _data) external payable returns (uint256) { - (bool success,) = _l1Target.call(_data); - require(success, "Arbsys: sendTxToL1 failed"); - return ++ticketId; - } -} diff --git a/tests/bridges/optimism/AaveOpEthERC20BridgeTest.t.sol b/tests/bridges/optimism/AaveOpEthERC20BridgeTest.t.sol deleted file mode 100644 index 042517b86..000000000 --- a/tests/bridges/optimism/AaveOpEthERC20BridgeTest.t.sol +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {AaveV3Optimism, AaveV3OptimismAssets} from 'aave-address-book/AaveV3Optimism.sol'; -import {GovernanceV3Optimism} from 'aave-address-book/GovernanceV3Optimism.sol'; - -import {AaveOpEthERC20Bridge} from 'src/bridges/optimism/AaveOpEthERC20Bridge.sol'; -import {IAaveOpEthERC20Bridge} from 'src/bridges/optimism/IAaveOpEthERC20Bridge.sol'; - -contract AaveOpEthERC20BridgeTest is Test { - event Bridge( - address indexed token, - address indexed l1token, - uint256 amount, - address indexed to, - uint256 nonce - ); - - address public constant WHALE = 0xe7804c37c13166fF0b37F5aE0BB07A3aEbb6e245; - - AaveOpEthERC20Bridge bridge; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('optimism'), 121507518); - - bytes32 salt = keccak256(abi.encode(tx.origin, uint256(0))); - bridge = new AaveOpEthERC20Bridge{salt: salt}(address(this)); - } -} - -contract BridgeTest is AaveOpEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 20110401); - bytes32 salt = keccak256(abi.encode(tx.origin, uint256(0))); - AaveOpEthERC20Bridge mainnetBridge = new AaveOpEthERC20Bridge{salt: salt}(address(this)); - - vm.expectRevert(IAaveOpEthERC20Bridge.InvalidChain.selector); - mainnetBridge.bridge( - AaveV3OptimismAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - 1_000e6 - ); - } - - function test_revertsIf_notOwner() public { - uint256 amount = 1_000e6; - - deal(AaveV3OptimismAssets.USDC_UNDERLYING, address(bridge), amount); - - bridge.transferOwnership(GovernanceV3Optimism.EXECUTOR_LVL_1); - - vm.expectRevert('Ownable: caller is not the owner'); - bridge.bridge( - AaveV3OptimismAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - 1_000e6 - ); - } - - function test_successful() public { - uint256 amount = 1_000e6; - - deal(AaveV3OptimismAssets.USDC_UNDERLYING, address(bridge), amount); - - bridge.transferOwnership(GovernanceV3Optimism.EXECUTOR_LVL_1); - - vm.startPrank(GovernanceV3Optimism.EXECUTOR_LVL_1); - vm.expectEmit(); - emit Bridge( - AaveV3OptimismAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - amount, - address(AaveV3Ethereum.COLLECTOR), - 0 - ); - bridge.bridge( - AaveV3OptimismAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - 1_000e6 - ); - vm.stopPrank(); - } -} - -contract TransferOwnership is AaveOpEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.startPrank(makeAddr('random-caller')); - vm.expectRevert('Ownable: caller is not the owner'); - bridge.transferOwnership(makeAddr('new-admin')); - vm.stopPrank(); - } - - function test_successful() public { - address newAdmin = GovernanceV3Optimism.EXECUTOR_LVL_1; - bridge.transferOwnership(newAdmin); - - assertEq(newAdmin, bridge.owner()); - } -} - -contract EmergencyTokenTransfer is AaveOpEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - vm.startPrank(makeAddr('random-caller')); - bridge.emergencyTokenTransfer( - AaveV3OptimismAssets.USDC_UNDERLYING, - address(AaveV3Optimism.COLLECTOR), - 1_000e6 - ); - vm.stopPrank(); - } - - function test_successful_governanceCaller() public { - assertEq(IERC20(AaveV3OptimismAssets.USDC_UNDERLYING).balanceOf(address(bridge)), 0); - - uint256 usdcAmount = 1_000e18; - - deal(AaveV3OptimismAssets.USDC_UNDERLYING, address(bridge), usdcAmount); - - assertEq(IERC20(AaveV3OptimismAssets.USDC_UNDERLYING).balanceOf(address(bridge)), usdcAmount); - - uint256 initialCollectorBalBalance = IERC20(AaveV3OptimismAssets.USDC_UNDERLYING).balanceOf( - address(AaveV3Optimism.COLLECTOR) - ); - - bridge.emergencyTokenTransfer( - AaveV3OptimismAssets.USDC_UNDERLYING, - address(AaveV3Optimism.COLLECTOR), - usdcAmount - ); - - assertEq( - IERC20(AaveV3OptimismAssets.USDC_UNDERLYING).balanceOf(address(AaveV3Optimism.COLLECTOR)), - initialCollectorBalBalance + usdcAmount - ); - assertEq(IERC20(AaveV3OptimismAssets.USDC_UNDERLYING).balanceOf(address(bridge)), 0); - } -} diff --git a/tests/bridges/polygon/AavePolEthERC20BridgeTest.t.sol b/tests/bridges/polygon/AavePolEthERC20BridgeTest.t.sol deleted file mode 100644 index 87c333d53..000000000 --- a/tests/bridges/polygon/AavePolEthERC20BridgeTest.t.sol +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {AaveV2Polygon, AaveV2PolygonAssets} from 'aave-address-book/AaveV2Polygon.sol'; -import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; -import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {GovernanceV3Polygon} from 'aave-address-book/GovernanceV3Polygon.sol'; - -import {AavePolEthERC20Bridge} from 'src/bridges/polygon/AavePolEthERC20Bridge.sol'; -import {IAavePolEthERC20Bridge} from 'src/bridges/polygon/IAavePolEthERC20Bridge.sol'; - -/** - * @dev Tests for AavePolEthERC20Bridge - */ -contract AavePolEthERC20BridgeTest is Test { - event Exit(); - event Bridge(address token, uint256 amount); - event WithdrawToCollector(address token, uint256 amount); - - AavePolEthERC20Bridge bridgeMainnet; - AavePolEthERC20Bridge bridgePolygon; - uint256 mainnetFork; - uint256 polygonFork; - - address USDC_WHALE = 0xf89d7b9c864f589bbF53a82105107622B35EaA40; - address USDC_WHALE_MAINNET = 0xcEe284F754E854890e311e3280b767F80797180d; - - function setUp() public { - bytes32 salt = keccak256(abi.encode(tx.origin, uint256(0))); - - mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 18579720); - bridgeMainnet = new AavePolEthERC20Bridge{salt: salt}(address(this)); - - polygonFork = vm.createSelectFork(vm.rpcUrl('polygon'), 49986900); - bridgePolygon = new AavePolEthERC20Bridge{salt: salt}(address(this)); - } -} - -contract BridgeTest is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(mainnetFork); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - bridgePolygon.bridge(AaveV3EthereumAssets.USDC_UNDERLYING, 1_000e6); - } - - function test_revertsIf_notOwner() public { - vm.selectFork(polygonFork); - - uint256 amount = 1_000e6; - - vm.startPrank(USDC_WHALE); - IERC20(AaveV3PolygonAssets.USDC_UNDERLYING).transfer(address(bridgePolygon), amount); - vm.stopPrank(); - - bridgePolygon.transferOwnership(GovernanceV3Polygon.EXECUTOR_LVL_1); - - vm.expectRevert('Ownable: caller is not the owner'); - bridgePolygon.bridge(AaveV3PolygonAssets.USDC_UNDERLYING, amount); - } - - function test_successful() public { - vm.selectFork(polygonFork); - - uint256 amount = 1_000e6; - - vm.startPrank(USDC_WHALE); - IERC20(AaveV3PolygonAssets.USDC_UNDERLYING).transfer(address(bridgePolygon), amount); - vm.stopPrank(); - - bridgePolygon.transferOwnership(GovernanceV3Polygon.EXECUTOR_LVL_1); - - vm.startPrank(GovernanceV3Polygon.EXECUTOR_LVL_1); - vm.expectEmit(); - emit Bridge(AaveV3PolygonAssets.USDC_UNDERLYING, amount); - bridgePolygon.bridge(AaveV3PolygonAssets.USDC_UNDERLYING, amount); - vm.stopPrank(); - } -} - -contract EmergencyTokenTransfer is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - vm.startPrank(makeAddr('random-caller')); - bridgePolygon.emergencyTokenTransfer( - AaveV2PolygonAssets.BAL_UNDERLYING, - address(AaveV2Polygon.COLLECTOR), - 1_000e6 - ); - vm.stopPrank(); - } - - function test_successful_governanceCaller() public { - address LINK_WHALE = 0x61167073E31b1DAd85a3E531211c7B8F1E5cAE72; - - assertEq(IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), 0); - - uint256 balAmount = 1_000e18; - - vm.startPrank(LINK_WHALE); - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).transfer(address(bridgePolygon), balAmount); - vm.stopPrank(); - - assertEq( - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), - balAmount - ); - - uint256 initialCollectorBalBalance = IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf( - address(AaveV2Polygon.COLLECTOR) - ); - - bridgePolygon.emergencyTokenTransfer( - AaveV2PolygonAssets.LINK_UNDERLYING, - address(AaveV2Polygon.COLLECTOR), - balAmount - ); - - assertEq( - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(AaveV2Polygon.COLLECTOR)), - initialCollectorBalBalance + balAmount - ); - assertEq(IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), 0); - } -} - -contract WithdrawToCollectorTest is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - bridgeMainnet.withdrawToCollector(AaveV3EthereumAssets.USDC_UNDERLYING); - } - - function test_successful() public { - vm.selectFork(mainnetFork); - - uint256 amount = 1_000e6; - - vm.startPrank(USDC_WHALE_MAINNET); - IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).transfer(address(bridgeMainnet), amount); - vm.stopPrank(); - - uint256 balanceCollectorBefore = IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf( - address(AaveV3Ethereum.COLLECTOR) - ); - uint256 balanceBridgeBefore = IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf( - address(bridgeMainnet) - ); - - assertEq(balanceBridgeBefore, amount); - - bridgeMainnet.withdrawToCollector(AaveV3EthereumAssets.USDC_UNDERLYING); - - assertEq( - IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf(address(AaveV3Ethereum.COLLECTOR)), - balanceCollectorBefore + amount - ); - assertEq(IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf(address(bridgeMainnet)), 0); - } -} - -contract IsTokenMapped is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - bridgeMainnet.isTokenMapped(AaveV3PolygonAssets.USDC_UNDERLYING); - } - - function test_successful_returnsTrue() public { - vm.selectFork(mainnetFork); - - assertTrue(bridgeMainnet.isTokenMapped(AaveV3PolygonAssets.USDC_UNDERLYING)); - } - - function test_successful_returnsFalse() public { - vm.selectFork(mainnetFork); - - assertFalse(bridgeMainnet.isTokenMapped(makeAddr('new-erc20-token'))); - } -} - -contract ReceiveEther is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - (bool a, ) = address(bridgePolygon).call{value: 1 ether}(''); - assertTrue(a); - } - - function test_successful_forwardsETH() public { - vm.selectFork(mainnetFork); - - uint256 balanceETHBefore = address(AaveV3Ethereum.COLLECTOR).balance; - - assertEq(address(bridgeMainnet).balance, 0); - - (bool a, ) = address(bridgeMainnet).call{value: 1 ether}(''); - assertTrue(a); - - assertEq(balanceETHBefore + 1 ether, address(AaveV3Ethereum.COLLECTOR).balance); - assertEq(address(bridgeMainnet).balance, 0); - } -} - -/* - * No good way of testing the full flow as proof is generated via API 30-90 minutes after the - * bridge() function is called on Polygon. - */ -contract ExitTest is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - bridgeMainnet.exit(new bytes(0)); - } - - function test_revertsIf_proofAlreadyProcessed() public { - vm.selectFork(mainnetFork); - - bytes - memory burnProof = hex'f90b7f841d64b820b901605a3ebbdce0b458c848c75ece30aebdc7f404de9f42a1a1d2fff616f4681f8239a5727c70050724191597596befd50c2db26c8c13cc424292fb8dca25990eec222a5378609f41effc1b6f8370a2fa3bff9c1701b0d63108094bc6255a69ffbdd28cdc2237e927128485372aaad7d4164d37669d61d82add0bcb6b8fb1ab7726d81a766ee748222e6253d91038cb42b06614c20fda1f61ede914ee3971321a91ba9674397ca6114056014024786d3b74639d792036e10be9fcca25cc63df3e90e9ce68a4c38ebdd54385ed78e7003995b50975ea080eac5178729d59ffe8c39ba44dce41d776560d9f83de07337ba28cf16a69f99c3be4c8f5001825b11a3e49fb966bcc41e4b74e001be2248c2e7d8319fddb180775cdf18660fa475f8b84db41cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e030e0542044c7c3e032f92fdf59c763bff5ec2b5c0b34323fff644d44074033f18402bf7ab28464d3b68aa0cb3e23ec4a01a3517fdb7d985bbcd704d8d243c4b6baac426457e5e2b9febad1a01ab4bd6b4a9aef048d60e20a15ad53347c92418591ac1bcafc493834c0b0bc37b9036802f9036401840184b1b4b9010000000200000000000000000008000000000000000000000000100000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000040008000000800000000000000000000100000000000000000000020000000000000000000800000000000000000180000010000004001041000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000004000000002000000000801000000000004000000000000000000120000000020000000008000000000000000000000000001000000000000200000000800100000f90258f89b942791bca1f2de4661ed88a30c99a7a9449aa84174f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000ca807a3e47684caee82fda347729788639ab9ee8a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000f4240f87994ca807a3e47684caee82fda347729788639ab9ee8e1a0884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364b8400000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000000000000000000000000000000000000000f4240f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000002fb7d6beb9ad75c1ffd392681cc68171b8551107a00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a000000000000000000000000000000000000000000000000000047f88eb62fdf8000000000000000000000000000000000000000000000000f6299bdc7ee7898c000000000000000000000000000000000000000000000231bb90e991a999704a000000000000000000000000000000000000000000000000f6251c5393848b94000000000000000000000000000000000000000000000231bb95691a94fc6e42b90659f90656f8d1a0edd856137974cc770c8ff2f0ae9691f6c343a5c3ea042cf43226064241cb4b48a060098e59303c6f97eb4ee11a31d7ff224886f7ee97e47046ffc12ae2cb345607a08c1c9ddcde956a2188fecf78ac3ffe88c5300e39016cedbc726eaa480528f2d9a0af1a8f4ebb2c2f62619a683563a51fcf38e82d6213ad60506a1f4472145a3d52a06a5a57546f33675a2827617483ba12e200a7666f107115010549cc72ce933a5c808080a04b654e084485e25f10ab6e63905b7b0320f3da65ed062eee77511204089557af8080808080808080f90211a0d18ede4a1807a43ea2daf1f43d94127479f5a5406ba4d9e1e1820b9fabc23f1ca0ae8d8894a06c033da2ef24d0e4b7f4d985fea9e4a808d0616a93e17c7d5ca556a08a42f3eed60ecb787277f3534c848ac3e881be498993840a4c550764414c45e7a0db5ed558b0871c5828866ff7ff1cdb6b7b28cce715c74837c704308e4e85d8d8a0e00d8c69aee0605693c270aa8bd5e4c156bf6782952df288e8f3002963ad51d1a06568d90c67a2972365abd5f2606aa2529d39cb7bc23eb0a130d673080697d715a0747a3b807241f10bee3360edb4345a815328fb885c8e8f693e1af88503c41bc4a01767769f78e7f63f7142b0468c85a7a98aad577dd31044167c60e4d77e5d5ad2a09e8fddbe949014bb311de991cb543da9fb3104cf4db4f87e4e800911c1d99f7da0de90b23b0cf3a2685afd3b221a1660d8655212ca01c82c5680a81f807e2b3aada0281f75fda5226a1f34390b09765843e2af5a3644ba577a555431b7f2dcef2c86a094065d6acf8901d70605b0c198b0ff5df364efc232f6c536c7df5a7632b4a7bea0a32affd2aad98f44bce23eed618177c1a51cdd617ef72ec8be8d55bda90bf59fa099a19c0a99d4913f691877ce52612a1da389b99ab2a51c471346ee07575f0780a0b948b78e59be6f2a016c545d93ae7efdf615bf212bbdc1fa568bc2c96752c044a09e07bfdc8af384b3f2f1a65561bfd28ebd85d3f2abbfba13108d25a38a25a1cd80f9036c20b9036802f9036401840184b1b4b9010000000200000000000000000008000000000000000000000000100000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000040008000000800000000000000000000100000000000000000000020000000000000000000800000000000000000180000010000004001041000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000004000000002000000000801000000000004000000000000000000120000000020000000008000000000000000000000000001000000000000200000000800100000f90258f89b942791bca1f2de4661ed88a30c99a7a9449aa84174f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000ca807a3e47684caee82fda347729788639ab9ee8a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000f4240f87994ca807a3e47684caee82fda347729788639ab9ee8e1a0884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364b8400000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000000000000000000000000000000000000000f4240f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000002fb7d6beb9ad75c1ffd392681cc68171b8551107a00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a000000000000000000000000000000000000000000000000000047f88eb62fdf8000000000000000000000000000000000000000000000000f6299bdc7ee7898c000000000000000000000000000000000000000000000231bb90e991a999704a000000000000000000000000000000000000000000000000f6251c5393848b94000000000000000000000000000000000000000000000231bb95691a94fc6e4282003580'; - - vm.expectRevert('RootChainManager: EXIT_ALREADY_PROCESSED'); - bridgeMainnet.exit(burnProof); - } -} - -/* - * No good way of testing the full flow as proof is generated via API 30-90 minutes after the - * bridge() function is called on Polygon. - */ -contract ExitMultipleTest is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - bytes[] memory proofs = new bytes[](1); - proofs[0] = new bytes(0); - - vm.expectRevert(AavePolEthERC20Bridge.InvalidChain.selector); - bridgeMainnet.exit(proofs); - } - - function test_revertsIf_proofAlreadyProcessed() public { - vm.selectFork(mainnetFork); - - bytes - memory burnProof = hex'f90b7f841d64b820b901605a3ebbdce0b458c848c75ece30aebdc7f404de9f42a1a1d2fff616f4681f8239a5727c70050724191597596befd50c2db26c8c13cc424292fb8dca25990eec222a5378609f41effc1b6f8370a2fa3bff9c1701b0d63108094bc6255a69ffbdd28cdc2237e927128485372aaad7d4164d37669d61d82add0bcb6b8fb1ab7726d81a766ee748222e6253d91038cb42b06614c20fda1f61ede914ee3971321a91ba9674397ca6114056014024786d3b74639d792036e10be9fcca25cc63df3e90e9ce68a4c38ebdd54385ed78e7003995b50975ea080eac5178729d59ffe8c39ba44dce41d776560d9f83de07337ba28cf16a69f99c3be4c8f5001825b11a3e49fb966bcc41e4b74e001be2248c2e7d8319fddb180775cdf18660fa475f8b84db41cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e030e0542044c7c3e032f92fdf59c763bff5ec2b5c0b34323fff644d44074033f18402bf7ab28464d3b68aa0cb3e23ec4a01a3517fdb7d985bbcd704d8d243c4b6baac426457e5e2b9febad1a01ab4bd6b4a9aef048d60e20a15ad53347c92418591ac1bcafc493834c0b0bc37b9036802f9036401840184b1b4b9010000000200000000000000000008000000000000000000000000100000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000040008000000800000000000000000000100000000000000000000020000000000000000000800000000000000000180000010000004001041000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000004000000002000000000801000000000004000000000000000000120000000020000000008000000000000000000000000001000000000000200000000800100000f90258f89b942791bca1f2de4661ed88a30c99a7a9449aa84174f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000ca807a3e47684caee82fda347729788639ab9ee8a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000f4240f87994ca807a3e47684caee82fda347729788639ab9ee8e1a0884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364b8400000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000000000000000000000000000000000000000f4240f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000002fb7d6beb9ad75c1ffd392681cc68171b8551107a00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a000000000000000000000000000000000000000000000000000047f88eb62fdf8000000000000000000000000000000000000000000000000f6299bdc7ee7898c000000000000000000000000000000000000000000000231bb90e991a999704a000000000000000000000000000000000000000000000000f6251c5393848b94000000000000000000000000000000000000000000000231bb95691a94fc6e42b90659f90656f8d1a0edd856137974cc770c8ff2f0ae9691f6c343a5c3ea042cf43226064241cb4b48a060098e59303c6f97eb4ee11a31d7ff224886f7ee97e47046ffc12ae2cb345607a08c1c9ddcde956a2188fecf78ac3ffe88c5300e39016cedbc726eaa480528f2d9a0af1a8f4ebb2c2f62619a683563a51fcf38e82d6213ad60506a1f4472145a3d52a06a5a57546f33675a2827617483ba12e200a7666f107115010549cc72ce933a5c808080a04b654e084485e25f10ab6e63905b7b0320f3da65ed062eee77511204089557af8080808080808080f90211a0d18ede4a1807a43ea2daf1f43d94127479f5a5406ba4d9e1e1820b9fabc23f1ca0ae8d8894a06c033da2ef24d0e4b7f4d985fea9e4a808d0616a93e17c7d5ca556a08a42f3eed60ecb787277f3534c848ac3e881be498993840a4c550764414c45e7a0db5ed558b0871c5828866ff7ff1cdb6b7b28cce715c74837c704308e4e85d8d8a0e00d8c69aee0605693c270aa8bd5e4c156bf6782952df288e8f3002963ad51d1a06568d90c67a2972365abd5f2606aa2529d39cb7bc23eb0a130d673080697d715a0747a3b807241f10bee3360edb4345a815328fb885c8e8f693e1af88503c41bc4a01767769f78e7f63f7142b0468c85a7a98aad577dd31044167c60e4d77e5d5ad2a09e8fddbe949014bb311de991cb543da9fb3104cf4db4f87e4e800911c1d99f7da0de90b23b0cf3a2685afd3b221a1660d8655212ca01c82c5680a81f807e2b3aada0281f75fda5226a1f34390b09765843e2af5a3644ba577a555431b7f2dcef2c86a094065d6acf8901d70605b0c198b0ff5df364efc232f6c536c7df5a7632b4a7bea0a32affd2aad98f44bce23eed618177c1a51cdd617ef72ec8be8d55bda90bf59fa099a19c0a99d4913f691877ce52612a1da389b99ab2a51c471346ee07575f0780a0b948b78e59be6f2a016c545d93ae7efdf615bf212bbdc1fa568bc2c96752c044a09e07bfdc8af384b3f2f1a65561bfd28ebd85d3f2abbfba13108d25a38a25a1cd80f9036c20b9036802f9036401840184b1b4b9010000000200000000000000000008000000000000000000000000100000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000040008000000800000000000000000000100000000000000000000020000000000000000000800000000000000000180000010000004001041000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000004000000002000000000801000000000004000000000000000000120000000020000000008000000000000000000000000001000000000000200000000800100000f90258f89b942791bca1f2de4661ed88a30c99a7a9449aa84174f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000ca807a3e47684caee82fda347729788639ab9ee8a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000f4240f87994ca807a3e47684caee82fda347729788639ab9ee8e1a0884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364b8400000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000000000000000000000000000000000000000f4240f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000002fb7d6beb9ad75c1ffd392681cc68171b8551107a00000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0b8a000000000000000000000000000000000000000000000000000047f88eb62fdf8000000000000000000000000000000000000000000000000f6299bdc7ee7898c000000000000000000000000000000000000000000000231bb90e991a999704a000000000000000000000000000000000000000000000000f6251c5393848b94000000000000000000000000000000000000000000000231bb95691a94fc6e4282003580'; - - bytes[] memory proofs = new bytes[](1); - proofs[0] = burnProof; - - vm.expectRevert('RootChainManager: EXIT_ALREADY_PROCESSED'); - bridgeMainnet.exit(proofs); - } -} - -contract TransferOwnership is AavePolEthERC20BridgeTest { - function test_revertsIf_invalidCaller() public { - vm.startPrank(makeAddr('random-caller')); - vm.expectRevert('Ownable: caller is not the owner'); - bridgeMainnet.transferOwnership(makeAddr('new-admin')); - vm.stopPrank(); - } - - function test_successful() public { - address newAdmin = GovernanceV3Ethereum.EXECUTOR_LVL_1; - bridgeMainnet.transferOwnership(newAdmin); - - assertEq(newAdmin, bridgeMainnet.owner()); - } -} - -/// This is a real proof one block prior to when it happened, with the Bridge address of: 0xc928002904Ec475663A83063D492EA2aE09EbDA1 -contract ForkedBridgeTests is Test { - function test_successful() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 18485843); // One block before an actual exit - - bytes - memory burnProof = hex'f94429841f8686b0b90140ec08e37a4c09ebcde82a99bbe213e98dadc3847b25fa2e7957d1b3d90d5eebff1006486861f9479c3750bc16f0a4d910572fb1fdc024e1115073f9919dc8f1ad8599af3e900ef15593699a15a84065e846f1db007495206c63a4b95f1e38dec961e0bbdec9a4e0b0f4d16c2b903b6a8dc6d6496b44da85a6786b8e8340bd50bafca7f6ad0593680a9fc6b174695fa0af5cf6febcbdd92c2bcf1de0e6936ca40bf1e57da148c5ec50554fd3f8497d575ccd04bba9a40cfbd62adce41fe2d47ec9bfaadefdd88c6d32c9f0dbbb2eb97a48ab84eacaf6d548770d8d19f01af48f23ad4bbb8fec633d28c0b782808b5180fdc191a3b79ec6279cd17b95422317cb4f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af183009cfbada5b6455c4e1187b67758b694698dc7ce8de85a74f6fe285f0ebe38402f0b5ca84653f7f37a041ea33e7ca127e9dcf3da38d9d153de8712864adac2403cc819f1ec23cb0e387a0a169587c035b52f56223839b8fb88019059d3299687edda67f36c51f4fd06c0fb91fcdf91fca0183a2ef0bb901000200420020000800008000000040000400900000000100008300000080000100000000020000002000000200040000080002800000004000200003100004001100004000000000008020000a08000481000200080804110080030008000040004040000002100000000008000000080000000400000802009400c0141000000000000000840000000000200000000008020040000822004000440040002000002100011100800000002020800000000020082080000200a0000000080100014000000002000000100001002000020120000000800000000004124000000061000000000800040000000280000000000002000400000804000020000000100000f91ebff89b94357d51124f59836ded84c8a1730d72b749d8bc23f863a0bb123b5c06d5408bbea3c4fef481578175cfb432e3b482c6186f02ed9086585ba0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a000000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6ea0000000000000000000000000000000000000000000000000005184a301f41195f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc9427f8d03b3a2196956ed754badc28d73be8830a6ef863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b840000000000000000000000000000000000000000000013da329b633647180000000000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000000000000000000000013da329b6336471800000f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc38380f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b840000000000000000000000000000000000000000000000204d12df5dc51c6da77000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc38380f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc94c4195d4060daeac44058ed668aa5efec50d77ff6f863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b84000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a00000000000000000000000000000000000000000000000000c9d8ca802c04a76f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b8400000000000000000000000000000000000000000000000000c9d8ca802c04a7600000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063b8a00000000000000000000000000000000000000000000bc4428ff25d5245e72c830000000000000000000000000000000000000000002f80c94c9ca324d9b145990000000000000000000000000000000000000000001e7c6e2036d5e2a5628b3200000000000000000000000000000000000000000366fb8ad9555a5e1baebe51000000000000000000000000000000000000000003874b6dbe3ec433d1b2fb37f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b948f3cf7ad23cd3cadbd9735aff958023239c6a063f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6ea0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000013da329b6336471800000f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000013da329b6336471800000f8bc9427f8d03b3a2196956ed754badc28d73be8830a6ef863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b840000000000000000000000000000000000000000000013da329b633647180000000000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000013da329b6336471800000f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a00000000000000000000000000000000000000000000000000bf117f1ff35aaa2f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b8400000000000000000000000000000000000000000000000000bf117f1ff35aaa2000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afb8a00000000000000000000000000000000000000000000000603e869f9450289e2c00000000000000000000000000000000000000000056368c96672550bfd7864d0000000000000000000000000000000000000000005fd07e54af1384c7481440000000000000000000000000000000000000000003ccb6fd0d85b250934abfee00000000000000000000000000000000000000000477de475fd95229353c433ff87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b94172370d5cd63279efa6d502dab29171933a610aff863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000003df8f92b7e798820ddcca2ebea7babda2c90c4ada0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f8bc943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b840000000000000000000000000000000000000000000000204d12df5dc51c6da77000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a000000000000000000000000000000000000000000000000000ce772a4f4e4308f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b84000000000000000000000000000000000000000000000000000ce772a4f4e4308000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3b8a000000000000000000000000000000000000000000008787373c577c1c258b0a80000000000000000000000000000000000000000003496b1bb9e79a4f34620b50000000000000000000000000000000000000000005df29b2a02800e654620b5000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd5070000000000000000000000000000000000000000050c2b7e22f9c35395d37b02f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b949a71012b13ca4d3d0cdc72a177df3ef03b0e76a3f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c4195d4060daeac44058ed668aa5efec50d77ff6a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f8bc94c4195d4060daeac44058ed668aa5efec50d77ff6f863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b84000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b948f3cf7ad23cd3cadbd9735aff958023239c6a063f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000013da329b6336471800000f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb8400000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063000000000000000000000000000000000000000000013da329b6336471800000f89b94172370d5cd63279efa6d502dab29171933a610aff863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb840000000000000000000000000172370d5cd63279efa6d502dab29171933a610af000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b949a71012b13ca4d3d0cdc72a177df3ef03b0e76a3f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb8400000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a300000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f8fb94dc9a35b16db4e126cfedc41322b3a36454b1f772f842a0f5efc4bb09a12b6c9561a7e7ab02938a72a4351316b473d574fdaaa89c43eb9aa0000000000000000000000000da98b308be8766501ec7fe3ed9a48efbd6c31a7bb8a000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f87b94da98b308be8766501ec7fe3ed9a48efbd6c31a7bf863a01d356dc5da7bf4f74d415f1adff04022530e2418a8e8458e4fa0dca4cec14250a00000000000000000000000000000000000000000000000000000000000000047a0000000000000000000000000000000000000000000000000000000000000000080f9015d9402777053d6764996e594c3e88af1d58d5363a2e6f884a0caacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6a00ba6f5a29753ee4861917fbae7122075257c5a8b702791ecdca09fd4abfb40e5a00000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000d9a31dc8347284a6bea9598d49d8dacbfd5774f1b8c00000000000000000000000000000000000000000000000000036fe68904af8cc00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000047f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000d9a31dc8347284a6bea9598d49d8dacbfd5774f1a0000000000000000000000000bdbd4347b082d9d6bdf2da4555a37ce52a2e2120b8a000000000000000000000000000000000000000000000000001140015237d04970000000000000000000000000000000000000000000000234e3393093dd75603000000000000000000000000000000000000000000004578091978720a7a78fe0000000000000000000000000000000000000000000000234d1f92f41a5a516c0000000000000000000000000000000000000000000045780a2d78872df77d95b922bef922bbf8d1a02e1cded6745b2647ded60567ef904b1488a2202d8c10b4ce2a6325c5874e70a1a0d55f193383311082b88c376ae4c155d14c4795e78d01b57df7ac1b2a0953a3aba0d3fd23c69be1a376891333316a4d4915b16b1ba2837b7395eafd138470a8a9c2a00f728e4cd94c8946176f3bab3285d0a4cf675c745ded223eea13c1749373b406a0d4fde17a9a997d82a718d0109fbad0865ae0f676a6d9453ba25f7cc9f7440ffa808080a091014260b7c5e3e034c1bb93e5c56d876bbafc5e9c45bee246a09c4d778918268080808080808080f90211a0dc223d7d9d1f62a17d6755b3ea49a459fdc841677a4d6ea3c10ae9fe3b74cc85a0d4386c4f27e167dd5904a6829137d4a071b807360b41c33e508da83c16ef0dcaa0ee33d016d743f18fcd1d3f441204cb6c7bbc7f27c348f00a1525f625a90d5351a012e159719d02a9bedefc92ba3b14aab8548930b4d96c4273270307a822b167b2a00ee37834474bd26aa665f7ec5471b7e36ca46bd285e4672feacf8ee117aaeb11a0f553c892c39772cc4e15f3014c132cdc1eec574aeb61c78b488288f0f3d687dba05fc1ab2dcb80faa44e595225cf7c9f776cc0a94a03dee4f00c1aabd1101916d2a0027633218ce323577d192ba3fe4fbb16f5ea20d5ced6dc8ac5388ecd69377150a0b0c37b48b21deb48d3597313e9b6044164b58b665266a89b76ce30bd86d158c9a029465187eb0c9d84221a82b868b22a542f6c2b51a738fb9207daaf92a2f28a91a052f6b425918430b09a6c2dc7226e57420d6dc0175f75ccfd0cd125128b0d1acca01ba7c6113177eb50a6309262f9da68c025f040e8223cab0660614dd87a534891a0553953d0786a7ea5c12eadbb3efed3e4167421f1fcecd0839311ca41fb52ec35a09760e1282cb44a42da18a26f79049948043218067c570de23d2b59306d3b0da6a02f5030a870e23986e7fbb32bd4c50174c34f725089a50bde3298ac398080e696a06f2c7fde9db1e657aed7c92b969b53769c16bdf8ea8706f3e92854b2efc9601e80f91fd120b91fcdf91fca0183a2ef0bb901000200420020000800008000000040000400900000000100008300000080000100000000020000002000000200040000080002800000004000200003100004001100004000000000008020000a08000481000200080804110080030008000040004040000002100000000008000000080000000400000802009400c0141000000000000000840000000000200000000008020040000822004000440040002000002100011100800000002020800000000020082080000200a0000000080100014000000002000000100001002000020120000000800000000004124000000061000000000800040000000280000000000002000400000804000020000000100000f91ebff89b94357d51124f59836ded84c8a1730d72b749d8bc23f863a0bb123b5c06d5408bbea3c4fef481578175cfb432e3b482c6186f02ed9086585ba0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a000000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6ea0000000000000000000000000000000000000000000000000005184a301f41195f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc9427f8d03b3a2196956ed754badc28d73be8830a6ef863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b840000000000000000000000000000000000000000000013da329b633647180000000000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000000000000000000000013da329b6336471800000f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc38380f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b840000000000000000000000000000000000000000000000204d12df5dc51c6da77000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc38380f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a000058a56ea94653cdf4f152d227ace22d4c00ad99e2a43f58cb7d9e3feb295f2a00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f8bc94c4195d4060daeac44058ed668aa5efec50d77ff6f863a04beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda8666a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772b84000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a00000000000000000000000000000000000000000000000000c9d8ca802c04a76f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b8400000000000000000000000000000000000000000000000000c9d8ca802c04a7600000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063b8a00000000000000000000000000000000000000000000bc4428ff25d5245e72c830000000000000000000000000000000000000000002f80c94c9ca324d9b145990000000000000000000000000000000000000000001e7c6e2036d5e2a5628b3200000000000000000000000000000000000000000366fb8ad9555a5e1baebe51000000000000000000000000000000000000000003874b6dbe3ec433d1b2fb37f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b948f3cf7ad23cd3cadbd9735aff958023239c6a063f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000027f8d03b3a2196956ed754badc28d73be8830a6ea0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000013da329b6336471800000f89b9427f8d03b3a2196956ed754badc28d73be8830a6ef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000013da329b6336471800000f8bc9427f8d03b3a2196956ed754badc28d73be8830a6ef863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b840000000000000000000000000000000000000000000013da329b633647180000000000000000000000000000000000000000000000366fb8ad9555a5e1baebe51f8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a00000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000013da329b6336471800000f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a00000000000000000000000000000000000000000000000000bf117f1ff35aaa2f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b8400000000000000000000000000000000000000000000000000bf117f1ff35aaa2000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afb8a00000000000000000000000000000000000000000000000603e869f9450289e2c00000000000000000000000000000000000000000056368c96672550bfd7864d0000000000000000000000000000000000000000005fd07e54af1384c7481440000000000000000000000000000000000000000003ccb6fd0d85b250934abfee00000000000000000000000000000000000000000477de475fd95229353c433ff87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b94172370d5cd63279efa6d502dab29171933a610aff863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000003df8f92b7e798820ddcca2ebea7babda2c90c4ada0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f8bc943df8f92b7e798820ddcca2ebea7babda2c90c4adf863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b840000000000000000000000000000000000000000000000204d12df5dc51c6da77000000000000000000000000000000000000000003ccb6fd0d85b250934abfeef8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a0000000000000000000000000172370d5cd63279efa6d502dab29171933a610afa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383a000000000000000000000000000000000000000000000000000ce772a4f4e4308f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f842a04c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fa0000000000000000000000000e8599f3cc5d38a9ad6f3684cd5cea72f10dbc383b84000000000000000000000000000000000000000000000000000ce772a4f4e4308000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f8fb948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff842a0804c9b842b2748a22bb64b345453a3de7ca54a6ca45ce00d415894979e22897aa00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3b8a000000000000000000000000000000000000000000008787373c577c1c258b0a80000000000000000000000000000000000000000003496b1bb9e79a4f34620b50000000000000000000000000000000000000000005df29b2a02800e654620b5000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd5070000000000000000000000000000000000000000050c2b7e22f9c35395d37b02f87b948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff863a044c58d81365b66dd4b1a7f36c25aa97b8c71c361ee4937adc1a00000227db5dda00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f77280f89b949a71012b13ca4d3d0cdc72a177df3ef03b0e76a3f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c4195d4060daeac44058ed668aa5efec50d77ff6a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b94c4195d4060daeac44058ed668aa5efec50d77ff6f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f8bc94c4195d4060daeac44058ed668aa5efec50d77ff6f863a05d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1b84000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8000000000000000000000000000000000000000003f3bf3d1f1ef75fa79fd507f8bc948dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcff884a03115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7a00000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3a0000000000000000000000000dc9a35b16db4e126cfedc41322b3a36454b1f772a0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f89b948f3cf7ad23cd3cadbd9735aff958023239c6a063f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000013da329b6336471800000f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb8400000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063000000000000000000000000000000000000000000013da329b6336471800000f89b94172370d5cd63279efa6d502dab29171933a610aff863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000204d12df5dc51c6da77f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb840000000000000000000000000172370d5cd63279efa6d502dab29171933a610af000000000000000000000000000000000000000000000204d12df5dc51c6da77f89b949a71012b13ca4d3d0cdc72a177df3ef03b0e76a3f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000c928002904ec475663a83063d492ea2ae09ebda1a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f87994c928002904ec475663a83063d492ea2ae09ebda1e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb8400000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a300000000000000000000000000000000000000000000006572fa5fbb2fb73ec8f8fb94dc9a35b16db4e126cfedc41322b3a36454b1f772f842a0f5efc4bb09a12b6c9561a7e7ab02938a72a4351316b473d574fdaaa89c43eb9aa0000000000000000000000000da98b308be8766501ec7fe3ed9a48efbd6c31a7bb8a000000000000000000000000000000000000000000000000000000000000000470000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f87b94da98b308be8766501ec7fe3ed9a48efbd6c31a7bf863a01d356dc5da7bf4f74d415f1adff04022530e2418a8e8458e4fa0dca4cec14250a00000000000000000000000000000000000000000000000000000000000000047a0000000000000000000000000000000000000000000000000000000000000000080f9015d9402777053d6764996e594c3e88af1d58d5363a2e6f884a0caacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6a00ba6f5a29753ee4861917fbae7122075257c5a8b702791ecdca09fd4abfb40e5a00000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000d9a31dc8347284a6bea9598d49d8dacbfd5774f1b8c00000000000000000000000000000000000000000000000000036fe68904af8cc00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000047f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000d9a31dc8347284a6bea9598d49d8dacbfd5774f1a0000000000000000000000000bdbd4347b082d9d6bdf2da4555a37ce52a2e2120b8a000000000000000000000000000000000000000000000000001140015237d04970000000000000000000000000000000000000000000000234e3393093dd75603000000000000000000000000000000000000000000004578091978720a7a78fe0000000000000000000000000000000000000000000000234d1f92f41a5a516c0000000000000000000000000000000000000000000045780a2d78872df77d9582002624'; - - uint256 balanceDaiBefore = IERC20(AaveV3EthereumAssets.DAI_UNDERLYING).balanceOf( - MiscEthereum.AAVE_POL_ETH_BRIDGE - ); - - - IAavePolEthERC20Bridge(0xc928002904Ec475663A83063D492EA2aE09EbDA1).exit(burnProof); // Old bridge address for this TX - - assertGt( - IERC20(AaveV3EthereumAssets.DAI_UNDERLYING).balanceOf(0xc928002904Ec475663A83063D492EA2aE09EbDA1), - balanceDaiBefore - ); - } -} diff --git a/tests/bridges/polygon/AavePolEthPlasmaBridge.t.sol b/tests/bridges/polygon/AavePolEthPlasmaBridge.t.sol deleted file mode 100644 index a7fc419d1..000000000 --- a/tests/bridges/polygon/AavePolEthPlasmaBridge.t.sol +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {AaveV2Polygon, AaveV2PolygonAssets} from 'aave-address-book/AaveV2Polygon.sol'; -import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; -import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {GovernanceV3Polygon} from 'aave-address-book/GovernanceV3Polygon.sol'; - -import {AavePolEthPlasmaBridge} from 'src/bridges/polygon/AavePolEthPlasmaBridge.sol'; -import {IAavePolEthPlasmaBridge} from 'src/bridges/polygon/IAavePolEthPlasmaBridge.sol'; - -contract AavePolEthPlasmaBridgeTest is Test { - event Bridge(address token, uint256 amount); - event ConfirmExit(bytes proof); - event Exit(address indexed token); - event ExitBatch(address[] indexed tokens); - event WithdrawToCollector(address token, uint256 amount); - - address public constant WHALE = 0xe7804c37c13166fF0b37F5aE0BB07A3aEbb6e245; - address public constant MATIC_WHALE_MAINNET = 0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908; - address public constant NATIVE_MATIC = 0x0000000000000000000000000000000000001010; - address public constant MATIC_MAINNET = 0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0; - - AavePolEthPlasmaBridge bridgeMainnet; - AavePolEthPlasmaBridge bridgePolygon; - uint256 mainnetFork; - uint256 polygonFork; - - function setUp() public { - bytes32 salt = keccak256(abi.encode(tx.origin, uint256(0))); - - mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 19321284); - bridgeMainnet = new AavePolEthPlasmaBridge{salt: salt}(address(this)); - - polygonFork = vm.createSelectFork(vm.rpcUrl('polygon'), 54032678); - bridgePolygon = new AavePolEthPlasmaBridge{salt: salt}(address(this)); - } -} - -contract BridgeTest is AavePolEthPlasmaBridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(mainnetFork); - - vm.expectRevert(IAavePolEthPlasmaBridge.InvalidChain.selector); - bridgePolygon.bridge(1_000e6); - } - - function test_revertsIf_notOwner() public { - vm.selectFork(polygonFork); - - uint256 amount = 1_000e6; - - vm.startPrank(WHALE); - IERC20(NATIVE_MATIC).transfer(address(bridgePolygon), amount); - vm.stopPrank(); - - bridgePolygon.transferOwnership(GovernanceV3Polygon.EXECUTOR_LVL_1); - - vm.expectRevert('Ownable: caller is not the owner'); - bridgePolygon.bridge(amount); - } - - function test_successful() public { - vm.selectFork(polygonFork); - - uint256 amount = 1_000e6; - - deal(address(bridgePolygon), amount); - - bridgePolygon.transferOwnership(GovernanceV3Polygon.EXECUTOR_LVL_1); - - vm.startPrank(GovernanceV3Polygon.EXECUTOR_LVL_1); - vm.expectEmit(); - emit Bridge(NATIVE_MATIC, amount); - bridgePolygon.bridge(amount); - vm.stopPrank(); - } -} - -contract TransferOwnership is AavePolEthPlasmaBridgeTest { - function test_revertsIf_invalidCaller() public { - vm.startPrank(makeAddr('random-caller')); - vm.expectRevert('Ownable: caller is not the owner'); - bridgeMainnet.transferOwnership(makeAddr('new-admin')); - vm.stopPrank(); - } - - function test_successful() public { - address newAdmin = GovernanceV3Ethereum.EXECUTOR_LVL_1; - bridgeMainnet.transferOwnership(newAdmin); - - assertEq(newAdmin, bridgeMainnet.owner()); - } -} - -contract WithdrawToCollectorTest is AavePolEthPlasmaBridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(IAavePolEthPlasmaBridge.InvalidChain.selector); - bridgeMainnet.withdrawToCollector(); - } - - function test_successful() public { - vm.selectFork(mainnetFork); - - uint256 amount = 1_000e6; - - vm.startPrank(0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908); - IERC20(MATIC_MAINNET).transfer(address(bridgeMainnet), amount); - vm.stopPrank(); - - uint256 balanceCollectorBefore = IERC20(MATIC_MAINNET).balanceOf( - address(AaveV3Ethereum.COLLECTOR) - ); - uint256 balanceBridgeBefore = IERC20(MATIC_MAINNET).balanceOf( - address(bridgeMainnet) - ); - - assertEq(balanceBridgeBefore, amount); - - bridgeMainnet.withdrawToCollector(); - - assertEq( - IERC20(MATIC_MAINNET).balanceOf(address(AaveV3Ethereum.COLLECTOR)), - balanceCollectorBefore + amount - ); - assertEq(IERC20(MATIC_MAINNET).balanceOf(address(bridgeMainnet)), 0); - } -} - -contract EmergencyTokenTransfer is AavePolEthPlasmaBridgeTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - vm.startPrank(makeAddr('random-caller')); - bridgePolygon.emergencyTokenTransfer( - AaveV2PolygonAssets.BAL_UNDERLYING, - address(AaveV2Polygon.COLLECTOR), - 1_000e6 - ); - vm.stopPrank(); - } - - function test_successful_governanceCaller() public { - address LINK_WHALE = 0x61167073E31b1DAd85a3E531211c7B8F1E5cAE72; - - assertEq(IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), 0); - - uint256 balAmount = 1_000e18; - - vm.startPrank(LINK_WHALE); - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).transfer(address(bridgePolygon), balAmount); - vm.stopPrank(); - - assertEq( - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), - balAmount - ); - - uint256 initialCollectorBalBalance = IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf( - address(AaveV2Polygon.COLLECTOR) - ); - - bridgePolygon.emergencyTokenTransfer( - AaveV2PolygonAssets.LINK_UNDERLYING, - address(AaveV2Polygon.COLLECTOR), - balAmount - ); - - assertEq( - IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(AaveV2Polygon.COLLECTOR)), - initialCollectorBalBalance + balAmount - ); - assertEq(IERC20(AaveV2PolygonAssets.LINK_UNDERLYING).balanceOf(address(bridgePolygon)), 0); - } -} - -/* - * No good way of testing the full flow as proof is generated via API 30-90 minutes after the - * bridge() function is called on Polygon. - */ -contract ExitTest is AavePolEthPlasmaBridgeTest { - function test_revertsIf_invalidChain() public { - vm.selectFork(polygonFork); - - vm.expectRevert(IAavePolEthPlasmaBridge.InvalidChain.selector); - bridgeMainnet.confirmExit(new bytes(0)); - } - - function test_revertsIf_proofAlreadyProcessed() public { - vm.selectFork(mainnetFork); - - bytes - memory burnProof = hex'f90d298422e1e6b0b90120433b0d2d0234f58cd9e8404894ba9f3687fc8b0927c359b4c9977f182677eed901942bbf20f1fd9032d1b173b911d2e1d9c0c9de6ae79f6e1330d16e09c833ca452ce56e950ea226ca527012f881475efdd7c622f17394e632a743de1ef352a8b72395afa69ed1137763e1c64f796e1e90a7b85f377f95f03d3ea1eba29f7ee50a60268d6d6a86697fd881c0f18ea8e643b3365e7dc533940650d7606b9d824994b9a9c26e68990484952e8955fdbb8a01177074bc0872e63af46be69c9a0ee3150e0114ebc8a68469240747e157b6a667ed8df73ec4560b77dd60c6dcc1d47517e30d0a87fde2ab53b50ba69a2355ba1086b1b9b88648a8110c4f01a0c57d952b9e4499ec65c0442fc2210d7a54856bb36d5b5fb080f1bfb36b0df40d04cdd784033864598465de198ba0ba95e013f19a21f66a47256c2e42b006ec54f3d13e4cd4ce32cbdba025859e46a01c7d305fdf034cd665c96da4d8902557e4e29b54116e0fd4a235fb16421248d6b9046d02f90469018303f667b9010000000000000000000000000000000000000200000000000000000000000000000000000000000000000810100000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000080000000000000000000000000000020000080000000001000000000000000000000080000000000000000000000000004000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000800000108000200000000100000000000000080000000000000000000000000000000000000000100000f9035ef9013d940000000000000000000000000000000000001010f884a0e6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c4a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638a00000000000000000000000000000000000000000000000000000000000001010b8a00000000000000000000000000000000000000000000008812d5ac25c01b45bf000000000000000000000000000000000000000000000088133e07ef64641f1f000000000000000000000000000000000000000001c5e2e002e82004460d76f970000000000000000000000000000000000000000000000000685bc9a448d960000000000000000000000000000000000000000001c5e36815bdcc2a0628bcb87f8dc940000000000000000000000000000000000001010f863a0ebff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4fa00000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638b8600000000000000000000000000000000000000000000008812d5ac25c01b45bf00000000000000000000000000000000000000000000000000685bc9a448d96000000000000000000000000000000000000000000000000000685bc9a448d9600f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638a0000000000000000000000000fcccd43296d9c1601a904eca9b339d94a5e5e098b8a00000000000000000000000000000000000000000000000000008ff34526de00000000000000000000000000000000000000000000000088134d9397f946a5bf00000000000000000000000000000000000000000000009e56bc92173ffaf923400000000000000000000000000000000000000000000088134d03a4b41fc7bf00000000000000000000000000000000000000000000009e56bd220a8521d7234b9073ef9073bf8d1a0d6213f494e7bb1418661069c6da13302d80fb5401182aa96d08220bc0dc8e071a09f6c1782a3c25bf4f666c950141efa981d6e384dcba2f7d6e187494e6b6da64ea0e2802b6c219907c6c4df3941d375d6af0178a87942214cd316153b7b80ba0b86a028698766cbf0cbe3ea9d11207f42080892266da139cbb88dfde2f61e9110f094a0bd71b87290463b0d762268927681cc8eb886ab9aa795e17afdb805288c72b515808080a0ace20d838d862dad238ab335ab3beaee728905d708276f3cb0959ef87a4c862f8080808080808080f901f180a034a531f189309d3615eaa5355b802540eec79d070a52783155500c7b6dbd90f3a038c800c74acdbfb17409a84d9fec28ddb1880095996693fe214604e8b41f02dba027d6ab89f4c64dc0fbd39a63fed8aa2456afc345c8d56e3b1f035dc58027b7f4a03260d7a2ef33945fff14a7d4254a54eb4dddfe2c8666296fc84d726532044082a0f218f242a23fb2006706d42b3e962e6606d5bae8ee2ee46dccd20c51479ae8dda060def2876dd04c270193c01b0911bcb2cf205bdd97fde1b411c1af54b98eb90fa09031ddbf92abfdcf8a5097ec49926df6ce56c600c1e9ecfd6ac5dff3003ddfc0a04962eac743a962f31f72999756fb6280262a2795ed61c5af866352aa140c63ada0bcaaf83e7f037d8965cff1cc28f1580c33958d46717fbf8556b3cea24a78b657a0c843c1561e9e5b73f9dd8b9dbf76d642509dac5f2c8181e8eabc09ec1ebfd1dda09686974194e882ff96c8c8dc0d4adee666b6ea074f6d297fc3de17e0de35b460a0408c89cc15230136f4a3d3e945d8c9ff1affe7360315de4079162eef95164210a0550a8f4f040ebf7fc1c58c4c0689f9e97b0079ef8d29d3ac31471e3d05e52e0da0a8fe18a87d802e43448d1b9ad5c0e3029018a1b47ba25dc2e8f85e82d8dfcaf3a045053b7bbc7d3081fdbc9eb37620c558888a8e9e8deabc89ada98a599862f88080f9047120b9046d02f90469018303f667b9010000000000000000000000000000000000000200000000000000000000000000000000000000000000000810100000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000080000000000000000000000000000020000080000000001000000000000000000000080000000000000000000000000004000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000800000108000200000000100000000000000080000000000000000000000000000000000000000100000f9035ef9013d940000000000000000000000000000000000001010f884a0e6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c4a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638a00000000000000000000000000000000000000000000000000000000000001010b8a00000000000000000000000000000000000000000000008812d5ac25c01b45bf000000000000000000000000000000000000000000000088133e07ef64641f1f000000000000000000000000000000000000000001c5e2e002e82004460d76f970000000000000000000000000000000000000000000000000685bc9a448d960000000000000000000000000000000000000000001c5e36815bdcc2a0628bcb87f8dc940000000000000000000000000000000000001010f863a0ebff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4fa00000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638b8600000000000000000000000000000000000000000000008812d5ac25c01b45bf00000000000000000000000000000000000000000000000000685bc9a448d96000000000000000000000000000000000000000000000000000685bc9a448d9600f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000ebaca92a7be0b5f658c0770a81951bba22da5638a0000000000000000000000000fcccd43296d9c1601a904eca9b339d94a5e5e098b8a00000000000000000000000000000000000000000000000000008ff34526de00000000000000000000000000000000000000000000000088134d9397f946a5bf00000000000000000000000000000000000000000000009e56bc92173ffaf923400000000000000000000000000000000000000000000088134d03a4b41fc7bf00000000000000000000000000000000000000000000009e56bd220a8521d723482000501'; - - vm.expectRevert('Withdrawer and burn exit tx do not match'); - bridgeMainnet.confirmExit(burnProof); - } -} - -/// This is a real proof that was manually created by efecarranza.eth -/// The TX can be found here: https://etherscan.io/tx/0x75849d87d15d6a5837c29e2d97a10a442fa71bee50c8cb8ddc01058a474e581e -contract ForkedBridgeTests is Test { - event ConfirmExit(bytes proof); - - function test_successful() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 19419577); // One block before an actual exit - - bytes - memory burnProof = hex'f90e4884233313f0b90160079c12baaa97cc4e197b379b04a0d04ff537b78de94c227d7b4c87c0d1dda4d040f844fd8ecd0959992f9f812c75b20b35fb22cc411e380440d4725f4654f2e8cb46ce66478ede0f30b8d7c2b8e05f8847fb92ee757dc4c958bc529981857a94c62ca2806fc3f04375fd482fa489f82f2f673d39f3885ea68d8163df00f9bde29b5596294480d231e68f32ed3825adeb8f0d8ecb71b823a76b6600245232128b87e25049d52f33341db8e5ccb3d5eba0c7c2aa14e5386ec387cd3126ccc21e2e62dbab2f63152fcecdf13977d662499c4d72c0f640ceaa9dc16619be69688d04189d212019c5e81c2735501c2ad17542304f0fe046796e959acdd0ffd1c2b109b048e06661087638c7dab809ede06f174232b5e1699cc295bd6f85b3c69ade936de28d0f1c0c0aa05370c2e28440590d18b25fb7bfbf9ba0198bd2eb467f91576109f3ed268808bb10b629748ab1dcfe7f84c99986f4df1f4eabca070999d92e84033f836c8465edc5b4a0d9f0e66f0783529b6f1c45593d7e1dcd1072fac53d47510a4a2f1ade9d29b632a063fd6c1c65e072cd9a1e639ed10a55fae606006c4b91dfe75df2a09b95fa44dbb904e902f904e5018401035d74b9010000000000000004000800000000000000000000000000000000000000880000000000080000000000000812100000000800008000000000000000000000000000200000000000000000000000000000800000000000000000000108000000000001000000000000000000000000000000000000000020000080000000001000000000000000000000000000000000010000000000000004000000000020000000200000000000000000000000000000000000000000000000000000000000004000000100000000000001000000000000000000000000800000108000280000002000000000000000000000000000000000000000000000000000000000100000f903d9f9013d940000000000000000000000000000000000001010f884a0e6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c4a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000752d9470d6895ffce597dac750d7e7cb602dd543a00000000000000000000000000000000000000000000000000000000000001010b8a000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000001c56091b1cdceef7ed6018e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c56091b23cd4a51c11218e8f8dc940000000000000000000000000000000000001010f863a0ebff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4fa00000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0a0000000000000000000000000752d9470d6895ffce597dac750d7e7cb602dd543b86000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f87994752d9470d6895ffce597dac750d7e7cb602dd543e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb840000000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000006f05b59d3b20000f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000003765a685a401622c060e5d700d9ad89413363a91a00000000000000000000000001efecb61a2f80aa34d3b9218b564a64d05946290b8a00000000000000000000000000000000000000000000000000004d3752576800000000000000000000000000000000000000000000000000030e709f5c54d02f5000000000000000000000000000000000000000000000810f6987c14573200cd00000000000000000000000000000000000000000000000030e236809fd682f5000000000000000000000000000000000000000000000810f69d4f897ca880cdb907a0f9079df90131a0cc6bad86ebf0f818392a12389f3bc53ebb9f94d27e9d0382d6a9db32d9c5de60a04b991800dfddc8b77c5ebd60e3abf0060bcb562f14ec3dacaf98e1ee10708b39a0a2ffea0972a886f6b61dd075bb593b214015d9bfc32f67dae13e29d91a49642da0136e0359a298c70878e9bbe9c7dc94bb775e4d91bcb7b21e79eb19e095899245a083b67235f8289fe24e85c5bb06fafef5d3d4c0d79213df82db59addabd09d902a0100bd7b2f394a1a9a735c20202824adcf96d5d0a70ff9263115baa0d7ffb3a7aa02aef965259bc088c423c15851cebd20f620013c42d1e2d0dfb7e9abdc1686d6ca04f996c1ee338e580e92ed19929d48004c61e43c84529057d074413547b7104e9a0d5a7f9411f393475392c386c78c04fb84d62e6c576ea494cb52a0bd397774ea98080808080808080f851a06715f19145ea190bac587bc8c167cf3c8dd68ae34e2310afeb5c443cb69c071ca0121575898ad38143b1859b1027ab00ef467464a5780bcebb2d6450c57f6e1c40808080808080808080808080808080f8918080808080808080a0d77f25545d6e8133022a5b6c177b2ad66d0be9375f856efd1f946f0a04966505a092b20e32a9ea59c9a1c3e2a5e6b7d90cf33a0ab2bae06c057b1e8a8e84ec3a04a051352578e2e8157b2859d1d79d12b77378c2b5dc47b066f071e0407b36b15bb4a0412b67856079f6d507f8a509329810d649a339a1504ca001739676aafd50b2718080808080f891a0a3a3aee21f0483dbfae1feec7566cd4a6612a553478f267cae62a00117d7fa3fa0a58c0f7532d68fcdfb97e0da91cd690ca6b45d6778bf07946b1da2d9c04a5c10a0aa79cc36876636b0daa60eacf1d85bfd0101afcda5939b6c3e09ca5514ea645ca04d502874cec64708160342c328195c93349b6a86b2f8624ac3b9b17f1257f4d480808080808080808080808080f904ed20b904e902f904e5018401035d74b9010000000000000004000800000000000000000000000000000000000000880000000000080000000000000812100000000800008000000000000000000000000000200000000000000000000000000000800000000000000000000108000000000001000000000000000000000000000000000000000020000080000000001000000000000000000000000000000000010000000000000004000000000020000000200000000000000000000000000000000000000000000000000000000000004000000100000000000001000000000000000000000000800000108000280000002000000000000000000000000000000000000000000000000000000000100000f903d9f9013d940000000000000000000000000000000000001010f884a0e6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c4a00000000000000000000000000000000000000000000000000000000000001010a0000000000000000000000000752d9470d6895ffce597dac750d7e7cb602dd543a00000000000000000000000000000000000000000000000000000000000001010b8a000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000001c56091b1cdceef7ed6018e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c56091b23cd4a51c11218e8f8dc940000000000000000000000000000000000001010f863a0ebff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4fa00000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0a0000000000000000000000000752d9470d6895ffce597dac750d7e7cb602dd543b86000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f87994752d9470d6895ffce597dac750d7e7cb602dd543e1a022e3f162fca16dc0fcfb65eddf406531a0c555a2c24c58cf5d10fc2d202a882eb840000000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000006f05b59d3b20000f9013d940000000000000000000000000000000000001010f884a04dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63a00000000000000000000000000000000000000000000000000000000000001010a00000000000000000000000003765a685a401622c060e5d700d9ad89413363a91a00000000000000000000000001efecb61a2f80aa34d3b9218b564a64d05946290b8a00000000000000000000000000000000000000000000000000004d3752576800000000000000000000000000000000000000000000000000030e709f5c54d02f5000000000000000000000000000000000000000000000810f6987c14573200cd00000000000000000000000000000000000000000000000030e236809fd682f5000000000000000000000000000000000000000000000810f69d4f897ca880cd830081b101'; - vm.expectEmit(true, true, true, true, 0x752d9470D6895fFCE597DAC750d7E7CB602dd543); - emit ConfirmExit(burnProof); - IAavePolEthPlasmaBridge(0x752d9470D6895fFCE597DAC750d7E7CB602dd543).confirmExit(burnProof); - } -} diff --git a/tests/mocks/AaveV2EthereumRatesUpdate.sol b/tests/mocks/AaveV2EthereumRatesUpdate.sol deleted file mode 100644 index 0a83173ae..000000000 --- a/tests/mocks/AaveV2EthereumRatesUpdate.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v2-config-engine/AaveV2Payload.sol'; -import {AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; - -/** - * @dev Smart contract for a mock rates update, for testing purposes - * IMPORTANT Parameters are pseudo-random, DON'T USE THIS ANYHOW IN PRODUCTION - * @author BGD Labs - */ -contract AaveV2EthereumRatesUpdate is AaveV2Payload { - constructor(IEngine customEngine) AaveV2Payload(customEngine) {} - - function rateStrategiesUpdates() - public - pure - override - returns (IEngine.RateStrategyUpdate[] memory) - { - IEngine.RateStrategyUpdate[] memory rateStrategy = new IEngine.RateStrategyUpdate[](1); - - rateStrategy[0] = IEngine.RateStrategyUpdate({ - asset: AaveV2EthereumAssets.USDC_UNDERLYING, - params: IV2RateStrategyFactory.RateStrategyParams({ - optimalUtilizationRate: _bpsToRay(69_00), - baseVariableBorrowRate: EngineFlags.KEEP_CURRENT, - variableRateSlope1: _bpsToRay(42_00), - variableRateSlope2: EngineFlags.KEEP_CURRENT, - stableRateSlope1: _bpsToRay(69_00), - stableRateSlope2: EngineFlags.KEEP_CURRENT - }) - }); - - return rateStrategy; - } -} diff --git a/tests/mocks/AaveV3AvalancheCollateralUpdate.sol b/tests/mocks/AaveV3AvalancheCollateralUpdate.sol deleted file mode 100644 index 23daeb6b6..000000000 --- a/tests/mocks/AaveV3AvalancheCollateralUpdate.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {AaveV3AvalancheAssets} from 'aave-address-book/AaveV3Avalanche.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 AaveV3AvalancheCollateralUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: AaveV3AvalancheAssets.AAVEe_UNDERLYING, - 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: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} diff --git a/tests/mocks/AaveV3AvalancheCollateralUpdateEdgeBonus.sol b/tests/mocks/AaveV3AvalancheCollateralUpdateEdgeBonus.sol deleted file mode 100644 index 22146e7e7..000000000 --- a/tests/mocks/AaveV3AvalancheCollateralUpdateEdgeBonus.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {AaveV3AvalancheAssets} from 'aave-address-book/AaveV3Avalanche.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 AaveV3AvalancheCollateralUpdateWrongBonus is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: AaveV3AvalancheAssets.AAVEe_UNDERLYING, - 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 AaveV3AvalancheCollateralUpdateCorrectBonus is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: AaveV3AvalancheAssets.AAVEe_UNDERLYING, - 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: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} diff --git a/tests/mocks/AaveV3AvalancheCollateralUpdateNoChange.sol b/tests/mocks/AaveV3AvalancheCollateralUpdateNoChange.sol deleted file mode 100644 index b66596ff5..000000000 --- a/tests/mocks/AaveV3AvalancheCollateralUpdateNoChange.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {AaveV3AvalancheAssets} from 'aave-address-book/AaveV3Avalanche.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 AaveV3AvalancheCollateralUpdateNoChange is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory) { - IEngine.CollateralUpdate[] memory collateralsUpdate = new IEngine.CollateralUpdate[](1); - - collateralsUpdate[0] = IEngine.CollateralUpdate({ - asset: AaveV3AvalancheAssets.AAVEe_UNDERLYING, - 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: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} diff --git a/tests/mocks/AaveV3AvalancheEModeCategoryUpdateNoChange.sol b/tests/mocks/AaveV3AvalancheEModeCategoryUpdateNoChange.sol deleted file mode 100644 index 30a2d75a7..000000000 --- a/tests/mocks/AaveV3AvalancheEModeCategoryUpdateNoChange.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadAvalanche.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 AaveV3AvalancheEModeCategoryUpdateNoChange is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(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: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} diff --git a/tests/mocks/AaveV3EthereumAssetEModeUpdate.sol b/tests/mocks/AaveV3EthereumAssetEModeUpdate.sol deleted file mode 100644 index 3b8e87b0d..000000000 --- a/tests/mocks/AaveV3EthereumAssetEModeUpdate.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadEthereum.sol'; -import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.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 AaveV3EthereumAssetEModeUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function assetsEModeUpdates() public pure override returns (IEngine.AssetEModeUpdate[] memory) { - IEngine.AssetEModeUpdate[] memory eModeUpdate = new IEngine.AssetEModeUpdate[](1); - - eModeUpdate[0] = IEngine.AssetEModeUpdate({ - asset: AaveV3EthereumAssets.rETH_UNDERLYING, - eModeCategory: 1 - }); - - return eModeUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Ethereum', networkAbbreviation: 'Eth'}); - } -} diff --git a/tests/mocks/AaveV3EthereumMockCapUpdate.sol b/tests/mocks/AaveV3EthereumMockCapUpdate.sol deleted file mode 100644 index ff8045917..000000000 --- a/tests/mocks/AaveV3EthereumMockCapUpdate.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadEthereum.sol'; -import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.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 AaveV3EthereumMockCapUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function capsUpdates() public pure override returns (IEngine.CapsUpdate[] memory) { - IEngine.CapsUpdate[] memory capsUpdate = new IEngine.CapsUpdate[](1); - - capsUpdate[0] = IEngine.CapsUpdate({ - asset: AaveV3EthereumAssets.AAVE_UNDERLYING, - supplyCap: 1_000_000, - borrowCap: EngineFlags.KEEP_CURRENT - }); - - return capsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Ethereum', networkAbbreviation: 'Eth'}); - } -} diff --git a/tests/mocks/AaveV3OptimismMockRatesUpdate.sol b/tests/mocks/AaveV3OptimismMockRatesUpdate.sol deleted file mode 100644 index a4fb5b899..000000000 --- a/tests/mocks/AaveV3OptimismMockRatesUpdate.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import '../../src/v3-config-engine/AaveV3PayloadOptimism.sol'; -import {AaveV3OptimismAssets} from 'aave-address-book/AaveV3Optimism.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 AaveV3OptimismMockRatesUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function rateStrategiesUpdates() - public - pure - override - returns (IEngine.RateStrategyUpdate[] memory) - { - IEngine.RateStrategyUpdate[] memory ratesUpdate = new IEngine.RateStrategyUpdate[](1); - - ratesUpdate[0] = IEngine.RateStrategyUpdate({ - asset: AaveV3OptimismAssets.USDT_UNDERLYING, - params: IEngine.InterestRateInputData({ - optimalUsageRatio: _bpsToRay(80_00), - baseVariableBorrowRate: EngineFlags.KEEP_CURRENT, - variableRateSlope1: EngineFlags.KEEP_CURRENT, - variableRateSlope2: _bpsToRay(75_00) - }) - }); - - return ratesUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Optimism', networkAbbreviation: 'Opt'}); - } -} diff --git a/tests/mocks/AaveV3PolygonBorrowUpdate.sol b/tests/mocks/AaveV3PolygonBorrowUpdate.sol deleted file mode 100644 index 73f8d041f..000000000 --- a/tests/mocks/AaveV3PolygonBorrowUpdate.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import 'aave-v3-origin/periphery/contracts/v3-config-engine/AaveV3Payload.sol'; -import {AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; - -/** - * @dev Smart contract for a mock listing, to be able to test without having a v3 instance on Ethereum - * 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 AaveV3PolygonBorrowUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function borrowsUpdates() public pure override returns (IEngine.BorrowUpdate[] memory) { - IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); - - borrowsUpdate[0] = IEngine.BorrowUpdate({ - asset: AaveV3PolygonAssets.AAVE_UNDERLYING, - 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: 'Polygon', networkAbbreviation: 'Pol'}); - } -} diff --git a/tests/mocks/AaveV3PolygonBorrowUpdateNoChange.sol b/tests/mocks/AaveV3PolygonBorrowUpdateNoChange.sol deleted file mode 100644 index cf2f57e53..000000000 --- a/tests/mocks/AaveV3PolygonBorrowUpdateNoChange.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import 'aave-v3-origin/periphery/contracts/v3-config-engine/AaveV3Payload.sol'; -import {AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; - -/** - * @dev Inheriting directly from AaveV3Payload for being able to inject a custom engine - * @author BGD Labs - */ -contract AaveV3PolygonBorrowUpdateNoChange is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function borrowsUpdates() public pure override returns (IEngine.BorrowUpdate[] memory) { - IEngine.BorrowUpdate[] memory borrowsUpdate = new IEngine.BorrowUpdate[](1); - - borrowsUpdate[0] = IEngine.BorrowUpdate({ - asset: AaveV3PolygonAssets.AAVE_UNDERLYING, - 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: 'Polygon', networkAbbreviation: 'Pol'}); - } -} diff --git a/tests/mocks/AaveV3PolygonEModeCategoryUpdate.sol b/tests/mocks/AaveV3PolygonEModeCategoryUpdate.sol deleted file mode 100644 index dc2e25db8..000000000 --- a/tests/mocks/AaveV3PolygonEModeCategoryUpdate.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import 'aave-v3-origin/periphery/contracts/v3-config-engine/AaveV3Payload.sol'; - -/** - * @dev Smart contract for a mock 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 AaveV3PolygonEModeCategoryUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(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: EngineFlags.KEEP_CURRENT_ADDRESS, - label: EngineFlags.KEEP_CURRENT_STRING - }); - - return eModeUpdates; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Polygon', networkAbbreviation: 'Pol'}); - } -} - -/** - * @dev Smart contract for a mock 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 AaveV3AvalancheEModeCategoryUpdateEdgeBonus is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(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: 'Avalanche', networkAbbreviation: 'Ava'}); - } -} diff --git a/tests/mocks/AaveV3PolygonPriceFeedUpdate.sol b/tests/mocks/AaveV3PolygonPriceFeedUpdate.sol deleted file mode 100644 index 0613e6282..000000000 --- a/tests/mocks/AaveV3PolygonPriceFeedUpdate.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import 'aave-v3-origin/periphery/contracts/v3-config-engine/AaveV3Payload.sol'; -import {AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; - -/** - * @dev Smart contract for a mock listing, to be able to test without having a v3 instance on Ethereum - * 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 AaveV3PolygonPriceFeedUpdate is AaveV3Payload { - constructor(IEngine customEngine) AaveV3Payload(customEngine) {} - - function priceFeedsUpdates() public pure override returns (IEngine.PriceFeedUpdate[] memory) { - IEngine.PriceFeedUpdate[] memory priceFeedsUpdate = new IEngine.PriceFeedUpdate[](1); - - priceFeedsUpdate[0] = IEngine.PriceFeedUpdate({ - asset: AaveV3PolygonAssets.AAVE_UNDERLYING, - priceFeed: AaveV3PolygonAssets.USDC_ORACLE - }); - - return priceFeedsUpdate; - } - - function getPoolContext() public pure override returns (IEngine.PoolContext memory) { - return IEngine.PoolContext({networkName: 'Polygon', networkAbbreviation: 'Pol'}); - } -} diff --git a/tests/swaps/AaveSwapperTest.t.sol b/tests/swaps/AaveSwapperTest.t.sol deleted file mode 100644 index 30007650f..000000000 --- a/tests/swaps/AaveSwapperTest.t.sol +++ /dev/null @@ -1,465 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {Test} from 'forge-std/Test.sol'; -import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol'; -import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; -import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; - -import {AaveSwapper} from '../../src/swaps/AaveSwapper.sol'; - -contract AaveSwapperTest is Test { - event DepositedIntoV2(address indexed token, uint256 amount); - event DepositedIntoV3(address indexed token, uint256 amount); - event GuardianUpdated(address oldGuardian, address newGuardian); - event SwapCanceled(address indexed fromToken, address indexed toToken, uint256 amount); - event SwapRequested( - address milkman, - address indexed fromToken, - address indexed toToken, - address fromOracle, - address toOracle, - uint256 amount, - address indexed recipient, - uint256 slippage - ); - event TokenUpdated(address indexed token, bool allowed); - - address public constant BAL80WETH20 = 0x5c6Ee304399DBdB9C8Ef030aB642B10820DB8F56; - address public constant BPT_PRICE_CHECKER = 0xBeA6AAC5bDCe0206A9f909d80a467C93A7D6Da7c; - address public constant CHAINLINK_PRICE_CHECKER = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; - address public constant MILKMAN = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; - - AaveSwapper public swaps; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 19733176); - - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps = new AaveSwapper(); - vm.stopPrank(); - } -} - -contract Initialize is AaveSwapperTest { - function test_revertsIf_alreadyInitialized() public { - vm.expectRevert('Initializable: contract is already initialized'); - swaps.initialize(); - } -} - -contract TransferOwnership is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('Ownable: caller is not the owner'); - swaps.transferOwnership(makeAddr('new-admin')); - } - - function test_successful() public { - address newAdmin = makeAddr('new-admin'); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps.transferOwnership(newAdmin); - vm.stopPrank(); - - assertEq(newAdmin, swaps.owner()); - } -} - -contract UpdateGuardian is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_BY_OWNER_OR_GUARDIAN'); - swaps.updateGuardian(makeAddr('new-admin')); - } - - function test_successful() public { - address newManager = makeAddr('new-admin'); - vm.expectEmit(); - emit GuardianUpdated(swaps.guardian(), newManager); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps.updateGuardian(newManager); - vm.stopPrank(); - - assertEq(newManager, swaps.guardian()); - } -} - -contract RemoveGuardian is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_BY_OWNER_OR_GUARDIAN'); - swaps.updateGuardian(address(0)); - } - - function test_successful() public { - vm.expectEmit(); - emit GuardianUpdated(swaps.guardian(), address(0)); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps.updateGuardian(address(0)); - vm.stopPrank(); - - assertEq(address(0), swaps.guardian()); - } -} - -contract AaveSwapperSwap is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - uint256 amount = 1_000e18; - vm.expectRevert('Ownable: caller is not the owner'); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.WETH_UNDERLYING, - AaveV2EthereumAssets.AAVE_UNDERLYING, - address(0), - AaveV2EthereumAssets.AAVE_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - amount, - 200 - ); - } - - function test_revertsIf_amountIsZero() public { - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - vm.expectRevert(AaveSwapper.InvalidAmount.selector); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.WETH_UNDERLYING, - AaveV2EthereumAssets.AAVE_UNDERLYING, - address(0), - AaveV2EthereumAssets.AAVE_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 0, - 200 - ); - vm.stopPrank(); - } - - function test_revertsIf_fromTokenIsZeroAddress() public { - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - vm.expectRevert(AaveSwapper.Invalid0xAddress.selector); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - address(0), - AaveV2EthereumAssets.AAVE_UNDERLYING, - address(0), - AaveV2EthereumAssets.AAVE_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - vm.stopPrank(); - } - - function test_revertsIf_toTokenIsZeroAddress() public { - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - vm.expectRevert(AaveSwapper.Invalid0xAddress.selector); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.WETH_UNDERLYING, - address(0), - address(0), - AaveV2EthereumAssets.AAVE_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - vm.stopPrank(); - } - - function test_revertsIf_invalidRecipient() public { - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - vm.expectRevert(AaveSwapper.InvalidRecipient.selector); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(0), - 1_000e18, - 200 - ); - vm.stopPrank(); - } - - function test_successful() public { - deal(AaveV2EthereumAssets.AAVE_UNDERLYING, address(swaps), 1_000e18); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - - vm.expectEmit(true, true, true, true); - emit SwapRequested( - MILKMAN, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - 1_000e18, - address(AaveV2Ethereum.COLLECTOR), - 200 - ); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - vm.stopPrank(); - } -} - -contract CancelSwap is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - uint256 amount = 1_000e18; - vm.expectRevert('ONLY_BY_OWNER_OR_GUARDIAN'); - swaps.cancelSwap( - makeAddr('milkman-instance'), - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.WETH_UNDERLYING, - AaveV2EthereumAssets.AAVE_UNDERLYING, - address(0), - AaveV2EthereumAssets.AAVE_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - amount, - 200 - ); - } - - function test_revertsIf_noMatchingTrade() public { - deal(AaveV2EthereumAssets.AAVE_UNDERLYING, address(swaps), 1_000e18); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - - vm.expectRevert(); - swaps.cancelSwap( - makeAddr('not-milkman-instance'), - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - vm.stopPrank(); - } - - function test_successful() public { - deal(AaveV2EthereumAssets.AAVE_UNDERLYING, address(swaps), 1_000e18); - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - - vm.expectEmit(true, true, true, true); - emit SwapRequested( - MILKMAN, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - 1_000e18, - address(AaveV2Ethereum.COLLECTOR), - 200 - ); - swaps.swap( - MILKMAN, - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - - vm.expectEmit(); - emit SwapCanceled( - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - 1_000e18 - ); - swaps.cancelSwap( - 0x7e05Cf4Ba19B4DF16d1c37845cF925e3Ba1f190b, // Address generated by tests - CHAINLINK_PRICE_CHECKER, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE, - address(AaveV2Ethereum.COLLECTOR), - 1_000e18, - 200 - ); - vm.stopPrank(); - } -} - -contract EmergencyTokenTransfer is AaveSwapperTest { - function test_revertsIf_invalidCaller() public { - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - swaps.emergencyTokenTransfer( - AaveV2EthereumAssets.BAL_UNDERLYING, - address(AaveV2Ethereum.COLLECTOR), - 1_000e6 - ); - } - - function test_successful_governanceCaller() public { - address AAVE_WHALE = 0xBE0eB53F46cd790Cd13851d5EFf43D12404d33E8; - - assertEq(IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).balanceOf(address(swaps)), 0); - - uint256 aaveAmount = 1_000e18; - - vm.startPrank(AAVE_WHALE); - IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).transfer(address(swaps), aaveAmount); - vm.stopPrank(); - - assertEq(IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).balanceOf(address(swaps)), aaveAmount); - - uint256 initialCollectorUsdcBalance = IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).balanceOf( - address(AaveV2Ethereum.COLLECTOR) - ); - - vm.startPrank(AaveGovernanceV2.SHORT_EXECUTOR); - swaps.emergencyTokenTransfer( - AaveV2EthereumAssets.AAVE_UNDERLYING, - address(AaveV2Ethereum.COLLECTOR), - aaveAmount - ); - vm.stopPrank(); - - assertEq( - IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).balanceOf(address(AaveV2Ethereum.COLLECTOR)), - initialCollectorUsdcBalance + aaveAmount - ); - assertEq(IERC20(AaveV2EthereumAssets.AAVE_UNDERLYING).balanceOf(address(swaps)), 0); - } -} - -contract GetExpectedOut is AaveSwapperTest { - function test_revertsIf_fromOracleIsAddressZero() public { - uint256 amount = 1e18; - vm.expectRevert(AaveSwapper.OracleNotSet.selector); - swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - address(0), - AaveV2EthereumAssets.USDC_ORACLE - ); - } - - function test_revertsIf_toOracleIsAddressZero() public { - uint256 amount = 1e18; - vm.expectRevert(AaveSwapper.OracleNotSet.selector); - swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - address(0) - ); - } - - function test_aaveToUsdc_withEthBasedOracles() public { - /* This test is only to show that oracles with the same base - * will return the correct value for trading, or at least very - * close to USD based oracles. Nonetheless, ETH based oracles - * should not be used. Please ensure only USD based oracles are - * set for trading. - * Using different bases in a swap can lead to destructive results. - */ - uint256 amount = 1e18; - uint256 expected = swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV2EthereumAssets.AAVE_UNDERLYING, - AaveV2EthereumAssets.USDC_UNDERLYING, - AaveV2EthereumAssets.AAVE_ORACLE, - AaveV2EthereumAssets.USDC_ORACLE - ); - - // April 25, 2024 AAVE/USD is around $90 - assertEq(expected / 1e4, 8941); // USDC is 6 decimals - } - - function test_aaveToUsdc() public { - uint256 amount = 1e18; - uint256 expected = swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV3EthereumAssets.AAVE_UNDERLYING, - AaveV3EthereumAssets.USDC_UNDERLYING, - AaveV3EthereumAssets.AAVE_ORACLE, - AaveV3EthereumAssets.USDC_ORACLE - ); - - // April 25, 2024 AAVE/USD is around $90 - assertEq(expected / 1e4, 9002); // USDC is 6 decimals - } - - function test_ethToDai() public { - uint256 amount = 1e18; - uint256 expected = swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV3EthereumAssets.WETH_UNDERLYING, - AaveV3EthereumAssets.DAI_UNDERLYING, - AaveV3EthereumAssets.WETH_ORACLE, - AaveV3EthereumAssets.DAI_ORACLE - ); - - // April 25, 2024 ETH/USD is around $3,122 - assertEq(expected / 1e18, 3122); // WETH is 18 decimals - } - - function test_ethToBal() public { - uint256 amount = 1e18; - uint256 expected = swaps.getExpectedOut( - CHAINLINK_PRICE_CHECKER, - amount, - AaveV3EthereumAssets.WETH_UNDERLYING, - AaveV3EthereumAssets.BAL_UNDERLYING, - AaveV3EthereumAssets.WETH_ORACLE, - AaveV3EthereumAssets.BAL_ORACLE - ); - - // April 25, 2024 ETH/BAL is 1 ETH is around 823 BAL tokens - assertEq(expected / 1e18, 823); // WETH and BAL are 18 decimals - } - - function test_balTo80BAL20WETH() public { - uint256 amount = 100e18; - uint256 expected = swaps.getExpectedOut( - BPT_PRICE_CHECKER, - amount, - AaveV3EthereumAssets.BAL_UNDERLYING, - BAL80WETH20, - address(0), - address(0) - ); - - // April 25, 2024 BAL/USD should be around 0.30 at 100 units traded, 30 units expected. - assertEq(expected / 1e18, 30); // WETH and BAL are 18 decimals - } -} diff --git a/tests/v2-config-engine/AaveV2ConfigEngineTest.t.sol b/tests/v2-config-engine/AaveV2ConfigEngineTest.t.sol deleted file mode 100644 index 7d87b2b58..000000000 --- a/tests/v2-config-engine/AaveV2ConfigEngineTest.t.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV2EthereumRatesUpdate} from '../mocks/AaveV2EthereumRatesUpdate.sol'; -import {IAaveV2ConfigEngine} from '../../src/v2-config-engine/IAaveV2ConfigEngine.sol'; -import {DeployV2EngineEthLib} from '../../scripts/AaveV2ConfigEngine.s.sol'; -import {DeployV2RatesFactoryEthLib} from '../../scripts/V2RateStrategyFactory.s.sol'; -import {AaveV2Ethereum} from 'aave-address-book/AaveAddressBook.sol'; -import {AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; -import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol'; -import {IV2RateStrategyFactory} from '../../src/v2-config-engine/IV2RateStrategyFactory.sol'; -import {GovHelpers} from '../../src/GovHelpers.sol'; -import '../../src/ProtocolV2TestBase.sol'; - -contract AaveV2ConfigEngineTest is ProtocolV2TestBase { - using stdStorage for StdStorage; - - function testV2RateStrategiesUpdates() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 16727659); - (address ratesFactory, ) = DeployV2RatesFactoryEthLib.deploy(); - IAaveV2ConfigEngine engine = IAaveV2ConfigEngine(DeployV2EngineEthLib.deploy(ratesFactory)); - - AaveV2EthereumRatesUpdate payload = new AaveV2EthereumRatesUpdate(engine); - - address initialStrategyAddress = AaveV2Ethereum - .POOL - .getReserveData(AaveV2EthereumAssets.USDC_UNDERLYING) - .interestRateStrategyAddress; - IDefaultInterestRateStrategy initialStrategy = IDefaultInterestRateStrategy( - initialStrategyAddress - ); - - createConfigurationSnapshot('preTestV2RatesUpdates', AaveV2Ethereum.POOL); - - GovHelpers.executePayload(vm, address(payload), AaveGovernanceV2.SHORT_EXECUTOR); - - createConfigurationSnapshot('postTestV2RatesUpdates', AaveV2Ethereum.POOL); - - diffReports('preTestV2RatesUpdates', 'postTestV2RatesUpdates'); - - address updatedStrategyAddress = AaveV2Ethereum - .POOL - .getReserveData(AaveV2EthereumAssets.USDC_UNDERLYING) - .interestRateStrategyAddress; - - InterestStrategyValues memory expectedInterestStrategyValues = InterestStrategyValues({ - addressesProvider: address(AaveV2Ethereum.POOL_ADDRESSES_PROVIDER), - optimalUsageRatio: _bpsToRay(69_00), - baseVariableBorrowRate: initialStrategy.baseVariableBorrowRate(), - variableRateSlope1: _bpsToRay(42_00), - variableRateSlope2: initialStrategy.variableRateSlope2(), - stableRateSlope1: _bpsToRay(69_00), - stableRateSlope2: initialStrategy.stableRateSlope2() - }); - - _validateInterestRateStrategy( - updatedStrategyAddress, - updatedStrategyAddress, - expectedInterestStrategyValues - ); - } - - function _bpsToRay(uint256 amount) internal pure returns (uint256) { - return (amount * 1e27) / 10_000; - } -} diff --git a/tests/v2-config-engine/V2RateStrategyFactory.t.sol b/tests/v2-config-engine/V2RateStrategyFactory.t.sol deleted file mode 100644 index a3f8cd0e1..000000000 --- a/tests/v2-config-engine/V2RateStrategyFactory.t.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; -import {IDefaultInterestRateStrategy} from 'aave-address-book/AaveV2.sol'; -import {V2RateStrategyFactory, IV2RateStrategyFactory} from '../../src/v2-config-engine/V2RateStrategyFactory.sol'; -import '../../src/ProtocolV2TestBase.sol'; - -contract V2RateStrategyFactoryTest is ProtocolV2TestBase { - using stdStorage for StdStorage; - V2RateStrategyFactory public rateStrategyFactory; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 16613098); - rateStrategyFactory = new V2RateStrategyFactory(AaveV2Ethereum.POOL_ADDRESSES_PROVIDER); - } - - function testCreateStrategies() public { - address strategyAddress = AaveV2Ethereum - .POOL - .getReserveData(AaveV2EthereumAssets.AAVE_UNDERLYING) - .interestRateStrategyAddress; - IDefaultInterestRateStrategy strategy = IDefaultInterestRateStrategy(strategyAddress); - - InterestStrategyValues memory expectedStrategyValues = InterestStrategyValues({ - addressesProvider: address(AaveV2Ethereum.POOL_ADDRESSES_PROVIDER), - optimalUsageRatio: strategy.OPTIMAL_UTILIZATION_RATE(), // TODO: Fix to optimalUtilizationRate - baseVariableBorrowRate: strategy.baseVariableBorrowRate(), - variableRateSlope1: strategy.variableRateSlope1(), - variableRateSlope2: strategy.variableRateSlope2(), - stableRateSlope1: strategy.stableRateSlope1(), - stableRateSlope2: strategy.stableRateSlope2() - }); - - IV2RateStrategyFactory.RateStrategyParams[] - memory rateStrategyParams = new IV2RateStrategyFactory.RateStrategyParams[](1); - - rateStrategyParams[0] = IV2RateStrategyFactory.RateStrategyParams({ - optimalUtilizationRate: expectedStrategyValues.optimalUsageRatio, - baseVariableBorrowRate: expectedStrategyValues.baseVariableBorrowRate, - variableRateSlope1: expectedStrategyValues.variableRateSlope1, - variableRateSlope2: expectedStrategyValues.variableRateSlope2, - stableRateSlope1: expectedStrategyValues.stableRateSlope1, - stableRateSlope2: expectedStrategyValues.stableRateSlope2 - }); - - address[] memory createdStrategyAddresses = rateStrategyFactory.createStrategies( - rateStrategyParams - ); - - _validateInterestRateStrategy( - createdStrategyAddresses[0], - createdStrategyAddresses[0], - expectedStrategyValues - ); - } - - function testMultipleCreateStrategies() public { - address strategyAddress = AaveV2Ethereum - .POOL - .getReserveData(AaveV2EthereumAssets.USDC_UNDERLYING) - .interestRateStrategyAddress; - IDefaultInterestRateStrategy strategy = IDefaultInterestRateStrategy(strategyAddress); - - IV2RateStrategyFactory.RateStrategyParams[] - memory rateStrategyParams = new IV2RateStrategyFactory.RateStrategyParams[](1); - rateStrategyParams[0] = IV2RateStrategyFactory.RateStrategyParams({ - optimalUtilizationRate: strategy.OPTIMAL_UTILIZATION_RATE(), - baseVariableBorrowRate: strategy.baseVariableBorrowRate(), - variableRateSlope1: strategy.variableRateSlope1(), - variableRateSlope2: strategy.variableRateSlope2(), - stableRateSlope1: strategy.stableRateSlope1(), - stableRateSlope2: strategy.stableRateSlope2() - }); - - address[] memory createdStrategyAddresses = rateStrategyFactory.createStrategies( - rateStrategyParams - ); - - address[] memory expectedStrategyAddresses = rateStrategyFactory.createStrategies( - rateStrategyParams - ); - - // Asserts multiple strategies with same params created to have the same address - assertEq(createdStrategyAddresses, expectedStrategyAddresses); - } -}