KVORUM
compoundSource: Compound governor bravo · #62

Split COMP rewards distribution and bug fixes

executedSep 27, 2021, 02:57 AM UTCbyC80xc8a6…dffc

01Summary

AISummary by Kvorumclaude-haiku-4-5

Upgrade Comptroller contract to enable split COMP reward distribution with separate borrow and supply rates per market, and fix three bugs affecting reward accrual and market state initialization.

Type
contract upgrade

Key changes

  • Split COMP rewards distribution into separate borrow-side (compBorrowSpeeds) and supply-side (compSupplySpeeds) rates per market to address negative interest rates(high)
  • Replace _setCompSpeed with _setCompSpeeds function to allow setting rates for multiple markets in a single call(high)
  • Fix bug where market state indices were not set when COMP rewards added to already active markets(high)
  • Fix bug where COMP rewards were distributed for periods before distribution rate was set(high)
  • Fix bug where borrowers had to manually accrue rewards if they borrowed before rates were set(high)
  • Initialize all market state indices on upgrade and ensure proper initialization for new markets instead of lazy initialization(high)
  • Slight gas reduction for deposits after initial user deposit(low)
  • Higher gas cost for claimComp calls to account for uninitialized borrow state indices(medium)

Notable concerns

  • claimComp function now uses significantly more gas; users recommended to specify which markets and sides to claim from rather than claiming across all markets
  • Depositing now requires different gas patterns depending on whether it is user's initial deposit
Contracts0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b0x374abb8ce19a73f2c4efad642bda76c797f19233
Generated by Kvorum
model: claude-haiku-4-5
provider: anthropic
profile: anthropic-fast-v1
prompt: v1.0
generated: 2mo ago
Read the description ↗

02Description

550 words

Split COMP rewards distribution and bug fixes

This proposal completes RFP 15: Dynamic COMP reward distribution as well as fixes a few bugs.

Split COMP rewards distribution

Problem

At the moment, the COMP rewards rate for any single market is applied at the same rate for both suppliers and borrowers. This creates undesirable market conditions such as, but not limited to, negative interest rates when borrowing various assets.

An example is the WBTC market - we want to distribute COMP rewards for suppliers, but since this distribution rate applies at the same rate for both borrowers and suppliers, we end up with WBTC being borrowed at a negative interest rate. The same applies to most non-stablecoin markets.

Solution

This proposal changes the Comptroller logic to have two different COMP distribution rates for each and every market - borrow-side (compBorrowSpeeds) rate and supply-side (compSupplySpeeds) rate.

The function Comptroller._setCompSpeeds(CToken[],uint256[],uint256[]) is introduced to enable governance to set these differing rates.

Example usage: Comptroller._setCompSpeeds([cUSDC],[0],[1e18]) - will set the COMP rewards for supplying USDC at 0 COMP per block, and for borrowing at 1 COMP per block.

COMP rewards distribution bug fixes

This proposal fixes the following bugs:

  • Market state indices were not being set when COMP rewards are added to already active markets. [Bug 1]
  • COMP rewards were distributed for periods preceding when the distribution rate is set. [Bug 2]
  • Borrowers were having to poke their borrow to accrue rewards if they borrowed before rewards rates were set. [Bug 3]

Technical changes

  • Comptroller#compSpeeds storage variable is no longer being used and has been effectively deleted. It's replaced by Comptroller#compBorrowSpeeds and Comptroller#compSupplySpeeds. This proposal copies the current rates into the new storage variables.
  • Comptroller#_setCompSpeed(CToken,uint256) function has been removed and replaced by Comptroller#_setCompSpeeds(CToken[],uint256[],uint256[]). This new function allows COMP rewards rates for multiple markets to be set with a single call.
  • An upgrade hook initializes all non-initialized market state indices (initial index is 1e36).
  • When new markets are added, their state indices are now properly initialized (used to use lazy initialization which caused many problems).

Other notable changes

  • Depositing now uses slightly less gas after a user's initial deposit.
  • Calling Comptroller#claimComp unfortunately uses a lot more gas to account for uninitialized borrow state indices. It's recommended to specify which markets (and which sides) to claim COMP in rather than claiming across all markets simultaneously.
  • Flywheel tests have been updated and expanded upon to prevent the bugs fixed in this proposal from occurring again.
  • These changes have been live on the Ropsten testnet for nearly a month and everything is working as expected.

