From aa6009fd0eb99620370334e75c9b9c8cd33f7d05 Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:32:12 +0100 Subject: [PATCH] Deploy ERC3156Wrapper to Ethereum --- .forge-snapshots/MakerDAO.snap | 2 +- README.md | 57 +++++++++++++++++----------------- script/ERC3156Deploy.s.sol | 57 ++++++++++++++++++++++++++++++++++ test/ERC3156Wrapper.t.sol | 26 ++++++++++++++-- test/UniswapV3Wrapper.t.sol | 2 +- 5 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 script/ERC3156Deploy.s.sol diff --git a/.forge-snapshots/MakerDAO.snap b/.forge-snapshots/MakerDAO.snap index d4f3e71..d405883 100644 --- a/.forge-snapshots/MakerDAO.snap +++ b/.forge-snapshots/MakerDAO.snap @@ -1 +1 @@ -313302 \ No newline at end of file +279102 \ No newline at end of file diff --git a/README.md b/README.md index 1e88d2e..1db367c 100644 --- a/README.md +++ b/README.md @@ -27,34 +27,35 @@ repayment approval. ## Deployments -| Lender | Address | Networks | Gas | Fees | Contract | -| ---------------------- | ------------------------------------------ | ------------------------------------------------- | ------- | -------- | --------------------------------------------------------------- | -| Aave v2 | | | 262190 | 0.05% | [AaveWrapper](src/aave/AaveWrapper.sol) | -| Aave v3 | 0x9D4D2C08b29A2Db1c614483cd8971734BFDCC9F2 | Arbitrum One, Optimism, Polygon | 212569 | 0.05% | [AaveWrapper](src/aave/AaveWrapper.sol) | -| Aave v3 (Permissioned) | 0x0c86c636ed5593705b5675d370c831972C787841 | Ethereum, Gnosis | 229742 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | -| Aerodrome | 0x69b6E55f00d908018E2D745c524995bc231D762b | Base | 163919 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | -| Balancer v2 | 0x9E092cb431e5F1aa70e47e052773711d2Ba4917E | Ethereum, Arbitrum One, Optimism, Polygon, Gnosis | 113032 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | -| Balancer v2 | 0xD534400B0555F8441c5a3e0E9e585615B54fB2F4 | Base | 113032 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | -| Balancer + Compound v2 | | | 836719 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | -| Balancer + Moonwell | 0x6207ec38da68902CC60D3760c9fe3EB64B426207 | Base | 1183309 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | -| Balancer + Pendle | 0xC1Ea6a6df39D991006b39706db7C51f5A1819da7 | Arbitrum One | 525422 | 0 | [BalancerPendleWrapper](src/pendle/BalancerPendleWrapper.sol) | -| Balancer + Silo | 0x0F9104Fec1a5C91e63632E215e8F5c57C8f32c77 | Arbitrum One | 1025824 | 1 | [SiloWrapper](src/silo/SiloWrapper.sol) | -| Balancer + Silo | 0xAa8F3BF0C9e1aD581547D9803066084E57907a33 | Optimism | 1025824 | 1 | [SiloWrapper](src/silo/SiloWrapper.sol) | -| Camelot | 0x5E8820B2832aD8451f65Fa2CCe2F3Cef29016D0d | Arbitrum One | 80679 | 0.01% | [AlgebraWrapper](src/algebra/AlgebraWrapper.sol) | -| Camelot + Pendle | 0xC9d66F655b7B35A2B4958bE2FB58E472736Bbc47 | Arbitrum One | 506792 | 0.01% | [AlgebraPendleWrapper](src/pendle/AlgebraPendleWrapper.sol) | -| Dolomite | 0x54F1ce5E6bdf027C9a6016C9F52fC5A445b77ed6 | Arbitrum One | 459815 | 0 | [DolomiteWrapper](src/dolomite/DolomiteWrapper.sol) | -| Gnosis Safe | | | 109223 | Variable | [GnosisSafeWrapper](src/gnosisSafe/GnosisSafeWrapper.sol) | -| MakerDAO | | | 313172 | 0 | [ERC3156Wrapper](src/erc3156/ERC3156Wrapper.sol) | -| MorphoBlue | 0xa0Cb4e1222d813D6e4dE79f2A7A0B7759209588F | Ethereum | 132114 | 0 | [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | -| MorphoBlue | 0xd0953257A5a2603Bf9fCA8aF1F2ecdac60EB8F52 | Base | 132114 | 0 | [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | -| MorphoBlue + Pendle | 0xE1f9e06006B2592dDe5b1bBA3ae2DD34DF557007 | Ethereum | 558536 | 0 | [MorphoPendleWrapper](src/pendle/MorphoPendleWrapper.sol) | -| Spark | 0x8cB701df93f2Dae295aE8D7beE5Aa7e4D40CB397 | Ethereum, Gnosis | 212569 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | -| Uniswap v3 | 0x319300462C37AD2D4f26B584C2b67De51F51f289 | Arbitrum One, Polygon, Ethereum | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | -| Uniswap v3 | 0xfFD51f0631E79c39646A09318B2E18432E788B75 | Optimism | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | -| Canonical | 0x6962ba38D6493B9Ed7E0a4b74624c43D844E1438 | Optimism | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | -| Uniswap v3 + Pendle | 0xa353Fd50210786F0E038ddD574A21d0CCefb3163 | Arbitrum One | 497567 | Variable | [UniswapV3PendleWrapper](src/pendle/UniswapV3PendleWrapper.sol) | -| Velodrome | 0xcF13CDdbA3aEf757c52466deC310F221e06238d6 | Optimism | 163919 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | -| ZeroLend | 0xA48Cc0e4159C51d73B42c824f1444D1C1cbdA531 | Ethereum, Linea | 212569 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Lender | Address | Networks | Gas | Fees | Contract | +| ----------------------------- | ------------------------------------------ | ------------------------------------------------- | ------- | -------- | --------------------------------------------------------------- | +| Aave v2 | | | 262190 | 0.05% | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Aave v3 | 0x9D4D2C08b29A2Db1c614483cd8971734BFDCC9F2 | Arbitrum One, Optimism, Polygon | 212569 | 0.05% | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Aave v3 (Permissioned) | 0x0c86c636ed5593705b5675d370c831972C787841 | Ethereum, Gnosis | 229742 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Aerodrome | 0x69b6E55f00d908018E2D745c524995bc231D762b | Base | 163919 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | +| Balancer v2 | 0x9E092cb431e5F1aa70e47e052773711d2Ba4917E | Ethereum, Arbitrum One, Optimism, Polygon, Gnosis | 113032 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | +| Balancer v2 | 0xD534400B0555F8441c5a3e0E9e585615B54fB2F4 | Base | 113032 | 0 | [BalancerWrapper](src/balancer/BalancerWrapper.sol) | +| Balancer + Compound v2 | | | 836719 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | +| Balancer + Moonwell | 0x6207ec38da68902CC60D3760c9fe3EB64B426207 | Base | 1183309 | 0 | [CompoundWrapper](src/compound/CompoundWrapper.sol) | +| Balancer + Pendle | 0xC1Ea6a6df39D991006b39706db7C51f5A1819da7 | Arbitrum One | 525422 | 0 | [BalancerPendleWrapper](src/pendle/BalancerPendleWrapper.sol) | +| Balancer + Silo | 0x0F9104Fec1a5C91e63632E215e8F5c57C8f32c77 | Arbitrum One | 1025824 | 1 | [SiloWrapper](src/silo/SiloWrapper.sol) | +| Balancer + Silo | 0xAa8F3BF0C9e1aD581547D9803066084E57907a33 | Optimism | 1025824 | 1 | [SiloWrapper](src/silo/SiloWrapper.sol) | +| Camelot | 0x5E8820B2832aD8451f65Fa2CCe2F3Cef29016D0d | Arbitrum One | 80679 | 0.01% | [AlgebraWrapper](src/algebra/AlgebraWrapper.sol) | +| Camelot + Pendle | 0xC9d66F655b7B35A2B4958bE2FB58E472736Bbc47 | Arbitrum One | 506792 | 0.01% | [AlgebraPendleWrapper](src/pendle/AlgebraPendleWrapper.sol) | +| Dolomite | 0x54F1ce5E6bdf027C9a6016C9F52fC5A445b77ed6 | Arbitrum One | 459815 | 0 | [DolomiteWrapper](src/dolomite/DolomiteWrapper.sol) | +| Gnosis Safe | | | 109223 | Variable | [GnosisSafeWrapper](src/gnosisSafe/GnosisSafeWrapper.sol) | +| MakerDAO | | | 313172 | 0 | [ERC3156Wrapper](src/erc3156/ERC3156Wrapper.sol) | +| MorphoBlue | 0xa0Cb4e1222d813D6e4dE79f2A7A0B7759209588F | Ethereum | 132114 | 0 | [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | +| MorphoBlue | 0xd0953257A5a2603Bf9fCA8aF1F2ecdac60EB8F52 | Base | 132114 | 0 | [MorphoBlueWrapper](src/morpho/MorphoBlueWrapper.sol) | +| MorphoBlue + Pendle | 0xE1f9e06006B2592dDe5b1bBA3ae2DD34DF557007 | Ethereum | 558536 | 0 | [MorphoPendleWrapper](src/pendle/MorphoPendleWrapper.sol) | +| Spark | 0x8cB701df93f2Dae295aE8D7beE5Aa7e4D40CB397 | Ethereum, Gnosis | 212569 | 0 | [AaveWrapper](src/aave/AaveWrapper.sol) | +| Uniswap v3 | 0x319300462C37AD2D4f26B584C2b67De51F51f289 | Arbitrum One, Polygon, Ethereum | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | +| Uniswap v3 | 0xfFD51f0631E79c39646A09318B2E18432E788B75 | Optimism | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | +| Canonical | 0x6962ba38D6493B9Ed7E0a4b74624c43D844E1438 | Optimism | 94720 | Variable | [UniswapV3Wrapper](src/uniswapV3/UniswapV3Wrapper.sol) | +| Uniswap v3 + Pendle | 0xa353Fd50210786F0E038ddD574A21d0CCefb3163 | Arbitrum One | 497567 | Variable | [UniswapV3PendleWrapper](src/pendle/UniswapV3PendleWrapper.sol) | +| Velodrome | 0xcF13CDdbA3aEf757c52466deC310F221e06238d6 | Optimism | 163919 | Variable | [SolidlyWrapper](src/solidly/SolidlyWrapper.sol) | +| ZeroLend | 0xA48Cc0e4159C51d73B42c824f1444D1C1cbdA531 | Ethereum, Linea | 212569 | Variable | [AaveWrapper](src/aave/AaveWrapper.sol) | +| ERC3156 (DAI, GHO, FlashMint) | 0x255bAFe2122722FC35E33cd503f4f0E722AB98fC | Ethereum | 279102 | Variable | [AaveWrapper](src/erc3156/ERC3156Wrapper.sol) | 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 diff --git a/script/ERC3156Deploy.s.sol b/script/ERC3156Deploy.s.sol new file mode 100644 index 0000000..6c39241 --- /dev/null +++ b/script/ERC3156Deploy.s.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.19 <=0.9.0; + +import { Script } from "forge-std/Script.sol"; + +import { console2 } from "forge-std/console2.sol"; + +import "./Network.sol"; + +import { ERC3156Wrapper, IERC3156FlashLender } from "../src/erc3156/ERC3156Wrapper.sol"; + +/// @dev See the Solidity Scripting tutorial: https://book.getfoundry.sh/tutorials/solidity-scripting +contract ERC3156Deploy is Script { + bytes32 public constant SALT = keccak256("ultrasecr.eth"); + + struct Deployment { + Network network; + address[] assets; + IERC3156FlashLender[] lenders; + } + + Deployment[] public deployments; + + constructor() { + address[] memory assets = new address[](2); + assets[0] = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + assets[1] = 0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f; + IERC3156FlashLender[] memory lenders = new IERC3156FlashLender[](2); + lenders[0] = IERC3156FlashLender(0x60744434d6339a6B27d73d9Eda62b6F66a0a04FA); + lenders[1] = IERC3156FlashLender(0xb639D208Bcf0589D54FaC24E655C79EC529762B8); + deployments.push(Deployment(MAINNET, assets, lenders)); + } + + function run() public { + console2.log("Deploying as %s", msg.sender); + + Network network = currentNetwork(); + + for (uint256 i = 0; i < deployments.length; i++) { + Deployment memory deployment = deployments[i]; + if (deployment.network != network) continue; + + require(deployment.assets.length == deployment.lenders.length, "Arrays must be the same length"); + + vm.broadcast(); + ERC3156Wrapper wrapper = new ERC3156Wrapper{ salt: SALT }(deployment.assets, deployment.lenders); + + // Belt and braces + for (uint256 j = 0; j < deployment.assets.length; j++) { + require(wrapper.maxFlashLoan(deployment.assets[j]) > 0, "Max flash loan is zero"); + require(wrapper.flashFee(deployment.assets[j], 1e18) == 0, "Fee is not zero"); + } + + console2.log("Deployed ERC3156Wrapper at %s", address(wrapper)); + } + } +} diff --git a/test/ERC3156Wrapper.t.sol b/test/ERC3156Wrapper.t.sol index 9f66bde..2e7064f 100644 --- a/test/ERC3156Wrapper.t.sol +++ b/test/ERC3156Wrapper.t.sol @@ -29,7 +29,7 @@ contract ERC3156WrapperTest is Test { revert("API_KEY_ALCHEMY variable missing"); } - vm.createSelectFork({ urlOrAlias: "mainnet", blockNumber: 16_428_000 }); + vm.createSelectFork({ urlOrAlias: "mainnet", blockNumber: 20_563_484 }); makerFlash = IERC3156FlashLender(0x60744434d6339a6B27d73d9Eda62b6F66a0a04FA); dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F; @@ -50,7 +50,7 @@ contract ERC3156WrapperTest is Test { function test_maxFlashLoan() external { console2.log("test_maxFlashLoan"); - assertEq(wrapper.maxFlashLoan(dai), 250_000_000.0e18, "Max flash loan not zero"); + assertEq(wrapper.maxFlashLoan(dai), 500_000_000.0e18, "Max flash loan"); } function test_flashLoan() external { @@ -81,4 +81,26 @@ contract ERC3156WrapperTest is Test { deal(address(token), address(borrower), fee); borrower.flashBorrowMeasureGas(token, loan, "MakerDAO"); } + + function test_flashMint() public { + console2.log("test_flashMint"); + address token = 0x183015a9bA6fF60230fdEaDc3F43b3D788b13e21; + uint256 loan = 1e18; + uint256 fee = wrapper.flashFee(token, loan); + deal(token, address(this), 1e18); // For fees + IERC20(token).safeTransfer(address(borrower), fee); + bytes memory result = borrower.flashBorrow(token, loan); + + // Test the return values passed through the wrapper + (bytes32 callbackReturn) = abi.decode(result, (bytes32)); + assertEq(uint256(callbackReturn), uint256(borrower.ERC3156PP_CALLBACK_SUCCESS()), "Callback failed"); + + // Test the borrower state during the callback + assertEq(borrower.flashInitiator(), address(borrower)); + assertEq(address(borrower.flashAsset()), address(token)); + assertEq(borrower.flashAmount(), loan); + assertEq(borrower.flashBalance(), loan + fee); // The amount we transferred to pay for fees, plus the amount we + // borrowed + assertEq(borrower.flashFee(), fee); + } } diff --git a/test/UniswapV3Wrapper.t.sol b/test/UniswapV3Wrapper.t.sol index 891f45d..4174561 100644 --- a/test/UniswapV3Wrapper.t.sol +++ b/test/UniswapV3Wrapper.t.sol @@ -43,7 +43,7 @@ contract UniswapV3WrapperTest is Test { Registry registry = new Registry(address(this).toArray(), address(this).toArray()); registry.set("UniswapV3Wrapper", abi.encode(address(factory), weth, usdc, usdt)); - wrapper = new UniswapV3Wrapper(registry); + wrapper = new UniswapV3Wrapper("UniswapV3Wrapper", registry); borrower = new MockBorrower(wrapper); }