<!-- canonical: https://0xsimao.com/findings/clip-finance-ii-compound-rewards-smaller-reward -->

# In PCLBaseSwapInside::_compoundRewards(), if the sellPortion is smaller than rewardSwapThreshold, some of the rewards will move to keepPortion

Crit/High · Three Sigma · DeFi infrastructure · 15th March 2024

Finding 3S-Clip-H01 of the Clip Finance Strategy Upgrade security review.

- Protocol: https://www.clip.finance/
- Report: /reports/clip-finance-strategy-upgrade
- Source: https://github.com/0xsimao/audits/blob/main/Three%20Sigma/2024-03-15-clip-finance-ii.pdf

---

### Description

Rewards allocated to compounding shares are only swapped to tokens 0 and 1 if the
sellPortion [exceeds](https://github.com/ClipFinance/StrategyRouter-private/pull/107/files#diff-beff087703331ce52098fdaead1b111bd9098796536448854363c93cf8b08707R393) the rewardSwapThreshold. However, the allocated sell portion is not
accounted for anywhere, which means that if the rewards are not sold due to being smaller
than the threshold, a portion of them will go to the keepPortion the next time
_compoundRewards() is called.
In the worst scenario, sell portion may always be smaller than the threshold if
_compoundRewards() is called frequently enough and no  rewards will be allocated to
compounding shares.

### Recommendation

Add a variable tracking the sell portion to make sure rewards never transition to the keep
portion.

### Status

Addressed in [#2464036](https://github.com/ClipFinance/StrategyRouter-private/pull/107/commits/246403632989e7540acab2238a5e40e170452de2).

Disclosed by 0xSimao (https://0xsimao.com/).

---

Related findings:

- [Users always pay fee on the full swapped amount in the `DeliHook`, even if the swap is smaller](https://0xsimao.com/findings/bmx-fee-full-swapped-hook): BMX Deli Swap
- [Base calculation in `Leverager::isLiquidateable()` is incorrect as the max leverage may be smaller](https://0xsimao.com/findings/yieldoor-leverager-liquidateable-leverage-smaller): Yieldoor
- [`rewardData.releaseRate` is incorrectly calculated on `RewardsController::config()` when `block.timestamp > start` and `rewardData.lastConfig != rewardData.start`](https://0xsimao.com/findings/exactly-protocol-update-staking-contract-reward-release-rewards-timestamp): Exactly Protocol Update - Staking Contract
- [Wrong reward distribution between early and late depositors because of the late `syncRewards()` call in the cycle, `syncReward()` logic should be executed in each withdraw or deposits (without reverting)](https://0xsimao.com/findings/gogopool-reward-rewards-withdraw-deposits): GoGoPool