Credits

  • Arr00: initial code supporting split COMP rewards; flywheel test re-writes
  • Getty: bugs 1 and 2 diagnosis help and disclosure
  • Elee: bugs 1 and 2 diagnosis help, fixing, and disclosure
  • Coburn: bug 3 identification; test case
  • Compound Labs (especially Jared): reviewing, guidance, general help, and coordination
  • TylerEther (me): full implementation of split COMP rewards; testing infrastructure changes; bugs 1 and 2 identification, diagnosis, fixing, and disclosure; bug 3 fix; overall coordination; general testing; addition of many new test cases; proposal

References

03Mismatch analysis

AIMismatch analysis by Kvorumclaude-sonnet-5
Consistent

This proposal follows the standard two-step Compound Comptroller upgrade pattern: (1) _setPendingImplementation on the Unitroller proxy pointing to the new Comptroller implementation address, and (2) _become(address) called on that new implementation to complete the proxy upgrade. This exactly matches what the description promises — a wholesale replacement of the Comptroller logic to support split COMP borrow/supply speeds, new _setCompSpeeds function, and the described bug fixes (index initialization, no COMP distribution before speed is set, borrower poke fix). The specific new logic (dual speed mappings, upgrade hook for index initialization, removal of old _setCompSpeed) lives in the bytecode of the new implementation contract, which cannot be independently decoded from calldata but is consistent with the described intent and the standard Compound governance upgrade mechanism. There is no mismatch in targets (Unitroller proxy and Comptroller implementation are used as expected), no unexpected fund transfers, role grants, or extra targets. This is a textbook, well-understood upgrade action pair for Compound governance proposals, so I have high confidence the description faithfully represents what the calldata does mechanically, even though the fine-grained internal logic changes are not independently verifiable from the two decoded calls alone.

Generated by Kvorum
model: claude-sonnet-5
provider: anthropic
profile: anthropic-strong-v1
prompt: v1.0
generated: 2mo ago
Review the decoded actions ↗

04Actions

2 total
#0_setPendingImplementation(address)chain 0x1
Target
0x3d98…cd3b
Value
0 wei
Function
_setPendingImplementation(address)
Arguments
{
  "0": "0x374ABb8cE19A73f2c4EFAd642bda76c797f19233"
}
Calldata
#1_become(address)chain 0x1
Target
0x374a…9233
Value
0 wei
Function
_become(address)
Arguments
{
  "0": "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B"
}
Calldata

05Tally

Summed from votes

Voters0
VP participating0
Outcome (current)—
Current support—

06Voters

0 total

No votes recorded yet.

07Forum

AIForum synthesis by Kvorumclaude-haiku-4-5
sentiment · favorablethread · constructive

Arguments for

  • Split rewards enable governance to independently incentivize suppliers and borrowers in each market, allowing more targeted market development.— TylerEther, getty, arr00
  • Setting separate borrow and supply rates directly is clearer for governance and more gas-efficient than storing and calculating ratios.— arr00, TylerEther
  • The implementation has been tested on Ropsten testnet with concrete reward distribution rates and functionality verified.— TylerEther, mistertom
  • Security review by Gauntlet confirmed the patch quality with appropriate scenario tests for supply/borrow permutations.— inkymaze

Arguments against

None surfaced.

Unresolved concerns

  • CompoundLens contract needs updating to expose separate compBorrowSpeeds and compSupplySpeeds mappings instead of the deprecated single compSpeed field.— mistertom
  • Long-term inefficiency risk if many markets accumulate zero rewards, causing claimComp to iterate through all markets including uncompensated ones, though a future fastClaimComp optimization was proposed.— inkymaze

Notable participants

  • TylerEtherProposal author who drove implementation, testing, and community coordination after taking over the grants request.
  • arr00Core contributor who initially proposed a similar approach, provided technical guidance on simplification, and collaborated on the final design.
  • gettyEarly supporter who endorsed the proposal as a much-needed improvement.
  • mistertomCommunity tester who identified the critical CompoundLens struct update requirement.
  • inkymazeGauntlet reviewer who confirmed the patch quality and voted in favor while flagging potential long-term gas optimization opportunities.
Generated by Kvorum
model: claude-haiku-4-5
provider: anthropic
profile: anthropic-fast-v1
prompt: v1.0
generated: 2mo ago
Open the thread ↗