Request for Comment : Updating Rewards Contract

Hey Compounders, for the past 2 weeks we have been engaging multiple stakeholders for Compound Partnerships. One of the key topics of our the Growth Program was to secure Grants and incentives for Compound V3 pools. As we engage integrated chains and prospect Chains like Optimism, we come across the opportunity of securing a Grant for Compound from the Partners. Some of these opportunities may actually offer 7 figure grants to the protocol. But there is a logistical challenge in terms of distributing the Grants given by partners.

Compound Rewards Contract

The current architecture of the Compound Rewards contract enables the distribution of COMP rewards to the users. But the limitation is that only COMP tokens can be distributed as rewards. For any other tokens like ARB, OP etc that may be given as grants, there is no easy way to directly reward the pools alongside COMP (or maybe we are missing something!). Furthermore, multiple integrated chains have chain side rewards for DeFi, that the protocol and its users are not utilizing to maximum potential.

Challenges with single token Rewards

Outside the smart contract, the methods that exist for utilization of any future Grants are indirect incentivization, like quests, marketing, etc. This leaves a room for challenges in efficiency and utilization of the Grant funds.

  • Efficiency: Marketing and Quests are a good way to utilize contracts, they generate awareness and buzz that brings new users. But the problem is that utilization of marketing channels means that some part of the funds will be utilized to fund third parties like Twitter, quest platforms and influencers who are not direct stakeholders of Compound Growth. Smart contract rewards ensure 100% efficiency of funds, other means will provide only 70% usability and most likely 30-40% effectiveness.
  • Trustless medium: A smart contract is a trustless method to utilize funds, this is fully transparent and can be easily managed by the DAO. The Grant funds being managed by a third party requires utmost transparency and competency in the field, which putsoverhead costs for reporting.
  • Reduced Competitiveness of Compound APR: A smart contract incentivized pool can directly add on the APR, thus giving an edge to Compound’s rates over the competition, which otherwise is not possible.

The Solution

We propose a revision of the Rewards smart contract that will allow the distribution of rewards in multiple tokens simultaneously. The parameters of the contract and the addition removal of tokens other than COMP in the smart contract will be modified by a governance vote. The aim of these will be to temporarily enable additional reward Tokens which can then be removed once the grants are all used up.

We are talking to multiple parties on possible solutions and their scopes. We are open to a revision of the smarts contracts reward and are actively sourcing dev teams. We invite community members to weigh in their opinions, suggest alternatives.

5 Likes

Seems worth pursuing if there is a reasonable likelihood of being able to offer multi-token incentives. Certainly there are plenty of other protocols with incentives like that in place. Could become an RFP within CGP’s protocol dapps and ideas domain if the community agrees it’s worth supporting.

I think there are at least two viable approaches that don’t require modifying the CometRewards contract internally, which is probably preferable from a security standpoint:

  • @kevin mentioned a little while back on Discord that multiple CometRewards contracts could be interfaced with the same Comet, with the wrinkle that speeds are set in Comet (perhaps the CometRewards contract for the other token could internally rescale the speed setting from Comet for its own purposes, but I haven’t looked closely at the logic to know if that’s viable).
  • I’m a bit out of my depth here, but it seems not entirely out of the question to wrap a predetermined ratio of COMP and the other token into an ERC-20 compliant contract for delivery via a single CometRewards contract (sort of like Uniswap V2 LP tokens, but also not). I feel like there is probably some basic detail I’m missing that makes it hard/impossible for this to be ERC-20 compliant. In any case, it would also require a pre-wrapping step and an awkward front-end(s) for users to unwrap the rewards, so probably unnecessarily complicated relative to the first approach.

There are also vault-style solutions like Alchemist/Ampleforth’s V2 geysers designed for the purpose of distributing multiple incentives (“subscribing to multiple rewards programs” in their language), but it’s not clear to me that they would “play nicely” with the Comet contracts. For borrowers specifically, there is no debt token that could be deposited to a vault as proof of claim on the other incentive token.

4 Likes

Thanks for sharing your insights on this topic @allthecolors . I agree, that an effort in this direction to be supported by the Dapps and Ideas domain would greatly benefit the community.

The speeds system as also mentioned by @kevin in this thread, is an interesting solution. Would love to see if it can be utilized for multiple tokens simultaneously.

I will research more on the vault-style solutions as well.

I believe we need a solution based on following requirements:

  1. Ability to incentivize existing and new Comets with 2 or more tokens at the same time;
  2. Seamless transition: users shall not perform any actions to start receiving rewards in additional tokens;
  3. Do not upgrade existing smart contracts, as @allthecolors mentioned.
  4. Ability to relaunch incentivization program with the same token (for example: distribute 100K USDC in Q1 2024, then stop distribution and redistribute another 200K USDC in Q3 2024);
  5. Reusable code: the solution shall be reusable for future EVM Comets and applicable to existing EVM Comets.
Multi-rewards state that flows out after the described requirements

