# Outflow fees can be bypassed by leveraging ERC7579’s withHook modifier

ERC-7579 account hooks run between Superform's preExecute and postExecute balance snapshots, letting users move redeemed assets out so outflow fees compute as zero.

- Payout: Contest reward
- Severity: medium
- Program: Superform
- Credited: Orion Security
- Disclosed: 2025-07-17
- Write-up quality: 8/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_superform_may2025.pdf#3.2.11
- Library page: https://bugbountylibrary.com/r/cantina%3Asuperform_may2025%3A3.2.11
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:fee-bypass

**Target:** BaseLedger.sol outflow fee accounting / ERC-7579 account hooks
**Root cause:** Outflow fees are derived from the balance delta measured in Superform's postExecute hook, but the account's own ERC-7579 hook (withHook modifier) executes after the redemption and before postExecute, so it can drain the account and zero the reported gain.
**Steps:**
1. Deploy a MaliciousHook implementing isModuleType(4), preCheck and postCheck.
2. Create a Nexus ERC-7579 account with the malicious hook installed via bootstrap config.
3. From the account, `approve(maliciousHook, type(uint256).max)` on the underlying token.
4. Batch through SuperformExecutor: approve, deposit4626, redeem4626 on a Morpho ERC4626 vault.
5. During redeem, withHook runs the malicious hook's postCheck which does `transferFrom(account, owner, balanceOf(account))` before Superform's postExecute.
6. postExecute sees zero balance delta, outAmount=0, fee receiver gets 0; assert fee delta == 0.
**How found:** Noticed the ordering: Superform's preExecute/postExecute balance snapshots bracket the account's withHook execution, so any code the account owner controls runs in between and can manipulate the measured balance.
**Exploitation:** Attacker self-deploys an ERC-7579 account with a custom hook, grants it infinite token approval, then performs outflow executions (e.g. ERC4626 redeem) through SuperformExecutor. The account hook fires inside withHook after assets land and sweeps them to an external wallet before Superform's postExecute balance snapshot, so the computed gain and thus the fee is zero.
**Insight:** When fee or accounting logic measures a balance delta around an external call, check whether user-controlled hooks/callbacks (ERC-7579 hooks, ERC-4337 validation, token hooks) execute inside that measurement window and can move funds before the post-snapshot.
