Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

launchpad_reward.gno

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