From 592cf9dea61bee0422645e7739fffcc4dbd95e83 Mon Sep 17 00:00:00 2001 From: miyachen Date: Fri, 9 Aug 2024 12:02:54 +0800 Subject: [PATCH 1/7] add foundry test --- .github/workflows/testing.yml | 2 ++ foundry.toml | 7 +++- .../immunefi/34300.InvalidWithdrawal.t.sol | 36 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/foundry/immunefi/34300.InvalidWithdrawal.t.sol diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index dd60f60f..84e4cf3a 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -124,6 +124,8 @@ jobs: run: npm run foundry-build-uniswap - name: Run tests + env: + OPTIMISM_WEB3_ENDPOINT_ARCHIVE: ${{ vars.OPTIMISM_WEB3_ENDPOINT_ARCHIVE }} # For fork tests run: npm run foundry-test - name: Run snapshot diff --git a/foundry.toml b/foundry.toml index 5ed6f6a9..f327c8f0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -7,4 +7,9 @@ cache_path = 'forge-cache' no_match_path = 'contracts/test/*' fs_permissions = [{ access = "read", path = "./out"}] -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file +# See more config options https://github.com/foundry-rs/foundry/tree/master/config + +[rpc_endpoints] +# All available network keywords: +# https://github.com/foundry-rs/forge-std/blob/ff4bf7db008d096ea5a657f2c20516182252a3ed/src/StdCheats.sol#L255-L271 +optimism = "${OPTIMISM_WEB3_ENDPOINT_ARCHIVE}" \ No newline at end of file diff --git a/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol b/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol new file mode 100644 index 00000000..44b2272a --- /dev/null +++ b/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.7.6; + +import "forge-std/Test.sol"; +import "../../../contracts/Vault.sol"; +import "../../../contracts/test/TestERC20.sol"; + +contract InvalidWithdrawalTest is Test { + uint256 forkBlock = 105_302_472; // Optimiam mainnet @ Thu Jun 8 05:55:21 UTC 2023 + + Vault vault; + TestERC20 usdc; + TestERC20 weth; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl("optimism"), forkBlock); + vault = Vault(0xAD7b4C162707E0B2b5f6fdDbD3f8538A5fbA0d60); + usdc = TestERC20(vault.getSettlementToken()); + weth = TestERC20(0x4200000000000000000000000000000000000006); + + deal(address(usdc), address(this), 1000 * 1e6, true); + } + + function test_exploit() external payable { + // Step 1: Deposit 1000 USDC into the Vault + // Assume the attacker already has 1000 USDC + usdc.approve(address(vault), 1000 * 1e6); // Approve Vault to spend USDC + vault.deposit(address(usdc), 1000 * 1e6); // Deposit 1000 USDC + assertEq(vault.getBalanceByToken(address(this), address(usdc)), 1000 * 1e6); + assertEq(vault.getBalanceByToken(address(this), address(weth)), 0); + + // Step 2: Withdraw 1 wei + vm.expectRevert("V_NEFC"); + vault.withdrawEther(1); // Attempt to withdraw 1 wei + } +} From 375af56129ba80510a65958fa0cfe3ead90ebb9c Mon Sep 17 00:00:00 2001 From: miyachen Date: Fri, 9 Aug 2024 15:04:24 +0800 Subject: [PATCH 2/7] enable unchecked_cheatcode_artifacts --- foundry.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/foundry.toml b/foundry.toml index f327c8f0..cd849bbd 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,6 +6,7 @@ test = 'test/foundry' cache_path = 'forge-cache' no_match_path = 'contracts/test/*' fs_permissions = [{ access = "read", path = "./out"}] +unchecked_cheatcode_artifacts = true # See more config options https://github.com/foundry-rs/foundry/tree/master/config From b0af9914e5cf2a2094944252ccf992394c199e15 Mon Sep 17 00:00:00 2001 From: miyachen Date: Fri, 9 Aug 2024 17:55:01 +0800 Subject: [PATCH 3/7] to resolve outOfGas in foundry tests --- foundry.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/foundry.toml b/foundry.toml index cd849bbd..cf00fc89 100644 --- a/foundry.toml +++ b/foundry.toml @@ -7,6 +7,7 @@ cache_path = 'forge-cache' no_match_path = 'contracts/test/*' fs_permissions = [{ access = "read", path = "./out"}] unchecked_cheatcode_artifacts = true +gas_limit = "18446744073709551615" # See more config options https://github.com/foundry-rs/foundry/tree/master/config From 2927ef7ad08a9ecc14d6515d1b943cfef3fe33c5 Mon Sep 17 00:00:00 2001 From: miyachen Date: Mon, 12 Aug 2024 00:23:24 +0800 Subject: [PATCH 4/7] forge update --- lib/forge-std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/forge-std b/lib/forge-std index 82e6f537..bf660614 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 82e6f5376c15341629ca23098e0b32d303f44f02 +Subproject commit bf6606142994b1e47e2882ce0cd477c020d77623 From 6b8f61ede012f480dcd65bc9b5793e2ea54aba6a Mon Sep 17 00:00:00 2001 From: miyachen Date: Mon, 12 Aug 2024 00:25:38 +0800 Subject: [PATCH 5/7] fix pragma abicoder v2 --- test/foundry/base/SafeOwnable.t.sol | 1 + test/foundry/helper/Constant.sol | 1 + test/foundry/immunefi/34300.InvalidWithdrawal.t.sol | 1 + 3 files changed, 3 insertions(+) diff --git a/test/foundry/base/SafeOwnable.t.sol b/test/foundry/base/SafeOwnable.t.sol index 9922bfef..94517917 100644 --- a/test/foundry/base/SafeOwnable.t.sol +++ b/test/foundry/base/SafeOwnable.t.sol @@ -1,4 +1,5 @@ pragma solidity 0.7.6; +pragma abicoder v2; import "../../../contracts/base/SafeOwnable.sol"; import "../interface/ISafeOwnableEvent.sol"; diff --git a/test/foundry/helper/Constant.sol b/test/foundry/helper/Constant.sol index 324e8488..07ab932c 100644 --- a/test/foundry/helper/Constant.sol +++ b/test/foundry/helper/Constant.sol @@ -1,4 +1,5 @@ pragma solidity 0.7.6; +pragma abicoder v2; import "forge-std/Test.sol"; diff --git a/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol b/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol index 44b2272a..7817c9d0 100644 --- a/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol +++ b/test/foundry/immunefi/34300.InvalidWithdrawal.t.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.7.6; +pragma abicoder v2; import "forge-std/Test.sol"; import "../../../contracts/Vault.sol"; From 737e37a797fc6bc5e6311d3561b5778f7cfe5558 Mon Sep 17 00:00:00 2001 From: miyachen Date: Mon, 12 Aug 2024 01:00:07 +0800 Subject: [PATCH 6/7] add OPTIMISM_WEB3_ENDPOINT_ARCHIVE for forge snapshot --- .github/workflows/testing.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 84e4cf3a..febcc9ae 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -129,5 +129,7 @@ jobs: run: npm run foundry-test - name: Run snapshot + env: + OPTIMISM_WEB3_ENDPOINT_ARCHIVE: ${{ vars.OPTIMISM_WEB3_ENDPOINT_ARCHIVE }} # For fork tests run: forge snapshot From 58020fc2331bd73142597aed76ee2a71b10bf4b4 Mon Sep 17 00:00:00 2001 From: miyachen Date: Mon, 12 Aug 2024 11:56:59 +0800 Subject: [PATCH 7/7] add comments for foundry config --- foundry.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/foundry.toml b/foundry.toml index cf00fc89..3bb49a54 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,7 +6,12 @@ test = 'test/foundry' cache_path = 'forge-cache' no_match_path = 'contracts/test/*' fs_permissions = [{ access = "read", path = "./out"}] + +# It's to solve vm.getCode is failed due to "No matching artifact found" error. +# https://github.com/foundry-rs/foundry/issues/7569#issuecomment-2040694197 unchecked_cheatcode_artifacts = true + +# In some foundry tests are failed due to outOfGas. gas_limit = "18446744073709551615" # See more config options https://github.com/foundry-rs/foundry/tree/master/config