From 2e000950d9f5073bbeb0cc67c851222781e7459d Mon Sep 17 00:00:00 2001 From: Benjamin Date: Mon, 5 Feb 2024 14:18:37 +0100 Subject: [PATCH 1/2] Update readme, fix tests, add mainnet fork test --- README.md | 10 +++ script/DeployPuffETH.s.sol | 7 +- src/NoImplementation.sol | 1 - test/Integration/PufferTest.integration.t.sol | 32 ++++----- test/Integration/PufferVault.fork.t.sol | 66 +++++++++++++++++++ 5 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 test/Integration/PufferVault.fork.t.sol diff --git a/README.md b/README.md index eec6243..83460b8 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,16 @@ Upon Puffer's full mainnet launch, stETH will be withdrawn from EigenLayer and t Following the withdrawal process, the ETH will be utilized to provision decentralized Ethereum validators within the Puffer protocol. This marks a transition from Lido LST rewards to Puffer Protocol rewards. Importantly, nothing needs to be done by pufETH holders! However, as the Puffer protocol operates, pufETH value is expected to increase faster as the token now captures both PoS and restaking rewards. +## Contract addresses +- PufferVault (pufETH token): 0xD9A442856C234a39a81a089C06451EBAa4306a72 +- PufferDepositor: 0x4aA799C5dfc01ee7d790e3bf1a7C2257CE1DcefF +- AccessManager: 0x8c1686069474410E6243425f4a10177a94EBEE11 +- Timelock: 0x3C28B7c7Ba1A1f55c9Ce66b263B33B204f2126eA + +## Audits +- [BlockSec](./audits/BlockSec-pufETH-v1.pdf) +- [SlowMist](./audits/SlowMist-pufETH-v1.pdf) + # Tests Make sure you have access to a valid archive node RPC for ETH Mainnet (e.g. Infura) diff --git a/script/DeployPuffETH.s.sol b/script/DeployPuffETH.s.sol index 3ab043d..007edba 100644 --- a/script/DeployPuffETH.s.sol +++ b/script/DeployPuffETH.s.sol @@ -88,14 +88,12 @@ contract DeployPuffETH is BaseScript { vm.label(address(vaultProxy), "PufferVault"); // Deploy mock Puffer oracle - // pufferOracle = new PufferOracle(); - pufferOracle = PufferOracle(address(0)); // skip deploying it timelock = new Timelock({ accessManager: address(accessManager), communityMultisig: communityMultisig, operationsMultisig: operationsMultisig, pauser: pauserMultisig, - initialDelay: 7 days + initialDelay: 7 days + 1 }); { @@ -130,7 +128,6 @@ contract DeployPuffETH is BaseScript { vm.serializeAddress(obj, "PufferDepositorImplementation", address(pufferDepositorImplementation)); vm.serializeAddress(obj, "PufferVault", address(vaultProxy)); vm.serializeAddress(obj, "PufferVaultImplementation", address(pufferVaultImplementation)); - vm.serializeAddress(obj, "PufferOracle", address(pufferOracle)); string memory finalJson = vm.serializeString(obj, "", ""); vm.writeJson(finalJson, "./output/puffer.json"); @@ -143,7 +140,7 @@ contract DeployPuffETH is BaseScript { pufferDepositor: address(depositorProxy), pufferVault: address(vaultProxy), pufferVaultImplementation: address(pufferVaultImplementation), - pufferOracle: address(pufferOracle), + pufferOracle: address(0), stETH: stETHAddress, timelock: address(timelock) }); diff --git a/src/NoImplementation.sol b/src/NoImplementation.sol index bfba1bd..73c7358 100644 --- a/src/NoImplementation.sol +++ b/src/NoImplementation.sol @@ -4,7 +4,6 @@ pragma solidity >=0.8.0 <0.9.0; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract NoImplementation is UUPSUpgradeable { - address immutable upgrader; constructor() { diff --git a/test/Integration/PufferTest.integration.t.sol b/test/Integration/PufferTest.integration.t.sol index 484bdd7..d7530e8 100644 --- a/test/Integration/PufferTest.integration.t.sol +++ b/test/Integration/PufferTest.integration.t.sol @@ -251,7 +251,7 @@ contract PufferTest is Test { // Calldata is generated by 1inch swap api // This one is `uniswapV3SwapTo` bytes memory callData = - hex"bc80f1a8000000000000000000000000adea807ce68b17a32ce7cb80757c1b16cbca78870000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000008e080218847ef7000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006c83b0feef04139eb5520b1ce0e78069c6e7e2c58b1ccac8"; + hex"bc80f1a80000000000000000000000001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F0000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000008e080218847ef7000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006c83b0feef04139eb5520b1ce0e78069c6e7e2c58b1ccac8"; uint256 pufETH = pufferDepositor.swapAndDeposit1Inch({ amountIn: 20_000_000_000, @@ -272,7 +272,7 @@ contract PufferTest is Test { // Calldata is generated by 1inch swap api // This one is `uniswapV3SwapTo` bytes memory callData = - hex"12aa3caf000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd090000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000adea807ce68b17a32ce7cb80757c1b16cbca788700000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000829cccd01419aa7000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000001f20001c400017a00a007e5c0d200000000000000000000000000000000015600013c0001000000e60000d05120b576491f1e6e5e62f1d8f26062ee822b40b0e0d44e3fbd56cd56c3e72c1403e103b45db9da5b9d2b0044394747c50000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000829cccd01419aa9000000000000000000000000000000000000000000000000000000000000000140607f39c581f595b53c5cb19bd0b3f8da6c935e2ca00020d6bdbf787f39c581f595b53c5cb19bd0b3f8da6c935e2ca041207f39c581f595b53c5cb19bd0b3f8da6c935e2ca00004de0e9a3e00000000000000000000000000000000000000000000000000000000000000000020d6bdbf78ae7ab96520de3a18e5e111b5eaab095312d7fe8400a0f2fa6b66ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000001053999a0283354e000000000000000000072ba767a2fd9980a06c4eca27ae7ab96520de3a18e5e111b5eaab095312d7fe841111111254eeb25477b68fb85ed929f73a960582000000000000000000000000000000008b1ccac8"; + hex"12aa3caf000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd090000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd090000000000000000000000001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F00000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000829cccd01419aa7000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000001f20001c400017a00a007e5c0d200000000000000000000000000000000015600013c0001000000e60000d05120b576491f1e6e5e62f1d8f26062ee822b40b0e0d44e3fbd56cd56c3e72c1403e103b45db9da5b9d2b0044394747c50000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000829cccd01419aa9000000000000000000000000000000000000000000000000000000000000000140607f39c581f595b53c5cb19bd0b3f8da6c935e2ca00020d6bdbf787f39c581f595b53c5cb19bd0b3f8da6c935e2ca041207f39c581f595b53c5cb19bd0b3f8da6c935e2ca00004de0e9a3e00000000000000000000000000000000000000000000000000000000000000000020d6bdbf78ae7ab96520de3a18e5e111b5eaab095312d7fe8400a0f2fa6b66ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000001053999a0283354e000000000000000000072ba767a2fd9980a06c4eca27ae7ab96520de3a18e5e111b5eaab095312d7fe841111111254eeb25477b68fb85ed929f73a960582000000000000000000000000000000008b1ccac8"; uint256 pufETH = pufferDepositor.swapAndDeposit1Inch({ amountIn: 1000 ether, tokenIn: address(CVX), callData: callData }); @@ -282,9 +282,9 @@ contract PufferTest is Test { function test_eth_sushi_swap() public withCaller(bob) { vm.deal(bob, 1 ether); - // https://production.sushi.com/swap/v3.2?chainId=1&tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&tokenOut=0xae7ab96520de3a18e5e111b5eaab095312d7fe84&amount=1000000000000000000&maxPriceImpact=0.01&gasPrice=38676325847&to=0xAdEa807cE68B17a32cE7CB80757c1B16cBca7887&preferSushi=false + // https://production.sushi.com/swap/v3.2?chainId=1&tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&tokenOut=0xae7ab96520de3a18e5e111b5eaab095312d7fe84&amount=1000000000000000000&maxPriceImpact=0.01&gasPrice=38676325847&to=0x1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F&preferSushi=false bytes memory routeCode = - hex"0301ffff02014028DAAC072e492d34a3Afdbef0ba7e35D8b55C4C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc204C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C400AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"0301ffff02014028DAAC072e492d34a3Afdbef0ba7e35D8b55C4C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc204C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C4001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; // 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE is native ETH on 1INCH uint256 pufETH = pufferDepositor.swapAndDeposit{ value: 1 ether }({ @@ -299,9 +299,9 @@ contract PufferTest is Test { function test_eth_1inch_swap() public withCaller(bob) { vm.deal(bob, 1 ether); - // https://api.1inch.dev/swap/v5.2/1/swap?src=0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&dst=0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84&amount=1000000000000000000&from=0xAdEa807cE68B17a32cE7CB80757c1B16cBca7887&slippage=1&includeTokensInfo=true&includeProtocols=true&includeGas=true&receiver=0xAdEa807cE68B17a32cE7CB80757c1B16cBca7887&allowPartialFill=true&disableEstimate=true + // https://api.1inch.dev/swap/v5.2/1/swap?src=0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&dst=0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84&amount=1000000000000000000&from=0x1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F&slippage=1&includeTokensInfo=true&includeProtocols=true&includeGas=true&receiver=0x1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F&allowPartialFill=true&disableEstimate=true bytes memory callData = - hex"12aa3caf000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000adea807ce68b17a32ce7cb80757c1b16cbca78870000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000dbd2fc137a2fffc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000001220000f40000aa00a007e5c0d200000000000000000000000000000000000000008600006c00003000001640607f39c581f595b53c5cb19bd0b3f8da6c935e2ca00020d6bdbf787f39c581f595b53c5cb19bd0b3f8da6c935e2ca041207f39c581f595b53c5cb19bd0b3f8da6c935e2ca00004de0e9a3e00000000000000000000000000000000000000000000000000000000000000000020d6bdbf78ae7ab96520de3a18e5e111b5eaab095312d7fe8400a0f2fa6b66ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000de0b6b3a763fffc000000000000000000082908e5322eff80a06c4eca27ae7ab96520de3a18e5e111b5eaab095312d7fe841111111254eeb25477b68fb85ed929f73a9605828b1ccac8"; + hex"12aa3caf000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd09000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000e37e799d5077682fa0a244d46e5649f71457bd090000000000000000000000001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000dbd2fc137a2fffc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000001220000f40000aa00a007e5c0d200000000000000000000000000000000000000008600006c00003000001640607f39c581f595b53c5cb19bd0b3f8da6c935e2ca00020d6bdbf787f39c581f595b53c5cb19bd0b3f8da6c935e2ca041207f39c581f595b53c5cb19bd0b3f8da6c935e2ca00004de0e9a3e00000000000000000000000000000000000000000000000000000000000000000020d6bdbf78ae7ab96520de3a18e5e111b5eaab095312d7fe8400a0f2fa6b66ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000de0b6b3a763fffc000000000000000000082908e5322eff80a06c4eca27ae7ab96520de3a18e5e111b5eaab095312d7fe841111111254eeb25477b68fb85ed929f73a9605828b1ccac8"; // 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE is native ETH on 1INCH uint256 pufETH = pufferDepositor.swapAndDeposit1Inch{ value: 1 ether }({ @@ -316,7 +316,7 @@ contract PufferTest is Test { // Calldata is generated by 1inch swap api // This one is `uniswapV3SwapTo` bytes memory callData = - hex"bc80f1a8000000000000000000000000adea807ce68b17a32ce7cb80757c1b16cbca78870000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000008e080218847ef7000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006c83b0feef04139eb5520b1ce0e78069c6e7e2c58b1ccac8"; + hex"bc80f1a80000000000000000000000001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F0000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000008e080218847ef7000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006c83b0feef04139eb5520b1ce0e78069c6e7e2c58b1ccac8"; IPufferDepositor.Permit memory permit = _signPermit( _testTemps( @@ -498,9 +498,9 @@ contract PufferTest is Test { // Manually edited the route code for USDT -> stETH // Last 20 bytes is the address of where the stETH is going - // (AdEa807cE68B17a32cE7CB80757c1B16cBca7887) is the address of PufferDepositor + // (1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F) is the address of PufferDepositor bytes memory routeCode = - hex"02dAC17F958D2ee523a2206206994597C13D831ec701ffff01c7bBeC68d12a0d1830360F8Ec58fA599bA1b0e9b004028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C400AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"02dAC17F958D2ee523a2206206994597C13D831ec701ffff01c7bBeC68d12a0d1830360F8Ec58fA599bA1b0e9b004028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C4001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; assertEq(pufferVault.balanceOf(alice), 0, "alice has 0 pufETH"); @@ -523,9 +523,9 @@ contract PufferTest is Test { // Manually edited the route code for USDC -> stETH // Last 20 bytes is the address of where the stETH is going - // (AdEa807cE68B17a32cE7CB80757c1B16cBca7887) is the address of pufferDepositor + // (1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F) is the address of pufferDepositor bytes memory routeCode = - hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C400AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C4001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; assertEq(pufferVault.balanceOf(dave), 0, "dave has 0 pufETH"); @@ -547,9 +547,9 @@ contract PufferTest is Test { // Manually edited the route code for APE -> stETH // Last 20 bytes is the address of where the stETH is going - // (AdEa807cE68B17a32cE7CB80757c1B16cBca7887) is the address of pufferDepositor + // (1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F) is the address of pufferDepositor bytes memory routeCode = - hex"024d224452801ACEd8B2F0aebE155379bb5D59438101ffff00130F4322e5838463ee460D5854F5D472cFC8f25301e43D6AAFce76f53670C4b7D6B38A7D8a67a4B67004C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc200e43D6AAFce76f53670C4b7D6B38A7D8a67a4B67000AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"024d224452801ACEd8B2F0aebE155379bb5D59438101ffff00130F4322e5838463ee460D5854F5D472cFC8f25301e43D6AAFce76f53670C4b7D6B38A7D8a67a4B67004C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc200e43D6AAFce76f53670C4b7D6B38A7D8a67a4B670001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; assertEq(pufferVault.balanceOf(charlie), 0, "charlie has 0 pufETH"); @@ -636,9 +636,9 @@ contract PufferTest is Test { // Manually edited the route code for USDC -> stETH // Last 20 bytes is the address of where the stETH is going - // (AdEa807cE68B17a32cE7CB80757c1B16cBca7887) is the address of pufferDepositor + // (1bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F) is the address of pufferDepositor bytes memory routeCode = - hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C400AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C4001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; assertEq(pufferVault.balanceOf(bob), 0, "bob has 0 pufETH"); @@ -673,7 +673,7 @@ contract PufferTest is Test { uint256 tokenInAmount = 10_000_000_000; // 10k USDC bytes memory routeCode = - hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C400AdEa807cE68B17a32cE7CB80757c1B16cBca7887"; + hex"02A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4801ffff0188e6A0c2dDD26FEEb64F039a2c41296FcB3f5640014028DAAC072e492d34a3Afdbef0ba7e35D8b55C404C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2004028DAAC072e492d34a3Afdbef0ba7e35D8b55C4001bA145F1BE82d7285FFfAee5f79dc7744ffD0a9F"; assertEq(pufferVault.balanceOf(bob), 0, "bob has 0 pufETH"); diff --git a/test/Integration/PufferVault.fork.t.sol b/test/Integration/PufferVault.fork.t.sol new file mode 100644 index 0000000..9f9ffb7 --- /dev/null +++ b/test/Integration/PufferVault.fork.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.8.0 <0.9.0; + +import { Test } from "forge-std/Test.sol"; +import { PufferDepositor } from "../../src/PufferDepositor.sol"; +import { IStETH } from "../../src/interface/Lido/IStETH.sol"; +import { IEigenLayer } from "src/interface/EigenLayer/IEigenLayer.sol"; +import { stdStorage, StdStorage } from "forge-std/Test.sol"; +import { PufferVault } from "src/PufferVault.sol"; +import { AccessManager } from "openzeppelin/access/manager/AccessManager.sol"; +import { IStETH } from "src/interface/Lido/IStETH.sol"; +import { IEigenLayer } from "src/interface/EigenLayer/IEigenLayer.sol"; +import { IStrategy } from "src/interface/EigenLayer/IStrategy.sol"; +import { Timelock } from "src/Timelock.sol"; + +contract PufferMainnetTest is Test { + /** + * @dev Ethereum Mainnet addresses + */ + IStrategy internal constant _EIGEN_STETH_STRATEGY = IStrategy(0x93c4b944D05dfe6df7645A86cd2206016c51564D); + IEigenLayer internal constant _EIGEN_STRATEGY_MANAGER = IEigenLayer(0x858646372CC42E1A627fcE94aa7A7033e7CF075A); + IStETH internal constant _ST_ETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); + + PufferDepositor public pufferDepositor; + PufferVault public pufferVault; + AccessManager public accessManager; + Timelock public timelock; + + address alice = makeAddr("alice"); + + address COMMUNITY_MULTISIG; + address OPERATIONS_MULTISIG; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl("mainnet")); + + _setupContracts(); + } + + function _setupContracts() internal { + pufferDepositor = PufferDepositor(payable(0x4aA799C5dfc01ee7d790e3bf1a7C2257CE1DcefF)); + pufferVault = PufferVault(payable(0xD9A442856C234a39a81a089C06451EBAa4306a72)); + accessManager = AccessManager(payable(0x8c1686069474410E6243425f4a10177a94EBEE11)); + timelock = Timelock(payable(0x3C28B7c7Ba1A1f55c9Ce66b263B33B204f2126eA)); + + COMMUNITY_MULTISIG = timelock.COMMUNITY_MULTISIG(); + OPERATIONS_MULTISIG = timelock.OPERATIONS_MULTISIG(); + + vm.label(COMMUNITY_MULTISIG, "COMMUNITY_MULTISIG"); + vm.label(OPERATIONS_MULTISIG, "OPERATIONS_MULTISIG"); + vm.label(address(_ST_ETH), "stETH"); + vm.label(address(_EIGEN_STETH_STRATEGY), "Eigen stETH strategy"); + } + + function test_el_stETH_deposit() public { + uint256 exchangeRateBefore = pufferVault.previewDeposit(1 ether); + + vm.startPrank(OPERATIONS_MULTISIG); + + pufferVault.depositToEigenLayer(1000 ether); + + uint256 exchangeRateAfterDeposit = pufferVault.previewDeposit(1 ether); + + assertEq(exchangeRateBefore, exchangeRateAfterDeposit, "exchange rate must not change after the deposit to EL"); + } +} From 49eee6023a9a1771d0da99887595fc312447abd2 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Mon, 5 Feb 2024 14:22:01 +0100 Subject: [PATCH 2/2] linter fix --- src/NoImplementation.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NoImplementation.sol b/src/NoImplementation.sol index 73c7358..3972faf 100644 --- a/src/NoImplementation.sol +++ b/src/NoImplementation.sol @@ -11,6 +11,7 @@ contract NoImplementation is UUPSUpgradeable { } function _authorizeUpgrade(address newImplementation) internal virtual override { + // solhint-disable-next-line custom-errors require(msg.sender == upgrader, "Unauthorized"); // anybody can steal this proxy }