# claimCOMPAndTransfer() COMP may be locked into the contract

Notional's claimCOMPAndTransfer only transfers the delta of COMP balance, so front-running the claimComp call makes netBalance zero and locks rewards in the contract.

- Payout: Contest reward
- Severity: high
- Program: Notional
- Credited: bin2chen
- Disclosed: 2023-03-09
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-03-notional-judging/issues/168
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-03-notional%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:race-condition

**Target:** TreasuryAction.claimCOMPAndTransfer() / Compound Comptroller
**Root cause:** claimCOMPAndTransfer computes netBalance as balanceAfter - balanceBefore and only transfers that delta, but COMPTROLLER.claimComp is permissionless, so anyone can claim first and zero out the delta.
**Steps:**
1. Attacker monitors mempool for Notional manager calling claimCOMPAndTransfer(cTokens).
2. Attacker front-runs with `COMPTROLLER.claimComp(address(notional), cTokens)` which is public and permissionless.
3. Notional's tx executes: balanceBefore already includes claimed COMP, claimComp yields nothing, balanceAfter == balanceBefore.
4. netBalance = 0, so `if (netBalance > 0)` skips safeTransfer; COMP stays in the contract.
5. Repeat each harvest cycle to continuously lock accrued COMP rewards.
**How found:** Code review of claimCOMPAndTransfer noticed it transfers only the balance delta, then checked Compound's Comptroller.claimComp and saw it is callable by anyone for any holder, making the delta manipulable via front-running.
**Exploitation:** Pure front-running griefing: no capital needed, attacker just calls the public Comptroller.claimComp for Notional's address before each harvest, causing netBalance to be zero and preventing transfer of COMP to the treasury manager.
**Insight:** When a harvest function pays out only the balance delta, check whether the underlying claim/reward function is permissionless for the holder address; if so, an attacker can pre-claim and zero the delta. Prefer transferring full balance or tracking internal accounting.
