# DOS set token through erc777 hook

wfCash ERC777 tokensToSend hook re-enters SetToken during issuance, letting attacker sync stale totalSupply and replay manager payload to remove a module, bricking issue/redeem.

- Payout: Contest reward
- Severity: medium
- Program: Notional
- Credited: jonah1005
- Disclosed: 2022-07-18
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-06-notional-coop-findings/issues/168
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-notional-coop%3AM-08
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained vuln:accounting-error vuln:dos vuln:reentrancy

**Target:** SetToken DebtIssuanceModule / wfCash ERC777 token
**Root cause:** wfCash is an ERC777 token whose tokensToSend hook executes attacker code mid-issuance, after components are pulled but before totalSupply is minted; nonReentrant is per-contract and does not block cross-module reentrancy.
**Steps:**
1. Deploy attacker contract; register as ERC1820 tokensToSend implementer via `_ERC1820_REGISTRY.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, address(this))`
2. Approve cToken and wfCash to issueModule; call `issueModule.issue(setToken, _amount, address(this))`
3. In `tokensToSend` hook (totalSupply still 100, cDAI=110, wfCash=110), call `compoundModule.sync(setToken, false)` to update DefaultUnit using inflated balance/totalSupply ratio
4. In same hook, replay manager multisig payload `manager.removeModule(address(setToken))` to remove CompoundLeverageModule
5. SetToken now reverts `undercollateralized` on issue/redeem and setValuer returns pumped valuation
**How found:** Code review of DebtIssuanceModule issuance ordering (pull tokens before mint) combined with knowledge that wfCash is ERC777 and that nonReentrant is not cross-contract; hypothesized hook executes with stale totalSupply and that manager payloads can be replayed inside the hook.
**Exploitation:** Attacker front-runs the manager multisig's removeModule transaction, issues a small amount of setToken to enter the ERC777 tokensToSend hook, syncs CompoundLeverageModule while balances exceed totalSupply, then replays the manager's removeModule payload during the hook to permanently desync accounting and brick issuance/redemption.
**Escalation:** Chains cross-contract reentrancy with front-running/replay of a privileged manager transaction; different module combinations yield different exploit paths.
**Insight:** When a SetToken/portfolio holds an ERC777 or hook-bearing token, the issuance flow pulls components before minting supply — any module reading balanceOf/totalSupply during that window (e.g. sync/DefaultUnit) can be poisoned; also check whether privileged manager calldata can be replayed inside a hook to bypass timing assumptions.
