Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}