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

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