Skip to content

Commit 59eb7aa

Browse files
committed
remove: reward_calculation from /launchpadr
1 parent 9ce175b commit 59eb7aa

10 files changed

+36
-530
lines changed

Diff for: contract/p/gnoswap/launchpad/reward_calculation.gno

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ type RewardState struct {
7373
// Getters for RewardState
7474
func (rs *RewardState) PriceAccumulation() *u256.Uint { return rs.priceAccumulation }
7575
func (rs *RewardState) TotalStake() uint64 { return rs.totalStake }
76+
func (rs *RewardState) SetTotalStake(amount uint64) { rs.totalStake = amount }
7677
func (rs *RewardState) LastHeight() uint64 { return rs.lastHeight }
7778
func (rs *RewardState) RewardPerBlock() *u256.Uint { return rs.rewardPerBlock }
7879
func (rs *RewardState) EndHeight() uint64 { return rs.endHeight }

Diff for: contract/r/gnoswap/launchpad/_helper_test.gno

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ var (
1313
adminAddr = consts.ADMIN
1414
adminUser = adminAddr
1515
adminRealm = std.NewUserRealm(adminAddr)
16+
17+
fooPath string = "gno.land/r/onbloc/foo"
18+
barPath string = "gno.land/r/onbloc/bar"
19+
bazPath string = "gno.land/r/onbloc/baz"
20+
quxPath string = "gno.land/r/onbloc/qux"
21+
22+
oblPath string = "gno.land/r/onbloc/obl"
1623
)
1724

1825
// MockXGNSToken implements basic functionality for testing xgns token

Diff for: contract/r/gnoswap/launchpad/api_deposit.gno

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ func ApiGetClaimableDepositByAddress(address std.Address) uint64 {
3131
}
3232

3333
rwd, _ := rewardStates.Get(deposit.projectId, deposit.tier)
34-
reward := rwd.Claim(depositId, uint64(std.GetHeight()))
34+
reward, err := rwd.Claim(depositId, uint64(std.GetHeight()))
35+
if err != nil {
36+
panic(err.Error())
37+
}
3538

3639
gnsToUser += reward
3740
}

Diff for: contract/r/gnoswap/launchpad/api_reward.gno

+11-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ func ApiGetDepositRewardByDepositId(depositId string) uint64 {
3636
return 0
3737
}
3838

39-
return rewardState.CalculateReward(depositId)
39+
res, err := rewardState.CalculateReward(depositId)
40+
if err != nil {
41+
return 0
42+
}
43+
44+
return res
4045
}
4146

4247
func ApiGetDepositRewardByAddress(address std.Address) uint64 {
@@ -59,7 +64,11 @@ func ApiGetDepositRewardByAddress(address std.Address) uint64 {
5964
if err != nil {
6065
continue
6166
}
62-
totalReward += rewardState.CalculateReward(depositId)
67+
reward, err := rewardState.CalculateReward(depositId)
68+
if err != nil {
69+
continue
70+
}
71+
totalReward += reward
6372
}
6473

6574
return totalReward

Diff for: contract/r/gnoswap/launchpad/deposit.gno

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"gno.land/r/gnoswap/v1/gns"
1414
gs "gno.land/r/gnoswap/v1/gov/staker"
1515
"gno.land/r/gnoswap/v1/gov/xgns"
16+
ppad "gno.land/p/gnoswap/v1/launchpad"
1617
)
1718

1819
var (
@@ -153,7 +154,7 @@ func DepositGns(targetProjectTierId string, amount uint64) string {
153154
"tierAmountPerBlockX128", tier.TierAmountPerBlockX128().ToString(),
154155
)
155156

156-
rewardState := NewRewardState(tier.tierAmountPerBlockX128, tier.started.height, tier.ended.height)
157+
rewardState := ppad.NewRewardState(tier.tierAmountPerBlockX128, tier.started.height, tier.ended.height)
157158
rewardStates.Set(info.Project.id, info.TierType, rewardState)
158159
}
159160

Diff for: contract/r/gnoswap/launchpad/launchpad.gno

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import (
1313
"gno.land/p/gnoswap/consts"
1414
"gno.land/r/gnoswap/v1/common"
1515
en "gno.land/r/gnoswap/v1/emission"
16-
"gno.land/r/gnoswap/v1/gns"
16+
17+
ppad "gno.land/p/gnoswap/v1/launchpad"
1718
)
1819

