# Incorrect share accounting in Redeem5115VaultHook and ApproveAndRedeem5115VaultHook When Burning from Internal Balance

Redeem5115VaultHook and ApproveAndRedeem5115VaultHook measured share deltas on the account even when burnFromInternalBalance=true, recording usedShares=0 and skipping fees and ledger updates.

- Payout: Contest reward
- Severity: medium
- Program: Superform
- Credited: 0xmechanic
- Disclosed: 2025-07-17
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_superform_may2025.pdf#3.2.9
- Library page: https://bugbountylibrary.com/r/cantina%3Asuperform_may2025%3A3.2.9
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** ERC-5115 redeem hooks (Redeem5115VaultHook, ApproveAndRedeem5115VaultHook) in Superform executor
**Root cause:** _preExecute/_postExecute compute usedShares as the delta of _getSharesBalance(account), but when burnFromInternalBalance=true the shares are burned from the vault itself, so the account balance is unchanged and the delta is zero.
**Steps:**
1. Deploy/execute a SuperExecutor op with Deposit5115VaultHook to mint shares to account.
2. Build redeem hookData via _create5115RedeemHookData with burnFromInternalBalance=true.
3. Execute Redeem5115VaultHook; _preExecute snapshots usedShares=_getSharesBalance(account).
4. _postExecute recomputes _getSharesBalance(account) which is unchanged, so usedShares=0 while outAmount is correct.
5. Observe BaseLedger._updateAccounting receives usedShares=0, amountAssets=0, no fee charged, usersAccumulatorShares and usersAccumulatorCostBasis not updated.
**How found:** Code reading of the hook's _preExecute/_postExecute share-delta pattern against the ERC-5115 redeem() semantics, noticing the burn source differs from the account parameter when burnFromInternalBalance is set.
**Exploitation:** Not weaponized; a user simply redeems with burnFromInternalBalance=true to avoid protocol fees and desynchronize the ledger's share-usage/cost-basis accounting.
**Insight:** When a hook measures state deltas to infer consumed amounts, verify which address actually mutates state for every flag combination in the calldata layout — flags like burnFromInternalBalance silently redirect the burn source away from the tracked account.