Let’s imitate that 1 accrued = 1 token. Inc = incentivize.
State 1: - accrued +100

  • Date X
  • Accured 1000
  • Claimed 900
  • Owned 1000 - 900 = 100
  • The user does not claim a reward

State 2: - accrued +100

  • Date X1
  • Accrued(COMP) 1100
  • Claimed(COMP) 900
  • Owned 1100 - 900 = 200(COMP)
  • Adding new inc reward (USDC)
  • Accrued(USDC) 0
  • Claimed(USDC) 0
  • Owned 0 - 0 = 0 USDC

State 3: - accrued +100

  • Date X2
  • Accrued(COMP) 1200
  • Claimed(COMP) 900
  • Owned 1200 - 900 = 300(COMP)
  • Accrued(USDC) 100
  • Claimed(USDC) 0
  • Owned 100 - 0 = 100 USDC
  • Stop USDC inc reward

State 4: - accrued +100

  • Date X4
  • Accrued(COMP) 1300
  • Claimed(COMP) 900
  • Owned 1300 - 900 = 400(COMP)
  • Accrued(USDC) 100
  • Claimed(USDC) 0
  • Owned 100 - 0 = 100 USDC
  • Start a new USDC’ inc reward
  • Accrued(USDC’) 0
  • Claimed(USDC’) 0
  • Owned 0 - 0 = 0 USDC’

State 5: - accrued +100

  • Date X4
  • Accrued(COMP) 1400
  • Claimed(COMP) 900
  • Owned 1400 - 900 = 500(COMP)
  • Accrued(USDC) 100
  • Claimed(USDC) 0
  • Owned 100 - 0 = 100 USDC
  • Accrued(USDC’) 100
  • Claimed(USDC’) 0
  • Owned 100 - 0 = 100 USDC’

Finally, claim: 500 COMP, 100 USDC, 100 USDC’

Overall - important not to receive more rewards than should be received and not to lose rewards for finished campaigns.

Challenge
@kevin shared some great ideas here. However this approach affect existing(deployed) smart contracts.

Firstly, I thought about some wrapper over the existing CometRewards.sol. The flow could look like this: User → CometRewardsV2.sol → CometRewards.sol → Comet. All the deployed contracts stayed untouched and new multi-token logic is implemented in CometRewardsV2 which has a similar interface to CometRewards.

However, from my perspective, It is not possible to create such state flow only on the smart contract side. It requires storing all periodical rewards on a contract, which is not possible without some trigger.

Most possible solutions

  1. Service that automatically triggers a new additional method to set the currently accrued amount for each user into the rewards storage in CometRewardsV2 - e.g. getInMomentRewardAccrued() - so we can store the accrued amount by the moment the campaign starts and finishes (for each user). But that will require indexing all current Comet users and paying for gas for such txs.
  2. Service that periodically stores a storage snapshot (some own or 3rd party one used for on-chain state forking) and use the timestamp to get the accrued amount at the moment - and integrate such call to the frontend. So when the user tries to claim rewards from the closed pool - UI will pass the accrued amount by the moment of campaign closing.

These are the only options for fulfilling requirements above, including keeping both multiple rewards and preventing rewards losing (or overcompensation) when the campaign is over: service to trigger accrue status update for each user for campaign start and finish (with expanses for backend service and gas payments), or 3rd party indexer for such info fetching (but with ugly frontend integration).

All other cases will require additional actions from users, as for now there is no info in Comet to use to bind to the start/end of the rewards campaign for each user.

Feedback is much appreciated!

2 Likes

@sharp agree important topic on multi token rewards on Comets.

Could be resistance on retrofitting a multi-token rewarder with existing Comets - will require a level of technical complexity and migration that Compound would need to take on.

Another option, maybe easier lift: introduce multi-token rewards on new markets. Link below.

2 Likes

This is correct. It is possible to get a multi-reward setup going with the current implementation, but it is very operationally burdensome. @pashabergman seems to have arrived at this point in his comment as well. I will explain why:

  1. Even though multiple CometRewards can be set up with different multipliers, they all depend on the one speed defined in Comet. This means when there are multiple reward tokens, there is no way to change the speed for only one reward and not the other. You can imagine this makes turning off one reward token while keeping another on very difficult.

  2. If you want to start distributing a new reward token to a Comet that has already been distributing rewards, the new CometReward will read from the non-zero baseTrackingAccrued values of existing users. Remember, the reward contracts are sharing the same speed, and therefore, the same baseTrackingAccrued values as well. This means you will need to seed the rewardsClaimed value for each user in CometRewards using setRewardsClaimed to ensure that each user starts with 0 accrued rewards for the new reward token.

As you can imagine, this is a lot of off-chain processing and on-chain data posting that needs to be done right.

The alternative longer-term approach is to go with one of the smart contract changes discussed here.

3 Likes

Should the logic of multi-token incentivization provide the ability to claim rewards for each token separately? Compound has institutional users who may not want to claim all rewards simultaneously due to internal accounting and other reasons.

1 Like

I think it should be able to support both claiming individual tokens and claiming all of them.

3 Likes