1920
var (
@@ -717,7 +718,7 @@ func createTier(
717718
reward: *reward,
718719
}
719720

720-
rewardState := NewRewardState(tier.tierAmountPerBlockX128, startHeight, endHeight)
721+
rewardState := ppad.NewRewardState(tier.tierAmountPerBlockX128, startHeight, endHeight)
721722
rewardStates.Set(projectId, strconv.FormatUint(duration, 10), rewardState)
722723

723724
projectTiersWithoutDeposit[tierId] = true

Diff for: contract/r/gnoswap/launchpad/reward_calculation.gno

+2-242
Original file line numberDiff line numberDiff line change
@@ -2,247 +2,7 @@
22
package launchpad
33

44
import (
5-
"gno.land/p/demo/avl"
6-
"gno.land/p/demo/ufmt"
7-
u256 "gno.land/p/gnoswap/uint256"
5+
ppad "gno.land/p/gnoswap/v1/launchpad"
86
)
97

10-
type StakerRewardInfo struct {
11-
StartHeight uint64 // height when launchpad started staking
12-
PriceDebt *u256.Uint // price debt per GNS stake, Q128
13-
Amount uint64 // amount of GNS staked
14-
Claimed uint64 // amount of reward claimed so far
15-
}
16-
17-
func (self *StakerRewardInfo) Debug() string {
18-
return ufmt.Sprintf("{ StartHeight: %d, PriceDebt: %d, Amount: %d, Claimed: %d }", self.StartHeight, self.PriceDebtUint64(), self.Amount, self.Claimed)
19-
}
20-
21-
func (self *StakerRewardInfo) PriceDebtUint64() uint64 {
22-
return u256.Zero().Rsh(self.PriceDebt, 128).Uint64()
23-
}
24-
25-
type RewardState struct {
26-
PriceAccumulation *u256.Uint // claimable Launchpad reward per xGNS stake, Q128
27-
TotalStake uint64 // total xGNS staked
28-
29-
LastHeight uint64 // last height when reward was calculated
30-
RewardPerBlock *u256.Uint // reward per block, = Tier.tierAmountPerBlockX128
31-
EndHeight uint64
32-
33-
TotalEmptyBlock uint64
34-
35-
info *avl.Tree // depositId -> StakerRewardInfo
36-
}
37-
38-
func NewRewardState(rewardPerBlock *u256.Uint, startHeight uint64, endHeight uint64) *RewardState {
39-
return &RewardState{
40-
PriceAccumulation: u256.Zero(),
41-
TotalStake: 0,
42-
LastHeight: startHeight,
43-
RewardPerBlock: rewardPerBlock,
44-
EndHeight: endHeight,
45-
info: avl.NewTree(),
46-
}
47-
}
48-
49-
func (self *RewardState) PriceAccumulationUint64() uint64 {
50-
return u256.Zero().Rsh(self.PriceAccumulation, 128).Uint64()
51-
}
52-
53-
func (self *RewardState) RewardPerBlockUint64() uint64 {
54-
return u256.Zero().Rsh(self.RewardPerBlock, 128).Uint64()
55-
}
56-
57-
func (self *RewardState) Debug() string {
58-
return ufmt.Sprintf("{ PriceAccumulation: %d, TotalStake: %d, LastHeight: %d, RewardPerBlock: %d, EndHeight: %d, info: len(%d) }", self.PriceAccumulationUint64(), self.TotalStake, self.LastHeight, self.RewardPerBlockUint64(), self.EndHeight, self.info.Size())
59-
}
60-
61-
type RewardStates struct {
62-
states *avl.Tree // projectId:tier string -> RewardState
63-
}
64-
65-
var rewardStates = RewardStates{
66-
states: avl.NewTree(),
67-
}
68-
69-
func (states RewardStates) Get(projectId string, tierStr string) (*RewardState, error) {
70-
key := projectId + ":" + tierStr
71-
statesI, exists := states.states.Get(key)
72-
if !exists {
73-
return nil, ufmt.Errorf("reward state not found for projectId %s and tierStr %s", projectId, tierStr)
74-
}
75-
return statesI.(*RewardState), nil
76-
}
77-
78-
func (states RewardStates) Set(projectId string, tierStr string, state *RewardState) {
79-
key := projectId + ":" + tierStr
80-
states.states.Set(key, state)
81-
}
82-
83-
func (states RewardStates) DeleteProject(projectId string) uint64 {
84-
totalLeftover := uint64(0)
85-
keys := []string{}
86-
states.states.Iterate(projectId+":", projectId+";", func(key string, value interface{}) bool {
87-
state := value.(*RewardState)
88-
totalEmptyBlock := state.TotalEmptyBlock
89-
if state.TotalStake == 0 {
90-
totalEmptyBlock += state.EndHeight - state.LastHeight
91-
}
92-
totalEmptyBlockU256 := u256.NewUint(totalEmptyBlock)
93-
totalEmptyRewards := u256.Zero().Mul(totalEmptyBlockU256, state.RewardPerBlock)
94-
totalLeftover += totalEmptyRewards.Uint64()
95-
keys = append(keys, key)
96-
return false
97-
})
98-
99-
for _, key := range keys {
100-
states.states.Remove(key)
101-
}
102-
103-
return totalLeftover
104-
}
105-
106-
func (self *RewardState) Info(depositId string) StakerRewardInfo {
107-
infoI, exists := self.info.Get(depositId)
108-
if !exists {
109-
panic(addDetailToError(
110-
errNotExistDeposit, ufmt.Sprintf("(%s)", depositId)))
111-
}
112-
return infoI.(StakerRewardInfo)
113-
}
114-
115-
func (self *RewardState) CalculateReward(depositId string) uint64 {
116-
info := self.Info(depositId)
117-
stakerPrice := u256.Zero().Sub(self.PriceAccumulation, info.PriceDebt)
118-
reward := stakerPrice.Mul(stakerPrice, u256.NewUint(info.Amount))
119-
reward = reward.Rsh(reward, 128)
120-
return reward.Uint64() - info.Claimed
121-
}
122-
123-
// amount MUST be less than or equal to the amount of xGNS staked
124-
// This function does not check it
125-
func (self *RewardState) deductReward(depositId string, currentHeight uint64) uint64 {
126-
if currentHeight < self.LastHeight {
127-
panic(addDetailToError(
128-
errInvalidRewardState,
129-
ufmt.Sprintf("currentHeight %d is less than LastHeight %d", currentHeight, self.LastHeight)))
130-
}
131-
132-
deposit := deposits[depositId]
133-
if deposit.claimableHeight > currentHeight {
134-
panic(addDetailToError(
135-
errInvalidRewardState,
136-
ufmt.Sprintf("currentHeight %d is less than claimableHeight %d", currentHeight, deposit.claimableHeight)))
137-
}
138-
139-
info := self.Info(depositId)
140-
if info.StartHeight > currentHeight {
141-
panic(addDetailToError(
142-
errInvalidRewardState,
143-
ufmt.Sprintf("currentHeight %d is less than StartHeight %d", currentHeight, info.StartHeight)))
144-
}
145-
reward64 := self.CalculateReward(depositId)
146-
147-
if reward64 == 0 {
148-
return 0
149-
}
150-
151-
info.Claimed += reward64
152-
self.info.Set(depositId, info)
153-
154-
return reward64
155-
}
156-
157-
// This function MUST be called as a part of AddStake or RemoveStake
158-
// CurrentBalance / StakeChange / IsRemoveStake will be updated in those functions
159-
func (self *RewardState) finalize(currentHeight uint64) {
160-
if currentHeight <= self.LastHeight {
161-
// Not started yet
162-
return
163-
}
164-
if self.LastHeight >= self.EndHeight {
165-
// already ended
166-
return
167-
}
168-
if currentHeight > self.EndHeight {
169-
currentHeight = self.EndHeight
170-
}
171-
172-
diff := currentHeight - self.LastHeight
173-
delta := u256.NewUint(diff)
174-
delta = delta.Mul(delta, self.RewardPerBlock)
175-
176-
if self.TotalStake == uint64(0) {
177-
self.TotalEmptyBlock += diff
178-
self.LastHeight = currentHeight
179-
return
180-
}
181-
182-
price := delta.Div(delta, u256.NewUint(self.TotalStake))
183-
self.PriceAccumulation = u256.Zero().Add(self.PriceAccumulation, price)
184-
self.LastHeight = currentHeight
185-
}
186-
187-
func (self *RewardState) AddStake(currentHeight uint64, depositId string, amount uint64) {
188-
if self.info.Has(depositId) {
189-
panic(addDetailToError(
190-
errAlreadyExistDeposit,
191-
ufmt.Sprintf("depositId %s already exists", depositId)))
192-
}
193-
194-
self.finalize(currentHeight)
195-
196-
self.TotalStake += amount
197-
198-
if self.info.Has(depositId) {
199-
info := self.Info(depositId)
200-
info.PriceDebt.Add(info.PriceDebt, u256.NewUint(info.Amount))
201-
info.PriceDebt.Add(info.PriceDebt, u256.Zero().Mul(self.PriceAccumulation, u256.NewUint(amount)))
202-
info.PriceDebt.Div(info.PriceDebt, u256.NewUint(self.TotalStake))
203-
info.Amount += amount
204-
self.info.Set(depositId, info)
205-
return
206-
}
207-
208-
info := StakerRewardInfo{
209-
StartHeight: currentHeight,
210-
PriceDebt: self.PriceAccumulation.Clone(),
211-
Amount: amount,
212-
Claimed: 0,
213-
}
214-
215-
self.info.Set(depositId, info)
216-
}
217-
218-
func (self *RewardState) Claim(depositId string, currentHeight uint64) uint64 {
219-
if !self.info.Has(depositId) {
220-
panic(addDetailToError(
221-
errNotExistDeposit,
222-
ufmt.Sprintf("depositId %s", depositId)))
223-
}
224-
225-
self.finalize(currentHeight)
226-
227-
reward := self.deductReward(depositId, currentHeight)
228-
229-
return reward
230-
}
231-
232-
func (self *RewardState) RemoveStake(depositId string, amount uint64, currentHeight uint64) uint64 {
233-
if !self.info.Has(depositId) {
234-
panic(addDetailToError(
235-
errNotExistDeposit,
236-
ufmt.Sprintf("depositId %s", depositId)))
237-
}
238-
239-
self.finalize(currentHeight)
240-
241-
reward := self.deductReward(depositId, currentHeight)
242-
243-
self.info.Remove(depositId)
244-
245-
self.TotalStake -= amount
246-
247-
return reward
248-
}
8+
var rewardStates = ppad.NewRewardStates()

0 commit comments

Comments
 (0)