init.gno
5.66 Kb · 227 lines
1package v1
2
3import (
4 "time"
5
6 "gno.land/r/gnoswap/emission"
7
8 sr "gno.land/r/gnoswap/staker"
9)
10
11const (
12 defaultDepositGnsAmount = int64(1_000_000_000)
13 defaultMinimumRewardAmount = int64(1_000_000_000)
14
15 // unstakingFee is the fee charged when unstaking positions.
16 // This parameter can be modified through governance.
17 defaultUnstakingFee = uint64(100) // 1%
18)
19
20func init(cur realm) {
21 registerStakerV1(cur)
22}
23
24func registerStakerV1(cur realm) {
25 sr.RegisterInitializer(cross(cur), func(_ int, rlm realm, stakerStore sr.IStakerStore, poolAccessor sr.PoolAccessor, emissionAccessor sr.EmissionAccessor, nftAccessor sr.NFTAccessor) sr.IStaker {
26 if !rlm.IsCurrent() {
27 panic(errSpoofedRealm)
28 }
29
30 err := initStoreData(0, rlm, stakerStore, emissionAccessor)
31 if err != nil {
32 panic(err)
33 }
34
35 instance := NewStakerV1(stakerStore, poolAccessor, emissionAccessor, nftAccessor)
36 instance.setupSwapHooks(0, rlm)
37 emissionAccessor.SetOnDistributionPctChangeCallback(0, rlm, instance.emissionCacheUpdateHook)
38
39 return instance
40 })
41}
42
43func initStoreData(_ int, rlm realm, stakerStore sr.IStakerStore, emissionAccessor sr.EmissionAccessor) error {
44 if !stakerStore.HasDepositGnsAmountStoreKey() {
45 err := stakerStore.SetDepositGnsAmount(0, rlm, defaultDepositGnsAmount)
46 if err != nil {
47 return err
48 }
49 }
50
51 if !stakerStore.HasMinimumRewardAmountStoreKey() {
52 err := stakerStore.SetMinimumRewardAmount(0, rlm, defaultMinimumRewardAmount)
53 if err != nil {
54 return err
55 }
56 }
57
58 if !stakerStore.HasDepositsStoreKey() {
59 err := stakerStore.SetDeposits(0, rlm, sr.NewBPTreeN(16))
60 if err != nil {
61 return err
62 }
63 }
64
65 if !stakerStore.HasExternalIncentivesStoreKey() {
66 err := stakerStore.SetExternalIncentives(0, rlm, sr.NewBPTreeN(16))
67 if err != nil {
68 return err
69 }
70 }
71
72 if !stakerStore.HasTotalEmissionSentStoreKey() {
73 err := stakerStore.SetTotalEmissionSent(0, rlm, 0)
74 if err != nil {
75 return err
76 }
77 }
78
79 if !stakerStore.HasAllowedTokensStoreKey() {
80 // Copy the package-level default slice so each store owns its own
81 // allowed-tokens slice. Storing sr.DefaultAllowedTokens directly would
82 // alias the shared (sr-owned) slice across every store, leaking
83 // mutations and tripping the readonly-taint gate on later writes.
84 err := stakerStore.SetAllowedTokens(0, rlm, sr.DefaultAllowedTokens())
85 if err != nil {
86 return err
87 }
88 }
89
90 if !stakerStore.HasIncentiveCounterStoreKey() {
91 err := stakerStore.SetIncentiveCounter(0, rlm, sr.NewCounter())
92 if err != nil {
93 return err
94 }
95 }
96
97 if !stakerStore.HasTokenSpecificMinimumRewardsStoreKey() {
98 err := stakerStore.SetTokenSpecificMinimumRewards(0, rlm, make(map[string]int64))
99 if err != nil {
100 return err
101 }
102 }
103
104 if !stakerStore.HasUnstakingFeeStoreKey() {
105 err := stakerStore.SetUnstakingFee(0, rlm, defaultUnstakingFee)
106 if err != nil {
107 return err
108 }
109 }
110
111 if !stakerStore.HasPendingProtocolFeesStoreKey() {
112 err := stakerStore.SetPendingProtocolFees(0, rlm, make(map[string]int64))
113 if err != nil {
114 return err
115 }
116 }
117
118 if !stakerStore.HasWarmupTemplateStoreKey() {
119 err := stakerStore.SetWarmupTemplate(0, rlm, sr.DefaultWarmupTemplate())
120 if err != nil {
121 return err
122 }
123 }
124
125 if !stakerStore.HasExternalIncentivesByCreationTimeStoreKey() {
126 err := stakerStore.SetExternalIncentivesByCreationTime(0, rlm, sr.NewUintTree())
127 if err != nil {
128 return err
129 }
130 }
131
132 initializedPoolTier, initializedPools := initializePoolTier(stakerStore)
133
134 if !stakerStore.HasPoolsStoreKey() {
135 err := stakerStore.SetPools(0, rlm, initializedPools.tree)
136 if err != nil {
137 return err
138 }
139 }
140
141 if !stakerStore.HasPoolTierMembershipsStoreKey() {
142 err := stakerStore.SetPoolTierMemberships(0, rlm, initializedPoolTier.membership)
143 if err != nil {
144 return err
145 }
146 }
147
148 if !stakerStore.HasPoolTierRatioStoreKey() {
149 err := stakerStore.SetPoolTierRatio(0, rlm, initializedPoolTier.tierRatio)
150 if err != nil {
151 return err
152 }
153 }
154
155 if !stakerStore.HasPoolTierCountsStoreKey() {
156 err := stakerStore.SetPoolTierCounts(0, rlm, initializedPoolTier.counts)
157 if err != nil {
158 return err
159 }
160 }
161
162 if !stakerStore.HasPoolTierLastRewardCacheTimestampStoreKey() {
163 err := stakerStore.SetPoolTierLastRewardCacheTimestamp(0, rlm, initializedPoolTier.lastRewardCacheTimestamp)
164 if err != nil {
165 return err
166 }
167 }
168
169 if !stakerStore.HasPoolTierCurrentEmissionStoreKey() {
170 err := stakerStore.SetPoolTierCurrentEmission(0, rlm, initializedPoolTier.currentEmission)
171 if err != nil {
172 return err
173 }
174 }
175
176 if !stakerStore.HasPoolTierGetEmissionStoreKey() {
177 getEmissionFn := func() int64 {
178 return emissionAccessor.GetStakerEmissionAmountPerSecond()
179 }
180
181 err := stakerStore.SetPoolTierGetEmission(0, rlm, getEmissionFn)
182 if err != nil {
183 return err
184 }
185 }
186
187 if !stakerStore.HasPoolTierGetHalvingBlocksInRangeStoreKey() {
188 getHalvingBlocksInRangeFn := func(start, end int64) ([]int64, []int64) {
189 return emissionAccessor.GetStakerEmissionAmountPerSecondInRange(start, end)
190 }
191
192 err := stakerStore.SetPoolTierGetHalvingBlocksInRange(0, rlm, getHalvingBlocksInRangeFn)
193 if err != nil {
194 return err
195 }
196 }
197
198 if !stakerStore.HasCurrentSwapBatchStoreKey() {
199 err := stakerStore.SetCurrentSwapBatch(0, rlm, nil)
200 if err != nil {
201 return err
202 }
203 }
204
205 return nil
206}
207
208func initializePoolTier(stakerStore sr.IStakerStore) (*PoolTier, *Pools) {
209 basicPoolPath := "gno.land/r/gnoland/wugnot:gno.land/r/gnoswap/gns:3000"
210
211 pools := NewPools()
212 pl := NewPools().GetPoolOrNil(basicPoolPath)
213 if pl == nil {
214 pl = sr.NewPool(basicPoolPath, time.Now().Unix())
215 pools.set(basicPoolPath, pl)
216 }
217
218 poolTier := NewPoolTier(
219 pools,
220 time.Now().Unix(),
221 basicPoolPath,
222 emission.GetStakerEmissionAmountPerSecond,
223 emission.GetStakerEmissionAmountPerSecondInRange,
224 )
225
226 return poolTier, pools
227}