# Broken invariant : the sum of all (delegateRewardsPerShare * delegated stake

Allora reward-debt accounting increases by untrimmed pending reward while only trimmed amount is paid, leaving the pending-reward module account over-funded.

- Payout: Contest reward
- Severity: medium
- Program: Allora
- Credited: imsrybr0
- Disclosed: 2024-06-24
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-06-allora-judging/issues/129
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AM-33
- Tags: domain:web3 impact:integrity kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:precision-loss

**Target:** Cosmos SDK emissions module reward distribution (RewardDelegateStake/AddDelegateStake/RemoveDelegateStake)
**Root cause:** RewardDebt is set to Amount*share (untrimmed) while only pendingReward.SdkIntTrim() is actually sent; sub-1 pending rewards also bump debt without any payout.
**Steps:**
1. Delegate stake to a reputer so delegateRewardsPerShare accrues a fractional pending reward
2. Call `MsgRewardDelegateStake` (or Add/RemoveDelegateStake) where pendingReward has a fractional part
3. Observe only `pendingReward.SdkIntTrim()` coins sent from AlloraPendingRewardForDelegatorAccountName
4. Observe RewardDebt set to full `Amount.Mul(share)`, not the trimmed amount
5. Repeat to accumulate unclaimed dust in the module account, breaking the README invariant
**How found:** Code review of reward accounting: noticed the send uses SdkIntTrim() while the debt update uses the untrimmed Amount*share, and that the >0 check is on untrimmed value.
**Insight:** When a payout trims decimals but the accounting variable stores the untrimmed product, the module balance and sum-of-debts diverge; check every place a trimmed amount is sent against the untrimmed value written to state.
