CIP#20 - Add a Performance Weighted Gauge

Summary:

This is a proposal [based on the discussion from [Discussion] Replace Gauge Weight Voting With A Performance Weighted CRV Distribution] to add a new gauge that weights CRV inflation to pools based on their average utilization rate.

Abstract:

This proposal is to add a new gauge that allows veCRV voters to allocate a portion of the CRV inflation to pools based on their relative weekly performance. This gauge would be available in conjunction with existing and future gauges that allocate directly to specific pools, or to some other initiative. Since it does not replace any existing system, it allows governance to scale the influence of performance weighting up or down, and safely experiment with its effectiveness.

Motivation:

The previous discussion on this topic was meant to get an idea of how the community feels about the gauge weight voting process, and the introduction of a system to reward pools based on performance metrics.

The previous discussion on this topic had some useful discussion and apparent interest from its poll results. Therefore, I’ve gone ahead and formed a signal vote with a formal proposal to determine if the community supports this performance weighting gauge.

Specification:

Since this gauge can be used in conjunction with other gauges, veCRV voters have the power to allocate more or less weight to rewarding performance as part of the weekly gauge weight vote. This flexibility lets governance trial the effectiveness of the performance weighting, and increase weighting over time if it proves effective.

The calculation being proposed here will only account for pool utilization, as it is the only performance metric that does not require a price oracle. For the sake of simplicity, I’ve omitted consideration of pool liquidity size and pool fees earned.

n = total number of Curve pools
U_n = utilization rate of pool n (averaged over previous week)
R = total daily reward allocated to the performance weight gauge
R_n = daily reward allocated to pool n
k = constant

Given some constant, k, the reward allocated to each pool is calculated as:
R_n = k * U_n

k can be determined by calculating:
k = R / (U_1 + U_2 + … + U_n)

Assume there are 3 Curve pools with various average utilization rates, and that governance has allotted 10% of the gauge weighting this week to the performance weight gauge (76,600 of 766,000 daily inflation) :
U_1 = 10%
U_2 = 35%
U_3 = 200%
R = 76,600 CRV

k = 76,600 / (10 + 35 + 200)
k = 312.653

Given k, we can calculate the daily inflation allocated to each pool as:
R_1 = 312.653 * 10
R_1 = 3126.53 CRV

R_2 = 312.653 * 35
R_2 = 10942.85 CRV

R_3 = 312.653 * 200
R_3 = 62530.6 CRV

This weighting would take effect for the week. The calculation would execute when the weekly gauge weighting takes effect, using data from the previous week. After a week, governance could allocate a different amount to the performance gauge, and a new calculation of the relative utilization between pools would execute.

For:

CRV inflation is a form of compensation that should be allocated to the pools that create the most value. Currently there is no way for the system to deterministically reward pools that create the most value. A performance gauge is needed to properly incentivize good use of liquidity on our platform.

Against:

This proposal doesn’t take total liquidity into consideration, so it may be possible for very small pools to wash trade a very high utilization rate and earn a large amount of CRV inflation. A formula to counteract this possibility would need an oracle that compares the liquidity amount and trade fees earned between pools denominated in different currencies. This creates complexity in the design.

A possible work around is to whitelist specific pools that have met adoption and liquidity requirements such that manipulation would be difficult to sustain.

Poll:

https://signal.curve.fi/#/curve/proposal/QmV1k5fyo52y6CyFQjsKggu1dpq6JQccijmbwHC924XegP

1 Like

I see this as a good use-case for veCRV holders that are not an L.P. to still participate in weighting in a valuable way while not needing a direct benefit from boost.
:+1:

2 Likes

If performance == volume traded, I like the idea.

I’d like to explore further the “wash-trading” attack vector. Could such an attack be economically viable, and in what context ? (proportions, CRV price, etc…)

For example, can we imagine that some whale moves all their funds from 3pool to randomPool and start wash-trading on that pool to get most of the weight ? (ex: they have 2B and they use 1.5B to put liquidity and 0.5B for wash-trading, so they collect all the fees plus can mint more CRVs).

One can also imagine manipulating the utilization rate of a pool, lowering it by depositing plenty of funds (at equal volume, that would lower the utilization rate, right ?), and wash-trading in another other pool.

Maybe I am overthinking this…

1 Like

In this proposal, performance = liquidity utilization. It is the:

Volume Traded / Pool Liquidity

The strength of this metric is that it shows you how much “work” each unit of liquidity is doing in a pool, regardless of the pool’s size. The reasons to use this metric are:

  1. It doesn’t distinguish between the size of the pool, so it can identify a small pool that isn’t earning a lot of fees overall, but is getting a lot of usage relative to its size. It can therefore incentivize the growth of a small pool that has high demand.
  2. The metric can be applied universally to all pools without the need for currency conversion (and therefore an oracle).

I think your thoughts on wash trading are probably something that would realistically happen. A whale who has a large stake in a pool might generate a large volume in their pool to boost their utilization. I hadn’t thought of it, but dumping liquidity into competing pools with the hope of lowering the utilization may also be a tactic. On the other hand, turning the utilization rate into a valuable metric may cause other LP’s to move into pools with growing utilization, and offset the effect of the manipulation and the rewards to be gained from doing this.

I think this effect is a net positive to Curve because I don’t think we want some pools with 50% utilization and others with .2%. We end up paying a lot in CRV inflation to liquidity that isn’t generating a whole lot of value back to the platform. We should be creating competition between pools to generate trading volume. The reality right now is that LP’s don’t care at all and don’t have reason to care at all whether their liquidity is being used or not. Something needs to be done to change this. I think this proposal is a good way to dip our toes into exploring this incentive mechanism, I’m also open to there being better ways if anyone wants to take a stab at it.

This proposal would also work if the CRV was distributed by volume traded instead. Pools that do more volume/earn more fees get more rewards.

Also, I’m not sure how easy this is to implement on top of the current liquidity gauges. Curve Team is currently doing a lot of development, and this might take up too much of their time.


Why this will be less of a problem in the future?

  • Lots of new pools will be launching, inflation will be split up among more pools.
  • Meta Pools further complicates this gauge, Incentivizing tBTC pool will drive more volume to the sbtc pool, sbtc ‘utilization’ will go up, but that doesn’t mean the sbtc gauge needs more rewards.
  • As inflation rewards get diluted from more pools - the CRV distribution to veCRV holders (actually getting the CRV), will naturally align stakers to weight gauges that have a higher liquidity utilization.

Also this is backwards looking, and volume can be quite volatile.

Would recommend weighting by volume vs weighting by liquidity utilization.

Weighting by volume still benefits small pools if they have high liquidity utilization.

Weighting by liquidity utilization is much more gamable.

You could try weighting by volume, but there’s a currency conversion issue. If you’re denominating volume in USD, the BTC pools need a BTC/USD price feed to determine the volume. I thought the logic to do this and the need for an oracle would make it too complicated and introduce a risk of price feed failure, but maybe there’s a way around this I haven’t thought of?

1 Like