Skip to content
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

[CL Incentives] Allow early withdrawals for frozen positions #4525

Merged
merged 199 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
199 commits
Select commit Hold shift + click to select a range
235653b
initial push
czarcas7ic Jan 26, 2023
e4941f6
push
czarcas7ic Jan 26, 2023
a3ac7b7
untracked files
czarcas7ic Jan 26, 2023
e888677
Merge branch 'adam/add-freeze-api' of https://github.com/osmosis-labs…
czarcas7ic Jan 26, 2023
61f5c76
add untracked files
czarcas7ic Jan 26, 2023
afc350f
Merge branch 'adam/add-freeze-api' of https://github.com/osmosis-labs…
czarcas7ic Jan 26, 2023
085bdc1
merge branches
czarcas7ic Jan 26, 2023
b7a2a70
Merge branch 'main' into adam/add-freeze-api
czarcas7ic Jan 26, 2023
2e4fd0f
add changes required for fees
czarcas7ic Jan 26, 2023
79017a3
lint
czarcas7ic Jan 26, 2023
8e68719
fix test errors
czarcas7ic Jan 26, 2023
b221dcf
clean up
czarcas7ic Jan 26, 2023
d2ede58
remove print lines
czarcas7ic Jan 26, 2023
a515d5d
feat: single fee accum (#4116)
czarcas7ic Jan 27, 2023
838c2ab
no longer need to get all positions for fee
czarcas7ic Jan 27, 2023
c75f163
incentive accum initialization
AlpinYukseloglu Jan 27, 2023
447967e
lint
AlpinYukseloglu Jan 27, 2023
0adb801
Update x/concentrated-liquidity/store_test.go
czarcas7ic Jan 28, 2023
17f47fe
add lower level tests and make uptime accum access private
AlpinYukseloglu Jan 29, 2023
75e0c14
lint
AlpinYukseloglu Jan 29, 2023
5f2e7a5
add gotests for helper fn
AlpinYukseloglu Jan 29, 2023
433e215
Merge branch 'main' into alpo/uptime-accums
AlpinYukseloglu Jan 29, 2023
008379a
Merge adam/add-freeze-api into alpo/uptime-accums
AlpinYukseloglu Jan 29, 2023
400ac3e
Update test to use existing variable
AlpinYukseloglu Jan 29, 2023
a4fbf0b
create or update records upon position creation/update
AlpinYukseloglu Jan 29, 2023
c604659
add tests and clean up
AlpinYukseloglu Jan 30, 2023
1f75cea
sync position-related changes
AlpinYukseloglu Jan 30, 2023
982830e
add support for negative liquidity delta
AlpinYukseloglu Jan 30, 2023
768ec68
add and test helper & set up tick initialization logic
AlpinYukseloglu Jan 31, 2023
c318fa0
implement accumulator updates on tick crossing and clean up proto
AlpinYukseloglu Jan 31, 2023
d0184b7
clean up comments
AlpinYukseloglu Jan 31, 2023
6020836
minor test cleanup
AlpinYukseloglu Feb 1, 2023
0d5559a
Merge branch 'alpo/position-uptime-accums' into alpo/CL-accum-update-…
AlpinYukseloglu Feb 1, 2023
01bd068
ensure accum initalization follows conventions and clean up tests
AlpinYukseloglu Feb 1, 2023
1bc68b5
update pool proto and CL pool extension for tracking liq changes
AlpinYukseloglu Feb 1, 2023
188778d
update new field at pool initialization and add tests
AlpinYukseloglu Feb 1, 2023
093024d
comment todos
AlpinYukseloglu Feb 2, 2023
a778dbb
clean up naming and move empty options to global var
AlpinYukseloglu Feb 2, 2023
6fbf412
Merge branch 'main' into alpo/position-uptime-accums
AlpinYukseloglu Feb 2, 2023
0c9c235
add clarifying comments and lint
AlpinYukseloglu Feb 2, 2023
a5fe6f6
Merge branch 'main' into alpo/position-uptime-accums
AlpinYukseloglu Feb 2, 2023
2ba1d26
Merge branch 'alpo/position-uptime-accums' into alpo/CL-accum-update-…
AlpinYukseloglu Feb 2, 2023
7c6eb8f
implement IncentiveRecord proto
AlpinYukseloglu Feb 2, 2023
a4b8620
add comments
AlpinYukseloglu Feb 2, 2023
d79c226
lint
AlpinYukseloglu Feb 2, 2023
677bc8a
Merge branch 'alpo/position-uptime-accums' into alpo/CL-accum-update-…
AlpinYukseloglu Feb 2, 2023
e0ae23e
set up wiring for proto
AlpinYukseloglu Feb 2, 2023
f9f11b3
implement updateUptimeAccumulatorsToNow
AlpinYukseloglu Feb 2, 2023
2c29631
implement and test calcAccruedIncentivesForAccum
AlpinYukseloglu Feb 3, 2023
798b66e
add tests for new helpers
AlpinYukseloglu Feb 3, 2023
fcc5c8c
minor comment updates
AlpinYukseloglu Feb 3, 2023
debab7f
Merge branch 'alpo/position-uptime-accums' into alpo/CL-accum-update-…
AlpinYukseloglu Feb 3, 2023
9287d3c
accum test updates
AlpinYukseloglu Feb 3, 2023
37aa74f
lint
AlpinYukseloglu Feb 3, 2023
a7986a3
Merge branch 'main' into alpo/CL-accum-update-logic
AlpinYukseloglu Feb 3, 2023
81a7b99
Merge branch 'main' into alpo/CL-accum-update-logic
AlpinYukseloglu Feb 5, 2023
7a7c52d
clean up diff
AlpinYukseloglu Feb 5, 2023
2961572
lint
AlpinYukseloglu Feb 5, 2023
19ef297
update go.mod for e2e
AlpinYukseloglu Feb 5, 2023
3d8a86e
clean up proto and add error message
AlpinYukseloglu Feb 7, 2023
2f93b76
lint
AlpinYukseloglu Feb 7, 2023
bec7d79
sketch out testing approach
AlpinYukseloglu Feb 9, 2023
a208eb2
set up keys
AlpinYukseloglu Feb 9, 2023
6ba9927
clean up diff
AlpinYukseloglu Feb 9, 2023
940f0b7
clean up comments
AlpinYukseloglu Feb 9, 2023
e35280e
lint
AlpinYukseloglu Feb 9, 2023
b777ee1
implement set and get for incentive records
AlpinYukseloglu Feb 10, 2023
8355980
comment cleanup
AlpinYukseloglu Feb 10, 2023
85da656
minor comment and test cleanup
AlpinYukseloglu Feb 10, 2023
d167d77
clean up tests and comments
AlpinYukseloglu Feb 11, 2023
de7c146
[CL Incentives] Implement `setIncentiveRecords` and `getIncentiveReco…
AlpinYukseloglu Feb 11, 2023
ad5db48
Revert "[CL Incentives] Implement `setIncentiveRecords` and `getIncen…
AlpinYukseloglu Feb 11, 2023
c65ddc1
Merge branch 'alpo-set-incentives' into alpo-cl-uptime-global
AlpinYukseloglu Feb 13, 2023
ad3938f
set incentive records in new position tests
AlpinYukseloglu Feb 13, 2023
9a5649e
Merge branch 'main' into alpo-cl-uptime-global
AlpinYukseloglu Feb 13, 2023
3859c0b
fix merge conflicts
AlpinYukseloglu Feb 13, 2023
3c5c9de
Merge branch 'main' into alpo-cl-uptime-proto-helpers
AlpinYukseloglu Feb 13, 2023
deaf70c
add check for init position record values
AlpinYukseloglu Feb 13, 2023
2661c58
fix and finalize uptime accum position tests
AlpinYukseloglu Feb 13, 2023
4c7f178
fix go mod for e2e
AlpinYukseloglu Feb 13, 2023
26b4505
Merge branch 'alpo-cl-uptime-proto-helpers' in
AlpinYukseloglu Feb 13, 2023
74cadb6
Merge branch 'alpo-cl-uptime-proto-helpers' into alpo-set-incentives
AlpinYukseloglu Feb 13, 2023
166656a
Merge branch 'alpo-set-incentives' into alpo-cl-uptime-global
AlpinYukseloglu Feb 13, 2023
a636539
clean up diff
AlpinYukseloglu Feb 13, 2023
ee5c2c6
add err check to accum update
AlpinYukseloglu Feb 13, 2023
5407223
fix rounding error
AlpinYukseloglu Feb 16, 2023
b5b6643
Merge branch 'alpo-cl-uptime-proto-helpers' into alpo-set-incentives
AlpinYukseloglu Feb 16, 2023
a1e4deb
Merge branch 'alpo-cl-uptime-proto-helpers' into alpo-cl-uptime-global
AlpinYukseloglu Feb 16, 2023
83bd08f
implement tick init uptime tracker logic
AlpinYukseloglu Feb 16, 2023
acd94eb
fix test compatibility
AlpinYukseloglu Feb 16, 2023
dde309a
implement fix for global accums falling out of sync before tick init
AlpinYukseloglu Feb 16, 2023
cc21105
add tests to ensure uptime trackers are initialized properly
AlpinYukseloglu Feb 16, 2023
5fe763c
add comment for new helper
AlpinYukseloglu Feb 17, 2023
10919f4
add core logic
AlpinYukseloglu Feb 17, 2023
9419d69
Merge branch 'main' into alpo-cl-uptime-proto-helpers
AlpinYukseloglu Feb 20, 2023
a16a58b
go mod tidy
AlpinYukseloglu Feb 20, 2023
586e7bd
fix conflicts
AlpinYukseloglu Feb 20, 2023
efe299c
fix e2e
AlpinYukseloglu Feb 20, 2023
4df2525
update go mod
AlpinYukseloglu Feb 20, 2023
05acab6
Merge branch 'alpo-cl-uptime-proto-helpers' into alpo-set-incentives
AlpinYukseloglu Feb 20, 2023
c68cca2
Merge branch 'alpo-cl-uptime-proto-helpers' into alpo-cl-uptime-global
AlpinYukseloglu Feb 20, 2023
dfa9215
Merge branch 'alpo-cl-uptime-global' into alpo-cl-uptime-tick-init
AlpinYukseloglu Feb 20, 2023
07f94f5
Merge branch 'main' into alpo-set-incentives
AlpinYukseloglu Feb 20, 2023
b7e5cd6
Merge branch 'alpo-set-incentives' into alpo-cl-uptime-global
AlpinYukseloglu Feb 20, 2023
736820b
fix and further test tick init logic
AlpinYukseloglu Feb 20, 2023
ea20428
remove redundant values from incentive record state
AlpinYukseloglu Feb 22, 2023
3738f83
cleanup from review
AlpinYukseloglu Feb 22, 2023
2cf4d75
Merge branch 'main' into alpo-cl-uptime-global
AlpinYukseloglu Feb 22, 2023
54b9bd3
Merge branch 'alpo-cl-uptime-global' into alpo-cl-uptime-tick-init
AlpinYukseloglu Feb 22, 2023
a607e48
comment cleanup
AlpinYukseloglu Feb 22, 2023
bbd6e49
set up cross tick tests
AlpinYukseloglu Feb 23, 2023
63bffa4
Merge branch 'alpo-cl-uptime-tick-init' into alpo-cl-uptime-cross
AlpinYukseloglu Feb 23, 2023
bba3209
add further tests
AlpinYukseloglu Feb 23, 2023
1d208be
test and comment cleanup
AlpinYukseloglu Feb 23, 2023
b080e81
Merge branch 'alpo-cl-uptime-tick-init' into alpo-cl-uptime-cross
AlpinYukseloglu Feb 23, 2023
2c0076a
implement core logic
AlpinYukseloglu Feb 23, 2023
37bc26b
update osmoutils go mod and remove curTick as fn param
AlpinYukseloglu Feb 23, 2023
49dc498
thorough tests for new functionality
AlpinYukseloglu Feb 23, 2023
a022dfb
clean up new functions for readability
AlpinYukseloglu Feb 23, 2023
bcf4abd
clean up test comments
AlpinYukseloglu Feb 23, 2023
30aa0c5
Merge branch 'alpo-cl-uptime-tick-init' into alpo-cl-uptime-cross
AlpinYukseloglu Feb 23, 2023
7ebd592
Merge branch 'alpo-cl-uptime-cross' into alpo-cl-uptime-inside
AlpinYukseloglu Feb 23, 2023
b0e9edb
fix test names
AlpinYukseloglu Feb 23, 2023
6d3c201
Merge branch 'alpo-cl-uptime-cross' into alpo-cl-uptime-inside
AlpinYukseloglu Feb 23, 2023
a7d07f0
Merge branch 'main' into alpo-cl-uptime-tick-init
AlpinYukseloglu Feb 23, 2023
e610a05
Merge branch 'alpo-cl-uptime-tick-init' into alpo-cl-uptime-cross
AlpinYukseloglu Feb 23, 2023
2ea1348
Merge branch 'alpo-cl-uptime-cross' into alpo-cl-uptime-inside
AlpinYukseloglu Feb 23, 2023
e83af52
lint
AlpinYukseloglu Feb 23, 2023
f5e0c70
add godoc and further comments
AlpinYukseloglu Feb 24, 2023
0c64337
update go mod for e2e
AlpinYukseloglu Feb 24, 2023
47bb8b4
update liq change logic
AlpinYukseloglu Feb 25, 2023
a55414b
update uptime accums before gettings them for tick crossing
AlpinYukseloglu Feb 25, 2023
1ec8a7f
Merge branch 'alpo-cl-uptime-cross' into alpo-cl-uptime-inside
AlpinYukseloglu Feb 25, 2023
972fb0d
Merge branch 'alpo-cl-uptime-inside' into alpo-cl-uptime-claim
AlpinYukseloglu Feb 25, 2023
12962ae
abstract uptime init and update logic to helper
AlpinYukseloglu Feb 25, 2023
333a2e7
add thorough tests for initOrUpdatePositionUptime
AlpinYukseloglu Feb 28, 2023
0536116
update liquidity update logic and tests to use new helper
AlpinYukseloglu Feb 28, 2023
51a7f56
add todo for frozenuntil issue
AlpinYukseloglu Feb 28, 2023
0a51d05
lint
AlpinYukseloglu Feb 28, 2023
9857baa
Merge branch 'alpo-cl-uptime-cross' into alpo-cl-uptime-inside
AlpinYukseloglu Feb 28, 2023
26ddf8b
Merge branch 'alpo-cl-uptime-inside' into alpo-cl-uptime-claim
AlpinYukseloglu Feb 28, 2023
8bb8240
lint
AlpinYukseloglu Feb 28, 2023
b117f72
clean up logic and add tests for helper
AlpinYukseloglu Mar 3, 2023
65abf78
go mod for osmoutils e2e
AlpinYukseloglu Mar 3, 2023
511d8a0
move position key computation outside loop
AlpinYukseloglu Mar 3, 2023
85d435d
Merge branch 'main' into alpo-cl-uptime-inside
AlpinYukseloglu Mar 3, 2023
65da1ae
Merge branch 'alpo-cl-uptime-inside' into alpo-cl-uptime-claim
AlpinYukseloglu Mar 3, 2023
874428f
Merge branch 'main' into alpo-cl-uptime-inside
AlpinYukseloglu Mar 3, 2023
654505d
clean up imports and go sum
AlpinYukseloglu Mar 3, 2023
120b213
Merge branch 'alpo-cl-uptime-inside' into alpo-cl-uptime-claim
AlpinYukseloglu Mar 3, 2023
77f158d
fix imports
AlpinYukseloglu Mar 3, 2023
391d74f
[CL Incentives][bugfix]: Replace all uses of frozenUntil with joinTim…
stackman27 Feb 28, 2023
78090a5
e2e passing
stackman27 Mar 3, 2023
5089a8e
implement message, proto, and core logic
AlpinYukseloglu Mar 3, 2023
a424bda
convert freezeduration to uint64
stackman27 Mar 3, 2023
8f10042
Merge branch 'sis/cl-inc-jt-fd' into alpo-uptime-claim
AlpinYukseloglu Mar 3, 2023
219d7b5
Merge branch 'main' into alpo-cl-uptime-claim
AlpinYukseloglu Mar 3, 2023
776c7e0
Merge branch 'alpo-cl-uptime-claim' into sis/cl-inc-jt-fd
AlpinYukseloglu Mar 3, 2023
f34e75c
Merge branch 'sis/cl-inc-jt-fd' into alpo-uptime-claim
AlpinYukseloglu Mar 3, 2023
93b08b4
Merge branch 'main' into sis/cl-inc-jt-fd
AlpinYukseloglu Mar 3, 2023
9dc78e6
Merge branch 'sis/cl-inc-jt-fd' into alpo-uptime-claim
AlpinYukseloglu Mar 3, 2023
9c6510c
Merge branch 'main' into alpo-uptime-claim
AlpinYukseloglu Mar 4, 2023
a13cbc6
implement tests for collectIncentives
AlpinYukseloglu Mar 4, 2023
90b4df4
add msg level tests and clean up logic/tests
AlpinYukseloglu Mar 4, 2023
620602b
draft implementation
AlpinYukseloglu Mar 4, 2023
6e1c365
begin testing
AlpinYukseloglu Mar 6, 2023
a39c147
add codec, cli, and simulation
AlpinYukseloglu Mar 6, 2023
034d272
claim incentives upon position deletion to clear records
AlpinYukseloglu Mar 6, 2023
cf428d7
comment cleanup
AlpinYukseloglu Mar 6, 2023
43573c3
add more test cases
AlpinYukseloglu Mar 6, 2023
4b12446
lint
AlpinYukseloglu Mar 6, 2023
fe7a39f
add error catching test cases
AlpinYukseloglu Mar 6, 2023
efe72bc
implement createIncentive message
AlpinYukseloglu Mar 6, 2023
3abe2a8
Merge branch 'alpo-uptime-claim' into alpo-create-incentive
AlpinYukseloglu Mar 6, 2023
580a7ca
cli and codec
AlpinYukseloglu Mar 6, 2023
21268ba
add check and related tests
AlpinYukseloglu Mar 6, 2023
c863344
add further tests and lint
AlpinYukseloglu Mar 6, 2023
a8c6d4c
add test case for existing incentive records
AlpinYukseloglu Mar 6, 2023
8d03bfa
pull relevant changes into new branch
AlpinYukseloglu Mar 6, 2023
3d882b6
lint
AlpinYukseloglu Mar 6, 2023
c28338a
minor test comment updates
AlpinYukseloglu Mar 10, 2023
2ab1610
godoc update
AlpinYukseloglu Mar 10, 2023
a781cd5
Merge branch 'main' into alpo-uptime-claim
AlpinYukseloglu Mar 10, 2023
a4afed1
expand withdraw tests to better include incentives logic
AlpinYukseloglu Mar 10, 2023
663a8d6
minor optimizations and cleanup from code review
AlpinYukseloglu Mar 10, 2023
899f0b0
Merge branch 'alpo-uptime-claim' of https://github.com/osmosis-labs/o…
AlpinYukseloglu Mar 10, 2023
2acb254
Merge branch 'alpo-uptime-claim' into alpo-create-incentive
AlpinYukseloglu Mar 10, 2023
b07e763
[CL Incentives] Implement `CreateIncentive` logic and message (#4519)
AlpinYukseloglu Mar 10, 2023
bded5b6
Revert "[CL Incentives] Implement `CreateIncentive` logic and message…
AlpinYukseloglu Mar 10, 2023
58a6f96
Merge branch 'alpo-create-incentive' into alpo-early-withdrawals-new
AlpinYukseloglu Mar 10, 2023
fd86d6a
make unit tests more robust
AlpinYukseloglu Mar 12, 2023
8ffa117
minor comment cleanup
AlpinYukseloglu Mar 12, 2023
0e4c1ca
Merge branch 'main' into alpo-uptime-claim
AlpinYukseloglu Mar 15, 2023
4cd2975
fix conflicts
AlpinYukseloglu Mar 15, 2023
f9d3efa
Merge branch 'alpo-uptime-claim' into alpo-create-incentive
AlpinYukseloglu Mar 15, 2023
3fcef27
Merge branch 'alpo-create-incentive' into alpo-early-withdrawals-new
AlpinYukseloglu Mar 15, 2023
82acd75
Merge branch 'main' into alpo-create-incentive
AlpinYukseloglu Mar 15, 2023
a10d0cd
Merge branch 'alpo-create-incentive' into alpo-early-withdrawals-new
AlpinYukseloglu Mar 15, 2023
972a2f5
Merge branch 'main' into alpo-early-withdrawals-new
AlpinYukseloglu Mar 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/Jeffail/gabs/v2 v2.6.0 h1:WdCnGaDhNa4LSRTMwhLZzJ7SRDXjABNP13SOKvCpL5w=
github.com/Jeffail/gabs/v2 v2.6.0/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
Expand Down
8 changes: 8 additions & 0 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,11 @@ func GetUptimeTrackerValues(uptimeTrackers []model.UptimeTracker) []sdk.DecCoins
func (k Keeper) CreateIncentive(ctx sdk.Context, poolId uint64, sender sdk.AccAddress, incentiveDenom string, incentiveAmount sdk.Int, emissionRate sdk.Dec, startTime time.Time, minUptime time.Duration) (types.IncentiveRecord, error) {
return k.createIncentive(ctx, poolId, sender, incentiveDenom, incentiveAmount, emissionRate, startTime, minUptime)
}

func PrepareAccumAndClaimRewards(accum accum.AccumulatorObject, positionKey string, growthOutside sdk.DecCoins) (sdk.Coins, error) {
return prepareAccumAndClaimRewards(accum, positionKey, growthOutside)
}

func (k Keeper) ClaimAllIncentivesForPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick int64, upperTick int64, joinTime time.Time, freezeDuration time.Duration, forfeitIncentives bool) (sdk.Coins, error) {
return k.claimAllIncentivesForPosition(ctx, poolId, owner, lowerTick, upperTick, joinTime, freezeDuration, forfeitIncentives)
}
27 changes: 2 additions & 25 deletions x/concentrated-liquidity/fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const (
uintBase = 10
)

var (
emptyCoins = sdk.DecCoins(nil)
)
var emptyCoins = sdk.DecCoins(nil)

// createFeeAccumulator creates an accumulator object in the store using the given poolId.
// The accumulator is initialized with the default(zero) values.
Expand Down Expand Up @@ -216,32 +214,11 @@ func (k Keeper) collectFees(ctx sdk.Context, poolId uint64, owner sdk.AccAddress
return sdk.Coins{}, err
}

// replace position's accumulator before calculating unclaimed rewards
err = preparePositionAccumulator(feeAccumulator, positionKey, feeGrowthOutside)
if err != nil {
return sdk.Coins{}, err
}

// claim fees.
feesClaimed, err := feeAccumulator.ClaimRewards(positionKey)
if err != nil {
return sdk.Coins{}, err
}

// Check if feeAccumulator was deleted after claiming rewards. If not, we update the custom accumulator value.
hasPosition, err = feeAccumulator.HasPosition(positionKey)
feesClaimed, err := prepareAccumAndClaimRewards(feeAccumulator, positionKey, feeGrowthOutside)
if err != nil {
return sdk.Coins{}, err
}

if hasPosition {
customAccumulatorValue := feeAccumulator.GetValue().Sub(feeGrowthOutside)
err := feeAccumulator.SetPositionCustomAcc(positionKey, customAccumulatorValue)
if err != nil {
return sdk.Coins{}, err
}
}

// Once we have iterated through all the positions, we do a single bank send from the pool to the owner.
pool, err := k.getPoolById(ctx, poolId)
if err != nil {
Expand Down
119 changes: 75 additions & 44 deletions x/concentrated-liquidity/incentives.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,28 +416,44 @@ func (k Keeper) initOrUpdatePositionUptime(ctx sdk.Context, poolId uint64, liqui
return nil
}

// collectIncentives collects incentives for all uptime accumulators for all positions belonging to `owner` that have exactly
// the same lower and upper ticks.
//
// Upon successful collection, it bank sends the incentives from the pool address to the owner and returns the collected coins.
// Returns error if:
// - pool with the given id does not exist
// - no position given by pool id, owner, lower tick and upper tick exists
// - other internal database or math errors.
func (k Keeper) collectIncentives(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick int64, upperTick int64) (sdk.Coins, error) {
uptimeAccumulators, err := k.getUptimeAccumulators(ctx, poolId)
// prepareAccumAndClaimRewards claims and returns the rewards that `positionKey` is entitled to, updating the accumulator's value before
// and after claiming to ensure that rewards are never overdistributed.
func prepareAccumAndClaimRewards(accum accum.AccumulatorObject, positionKey string, growthOutside sdk.DecCoins) (sdk.Coins, error) {
err := preparePositionAccumulator(accum, positionKey, growthOutside)
if err != nil {
return sdk.Coins{}, err
}

// Get all of owner's positions with the same lower and upper ticks
positionsInRange, err := osmoutils.GatherValuesFromStorePrefixWithKeyParser(ctx.KVStore(k.storeKey), types.KeyPosition(poolId, owner, lowerTick, upperTick), ParseFullPositionFromBytes)
// Claim incentives
incentivesClaimedCurrAccum, err := accum.ClaimRewards(positionKey)
if err != nil {
return sdk.Coins{}, err
}

if len(positionsInRange) == 0 {
return sdk.Coins{}, types.PositionNotFoundError{PoolId: poolId, LowerTick: lowerTick, UpperTick: upperTick}
// Check if position record was deleted after claiming rewards. If not, we update the custom accumulator value.
hasPosition, err := accum.HasPosition(positionKey)
if err != nil {
return sdk.Coins{}, err
}

if hasPosition {
customAccumulatorValue := accum.GetValue().Sub(growthOutside)
err := accum.SetPositionCustomAcc(positionKey, customAccumulatorValue)
if err != nil {
return sdk.Coins{}, err
}
}

return incentivesClaimedCurrAccum, nil
}

// claimAllIncentivesForPosition claims and returns all the incentives for a given position.
// It takes in a `forfeitIncentives` boolean to indicate whether the accrued incentives should be forfeited, in which case it
// redeposits the accrued rewards back into the accumulator as additional rewards for other participants.
Comment on lines +450 to +452
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor test case I think would be good to see is that, if we have three positions (one 20%, one 50%, and one 30%) that get created at the same time, if the 20% forfeits rewards that is is properly distributed between the 50% and 30% proportionally. Not at all blocking, just something I thought would be good to verify.

func (k Keeper) claimAllIncentivesForPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick int64, upperTick int64, joinTime time.Time, freezeDuration time.Duration, forfeitIncentives bool) (sdk.Coins, error) {
uptimeAccumulators, err := k.getUptimeAccumulators(ctx, poolId)
if err != nil {
return sdk.Coins{}, err
}

// Compute uptime growth outside of the range between lower tick and upper tick
Expand All @@ -446,52 +462,67 @@ func (k Keeper) collectIncentives(ctx sdk.Context, poolId uint64, owner sdk.AccA
return sdk.Coins{}, err
}

collectedIncentives := sdk.Coins{}
for _, position := range positionsInRange {
positionName := string(types.KeyFullPosition(poolId, owner, lowerTick, upperTick, position.JoinTime, position.FreezeDuration))
positionName := string(types.KeyFullPosition(poolId, owner, lowerTick, upperTick, joinTime, freezeDuration))
collectedIncentivesForPosition := sdk.Coins{}
for uptimeIndex, uptimeAccum := range uptimeAccumulators {
hasPosition, err := uptimeAccum.HasPosition(positionName)
if err != nil {
return sdk.Coins{}, err
}

for uptimeIndex, uptimeAccum := range uptimeAccumulators {
hasPosition, err := uptimeAccum.HasPosition(positionName)
if hasPosition {
collectedIncentivesForUptime, err := prepareAccumAndClaimRewards(uptimeAccum, positionName, uptimeGrowthOutside[uptimeIndex])
if err != nil {
return sdk.Coins{}, err
}

if hasPosition {
// Replace position's accumulator before calculating unclaimed rewards
err = preparePositionAccumulator(uptimeAccum, positionName, uptimeGrowthOutside[uptimeIndex])
if err != nil {
return sdk.Coins{}, err
}
// If the collected incentives are forfeited, we deposit them back into the accumulator to be distributed
// to other qualifying positions.
if forfeitIncentives {
uptimeAccum.AddToAccumulator(sdk.NewDecCoinsFromCoins(collectedIncentivesForUptime...))
}

// Claim incentives
incentivesClaimedCurrAccum, err := uptimeAccum.ClaimRewards(positionName)
if err != nil {
return sdk.Coins{}, err
}
collectedIncentives = collectedIncentives.Add(incentivesClaimedCurrAccum...)
collectedIncentivesForPosition = collectedIncentivesForPosition.Add(collectedIncentivesForUptime...)
}
}

// Check if position record was deleted after claiming rewards. If not, we update the custom accumulator value.
hasPosition, err = uptimeAccum.HasPosition(positionName)
if err != nil {
return sdk.Coins{}, err
}
return collectedIncentivesForPosition, nil
}

if hasPosition {
customAccumulatorValue := uptimeAccum.GetValue().Sub(uptimeGrowthOutside[uptimeIndex])
err := uptimeAccum.SetPositionCustomAcc(positionName, customAccumulatorValue)
if err != nil {
return sdk.Coins{}, err
}
}
}
// collectIncentives collects incentives for all uptime accumulators for all positions belonging to `owner` that have exactly
// the same lower and upper ticks.
//
// Upon successful collection, it bank sends the incentives from the pool address to the owner and returns the collected coins.
// Returns error if:
// - pool with the given id does not exist
// - no position given by pool id, owner, lower tick and upper tick exists
// - other internal database or math errors.
func (k Keeper) collectIncentives(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick int64, upperTick int64) (sdk.Coins, error) {
positionsInRange, err := osmoutils.GatherValuesFromStorePrefixWithKeyParser(ctx.KVStore(k.storeKey), types.KeyPosition(poolId, owner, lowerTick, upperTick), ParseFullPositionFromBytes)
if err != nil {
return sdk.Coins{}, err
}

if len(positionsInRange) == 0 {
return sdk.Coins{}, types.PositionNotFoundError{PoolId: poolId, LowerTick: lowerTick, UpperTick: upperTick}
}

collectedIncentives := sdk.Coins{}
for _, position := range positionsInRange {
collectedIncentivesForPosition, err := k.claimAllIncentivesForPosition(ctx, poolId, owner, lowerTick, upperTick, position.JoinTime, position.FreezeDuration, false)
if err != nil {
return sdk.Coins{}, err
}

collectedIncentives = collectedIncentives.Add(collectedIncentivesForPosition...)
}

// Once we have iterated through all the positions, we do a single bank send from the pool to the owner.
// We skip this step if collected incentives are zero.
if collectedIncentives.IsZero() {
return collectedIncentives, nil
}

pool, err := k.getPoolById(ctx, poolId)
if err != nil {
return sdk.Coins{}, err
Expand Down
Loading