# _checkAndLockForSuperPosition() works incorrectly with EthenaUnstakeHook

EthenaUnstakeHook sets spToken to the vault share address instead of the received asset, so _checkAndLockForSuperPosition approves the wrong token and the follow-up bridge hook reverts.

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

**Target:** Superform hook executor / EthenaUnstakeHook cross-chain position locking
**Root cause:** EthenaUnstakeHook is an outflow hook receiving the underlying asset, but _preExecute assigns spToken = yieldSource (share token) rather than asset, so the approval in _checkAndLockForSuperPosition targets the wrong token.
**Steps:**
1. Read SuperBaseExecutor._processHook: after postExecute and _updateAccounting it calls _checkAndLockForSuperPosition(account, hook).
2. Note _checkAndLockForSuperPosition reads vaultBank, dstChainId, spToken, outAmount from the hook and executes `spToken.approve(vaultBank, outAmount)`.
3. Compare deposit hooks: spToken is the share token and outAmount is shares received, consistent with the approval.
4. Inspect EthenaUnstakeHook._preExecute: `spToken = yieldSource` while `outAmount` is the USDe asset amount received.
5. Trigger an unstake followed by a bridge hook; the bridge pulls the asset but approval was granted on the share token, so the transfer reverts.
6. Fix: set `spToken = asset` in EthenaUnstakeHook._preExecute (PR 607).
**How found:** Code-reading comparison of the outflow hook EthenaUnstakeHook against deposit hooks: noticed outAmount tracked the asset balance while spToken was still assigned the yield source/share address, making the downstream approve target inconsistent.
**Insight:** When a shared finalizer derives token/amount from hook state, audit each hook implementation for whether it is inflow or outflow and whether its spToken/outAmount pair refers to the same token; mismatched pairs silently break approvals.
