# Risk of reward tokens being sold by malicious users under certain conditions

Curve adapters' EXACT_IN_BATCH trades skip sellToken/buyToken validation, letting attackers route arbitrary vault-held reward or Convex deposit tokens out during deposit/redeem.

- Payout: Contest reward
- Severity: high
- Program: Notional
- Credited: xiaoming90
- Disclosed: 2023-02-27
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-notional-judging/issues/13
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-notional%3AH-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:accounting-error vuln:business-logic

**Target:** CurveV2Adapter / CurveAdapter batch trade execution in leveraged vaults
**Root cause:** EXACT_IN_BATCH decodes user-supplied data.route and passes it directly to Curve's exchange_multiple/exchange without checking route[0]==sellToken or route[last]==buyToken, unlike EXACT_IN_SINGLE which pins from/to.
**Steps:**
1. Call vault deposit or redeem with a Trade of type EXACT_IN_BATCH targeting CurveV2Adapter/CurveAdapter.
2. Set exchangeData.route so _route[0] is a vault-held reward token (CRV/CVX/LDO) or Convex deposit token and last route element is the primary/secondary token.
3. Trigger _tradePrimaryForSecondary (deposit) or _sellSecondaryBalance (redeem) with minimal amount.
4. Swapped-in primary/secondary tokens inflate finalPrimaryBalance or secondaryAmount, crediting attacker more than deposited.
**How found:** Code review comparing EXACT_IN_SINGLE (from/to pinned to sellToken/buyToken) against EXACT_IN_BATCH (route fully user-controlled); then traced _approve to see the mitigating allowance constraint and reasoned about when reward tokens equal primary/secondary tokens.
**Exploitation:** Attacker races the admin's reinvest after rewards are claimed to the vault, submits a minimal deposit/redeem whose batch route swaps vault-held reward or Convex deposit tokens into primary/secondary tokens, inflating the credited balance; only works when reward token equals primary/secondary token or another exploit exists, since _approve only approves trade.sellToken.
**Escalation:** If a reward token or Convex deposit token coincides with primary/secondary token (or governance adds such a reward token), all Convex deposit tokens could be swapped away, draining the vault.
**Insight:** When an adapter has a safe single-swap path and a batch path, diff their validation: batch routes often bypass the token pinning that single swaps enforce. Also check whether the approval layer (only sellToken approved) is the sole thing preventing abuse, since that breaks if reward tokens ever equal the traded token.
