# `exchangeFee` can be escaped

Reentrancy through 1inch swap callback lets attacker nest a real swap inside a fake one, inflating amountReceived to reclaim the exchangeFee.

- Payout: Contest reward
- Severity: medium
- Program: Mover
- Credited: WATCHPUG
- Disclosed: 2022-10-11
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2022-10-mover-judging/issues/120
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-10-mover%3AM-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:fee-bypass vuln:reentrancy

**Target:** HardenedTopupProxy / ExchangeProxy swap flow
**Root cause:** exchangeFee is computed from the before/after balance delta of the swap call, but the swap target (1inch) can reenter CardTopupPermit, so the inner swap's received amount is counted in the outer swap's amountReceived and refunded to the user.
**Steps:**
1. Call `CardTopupPermit()` with a small swap amount routed through 1inch via `ExchangeProxy#executeSwapDirect()` (L174).
2. Inside the 1inch swap callback, reenter `HardenedTopupProxy.sol#CardTopupPermit()` and perform the real swap of $1M.
3. Inner swap completes; its `amountReceived` (including the $1000 exchangeFee) is credited.
4. Outer swap's balance-delta accounting includes the inner swap proceeds, so the fee is returned to the user instead of retained.
**How found:** Code review of the balance-delta fee accounting in HardenedTopupProxy combined with the external call to 1inch in ExchangeProxy; noticed the swap target is attacker-influenced and can reenter the fee-bearing entrypoints.
**Exploitation:** Attacker controls the swap calldata to 1inch and uses the swap callback to reenter the topup entrypoint, nesting the genuine large swap inside a decoy swap so the fee-inclusive amount is refunded.
**Insight:** When a fee or accounting value is derived from a before/after balance delta around an external call to an attacker-influenced target, that target can reenter and fold its own balance changes into the delta; check every external swap/router call for missing nonReentrant on the accounting entrypoints.
