{"id":20533079,"url":"https://github.com/hellotokenio/helloflashloan","last_synced_at":"2025-10-11T01:40:54.324Z","repository":{"id":101353482,"uuid":"337464918","full_name":"HelloTokenIO/HelloFlashLoan","owner":"HelloTokenIO","description":"Flash Loan with Aave","archived":false,"fork":false,"pushed_at":"2021-02-09T16:27:48.000Z","size":282,"stargazers_count":2,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-13T17:51:18.788Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HelloTokenIO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-09T16:24:34.000Z","updated_at":"2025-03-27T20:55:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"39e5c7d3-63a1-4a8e-817e-8e3ce475c05f","html_url":"https://github.com/HelloTokenIO/HelloFlashLoan","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/HelloTokenIO/HelloFlashLoan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloTokenIO%2FHelloFlashLoan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloTokenIO%2FHelloFlashLoan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloTokenIO%2FHelloFlashLoan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloTokenIO%2FHelloFlashLoan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HelloTokenIO","download_url":"https://codeload.github.com/HelloTokenIO/HelloFlashLoan/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HelloTokenIO%2FHelloFlashLoan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005928,"owners_count":26083986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T00:18:35.095Z","updated_at":"2025-10-11T01:40:54.307Z","avatar_url":"https://github.com/HelloTokenIO.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aave Flash Loan Brownie Mix\n\n![Aave Banner](box-img-sm.png)\n\n*Adapted from [aave/flashloan-box](https://github.com/aave/flashloan-box) by [mrdavey](https://github.com/mrdavey/).*\n\nThis Brownie mix comes with everything you need to start [developing on flash loans](https://docs.aave.com/developers/guides/flash-loans).\n\nThis mix is configured for use with [Ganache](https://github.com/trufflesuite/ganache-cli) on a [forked mainnet](https://eth-brownie.readthedocs.io/en/stable/network-management.html#using-a-forked-development-network).\n\n*It supports both Aave V1 and V2.*\n\n## Installation and Setup\n\n1. [Install Brownie](https://eth-brownie.readthedocs.io/en/stable/install.html) \u0026 [Ganache-CLI](https://github.com/trufflesuite/ganache-cli), if you haven't already.\n\n2. Sign up for [Infura](https://infura.io/) and generate an API key. Store it in the `WEB3_INFURA_PROJECT_ID` environment variable.\n\n```bash\nexport WEB3_INFURA_PROJECT_ID=YourProjectID\n```\n\n3. Sign up for [Etherscan](www.etherscan.io) and generate an API key. This is required for fetching source codes of the mainnet contracts we will be interacting with. Store the API key in the `ETHERSCAN_TOKEN` environment variable.\n\n```bash\nexport ETHERSCAN_TOKEN=YourApiToken\n```\n\n4. Download the mix.\n\n```bash\nbrownie bake aave-flashloan\n```\n\n## Basic Use\n\nTo perform a simple flash loan in a development environment:\n\n1. Open the Brownie console. This automatically launches Ganache on a forked mainnet.\n\n```bash\n$ brownie console\n```\n\n2. Create variables for the Aave lending pool.\n\n```python\n\u003e\u003e\u003e aave_lending_pool_v2 = \"0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5\"\n```\n\n3. Deploy the [`FlashloanV2.sol`](contracts/v2/FlashloanV2.sol) contract.\n\n```python\n\u003e\u003e\u003e flashloan = FlashloanV2.deploy(aave_lending_pool_v2, {\"from\": accounts[0]})\nTransaction sent: 0xb0f70b42d2cec9c027b664e9f37490ad50fb934e61f0c58cfe5a77d96dfad681\n  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 8\n  FlashloanV2.constructor confirmed - Block: 11577534   Gas used: 957504 (7.98%)\n  FlashloanV2 deployed at: 0x420b1099B9eF5baba6D92029594eF45E19A04A4A\n```\n\n4. Transfer some Ether in form of WETH to the newly deployed contract. We must do this because we have not implemented any custom flash loan logic, otherwise the loan will fail from an inability to pay the fee.\n\n```python\n\u003e\u003e\u003e WETH = Contract(\"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\")\n\u003e\u003e\u003e accounts[0].transfer(WETH, \"1 ether\")\nTransaction sent: 0x29ac98c861356bc65e19407d8389e53f8c3d9a05513a8610c9de2ef013aac525\n  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 10\n  Transaction confirmed - Block: 11577536   Gas used: 28431 (0.24%)\n\u003e\u003e\u003e WETH.transfer(flashloan, \"1 ether\", {\"from\": accounts[0]})\nTransaction sent: 0x1bff7e44779eb92d426bc432d22ecb9821e0b66afb66d48404a23e37b34044e6\n  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 11\n  ERC20.transfer confirmed - Block: 11577537   Gas used: 36794 (0.31%)\n```\n\n5. Now we are ready to perform our first flash loan!\n\n```python\n\u003e\u003e\u003e tx = flashloan.flashloan(WETH, {\"from\": accounts[0]})\nTransaction sent: 0x335530e6d2b7588ee4727b35ae1ed8634a264aca04b325640101ec1c2b89d499\n  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 12\n  FlashloanV2.flashloan confirmed - Block: 11577538   Gas used: 193010 (1.61%)\n```\n\n## Implementing Flash Loan Logic\n\n[`contracts/v2/FlashloanV2.sol`](contracts/v2/FlashloanV2.sol) is where you implement your own logic for flash loans. In particular:\n\n* The size of the loan is set in line 39 in `flashloan`.\n* Custom flash loan logic is added after line 23 in `executeOperation`.\n\nSee the Aave documentation on [Performing a Flash Loan](https://docs.aave.com/developers/guides/flash-loans) for more detailed information.\n\n## Testing\n\nTo run the tests:\n\n```\nbrownie test\n```\n\nThe example tests provided in this mix start by transfering funds to the [`FlashloanV2.sol`](contracts/v2/FlashloanV2.sol) contract. This ensures that the loan executes succesfully without any custom logic. Once you have built your own logic, you should edit [`tests/test_flashloan_v2.py`](tests/test_flashloan_v2.py) and remove this initial funding logic.\n\nSee the [Brownie documentation](https://eth-brownie.readthedocs.io/en/stable/tests-pytest-intro.html) for more detailed information on testing your project.\n\n## Debugging Failed Transactions\n\nUse the `--interactive` flag to open a console immediatly after each failing test:\n\n```\nbrownie test --interactive\n```\n\nWithin the console, transaction data is available in the [`history`](https://eth-brownie.readthedocs.io/en/stable/api-network.html#txhistory) container:\n\n```python\n\u003e\u003e\u003e history\n[\u003cTransaction '0x50f41e2a3c3f44e5d57ae294a8f872f7b97de0cb79b2a4f43cf9f2b6bac61fb4'\u003e,\n \u003cTransaction '0x7af1ce1c30de8b939f481fd6c340226415428f7e6b59e09d7fa5383939091824'\u003e]\n```\n\nExamine the [`TransactionReceipt`](https://eth-brownie.readthedocs.io/en/stable/api-network.html#transactionreceipt) for the failed test to determine what went wrong. For example, to view a traceback:\n\n```python\n\u003e\u003e\u003e tx = history[-1]\n\u003e\u003e\u003e tx.traceback()\n\nTraceback for '0x7af1ce1c30de8b939f481fd6c340226415428f7e6b59e09d7fa5383939091824':\n\n\nTrace step 13656, program counter 6555:\n  File \"contracts/protocol/lendingpool/LendingPool.sol\", lines 532-536, in LendingPool.flashLoan:    \n    IERC20(vars.currentAsset).safeTransferFrom(\n      receiverAddress,\n      vars.currentATokenAddress,\n      vars.currentAmountPlusPremium\n    );\nTrace step 13750, program counter 11619:\n  File \"contracts/dependencies/openzeppelin/contracts/SafeERC20.sol\", line 36, in SafeERC20.safeTransferFrom:    \n    callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\nTrace step 13937, program counter 16308:\n  File \"contracts/dependencies/openzeppelin/contracts/SafeERC20.sol\", line 55, in SafeERC20.callOptionalReturn:    \n    (bool success, bytes memory returndata) = address(token).call(data);\nTrace step 13937, program counter 16308:\n  File \"contracts/dependencies/openzeppelin/contracts/SafeERC20.sol\", line 55, in SafeERC20.callOptionalReturn:    \n    (bool success, bytes memory returndata) = address(token).call(data);\n```\n\nTo view a tree map of how the transaction executed:\n\n```python\n\u003e\u003e\u003e tx.call_trace()\n\nCall trace for '0x7af1ce1c30de8b939f481fd6c340226415428f7e6b59e09d7fa5383939091824':\nInitial call cost  [21432 gas]\nFlashloanV2.flashloan  0:14132  [3717 / 174153 gas]\n└── ILendingPoolV2.flashLoan  [CALL]  662:14120  [1996 / 170436 gas]\n    └── LendingPool.flashLoan  [DELEGATECALL]  759:14107  [218057 / 168440 gas]\n        ├── ValidationLogic.validateFlashloan  1428:1461  [106 gas]\n        ├── SafeMath.mul  1752:1779  [100 gas]\n        ├── SafeMath.div  1783:1831  [161 gas]\n        ├── IAtoken  [CALL]  1963:2807  [1914 / 20764 gas]\n        │   └── AToken.transferUnderlyingTo  [DELEGATECALL]  2060:2795  [2988 / 18850 gas]\n        │       └── ERC20.transfer  [CALL]  2422:2695  [15862 gas]\n        ├── FlashloanV2.executeOperation  [CALL]  3252:3904  [3035 / 11055 gas]\n        │   └── ERC20.approve  [CALL]  3681:3836  [8020 gas]\n        ├── SafeMath.add  4186:4204  [59 gas]\n        ├── ReserveLogic.updateState  4270:5480  [10868 / 17605 gas]\n        │   ├── InitializableImmutableAdminUpgradeabilityProxy.scaledTotalSupply  [STATICCALL]  4322:4500  [1908 / 3663 gas]\n        │   │   └── VariableDebtToken.scaledTotalSupply  [DELEGATECALL]  4419:4488  [1755 gas]\n        │   ├── ReserveLogic._updateIndexes  4593:4758  [995 / 1352 gas]\n        │   │   ├── MathUtils.calculateLinearInterest  4620:4678  [53 / 183 gas]\n        │   │   │   └── SafeMath.sub  4630:4671  [130 gas]\n        │   │   ├── WadRayMath.ray  4685:4689  [15 gas]\n        │   │   ├── SafeMath.mul  4696:4723  [100 gas]\n        │   │   └── SafeMath.add  4732:4750  [59 gas]\n        │   ├── WadRayMath.rayMul  4766:4836  [238 gas]\n        │   ├── MathUtils.calculateCompoundedInterest  4919:4985  [80 / 210 gas]\n        │   │   └── SafeMath.sub  4937:4978  [130 gas]\n        │   ├── WadRayMath.rayMul  5018:5088  [238 gas]\n        │   ├── WadRayMath.rayMul  5097:5167  [244 gas]\n        │   ├── SafeMath.mul  5179:5206  [100 gas]\n        │   ├── SafeMath.mul  5210:5237  [100 gas]\n        │   ├── SafeMath.mul  5256:5283  [100 gas]\n        │   ├── SafeMath.mul  5287:5314  [100 gas]\n        │   ├── SafeMath.mul  5318:5345  [100 gas]\n        │   ├── SafeMath.mul  5363:5390  [100 gas]\n        │   ├── WadRayMath.ray  5394:5398  [15 gas]\n        │   ├── SafeMath.add  5402:5420  [59 gas]\n        │   ├── SafeMath.add  5424:5442  [59 gas]\n        │   └── SafeMath.add  5446:5464  [59 gas]\n        ├── WadRayMath.rayMul  5495:5565  [245 gas]\n        ├── ReserveLogic._mintToTreasury  5672:7537  [2857 / 14960 gas]\n        │   ├── ReserveConfiguration.getReserveFactor  5748:5756  [824 gas]\n        │   ├── InitializableImmutableAdminUpgradeabilityProxy.getSupplyData  [STATICCALL]  5820:6706  [1929 / 9318 gas]\n        │   │   └── StableDebtToken.getSupplyData  [DELEGATECALL]  5917:6694  [7389 gas]\n        │   ├── WadRayMath.rayMul  6813:6883  [245 gas]\n        │   ├── WadRayMath.rayMul  6893:6963  [244 gas]\n        │   ├── MathUtils.calculateCompoundedInterest  6984:7042  [54 / 191 gas]\n        │   │   └── SafeMath.sub  6994:7035  [137 gas]\n        │   ├── WadRayMath.rayMul  7075:7145  [244 gas]\n        │   ├── WadRayMath.rayMul  7154:7224  [245 gas]\n        │   ├── SafeMath.mul  7236:7263  [100 gas]\n        │   ├── SafeMath.mul  7267:7294  [100 gas]\n        │   ├── SafeMath.mul  7313:7340  [100 gas]\n        │   ├── SafeMath.mul  7344:7371  [100 gas]\n        │   ├── SafeMath.mul  7375:7402  [100 gas]\n        │   ├── SafeMath.mul  7420:7447  [100 gas]\n        │   ├── WadRayMath.ray  7451:7455  [15 gas]\n        │   ├── SafeMath.add  7459:7477  [59 gas]\n        │   ├── SafeMath.add  7481:7499  [59 gas]\n        │   └── SafeMath.add  7503:7521  [59 gas]\n        ├── WadRayMath.rayMul  7552:7622  [244 gas]\n        ├── SafeMath.add  7650:7668  [59 gas]\n        ├── SafeMath.sub  7672:7713  [137 gas]\n        ├── SafeMath.sub  7724:7765  [137 gas]\n        ├── PercentageMath.percentMul  7788:7860  [255 gas]\n        ├── IAtoken  [CALL]  7938:8460  [1911 / 19056 gas]\n        │   └── AToken.mintToTreasury  [DELEGATECALL]  8035:8448  [17145 gas]\n        ├── IAtoken.totalSupply  [STATICCALL]  8530:9167  [1908 / 9796 gas]\n        │   └── AToken.totalSupply  [DELEGATECALL]  8627:9155  [3006 / 7888 gas]\n        │       └── ILendingPoolV2.getReserveNormalizedIncome  [STATICCALL]  8755:9048  [1911 / 4882 gas]\n        │           └── LendingPool.getReserveNormalizedIncome  [DELEGATECALL]  8852:9036  [1237 / 2971 gas]\n        │               └── ReserveLogic.getNormalizedIncome  8963:9006  [1734 gas]\n        ├── ReserveLogic.cumulateToLiquidityIndex  9246:9616  [2768 / 3626 gas]\n        │   ├── WadRayMath.wadToRay  9253:9294  [131 gas]\n        │   ├── WadRayMath.wadToRay  9299:9340  [138 gas]\n        │   ├── WadRayMath.rayDiv  9344:9423  [270 gas]\n        │   ├── WadRayMath.ray  9431:9435  [15 gas]\n        │   ├── SafeMath.add  9440:9458  [59 gas]\n        │   └── WadRayMath.rayMul  9478:9548  [245 gas]\n        ├── ReserveLogic.updateInterestRates  9656:11398  [6759 / 20432 gas]\n        │   ├── InitializableImmutableAdminUpgradeabilityProxy.getTotalSupplyAndAvgRate  [STATICCALL]  9767:10627  [1915 / 7639 gas]\n        │   │   └── StableDebtToken.getTotalSupplyAndAvgRate  [DELEGATECALL]  9864:10615  [5724 gas]\n        │   ├── InitializableImmutableAdminUpgradeabilityProxy.scaledTotalSupply  [STATICCALL]  10769:10947  [1908 / 3663 gas]\n        │   │   └── VariableDebtToken.scaledTotalSupply  [DELEGATECALL]  10866:10935  [1755 gas]\n        │   ├── WadRayMath.rayMul  11001:11071  [245 gas]\n        │   ├── ERC20.balanceOf  [STATICCALL]  11137:11247  [1934 gas]\n        │   ├── SafeMath.add  11328:11346  [59 gas]\n        │   └── SafeMath.sub  11350:11391  [133 gas]\n        ├── ReserveConfiguration.getReserveFactor  11415:11423  [824 gas]\n        ├── DefaultReserveInterestRateStrategy.calculateInterestRates  [STATICCALL]  11507:13284  [7330 / 11175 gas]\n        │   ├── ILendingPoolAddressesProviderV2.getLendingRateOracle  [STATICCALL]  11838:11954  [1959 gas]\n        │   └── LendingRateOracle.getMarketBorrowRate  [STATICCALL]  12031:12129  [1886 gas]\n        └── SafeERC20.safeTransferFrom  13657:14107  [291 / -180413 gas]\n            └── SafeERC20.callOptionalReturn  13751:14107  [-183382 / -180704 gas]\n                ├── Address.isContract  13762:13784  [769 gas]\n                └── ERC20.transferFrom  [CALL]  13938:14045  [1909 gas]\n```\n\nSee the [Brownie documentation](https://eth-brownie.readthedocs.io/en/stable/core-transactions.html) for more detailed information on debugging failed transactions.\n\n## Deployment\n\nWhen you are finished testing and ready to deploy to the mainnet:\n\n1. [Import a keystore](https://eth-brownie.readthedocs.io/en/stable/account-management.html#importing-from-a-private-key) into Brownie for the account you wish to deploy from.\n2. Edit [`scripts/deployment.py`](scripts/deployment.py) and add your keystore ID according to the comments.\n3. Run the deployment script on the mainnet using the following command:\n\n```bash\n$ brownie run deployment --network mainnet\n```\n\nYou will be prompted to enter your keystore password, and then the contract will be deployed.\n\n## Known issues\n\n### No access to archive state errors\n\nIf you are using Ganache to fork a network, then you may have issues with the blockchain archive state every 30 minutes. This is due to your node provider (i.e. Infura) only allowing free users access to 30 minutes of archive state. To solve this, upgrade to a paid plan, or simply restart your ganache instance and redploy your contracts.\n\n## Troubleshooting\n\nSee our [Troubleshooting Errors](https://docs.aave.com/developers/tutorials/troubleshooting-errors) documentation.\n\n# Resources\n\n - Aave [flash loan documentation](https://docs.aave.com/developers/guides/flash-loans)\n - Aave [Developer Discord channel](https://discord.gg/CJm5Jt3)\n - Brownie [Gitter channel](https://gitter.im/eth-brownie/community)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellotokenio%2Fhelloflashloan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhellotokenio%2Fhelloflashloan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellotokenio%2Fhelloflashloan/lists"}