# Reentrancy may allow an admin to steal funds

Reentrant ERC777 token lets an admin recursively call withdrawAdmin before balance updates, draining tokens reserved for active vestings.

- Payout: Contest reward
- Severity: medium
- Program: VTVL
- Credited: Czar102
- Disclosed: 2022-11-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-09-vtvl-findings/issues/6
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-vtvl%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:reentrancy

**Target:** VTVLVesting.sol withdrawAdmin function
**Root cause:** withdrawAdmin computes surplus from tokenAddress.balanceOf minus numTokensReservedForVesting but performs the external safeTransfer before the balance decreases; a reentrant token callback re-enters while balance is stale.
**Steps:**
1. Deploy/use a reentrant token (e.g. ERC777) as tokenAddress.
2. Admin sends 100k tokens to contract, creating surplus.
3. Admin calls `withdrawAdmin(100k)`; during safeTransfer the token callback re-enters `withdrawAdmin(100k)`.
4. Balance still unchanged, so require passes again; repeat recursively ~11 times to drain $1m of reserved vestings.
**How found:** Code reading of withdrawAdmin: noted surplus check depends on live token balance and external transfer occurs before any state change, so a reentrant token could re-enter with stale balance.
**Exploitation:** Admin with surplus deposits recursively re-enters withdrawAdmin via malicious token transfer hook before balance decrement, extracting tokens backing active vestings and leaving contract insolvent.
**Insight:** When a solvency check reads token.balanceOf directly and the transfer is the only balance mutation, any reentrant token hook re-enters with the pre-transfer balance; check whether reserved-liability accounting relies on live balance rather than internal counters.
