Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}