├── remappings.txt ├── foundry.toml ├── .gitignore ├── script └── Counter.s.sol ├── .gitmodules ├── test ├── interface │ └── IWETH9.sol └── Flashloan.t.sol └── src ├── test ├── test2 └── Flashloan.sol /remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/=lib/openzeppelin-contracts/ 2 | @aave/core-v3/=lib/aave-v3-core/ 3 | forge-std/=lib/forge-std/src/ -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | -------------------------------------------------------------------------------- /script/Counter.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Script.sol"; 5 | 6 | contract CounterScript is Script { 7 | function setUp() public {} 8 | 9 | function run() public { 10 | vm.broadcast(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | branch = v1.4.0 5 | [submodule "lib/openzeppelin-contracts"] 6 | path = lib/openzeppelin-contracts 7 | url = https://github.com/OpenZeppelin/openzeppelin-contracts 8 | branch = v4.8.1 9 | [submodule "lib/aave-v3-core"] 10 | path = lib/aave-v3-core 11 | url = https://github.com/aave/aave-v3-core 12 | branch = v1.17.2 13 | -------------------------------------------------------------------------------- /test/interface/IWETH9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.10; 3 | 4 | interface WETH9 { 5 | function name() external view returns (string memory); 6 | 7 | function approve(address guy, uint256 wad) external returns (bool); 8 | 9 | function totalSupply() external view returns (uint256); 10 | 11 | function transferFrom( 12 | address src, 13 | address dst, 14 | uint256 wad 15 | ) external returns (bool); 16 | 17 | function withdraw(uint256 wad) external; 18 | 19 | function decimals() external view returns (uint8); 20 | 21 | function balanceOf(address) external view returns (uint256); 22 | 23 | function symbol() external view returns (string memory); 24 | 25 | function transfer(address dst, uint256 wad) external returns (bool); 26 | 27 | function deposit() external payable; 28 | 29 | function allowance(address, address) external view returns (uint256); 30 | 31 | event Approval(address indexed src, address indexed guy, uint256 wad); 32 | event Transfer(address indexed src, address indexed dst, uint256 wad); 33 | event Deposit(address indexed dst, uint256 wad); 34 | event Withdrawal(address indexed src, uint256 wad); 35 | } -------------------------------------------------------------------------------- /src/test: -------------------------------------------------------------------------------- 1 | 0xfb0f3ee10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ac4bf674b3e0000000000000000000000000004b6ef4fe7549d71e3f9945f027a70e5cb5cd8cf4000000000000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c0000000000000000000000000013bd972b0bfaefc9538a43c1fda11d71c720cd4700000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000063f559f500000000000000000000000000000000000000000000000000000000641a35e50000000000000000000000000000000000000000000000000000000000000000360c6ebe0000000000000000000000000000000000000000349ef95bd89919110000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f00000000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f00000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000004b9a0c18d2000000000000000000000000000cf6170576e1b6178f1de9eab0540034d832f196b0000000000000000000000000000000000000000000000000000000000000041c358c1713b605bcec7d8960a51dab8cee85ff0def6fa5c2c4eb7a1100177f15b48d9a8c68d0b3a97324221ba8c4e216ede320e3243873938ce49a1d1f77d6f6d1c00000000000000000000000000000000000000000000000000000000000000c5d24601 -------------------------------------------------------------------------------- /src/test2: -------------------------------------------------------------------------------- 1 | 0xfb0f3ee10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000564d702d38f5e00000000000000000000000000004b6ef4fe7549d71e3f9945f027a70e5cb5cd8cf4000000000000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c0000000000000000000000000013bd972b0bfaefc9538a43c1fda11d71c720cd47000000000000000000000000000000000000000000000000000000000000015b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000063f4f4c0000000000000000000000000000000000000000000000000000000006419d0b00000000000000000000000000000000000000000000000000000000000000000360c6ebe00000000000000000000000000000000000000005aa1507ba5c24c6e0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f00000000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f00000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000cf6170576e1b6178f1de9eab0540034d832f196b00000000000000000000000000000000000000000000000000000000000000418e6ab3d73fa52a7fb5ce636e46daddd90f783f420c62c0a7c36a469ffb37a0181600f495e29504b191d87e385444f25d52409e1cde986bb1fbc3c956794aeea41c00000000000000000000000000000000000000000000000000000000000000c5d24601 -------------------------------------------------------------------------------- /test/Flashloan.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../src/Flashloan.sol"; 6 | import "./interface/IWETH9.sol"; 7 | 8 | import {IERC20} from "@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol"; 9 | 10 | contract FlashLoanTest is Test { 11 | WETH9 WETH = WETH9(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); 12 | FlashLoanAAVE public flashLoan = new FlashLoanAAVE(); 13 | function setUp() public { 14 | // vm.createSelectFork(vm.envString("MAINNET_RPC_URL"), 16_675_533); //fork mainnet at block 16675533 15 | vm.label(address(WETH), "WETH"); 16 | vm.startPrank(); 17 | // vm.stopPrank(); 18 | } 19 | 20 | function fromHexChar(uint8 c) public pure returns (uint8) { 21 | if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) { 22 | return c - uint8(bytes1('0')); 23 | } 24 | if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) { 25 | return 10 + c - uint8(bytes1('a')); 26 | } 27 | if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) { 28 | return 10 + c - uint8(bytes1('A')); 29 | } 30 | revert("fail"); 31 | } 32 | 33 | // Convert an hexadecimal string to raw bytes 34 | function fromHex(string memory s) public pure returns (bytes memory) { 35 | bytes memory ss = bytes(s); 36 | require(ss.length%2 == 0); // length must be even 37 | bytes memory r = new bytes(ss.length/2); 38 | for (uint i=0; i; 22 | 23 | constructor () { 24 | POOL = IPool(ADRESSES_PROVIDER.getPool()); 25 | } 26 | 27 | function ADDRESSES_PROVIDER() external view returns(IPoolAddressesProvider){ 28 | return ADRESSES_PROVIDER; 29 | } 30 | 31 | function executeFlashLoan(address asset, uint256 amount, bytes calldata params) public { 32 | // perform a flashLoanSimple() on the pool contract 33 | uint16 referralCode = 0; 34 | POOL.flashLoanSimple(address(this), asset, amount, params, referralCode); 35 | } 36 | 37 | function callProxy( 38 | address _exchange, 39 | bytes calldata _calldata 40 | ) public { 41 | (bool success, ) = _exchange.call(_calldata); 42 | require(success); 43 | } 44 | 45 | function executeOperation(address asset, uint256 amount, uint256 premium, address initiator, bytes calldata params) external override returns(bool) { //this will be called by Pool 46 | 47 | emit CurrentBalance(IERC20(weth).balanceOf(address(this))); 48 | callProxy(address(0x00000000006c3852cbEf3e08E8dF289169EdE581),params); 49 | IERC20(weth).transferFrom(seller, address(this), IERC20(weth).balanceOf(seller)); 50 | return true; 51 | } 52 | 53 | function approvalWeth(address _token) public { 54 | IERC20(_token).approve(address(0x1E0049783F008A0085193E00003D00cd54003c71), 10000 ether); // opensea 55 | IERC20(_token).approve(address(0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2), 10000 ether); // aave 56 | } 57 | 58 | function onERC721Received( 59 | address _operator, 60 | address _from, 61 | uint256 _tokenId, 62 | bytes memory _data 63 | ) public override returns (bytes4) { 64 | // IERC20(weth).transferFrom(seller, address(this), IERC20(weth).balanceOf(seller)); 65 | emit CurrentBalance(IERC20(weth).balanceOf(address(this))); 66 | return 0x150b7a02; 67 | } 68 | } 69 | 70 | // deployed on goerli using hardhat and the address is 0x6dc85a986Fbad7A60a2130D806F5bdF327BbD8f9 --------------------------------------------------------------------------------