# BathToken.sol#_deposit() attacker can mint more shares with re-entrancy from hookable tokens

BathToken._deposit lacks a reentrancy guard; an ERC777 tokensToSend hook re-enters deposit so the balance-delta share calculation double-counts, minting inflated shares.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: WatchPug
- Disclosed: 2022-08-01
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-05-rubicon-findings/issues/350
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-rubicon%3AH-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:reentrancy vuln:share-inflation

**Target:** BathToken.sol _deposit() share-minting via underlyingToken.transferFrom
**Root cause:** _deposit computes shares from the balance delta (after - before) around transferFrom without a reentrancy guard; a hookable token's callback re-enters before the outer call's balance snapshot resolves, so the inner deposit's funds are counted again in the outer delta.
**Steps:**
1. Deploy attacker contract implementing ERC777TokensSender.tokensToSend that calls BathToken.deposit(1000e18) on first invocation.
2. Call deposit(1) on BathToken with an ERC777 underlying token; preBalance=100000e18.
3. transferFrom triggers tokensToSend hook; re-enter deposit(1000e18): preBalance=100000e18, transfer 1000e18, postBalance=101000e18, assets=1000e18, mint 1000 shares.
4. Outer call resumes: postBalance=101000e18+1, assets=(101000e18+1)-100000e18=1000e18+1, mint another 1000 shares.
5. Net: 1+1000e18 transferred mints 2000e18 worth of shares.
**How found:** Code review of _deposit's balance-delta accounting (before/after balanceOf around transferFrom) combined with knowledge that ERC777 tokensToSend fires before balances update, enabling re-entry into the unguarded function.
**Exploitation:** Attacker deposits a tiny amount with a hookable (ERC777-style) underlying token; the tokensToSend callback re-enters deposit with a larger amount, and the outer call's balance-delta recomputation counts the inner deposit's funds again, minting roughly double the shares for the capital deposited, diluting existing LPs.
**Insight:** When share/asset accounting uses before/after balanceOf deltas around an external transferFrom, any token with a pre-transfer callback (ERC777, ERC1363, hooks) lets an attacker re-enter and have the inner transfer counted in the outer delta; check every delta-based accounting path for missing nonReentrant.
