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