-
Notifications
You must be signed in to change notification settings - Fork 607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: add indirect incentivized pools to incentivized pools query #5589
Conversation
|
||
// MigrationRecords contains all the links between balancer and concentrated | ||
// pools. | ||
// | ||
// This is copied over from the gamm proto file in order to circumnavigate | ||
// the circular dependency between the two modules. | ||
message MigrationRecords { | ||
repeated BalancerToConcentratedPoolLink balancer_to_concentrated_pool_links = | ||
1 [ (gogoproto.nullable) = false ]; | ||
} | ||
|
||
// BalancerToConcentratedPoolLink defines a single link between a single | ||
// balancer pool and a single concentrated liquidity pool. This link is used to | ||
// allow a balancer pool to migrate to a single canonical full range | ||
// concentrated liquidity pool position | ||
// A balancer pool can be linked to a maximum of one cl pool, and a cl pool can | ||
// be linked to a maximum of one balancer pool. | ||
// | ||
// This is copied over from the gamm proto file in order to circumnavigate | ||
// the circular dependency between the two modules. | ||
message BalancerToConcentratedPoolLink { | ||
option (gogoproto.equal) = true; | ||
uint64 balancer_pool_id = 1; | ||
uint64 cl_pool_id = 2; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was sadly the cleanest way knew to get passed the circular dependency issue. The only module that pool-incentives had access to that could access gamm's store was superfluid. So I basically called GetAllMigrationInfo in pool-incentives via superfluid and parsed the result into an identical struct. Please lmk if there is a better way to achieve this without a major refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this might sound a bit unorthodox but how about we create a separate file that store shared interfaces between modules
for instance;
-
gamm
- shared_keepers.go (includes PoolIncentiveKeeper)
-
pool-incentives
- shared_keepers.go (includes GammKeeper)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this! I think it makes it simpler to reason about when we come back around and resolve this with the solution Roman recommended. Added here e70ac41
// If the linked concentrated liquidity pool is in the list of incentivized pools, | ||
// note this and add its balancer counterpart to the list of incentivized pools. | ||
for _, incentivizedPool := range incentivizedPools { | ||
if incentivizedPool.PoolId == record.ClPoolId { | ||
linkedClPoolIsIncentivized = true | ||
duration = incentivizedPool.LockableDuration | ||
continue | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider creating a map[uint64]struct{}
of incentivized pool IDs in the first loop above. This would allow checking the map here in O(1) instead of repeatedly iterating all incentivized pools for every link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, added here bba673d
for _, incentivizedPool := range incentivizedPools { | ||
if incentivizedPool.PoolId == record.ClPoolId { | ||
linkedClPoolIsIncentivized = true | ||
duration = incentivizedPool.LockableDuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it correct to use this for duration?
AFAIR, we update the largest lockable duration gauge for the balancer pool while using incentivized epoch duration for CL pool which might not necessarily match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its just a holder value, but we can set this as the longest duration just in case, because I agree that is "default"
Done here 18ee857
gaugeId, err := q.Keeper.GetPoolGaugeId(sdkCtx, record.BalancerPoolId, duration) | ||
if err == nil { | ||
incentivizedPool := types.IncentivizedPool{ | ||
PoolId: record.BalancerPoolId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we never expect PoolId to be a CL pool Id?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In every case the balancer pool will be the pool that is getting indirectly incentivized. This means that there is never a case in which a CL pool does not appear in the incentivized pools list that should be there. That is why we only retrieve the balancer pools at the end, since they are the ones that are getting replaced and funded via the CL gauge
|
||
// MigrationRecords contains all the links between balancer and concentrated | ||
// pools. | ||
// | ||
// This is copied over from the gamm proto file in order to circumnavigate | ||
// the circular dependency between the two modules. | ||
message MigrationRecords { | ||
repeated BalancerToConcentratedPoolLink balancer_to_concentrated_pool_links = | ||
1 [ (gogoproto.nullable) = false ]; | ||
} | ||
|
||
// BalancerToConcentratedPoolLink defines a single link between a single | ||
// balancer pool and a single concentrated liquidity pool. This link is used to | ||
// allow a balancer pool to migrate to a single canonical full range | ||
// concentrated liquidity pool position | ||
// A balancer pool can be linked to a maximum of one cl pool, and a cl pool can | ||
// be linked to a maximum of one balancer pool. | ||
// | ||
// This is copied over from the gamm proto file in order to circumnavigate | ||
// the circular dependency between the two modules. | ||
message BalancerToConcentratedPoolLink { | ||
option (gogoproto.equal) = true; | ||
uint64 balancer_pool_id = 1; | ||
uint64 cl_pool_id = 2; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this might sound a bit unorthodox but how about we create a separate file that store shared interfaces between modules
for instance;
-
gamm
- shared_keepers.go (includes PoolIncentiveKeeper)
-
pool-incentives
- shared_keepers.go (includes GammKeeper)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once minor suggestions are addressed
// MigrationRecords contains all the links between balancer and concentrated | ||
// pools | ||
message MigrationRecords { | ||
repeated BalancerToConcentratedPoolLink balancer_to_concentrated_pool_links = | ||
1 [ (gogoproto.nullable) = false ]; | ||
} | ||
|
||
// BalancerToConcentratedPoolLink defines a single link between a single | ||
// balancer pool and a single concentrated liquidity pool. This link is used to | ||
// allow a balancer pool to migrate to a single canonical full range | ||
// concentrated liquidity pool position | ||
// A balancer pool can be linked to a maximum of one cl pool, and a cl pool can | ||
// be linked to a maximum of one balancer pool. | ||
message BalancerToConcentratedPoolLink { | ||
option (gogoproto.equal) = true; | ||
uint64 balancer_pool_id = 1; | ||
uint64 cl_pool_id = 2; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make an issue to track unifying this?
I know we discussed this, and I'm not intending to block on this but it really feels like less overall overhead if we just unified it in this PR. This should be faster to do than writing up a good issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for _, pool := range incentivizedPools { | ||
if pool.PoolId == record.ClPoolId { | ||
duration = pool.LockableDuration | ||
break | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's put the duration into the incentivizedPoolIDs
map from above. That way, we don't need to iterate over incentivizedPools
repeatedly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closes: #XXX
What is the purpose of the change
When we link a concentrated pool to a balancer pool, the concentrated pool's gauge ID completely replaces the balancer pool's gauge ID in the incentivized gauges list. This is because all incentives for that denom pair is sent to the CL pool, the balancer pool determines it's share of the rewards via pseudo full range creation and taking into account a discount factor, and the CL pool sends these funds to the balancer pool's gauge for distribution to it's LPs.
The pool is still incentivized, but in an indirect way. We must therefore include these gauges still in the incentivized pools query, despite not being incentivized directly via inflation.
Testing and Verifying
Incentivized pools query tested via gotest
Documentation and Release Note
Unreleased
section ofCHANGELOG.md
?Where is the change documented?
x/{module}/README.md
)