# Curve LP staking allows adding false tokensIn to account by setting _claim_rewards to false

Curve/Balancer LP staking controllers add reward tokens to a user's tokensIn array whenever the full deposit/withdraw signature is used, even with _claim_rewards=false, corrupting account accounting.

- Payout: Contest reward
- Severity: medium
- Program: Sentiment
- Credited: obront
- Disclosed: 2022-10-31
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-11-sentiment-judging/issues/20
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-11-sentiment%3AM-2
- Tags: domain:web3 impact:integrity kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** CurveLPStakingController / BalancerLPStakingController canCall dispatch
**Root cause:** canCall() selects canDepositAndClaim()/canWithdrawAndClaim() based solely on the full function signature (deposit(uint256,address,bool), withdraw(uint256,bool)), assuming the caller is claiming rewards, without decoding the _claim_rewards bool.
**Steps:**
1. Call `deposit(uint256,address,bool)` with `_claim_rewards=false` (or `withdraw(uint256,bool)` with false).
2. Controller routes to canDepositAndClaim()/canWithdrawAndClaim() because the full selector matches.
3. Reward token addresses are appended to the returned tokensIn array.
4. Account adds those tokens to assets array and hasAsset mapping despite no rewards being claimed.
**How found:** Code reading of the controller's canCall() dispatch: noticed overlapping function signatures and that the branch selection keys off signature rather than the decoded _claim_rewards argument.
**Exploitation:** User (intentionally or not) invokes the full-signature deposit/withdraw with _claim_rewards=false; the controller reports reward tokens as tokensIn, so the account registers assets it does not actually hold, desynchronizing assets array and hasAsset mapping from reality.
**Insight:** When a controller whitelists calldata by function selector, check whether overloaded signatures with defaulted bool/address args let a caller reach a more permissive branch than their actual arguments warrant; decode args instead of trusting the selector.
