launchpad_reward.gno
2.65 Kb ยท 103 lines
1package v1
2
3import (
4 "chain"
5 "chain/runtime"
6 "time"
7
8 "gno.land/r/gnoswap/access"
9 "gno.land/r/gnoswap/common"
10 "gno.land/r/gnoswap/halt"
11 "gno.land/r/gnoswap/launchpad"
12)
13
14// CollectRewardByDepositId collects reward from a specific deposit.
15//
16// Parameters:
17// - depositID: ID of the deposit to collect from
18//
19// Returns amount of reward collected.
20// Only callable by deposit owner.
21func (lp *launchpadV1) CollectRewardByDepositId(depositID string) int64 {
22 halt.AssertIsNotHaltedLaunchpad()
23 halt.AssertIsNotHaltedWithdraw()
24
25 previousRealm := runtime.PreviousRealm()
26 access.AssertIsUser(previousRealm)
27
28 caller := previousRealm.Address()
29 lp.assertIsDepositOwner(depositID, caller)
30
31 deposit := lp.mustGetDeposit(depositID)
32 currentHeight := runtime.ChainHeight()
33 currentTime := time.Now().Unix()
34
35 rewardTokenPath, rewardAmount, err := lp.collectDepositReward(deposit, currentHeight, currentTime)
36 if err != nil {
37 panic(err)
38 }
39
40 // Transfer reward token to depositor
41 if rewardAmount > 0 {
42 common.SafeGRC20Transfer(cross, rewardTokenPath, deposit.Depositor(), rewardAmount)
43 }
44
45 chain.Emit(
46 "CollectRewardByDepositId",
47 "prevAddr", caller.String(),
48 "prevRealm", previousRealm.PkgPath(),
49 "depositId", depositID,
50 "amount", formatInt(rewardAmount),
51 )
52
53 return rewardAmount
54}
55
56// collectDepositReward calculates and collects the reward for a deposit.
57func (lp *launchpadV1) collectDepositReward(deposit *launchpad.Deposit, currentHeight, currentTime int64) (string, int64, error) {
58 if currentTime <= 0 {
59 return "", 0, makeErrorWithDetails(errInvalidTime, "currentTime must be positive")
60 }
61
62 // Get project and tier data
63 project, err := lp.getProject(deposit.ProjectID())
64 if err != nil {
65 return "", 0, err
66 }
67
68 projectTier, err := getProjectTier(project, deposit.Tier())
69 if err != nil {
70 return "", 0, err
71 }
72
73 // Get reward manager
74 rewardManager, err := lp.getProjectTierRewardManager(projectTier.ID())
75 if err != nil {
76 return "", 0, err
77 }
78
79 // Update reward state before collection
80 err = updateRewardPerDepositX128(rewardManager, getTierCurrentDepositAmount(projectTier), currentHeight, currentTime)
81 if err != nil {
82 return "", 0, err
83 }
84
85 // Collect reward
86 rewardAmount, err := collectReward(rewardManager, deposit.ID(), currentTime)
87 if err != nil {
88 return "", 0, err
89 }
90
91 // Update total collected amount for the tier
92 if rewardAmount > 0 {
93 projectTier.SetTotalCollectedAmount(safeAddInt64(projectTier.TotalCollectedAmount(), rewardAmount))
94 project.SetTier(deposit.Tier(), projectTier)
95
96 projects := lp.store.GetProjects()
97 if err := lp.store.SetProjects(projects); err != nil {
98 return "", 0, err
99 }
100 }
101
102 return project.TokenPath(), rewardAmount, nil
103}