A direct transfer moves the share price, and deposit accepts zero shares
- input-1/SaltmarshVault.sol:44-50
- input-1/SaltmarshVault.sol:58-60
- Impact
The first depositor takes the next deposit in full. Bound: any deposit smaller than the balance donated to the vault.
- Observed
totalAssets()returns the vault’s raw token balance (lines 58-60). A plain transfer raises it.depositdivides by that balance at line 46 and rounds down. Nothing rejectsshares == 0.- The attacker deposits 1 unit into the empty vault for 1 share, then transfers 10,000 USDC to the vault.
- A victim deposits 9,999 USDC.
9_999e6 * 1 / (10_000e6 + 1)is 0 shares. The attacker redeems 1 share for the whole balance.
input-1/SaltmarshVault.sol44–50 function deposit(uint256 assets, address receiver) external returns (uint256 shares) { uint256 supply = totalSupply(); shares = supply == 0 ? assets : (assets * supply) / totalAssets(); asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); }- Counterargument
The deployer seeds the vault in the deployment script, so it is never empty.
OpenNo deployment script was supplied. Lines 44-50 hold no minimum-share check and no dead shares.
- Evidence gap
- The deployment script, or the transaction of the first deposit.
- Next
Run the test, then read the deployment script for a seed deposit.