// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "../contracts/examples/AaveSupplyBorrow.sol"; import "../contracts/examples/AaveFlashLoanReceiver.sol"; import "../contracts/interfaces/IAavePool.sol"; import "../contracts/interfaces/IERC20.sol"; contract AaveTest is Test { AaveSupplyBorrow public aaveSupplyBorrow; AaveFlashLoanReceiver public flashLoanReceiver; // Mainnet addresses address constant AAVE_POOL = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2; address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; uint256 mainnetFork; function setUp() public { // Fork mainnet at a recent block mainnetFork = vm.createFork(vm.envString("MAINNET_RPC_URL")); vm.selectFork(mainnetFork); // Deploy contracts aaveSupplyBorrow = new AaveSupplyBorrow(AAVE_POOL); flashLoanReceiver = new AaveFlashLoanReceiver(AAVE_POOL); } function testSupplyAndBorrow() public { // Setup: Get some USDC from a whale address whale = 0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503; // USDC whale uint256 supplyAmount = 1000 * 10**6; // 1000 USDC uint256 borrowAmount = 500 * 10**6; // 500 USDT // Impersonate whale and transfer USDC to test contract vm.startPrank(whale); IERC20(USDC).transfer(address(this), supplyAmount); vm.stopPrank(); // Approve and supply IERC20(USDC).approve(address(aaveSupplyBorrow), supplyAmount); aaveSupplyBorrow.supplyAndBorrow(USDC, supplyAmount, USDT, borrowAmount); // Check balances uint256 usdtBalance = IERC20(USDT).balanceOf(address(this)); assertGt(usdtBalance, 0, "Should have borrowed USDT"); } function testFlashLoanSimple() public { uint256 flashLoanAmount = 10000 * 10**6; // 10,000 USDC // Execute flash loan flashLoanReceiver.flashLoanSimple(USDC, flashLoanAmount, ""); // Flash loan should complete successfully (repaid in executeOperation) assertTrue(true, "Flash loan completed"); } function testFlashLoanMulti() public { address[] memory assets = new address[](2); assets[0] = USDC; assets[1] = USDT; uint256[] memory amounts = new uint256[](2); amounts[0] = 10000 * 10**6; // 10,000 USDC amounts[1] = 5000 * 10**6; // 5,000 USDT uint256[] memory modes = new uint256[](2); modes[0] = 0; // No debt modes[1] = 0; // No debt // Execute multi-asset flash loan flashLoanReceiver.flashLoan(assets, amounts, modes, ""); // Flash loan should complete successfully assertTrue(true, "Multi-asset flash loan completed"); } }