diff --git a/README.md b/README.md index c7ed729..f5c1174 100644 --- a/README.md +++ b/README.md @@ -26,32 +26,29 @@ sequenceDiagram † For the BalancerWrapper and Uniswap v3 the borrower transfers the repayment to the lender and the wrapper skips the repayment approval. -## Addresses - -Contracts are deployed at the same address for all supported networks. - -| Contract | Lender | Address | Networks | -| ------------------------------------------------------------- | ------------------- | ------------------------------------------ | ------------------------------------------------- | -| [AaveWrapper](src/aave/AaveWrapper.sol) | Aave v3 | 0x9D4D2C08b29A2Db1c614483cd8971734BFDCC9F2 | Arbitrum One, Optimism, Polygon | -| [AaveWrapper](src/aave/AaveWrapper.sol) | Aave v3 | 0x0c86c636ed5593705b5675d370c831972C787841 | Ethereum, Gnosis | -| [AaveWrapper](src/aave/AaveWrapper.sol) | Spark | 0x8cB701df93f2Dae295aE8D7beE5Aa7e4D40CB397 | Ethereum, Gnosis | -| [BalancerWrapper](src/balancer/BalancerWrapper.sol) | Balancer v2 | 0x9E092cb431e5F1aa70e47e052773711d2Ba4917E | Ethereum, Arbitrum One, Optimism, Polygon, Gnosis | -| [BalancerWrapper](src/balancer/BalancerWrapper.sol) | Balancer v2 | 0xD534400B0555F8441c5a3e0E9e585615B54fB2F4 | Base | -| [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | Uniswap v3 | 0x319300462C37AD2D4f26B584C2b67De51F51f289 | Arbitrum One, Optimism, Polygon | -| [CompoundWrapper](src/compound/CompoundWrapper.sol) | Balancer + Moonwell | 0x6207ec38da68902CC60D3760c9fe3EB64B426207 | Base | -| [CompoundWrapper](src/compound/CompoundWrapper.sol) | Balancer + Sonne | 0x6412183C579a276f467ad38468D19CC8f1F2b5cb | Optimism | -| [SiloWrapper](src/silo/SiloWrapper.sol) | Balancer + Silo | 0x0F9104Fec1a5C91e63632E215e8F5c57C8f32c77 | Arbitrum One | -| [DolomiteWrapper](src/dolomite/DolomiteWrapper.sol) | Dolomite | 0x54F1ce5E6bdf027C9a6016C9F52fC5A445b77ed6 | Arbitrum One | -| [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | MorphoBlue | 0xa0Cb4e1222d813D6e4dE79f2A7A0B7759209588F | Ethereum | -| [AlgebraWrapper](src/algebra/DolomiteWrapper.sol) | Camelot | 0x5E8820B2832aD8451f65Fa2CCe2F3Cef29016D0d | Arbitrum One | -| [AlgebraPendleWrapper](src/pendle/AlgebraPendleWrapper.sol) | Algebra + Pendle | 0xC9d66F655b7B35A2B4958bE2FB58E472736Bbc47 | Arbitrum One | -| [BalancerPendleWrapper](src/pendle/BalancerPendleWrapper.sol) | Balancer + Pendle | 0xC1Ea6a6df39D991006b39706db7C51f5A1819da7 | Arbitrum One | -| [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | Aerodrome | 0x69b6E55f00d908018E2D745c524995bc231D762b | Base | -| [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | Velodrome | 0xcF13CDdbA3aEf757c52466deC310F221e06238d6 | Optimism | - -When a contract requires constructor parameters which vary per network, these are supplied by the -[Registry](https://github.com/alcueca/registry) deployed at 0x1BFf8Eee6ECF1c8155E81dba8894CE9cF49a220c in each supported -network. +## Deployments + +| Lender | Networks | Address | Gas | Fees | Contract | +| ---------------------- | ------------------------------------------------- | ------------------------------------------ | --------------- | -------- | ------------------------------------------------------------- | +| Aave v3 | Arbitrum One, Optimism, Polygon | 0x9D4D2C08b29A2Db1c614483cd8971734BFDCC9F2 | 302483 | 0.05% | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Aave v3 (Permissioned) | Ethereum, Gnosis | 0x0c86c636ed5593705b5675d370c831972C787841 | 299756 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Spark | Ethereum, Gnosis | 0x8cB701df93f2Dae295aE8D7beE5Aa7e4D40CB397 | 302483 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Balancer v2 | Ethereum, Arbitrum One, Optimism, Polygon, Gnosis | 0x9E092cb431e5F1aa70e47e052773711d2Ba4917E | 183039 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | +| Balancer v2 | Base | 0xD534400B0555F8441c5a3e0E9e585615B54fB2F4 | 183039 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | +| Uniswap v3 | Arbitrum One, Optimism, Polygon | 0x319300462C37AD2D4f26B584C2b67De51F51f289 | 184417 - 202711 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | +| Balancer + Moonwell | Base | 0x6207ec38da68902CC60D3760c9fe3EB64B426207 | 1253325 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | +| Balancer + Sonne | Optimism | 0x6412183C579a276f467ad38468D19CC8f1F2b5cb | 1142829 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | +| Balancer + Silo | Arbitrum One | 0x0F9104Fec1a5C91e63632E215e8F5c57C8f32c77 | 1115741 | 1 | [SiloWrapper](src/silo/SiloWrapper.sol) | +| Dolomite | Arbitrum One | 0x54F1ce5E6bdf027C9a6016C9F52fC5A445b77ed6 | 529843 | 0 | [DolomiteWrapper](src/dolomite/DolomiteWrapper.sol) | +| MorphoBlue | Ethereum | 0xa0Cb4e1222d813D6e4dE79f2A7A0B7759209588F | 202128 | 0 | [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | +| Camelot | Arbitrum One | 0x5E8820B2832aD8451f65Fa2CCe2F3Cef29016D0d | 148686 - 155940 | 0.01% | [AlgebraWrapper](src/algebra/AlgebraWrapper.sol) | +| Algebra + Pendle | Arbitrum One | 0xC9d66F655b7B35A2B4958bE2FB58E472736Bbc47 | 596718 | 0.01% | [AlgebraPendleWrapper](src/pendle/AlgebraPendleWrapper.sol) | +| Balancer + Pendle | Arbitrum One | 0xC1Ea6a6df39D991006b39706db7C51f5A1819da7 | 595448 | 0 | [BalancerPendleWrapper](src/pendle/BalancerPendleWrapper.sol) | +| Aerodrome | Base | 0x69b6E55f00d908018E2D745c524995bc231D762b | 253829 - 314321 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | +| Velodrome | Optimism | 0xcF13CDdbA3aEf757c52466deC310F221e06238d6 | 253829 - 314321 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | + +Approximate gas costs and fees are provided. For AMMs the fees often vary according to pool parameters and state. Gas +costs can also vary according to state. ## Flash Loans diff --git a/test/AaveWrapper.v2.t.sol b/test/AaveWrapper.v2.t.sol index 261848a..29965c9 100644 --- a/test/AaveWrapper.v2.t.sol +++ b/test/AaveWrapper.v2.t.sol @@ -84,6 +84,8 @@ contract AaveWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Aave v2: ", borrower.usedGas()); } function test_executeOperation_permissions() public { diff --git a/test/AaveWrapper.v3.t.sol b/test/AaveWrapper.v3.t.sol index f3db4a9..9af0def 100644 --- a/test/AaveWrapper.v3.t.sol +++ b/test/AaveWrapper.v3.t.sol @@ -77,6 +77,8 @@ contract AaveWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Aave v3: ", borrower.usedGas()); } function test_executeOperation_permissions() public { diff --git a/test/AlgebraPendleWrapper.t.sol b/test/AlgebraPendleWrapper.t.sol index cceb647..bf6fb2e 100644 --- a/test/AlgebraPendleWrapper.t.sol +++ b/test/AlgebraPendleWrapper.t.sol @@ -115,6 +115,8 @@ contract AlgebraPendleWrapperTest is Test { wrapper.retrieve(IERC20(token), treasury, 0.001e18); assertEqDecimal(IERC20(token).balanceOf(treasury), 0.001e18, 18, "Fee not transferred"); assertEqDecimal(IERC20(token).balanceOf(address(wrapper)), 0, 18, "Fee still in wrapper"); + + console2.log("Algebra + Pendle: ", borrower.usedGas()); } function testRetrievePermissions() public { diff --git a/test/AlgebraWrapper.t.sol b/test/AlgebraWrapper.t.sol index 0c20db9..7e8265a 100644 --- a/test/AlgebraWrapper.t.sol +++ b/test/AlgebraWrapper.t.sol @@ -90,6 +90,8 @@ contract AlgebraWrapperTest is Test { // The amount we transferred to pay for fees, plus the amount we borrowed assertEq(borrower.flashBalance(), loan + fee, "flashBalance"); assertEq(borrower.flashFee(), fee, "flashFee"); + + console2.log("Algebra: ", borrower.usedGas()); } function test_AlgebraFlashCallback_permissions() public { diff --git a/test/BalancerPendleWrapper.t.sol b/test/BalancerPendleWrapper.t.sol index ed2b65e..a60da28 100644 --- a/test/BalancerPendleWrapper.t.sol +++ b/test/BalancerPendleWrapper.t.sol @@ -91,6 +91,8 @@ contract BalancerPendleWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Balancer + Pendle: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/BalancerWrapper.t.sol b/test/BalancerWrapper.t.sol index e986b3e..c8bba79 100644 --- a/test/BalancerWrapper.t.sol +++ b/test/BalancerWrapper.t.sol @@ -72,6 +72,8 @@ contract BalancerWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Balancer: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/CompoundWrapper.Moonwell.t.sol b/test/CompoundWrapper.Moonwell.t.sol index b02be57..94a3d66 100644 --- a/test/CompoundWrapper.Moonwell.t.sol +++ b/test/CompoundWrapper.Moonwell.t.sol @@ -88,6 +88,8 @@ contract MoonwellWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Compound/Moonwell: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/CompoundWrapper.Sonne.t.sol b/test/CompoundWrapper.Sonne.t.sol index 9565432..aab54f3 100644 --- a/test/CompoundWrapper.Sonne.t.sol +++ b/test/CompoundWrapper.Sonne.t.sol @@ -86,6 +86,8 @@ contract SonneWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Compound/Sonne: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/CompoundWrapper.erc20.t.sol b/test/CompoundWrapper.erc20.t.sol index 62e55ea..7a0aff5 100644 --- a/test/CompoundWrapper.erc20.t.sol +++ b/test/CompoundWrapper.erc20.t.sol @@ -88,6 +88,8 @@ contract CompoundWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Compound: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/CompoundWrapper.native.t.sol b/test/CompoundWrapper.native.t.sol index 19a9f39..f68db12 100644 --- a/test/CompoundWrapper.native.t.sol +++ b/test/CompoundWrapper.native.t.sol @@ -88,6 +88,8 @@ contract CompoundWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Compound Native: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/DolomiteWrapper.t.sol b/test/DolomiteWrapper.t.sol index 61a0350..277e0f5 100644 --- a/test/DolomiteWrapper.t.sol +++ b/test/DolomiteWrapper.t.sol @@ -71,6 +71,8 @@ contract DolomiteWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Dolomite: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/ERC3156Wrapper.t.sol b/test/ERC3156Wrapper.t.sol index c277d22..65b1cb5 100644 --- a/test/ERC3156Wrapper.t.sol +++ b/test/ERC3156Wrapper.t.sol @@ -72,5 +72,7 @@ contract ERC3156WrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("ERC3156: ", borrower.usedGas()); } } diff --git a/test/MockBorrower.sol b/test/MockBorrower.sol index 10d00fb..44508bb 100644 --- a/test/MockBorrower.sol +++ b/test/MockBorrower.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.19; import "erc7399/IERC7399.sol"; import "src/BaseWrapper.sol"; +import { console2 } from "forge-std/console2.sol"; contract LoanReceiver { using SafeERC20 for IERC20; @@ -25,6 +26,8 @@ contract MockBorrower { address public flashAsset; uint256 public flashAmount; uint256 public flashFee; + uint256 public innerGas; + uint256 public usedGas; constructor(IERC7399 lender_) { setLender(lender_); @@ -47,6 +50,7 @@ contract MockBorrower { external returns (bytes memory) { + uint256 startingGas = gasleft(); require(msg.sender == address(lender), "MockBorrower: Untrusted lender"); require(initiator == address(this), "MockBorrower: External loan initiator"); @@ -56,6 +60,8 @@ contract MockBorrower { flashFee = fee; loanReceiver.retrieve(asset); flashBalance = IERC20(asset).balanceOf(address(this)); + + innerGas = startingGas - gasleft(); // Transferring the repayment is counted towards the flash loan cost IERC20(asset).safeTransfer(paymentReceiver, amount + fee); return abi.encode(ERC3156PP_CALLBACK_SUCCESS); @@ -137,8 +143,11 @@ contract MockBorrower { return ""; } - function flashBorrow(address asset, uint256 amount) public returns (bytes memory) { - return lender.flash(address(loanReceiver), asset, amount, "", this.onFlashLoan); + function flashBorrow(address asset, uint256 amount) public returns (bytes memory out) { + uint256 startingGas = gasleft(); + out = lender.flash(address(loanReceiver), asset, amount, "", this.onFlashLoan); + uint256 endingGas = gasleft(); + usedGas = startingGas - endingGas - innerGas; } function flashBorrowNoPointers(address asset, uint256 amount) public returns (bytes memory) { diff --git a/test/MorphoBlueWrapper.t.sol b/test/MorphoBlueWrapper.t.sol index 47105e4..ecfddff 100644 --- a/test/MorphoBlueWrapper.t.sol +++ b/test/MorphoBlueWrapper.t.sol @@ -85,6 +85,8 @@ contract MorphoBlueWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Morpho Blue: ", borrower.usedGas()); } function test_onMorphoFlashLoan_permissions() public { diff --git a/test/PermissionedAaveWrapper.v3.t.sol b/test/PermissionedAaveWrapper.v3.t.sol index c8a08c6..5081fe2 100644 --- a/test/PermissionedAaveWrapper.v3.t.sol +++ b/test/PermissionedAaveWrapper.v3.t.sol @@ -86,6 +86,8 @@ contract PermissionedAaveWrapperTest is Test { assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we // borrowed assertEq(borrower.flashFee(), fee); + + console2.log("Aave v3 (Permissioned): ", borrower.usedGas()); } function test_executeOperation_permissions() public { diff --git a/test/SiloWrapper.t.sol b/test/SiloWrapper.t.sol index f7aa3d1..75c974a 100644 --- a/test/SiloWrapper.t.sol +++ b/test/SiloWrapper.t.sol @@ -105,6 +105,8 @@ contract SiloWrapperTest is Test { assertEq(borrower.flashFee(), fee); assertEq(intermediateToken.balanceOf(address(wrapper)), dust - 1, "Too much dust spent"); + + console2.log("Silo: ", borrower.usedGas()); } function test_receiveFlashLoan_permissions() public { diff --git a/test/SolidlyWrapper.t.sol b/test/SolidlyWrapper.t.sol index 73a18ee..a7f1ae5 100644 --- a/test/SolidlyWrapper.t.sol +++ b/test/SolidlyWrapper.t.sol @@ -92,6 +92,8 @@ contract SolidlyWrapperTest is Test { // The amount we transferred to pay for fees, plus the amount we borrowed assertEq(borrower.flashBalance(), loan + fee, "flashBalance"); assertEq(borrower.flashFee(), fee, "flashFee"); + + console2.log("Solidly: ", borrower.usedGas()); } function test_SolidlyFlashCallback_permissions() public { diff --git a/test/UniswapV3Wrapper.t.sol b/test/UniswapV3Wrapper.t.sol index 1a67364..f3082cd 100644 --- a/test/UniswapV3Wrapper.t.sol +++ b/test/UniswapV3Wrapper.t.sol @@ -98,6 +98,8 @@ contract UniswapV3WrapperTest is Test { // The amount we transferred to pay for fees, plus the amount we borrowed assertEq(borrower.flashBalance(), loan + fee, "flashBalance"); assertEq(borrower.flashFee(), fee, "flashFee"); + + console2.log("Uniswap v3: ", borrower.usedGas()); } function test_uniswapV3FlashCallback_permissions() public {