# Reentrancy in depositBribeERC20 function

Reentrancy in BribeVault.depositBribeERC20 lets a DEPOSITOR_ROLE contract inflate a bribe's recorded amount to uint max via a malicious token, stealing vault funds.

- Payout: Audit contest
- Severity: medium
- Program: Redacted Cartel
- Found by: Czar102
- Disclosed: 2022-05-11
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2022-02-redacted-cartel#m-13
- Library page: http://bugbountylibrary.com/r/c4%3A2022-02-redacted-cartel%3AM-13
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:accounting-error vuln:reentrancy

**Target:** BribeVault.depositBribeERC20 (Solidity contract)
**Root cause:** The bribe token is registered in storage only after transferFrom, so a reentrant call with the same bribeIdentifier passes checks before the first token is recorded, and the outer call then adds the transfer amount to the inner-set amount.
**Steps:**
1. Attacker contract holds DEPOSITOR_ROLE and deploys a dummy token whose transferFrom reenters depositBribeERC20.
2. First call: novel bribeIdentifier, token=dummy, amount=uint(-2); checks pass, transferFrom triggers attacker reentry.
3. Reentrant call: same bribeIdentifier, 1 wei of a valuable token; token not yet registered so checks pass, transfer succeeds, amount set to 1 wei and token saved.
4. Return to outer call: amount incremented by transfer value, pushing b.amount to max uint; token nonzero so check passes.
5. Withdraw the bribe to drain all vault funds.
**How found:** Code reading of depositBribeERC20 spotted an external call to a caller-supplied address (line 187) before the token was persisted to storage, indicating a reentrancy window on bribeIdentifier.
**Exploitation:** A permissioned depositor contract uses a malicious token to reenter with the same bribeIdentifier, setting the stored amount to 1 wei then adding the outer transfer value to reach uint max, granting itself the entire vault balance for that bribe.
**Insight:** When a mapping keyed by an identifier is written only after an external transferFrom, a reentrant call with the same identifier sees stale state; check whether the post-call arithmetic (amount += transfer) can be weaponized to inflate balances.

