This repository contains contracts that work as ERC7399 entry points for popular flash lenders.
sequenceDiagram
title ERC3156Wrapper
Borrower->>Wrapper: ERC7399.flash(to,token,amt,data,callback)
Wrapper->>Lender: lender specific flashLoan call
Lender-->>Wrapper: transfer loan amount
Lender->>Wrapper: lender specific callback()
Wrapper -->>Wrapper: bridgeToCallback()
Wrapper-->>Borrower: transfer loan amount
Wrapper->>Borrower: callback()
Borrower -> Borrower: Borrower does stuff
Borrower -->> Wrapper: transfer loan amount + fee †
Borrower ->> Wrapper: callback return
Wrapper --> Wrapper: approves token repayment to lender †
Wrapper -->> Lender: lender calls transferFrom(wrapper, amount + fee) †
† For the BalancerWrapper and Uniswap v3 the borrower transfers the repayment to the lender and the wrapper skips the repayment approval.
Lender | Address | Networks | Gas | Fees | Contract |
---|---|---|---|---|---|
Aave v2 | 262190 | 0.05% | AaveWrapper | ||
Aave v3 | 0x9D4D2C08b29A2Db1c614483cd8971734BFDCC9F2 | Arbitrum One, Optimism, Polygon | 212569 | 0.05% | AaveWrapper |
Aave v3 (Permissioned) | 0x0c86c636ed5593705b5675d370c831972C787841 | Ethereum, Gnosis | 229742 | 0 | AaveWrapper |
Aerodrome | 0x69b6E55f00d908018E2D745c524995bc231D762b | Base | 163919 | Variable | SolidlyWrapper |
Balancer v2 | 0x9E092cb431e5F1aa70e47e052773711d2Ba4917E | Ethereum, Arbitrum One, Optimism, Polygon, Gnosis | 113032 | 0 | BalancerWrapper |
Balancer v2 | 0xD534400B0555F8441c5a3e0E9e585615B54fB2F4 | Base | 113032 | 0 | BalancerWrapper |
Balancer + Compound v2 | 836719 | 0 | CompoundWrapper | ||
Balancer + Moonwell | 0x6207ec38da68902CC60D3760c9fe3EB64B426207 | Base | 1183309 | 0 | CompoundWrapper |
Balancer + Pendle | 0xC1Ea6a6df39D991006b39706db7C51f5A1819da7 | Arbitrum One | 525422 | 0 | BalancerPendleWrapper |
Balancer + Silo | 0x0F9104Fec1a5C91e63632E215e8F5c57C8f32c77 | Arbitrum One | 1025824 | 1 | SiloWrapper |
Balancer + Silo | 0xAa8F3BF0C9e1aD581547D9803066084E57907a33 | Optimism | 1025824 | 1 | SiloWrapper |
Camelot | 0x5E8820B2832aD8451f65Fa2CCe2F3Cef29016D0d | Arbitrum One | 80679 | 0.01% | AlgebraWrapper |
Camelot + Pendle | 0xC9d66F655b7B35A2B4958bE2FB58E472736Bbc47 | Arbitrum One | 506792 | 0.01% | AlgebraPendleWrapper |
Dolomite | 0x54F1ce5E6bdf027C9a6016C9F52fC5A445b77ed6 | Arbitrum One | 459815 | 0 | DolomiteWrapper |
Gnosis Safe | 109223 | Variable | GnosisSafeWrapper | ||
MakerDAO | 313172 | 0 | ERC3156Wrapper | ||
MorphoBlue | 0xa0Cb4e1222d813D6e4dE79f2A7A0B7759209588F | Ethereum | 132114 | 0 | MorphoBlueWrapper |
MorphoBlue | 0xd0953257A5a2603Bf9fCA8aF1F2ecdac60EB8F52 | Base | 132114 | 0 | MorphoBlueWrapper |
MorphoBlue + Pendle | 0xE1f9e06006B2592dDe5b1bBA3ae2DD34DF557007 | Ethereum | 558536 | 0 | MorphoPendleWrapper |
Spark | 0x8cB701df93f2Dae295aE8D7beE5Aa7e4D40CB397 | Ethereum, Gnosis | 212569 | 0 | AaveWrapper |
Uniswap v3 | 0x319300462C37AD2D4f26B584C2b67De51F51f289 | Arbitrum One, Polygon, Ethereum | 94720 | Variable | UniswapV3Wrapper |
Uniswap v3 | 0xfFD51f0631E79c39646A09318B2E18432E788B75 | Optimism | 94720 | Variable | UniswapV3Wrapper |
Canonical | 0x6962ba38D6493B9Ed7E0a4b74624c43D844E1438 | Optimism | 94720 | Variable | UniswapV3Wrapper |
Uniswap v3 + Pendle | 0xa353Fd50210786F0E038ddD574A21d0CCefb3163 | Arbitrum One | 497567 | Variable | UniswapV3PendleWrapper |
Velodrome | 0xcF13CDdbA3aEf757c52466deC310F221e06238d6 | Optimism | 163919 | Variable | SolidlyWrapper |
ZeroLend | 0xA48Cc0e4159C51d73B42c824f1444D1C1cbdA531 | Ethereum, Linea | 212569 | Variable | AaveWrapper |
ZeroLendBTC | 0xB21a09be03Ce5318b3f3089665D917aFfA0aeA90 | Ethereum | 212569 | Variable | AaveWrapper |
ERC3156 (DAI, GHO, FlashMint) | 0x255bAFe2122722FC35E33cd503f4f0E722AB98fC | Ethereum | 279102 | Variable | ERC3156Wrapper |
ERC3156 (FlashMint) | 0xDDA4104c96Df0cf7af14856473F597362211Dfa1 | Arbitrum | 279102 | Variable | ERC3156Wrapper |
Disclaimer: The gas costs are calculated for calling flashLoan
on each wrapper for an arbitrarily chosen token and
loan amount. Gas refunds are not taken into account and might be significant in some cases. Calling the underlying flash
lender directly may have larger gas savings in some instances than others. Requesting loans for different tokens or
amounts might have different gas costs. For AMMs the fees often vary according to pool parameters and state.
The Gnosis Safe Wrapper is intended for individual users to flash lend their own assets held in a Gnosis Safe and earn a fee. To enable it, from your own Gnosis Safe, execute a transaction bundle to enable the GnosisSafeWrapperFactory and set the fees for individual assets.
safe.enableModule(gnosisSafeWrapperFactory);
gnosisSafeWrapperFactory.lend(asset, fee);
...
or an override to lend all assets in the safe:
safe.enableModule(gnosisSafeWrapperFactory);
gnosisSafeWrapperFactory.lendAll(fee);
...
The fee
parameter can be zero for free flash loans. To disable lending, execute from your safe the following command:
gnosisSafeWrapperFactory.disableLend(asset);
...
If you set a lending override, you can disable it to go back to individual asset configuration:
gnosisSafeWrapperFactory.disableLendAll();
...
The Gnosis Safe Wrapper is intended for individual users to flash lend their own assets held in a Gnosis Safe and earn a fee. To enable it, from your own Gnosis Safe, execute a transaction bundle to enable the GnosisSafeWrapperFactory and set the fees for individual assets.
safe.enableModule(gnosisSafeWrapperFactory);
gnosisSafeWrapperFactory.lend(asset, fee);
...
or an override to lend all assets in the safe:
safe.enableModule(gnosisSafeWrapperFactory);
gnosisSafeWrapperFactory.lendAll(fee);
...
The fee
parameter can be zero for free flash loans. To disable lending, execute from your safe the following command:
gnosisSafeWrapperFactory.disableLend(asset);
...
If you set a lending override, you can disable it to go back to individual asset configuration:
gnosisSafeWrapperFactory.disableLendAll();
...
For detail on executing flash loans, please refer to the ERC7399 EIP.
This is experimental software and is provided on an "as is" and "as available" basis.
While care has been taken during development, and most contracts have seen significant use, we do not give any warranties and will not be liable for any loss incurred through any use of this codebase.
This is a list of the most frequently needed commands.
Build the contracts:
$ forge build
Delete the build artifacts and cache directories:
$ forge clean
Compile the contracts:
$ forge build
Get a test coverage report:
$ forge coverage
Deploy to Anvil:
$ forge script script/Deploy.s.sol --broadcast --fork-url http://localhost:8545
For this script to work, you need to have a MNEMONIC
environment variable set to a valid
BIP39 mnemonic.
For instructions on how to deploy to a testnet or mainnet, check out the Solidity Scripting tutorial.
Format the contracts:
$ forge fmt
Get a gas report:
$ forge test --gas-report
Lint the contracts:
$ pnpm lint
Run the tests:
$ forge test
- Foundry uses git submodules to manage dependencies. For detailed instructions on working with dependencies, please refer to the guide in the book
- You don't have to create a
.env
file, but filling in the environment variables may be useful when debugging and testing against a fork.
This project is licensed under MIT.