# ERC777 and similar token implementations allow a stealing of funds when transferring tokens

Reentrancy via ERC777 tokensToSend hook in TokenManager._takeToken inflates balance-delta accounting, letting attacker mint extra cross-chain tokens on destination chain.

- Payout: Contest reward
- Severity: high
- Program: Axelar Network
- Credited: Jeiwan
- Disclosed: 2023-11-29
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2023-07-axelar-findings/issues/317
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AH-02
- 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

**Target:** TokenManagerLockUnlock / TokenManagerLiquidityPool _takeToken
**Root cause:** _takeToken measures transferred amount via before/after balance delta but is not reentrancy-protected; ERC777 tokensToSend hook fires before balance state update, so nested sendToken calls corrupt the delta accounting.
**Steps:**
1. Deploy malicious contract holding 200 ERC777 tokens; call `TokenManager.sendToken(100)`
2. `_takeToken` calls `transferFrom`, triggering `tokensToSend` hook on attacker contract
3. In hook, re-enter `TokenManager.sendToken(100)`; nested `_takeToken` sees delta=100 (balance not yet updated) and emits message for 100
4. Outer `_takeToken` completes, balance delta now 200, emits message for 200
5. Attacker spent 200 tokens but destination chain mints/releases 300
**How found:** Code review of _takeToken's balance-delta accounting combined with knowledge that ERC777 hooks execute before balance state updates, enabling reentrancy to double-count.
**Exploitation:** Attacker contract re-enters sendToken from the ERC777 tokensToSend hook during transferFrom; the outer balance-delta measurement captures both transfers (200) while the nested call already emitted its own 100-token message, yielding 300 tokens on destination for 200 spent.
**Insight:** When a contract derives transfer amounts from before/after balance deltas, any token with pre-balance-update hooks (ERC777 tokensToSend, ERC677, custom) lets a reentrant nested call be counted twice; check delta-based accounting for reentrancy guards.
