PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/launchpad/v1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v1
Namespace
gnoswap / launchpad
Files
23 (README)(gnomod.toml)
Exported functions
1
Module
gno.land/r/gnoswap/launchpad/v1
gno
0.9

Files (23)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • consts.gnogno
  • deposit.gnogno
  • emits.gnogno
  • errors.gnogno
  • getter_utils.gnogno
  • getter.gnogno
  • init.gnogno
  • instance.gnogno
  • launchpad_deposit.gnogno
  • launchpad_project.gnogno
  • launchpad_protocol_fee.gnogno
  • launchpad_reward.gnogno
  • launchpad_withdraw.gnogno
  • project_tier.gnogno
  • project.gnogno
  • render.gnogno
  • reward_manager.gnogno
  • reward_state.gnogno
  • state.gnogno
  • utils.gnogno
  • reward_manager.gnogno
    1package launchpad23import (4	"errors"56	ufmt "gno.land/p/nt/ufmt/v0"7	"gno.land/r/gnoswap/launchpad"8

    Functions

    • NewLaunchpadV1(launchpadStore interface {GetDepositCounter func() *gno.land/r/gnoswap/launchpad.Counter; GetDeposits func() *gno.land/p/nt/bptree/v0.BPTree; GetProjectRecipients func() *gno.land/p/nt/bptree/v0.BPTree; GetProjectTierRewardManagers func() *gno.land/p/nt/bptree/v0.BPTree; GetProjects func() *gno.land/p/nt/bptree/v0.BPTree; GetTotalGNSStakedAmount func() int64; HasDepositCounterStoreKey func() bool; HasDepositsKey func() bool; HasProjectRecipientsKey func() bool; HasProjectTierRewardManagersKey func() bool; HasProjectsKey func() bool; HasTotalGNSStakedAmountKey func() bool; NextDepositID func() string; SetDepositCounter func(int, .uverse.realm, *gno.land/r/gnoswap/launchpad.Counter) .uverse.error; SetDeposits func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetProjectRecipients func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetProjectTierRewardManagers func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetProjects func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetTotalGNSStakedAmount func(int, .uverse.realm, int64) .uverse.error}) interface {CollectDepositGns func(int, .uverse.realm, string) (int64, .uverse.error); CollectEmissionReward func(int, .uverse.realm); CollectProtocolFee func(int, .uverse.realm); CollectProtocolFeeReward func(int, .uverse.realm, string); CollectRewardByDepositId func(int, .uverse.realm, string) int64; CreateProject func(int, .uverse.realm, string, string, .uverse.address, int64, string, string, int64, int64, int64, int64) string; DepositGns func(int, .uverse.realm, string, int64, string) string; GetCurrentDepositId func() int64; GetDeposit func(string) (gno.land/r/gnoswap/launchpad.Deposit, .uverse.error); GetDepositAmount func(string) (int64, .uverse.error); GetDepositCount func() int; GetDepositCreatedAt func(string) (int64, .uverse.error); GetDepositCreatedHeight func(string) (int64, .uverse.error); GetDepositEndTime func(string) (int64, .uverse.error); GetDepositProjectID func(string) (string, .uverse.error); GetDepositProjectTierID func(string) (string, .uverse.error); GetDepositTier func(string) (int64, .uverse.error); GetDepositWithdrawnHeight func(string) (int64, .uverse.error); GetDepositWithdrawnTime func(string) (int64, .uverse.error); GetProjectActiveStatus func(string) (bool, .uverse.error); GetProjectCondition func(string, string) (*gno.land/r/gnoswap/launchpad.ProjectCondition, .uverse.error); GetProjectCreatedAt func(string) (int64, .uverse.error); GetProjectCreatedHeight func(string) (int64, .uverse.error); GetProjectDepositAmount func(string) (int64, .uverse.error); GetProjectName func(string) (string, .uverse.error); GetProjectRecipient func(string) (.uverse.address, .uverse.error); GetProjectTier func(string, int64) (*gno.land/r/gnoswap/launchpad.ProjectTier, .uverse.error); GetProjectTierDistributeAmountPerSecondX128 func(string, int64) (*gno.land/p/gnoswap/uint256/v1.Uint, .uverse.error); GetProjectTierEndTime func(string, int64) (int64, .uverse.error); GetProjectTierRewardAccumulatedDistributeAmount func(string) (int64, .uverse.error); GetProjectTierRewardAccumulatedRewardPerDepositX128 func(string) (*gno.land/p/gnoswap/uint256/v1.Uint, .uverse.error); GetProjectTierRewardAccumulatedTime func(string) (int64, .uverse.error); GetProjectTierRewardClaimableDuration func(string) (int64, .uverse.error); GetProjectTierRewardDistributeAmountPerSecondX128 func(string) (*gno.land/p/gnoswap/uint256/v1.Uint, .uverse.error); GetProjectTierRewardDistributeEndTime func(string) (int64, .uverse.error); GetProjectTierRewardDistributeStartTime func(string) (int64, .uverse.error); GetProjectTierRewardManager func(string) (*gno.land/r/gnoswap/launchpad.RewardManager, .uverse.error); GetProjectTierRewardManagerCount func() int; GetProjectTierRewardTotalClaimedAmount func(string) (int64, .uverse.error); GetProjectTierRewardTotalDistributeAmount func(string) (int64, .uverse.error); GetProjectTierRewards func(string, int64) *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree; GetProjectTierStartTime func(string, int64) (int64, .uverse.error); GetProjectTierTotalCollectedAmount func(string, int64) (int64, .uverse.error); GetProjectTierTotalDepositAmount func(string, int64) (int64, .uverse.error); GetProjectTierTotalDepositCount func(string, int64) (int64, .uverse.error); GetProjectTierTotalDistributeAmount func(string, int64) (int64, .uverse.error); GetProjectTierTotalWithdrawAmount func(string, int64) (int64, .uverse.error); GetProjectTierTotalWithdrawCount func(string, int64) (int64, .uverse.error); GetProjectTiersRatios func(string) (map[int64]int64, .uverse.error); GetProjectTokenPath func(string) (string, .uverse.error); GetProjects func() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree; GetRewardState func(string, string) (*gno.land/r/gnoswap/launchpad.RewardState, .uverse.error); GetTotalGNSStakedAmount func() int64; Render func(string) string; TransferLeftFromProjectByAdmin func(int, .uverse.realm, string, .uverse.address) int64}

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    Rendered

    RenderedRawgnoweb ↗
    This realm does not provide renderable output (vm/qrender → NoRenderDeclError). View on gnoweb ↗

    vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.

    9 gnsmath "gno.land/p/gnoswap/gnsmath/v1"
    10 u256 "gno.land/p/gnoswap/uint256/v1"
    11)
    12
    13// Helper functions for RewardManager
    14
    15func isRewardManagerInitialized(r *launchpad.RewardManager) bool {
    16 return r.Rewards().Size() > 0
    17}
    18
    19func getDepositRewardState(r *launchpad.RewardManager, depositId string) (*launchpad.RewardState, error) {
    20 rewardStateI := r.Rewards().Get(depositId)
    21 if rewardStateI == nil {
    22 return nil, makeErrorWithDetails(errNotExistDeposit, ufmt.Sprintf("(%s)", depositId))
    23 }
    24
    25 rewardState, ok := rewardStateI.(*launchpad.RewardState)
    26 if !ok {
    27 return nil, ufmt.Errorf("failed to cast rewardState to *launchpad.RewardState: %T", rewardStateI)
    28 }
    29
    30 return rewardState, nil
    31}
    32
    33func calculateRewardPerDepositX128(r *launchpad.RewardManager, rewardPerSecondX128 *u256.Uint, totalStaked int64, currentTime int64) (*u256.Uint, error) {
    34 accumulatedTime := r.AccumulatedTime()
    35 if r.DistributeStartTime() > accumulatedTime {
    36 accumulatedTime = r.DistributeStartTime()
    37 }
    38
    39 // not started yet
    40 if currentTime < accumulatedTime {
    41 return u256.Zero(), nil
    42 }
    43
    44 // past distribute end time
    45 if accumulatedTime > r.DistributeEndTime() {
    46 return u256.Zero(), nil
    47 }
    48
    49 // past distribute end time, set to distribute end time
    50 if currentTime > r.DistributeEndTime() {
    51 currentTime = r.DistributeEndTime()
    52 }
    53
    54 if rewardPerSecondX128.IsZero() {
    55 return nil, makeErrorWithDetails(
    56 errNoLeftReward,
    57 ufmt.Sprintf("rewardPerSecond(%d)", rewardPerSecondX128),
    58 )
    59 }
    60
    61 // no left reward
    62 if totalStaked == 0 {
    63 return u256.Zero(), nil
    64 }
    65
    66 // timeDuration * rewardPerSecond / totalStaked
    67 timeDuration := currentTime - accumulatedTime
    68 rewardPerDepositX128 := u256.MulDiv(
    69 u256.NewUintFromInt64(timeDuration),
    70 rewardPerSecondX128,
    71 u256.NewUintFromInt64(totalStaked),
    72 )
    73
    74 return rewardPerDepositX128, nil
    75}
    76
    77func addRewardStateByDeposit(r *launchpad.RewardManager, deposit launchpad.Deposit) *launchpad.RewardState {
    78 claimableTime := deposit.CreatedAt() + r.RewardClaimableDuration()
    79 if claimableTime > r.DistributeEndTime() {
    80 claimableTime = r.DistributeEndTime()
    81 }
    82
    83 rewardState := launchpad.NewRewardState(
    84 r.AccumulatedRewardPerDepositX128().Clone(),
    85 deposit.DepositAmount(),
    86 deposit.CreatedAt(),
    87 r.DistributeEndTime(),
    88 claimableTime,
    89 )
    90
    91 // if the first deposit, set the distribute start time
    92 if !isRewardManagerInitialized(r) {
    93 rewardState.SetDistributeStartTime(r.DistributeStartTime())
    94 rewardState.SetDistributeEndTime(r.DistributeEndTime())
    95 rewardState.SetAccumulatedTime(r.DistributeStartTime())
    96 rewardState.SetPriceDebtX128(u256.Zero())
    97 }
    98
    99 return addRewardState(r, deposit, rewardState)
    100}
    101
    102func addRewardState(r *launchpad.RewardManager, deposit launchpad.Deposit, rewardState *launchpad.RewardState) *launchpad.RewardState {
    103 addActiveRewardState(r, rewardState)
    104 r.SetReward(deposit.ID(), rewardState)
    105
    106 return rewardState
    107}
    108
    109func removeRewardState(r *launchpad.RewardManager, depositId string) error {
    110 rewardState, err := getDepositRewardState(r, depositId)
    111 if err != nil {
    112 return err
    113 }
    114
    115 removeActiveRewardState(r, rewardState)
    116 r.RemoveReward(depositId)
    117 return nil
    118}
    119
    120func addActiveRewardState(r *launchpad.RewardManager, rewardState *launchpad.RewardState) {
    121 debt, overflow := u256.Zero().MulOverflow(
    122 rewardState.PriceDebtX128(),
    123 u256.NewUintFromInt64(rewardState.DepositAmount()),
    124 )
    125 if overflow {
    126 panic(errors.New(errOverflow))
    127 }
    128
    129 r.SetActiveDepositAmount(gnsmath.SafeAddInt64(r.ActiveDepositAmount(), rewardState.DepositAmount()))
    130 r.SetActivePriceDebtX128(u256.Zero().Add(r.ActivePriceDebtX128(), debt))
    131}
    132
    133func removeActiveRewardState(r *launchpad.RewardManager, rewardState *launchpad.RewardState) {
    134 debt, overflow := u256.Zero().MulOverflow(
    135 rewardState.PriceDebtX128(),
    136 u256.NewUintFromInt64(rewardState.DepositAmount()),
    137 )
    138 if overflow {
    139 panic(errors.New(errOverflow))
    140 }
    141
    142 r.SetActiveDepositAmount(gnsmath.SafeSubInt64(r.ActiveDepositAmount(), rewardState.DepositAmount()))
    143 r.SetActiveClaimedAmount(gnsmath.SafeSubInt64(r.ActiveClaimedAmount(), rewardState.ClaimedAmount()))
    144 r.SetActivePriceDebtX128(u256.Zero().Sub(r.ActivePriceDebtX128(), debt))
    145}
    146
    147func addRewardPerDepositX128(r *launchpad.RewardManager, rewardPerDepositX128 *u256.Uint, currentTime int64) error {
    148 if rewardPerDepositX128.IsZero() {
    149 return nil
    150 }
    151
    152 if r.AccumulatedTime() > currentTime || r.DistributeStartTime() > currentTime {
    153 return nil
    154 }
    155
    156 if currentTime > r.DistributeEndTime() {
    157 currentTime = r.DistributeEndTime()
    158 }
    159
    160 accumulated := u256.Zero().Add(r.AccumulatedRewardPerDepositX128(), rewardPerDepositX128)
    161 r.SetAccumulatedRewardPerDepositX128(accumulated)
    162 r.SetAccumulatedTime(currentTime)
    163
    164 return nil
    165}
    166
    167// updateRewardPerDepositX128 updates the reward per deposit state.
    168// This function calculates and updates the accumulated reward per deposit
    169// based on the current total deposit amount and time.
    170//
    171// Parameters:
    172// - totalDepositAmount (int64): Current total deposit amount
    173// - time (int64): Current timestamp
    174//
    175// Returns:
    176// - error: If the update fails
    177func updateRewardPerDepositX128(r *launchpad.RewardManager, totalDepositAmount int64, currentTime int64) error {
    178 if currentTime <= 0 {
    179 return makeErrorWithDetails(errInvalidTime, "time must be positive")
    180 }
    181
    182 // Calculate and update rewards
    183 rewardPerDepositX128, err := calculateRewardPerDepositX128(
    184 r,
    185 r.DistributeAmountPerSecondX128(),
    186 totalDepositAmount,
    187 currentTime,
    188 )
    189 if err != nil {
    190 return err
    191 }
    192
    193 err = addRewardPerDepositX128(r, rewardPerDepositX128, currentTime)
    194 if err != nil {
    195 return err
    196 }
    197
    198 return nil
    199}
    200
    201func updateDistributeAmountPerSecondX128(r *launchpad.RewardManager, totalDistributeAmount int64, distributeStartTime int64, distributeEndTime int64) {
    202 // Use time duration for per-second calculation
    203 timeDuration := distributeEndTime - distributeStartTime
    204 if timeDuration <= 0 {
    205 return
    206 }
    207
    208 totalDistributeAmountX128 := u256.Zero().Lsh(
    209 u256.NewUintFromInt64(totalDistributeAmount),
    210 128,
    211 )
    212
    213 // Divide by time duration in seconds
    214 amountPerSecondX128 := u256.Zero().Div(
    215 totalDistributeAmountX128,
    216 u256.NewUintFromInt64(timeDuration),
    217 )
    218
    219 r.SetDistributeAmountPerSecondX128(amountPerSecondX128)
    220 r.SetDistributeStartTime(distributeStartTime)
    221 r.SetDistributeEndTime(distributeEndTime)
    222}
    223
    224// collectReward processes the reward collection for a specific deposit.
    225// This function ensures that the reward collection is valid and updates
    226// the claimed amount accordingly.
    227//
    228// Parameters:
    229// - depositId (string): The ID of the deposit
    230// - currentTime (int64): Current timestamp
    231//
    232// Returns:
    233// - int64: The amount of reward collected
    234// - error: If the collection fails
    235func collectReward(r *launchpad.RewardManager, depositId string, currentTime int64) (int64, error) {
    236 if currentTime < r.AccumulatedTime() {
    237 return 0, makeErrorWithDetails(
    238 errInvalidRewardState,
    239 ufmt.Sprintf("currentTime %d is less than AccumulatedTime %d", currentTime, r.AccumulatedTime()),
    240 )
    241 }
    242
    243 rewardState, err := getDepositRewardState(r, depositId)
    244 if err != nil {
    245 return 0, err
    246 }
    247
    248 if !isRewardStateClaimable(rewardState, currentTime) {
    249 return 0, makeErrorWithDetails(
    250 errInvalidRewardState,
    251 ufmt.Sprintf("currentTime %d is less than claimableTime %d", currentTime, rewardState.ClaimableTime()),
    252 )
    253 }
    254
    255 if currentTime < rewardState.DistributeStartTime() {
    256 return 0, makeErrorWithDetails(
    257 errInvalidRewardState,
    258 ufmt.Sprintf("currentTime %d is less than DistributeStartTime %d", currentTime, rewardState.DistributeStartTime()),
    259 )
    260 }
    261
    262 claimableReward := calculateClaimableReward(rewardState, r.AccumulatedRewardPerDepositX128())
    263 if claimableReward == 0 {
    264 return 0, nil
    265 }
    266
    267 rewardState.SetClaimedAmount(rewardState.ClaimedAmount() + claimableReward)
    268 rewards := r.Rewards()
    269 rewards.Set(depositId, rewardState)
    270 r.SetRewards(rewards)
    271 r.SetTotalClaimedAmount(r.TotalClaimedAmount() + claimableReward)
    272 r.SetActiveClaimedAmount(gnsmath.SafeAddInt64(r.ActiveClaimedAmount(), claimableReward))
    273
    274 return claimableReward, nil
    275}
    276
    277// newRewardManager returns a pointer to a new RewardManager with the given values.
    278func newRewardManager(
    279 totalDistributeAmount int64,
    280 distributeStartTime int64,
    281 distributeEndTime int64,
    282 rewardCollectableDuration int64,
    283) *launchpad.RewardManager {
    284 manager := launchpad.NewRewardManager(totalDistributeAmount, distributeStartTime, distributeEndTime, rewardCollectableDuration)
    285
    286 updateDistributeAmountPerSecondX128(manager, totalDistributeAmount, distributeStartTime, distributeEndTime)
    287
    288 return manager
    289}
    290
    291// calculateMaximumClaimableRewardsForActiveDeposits reserves every active
    292// claim without traversing the attacker-controlled reward tree. Aggregating
    293// before Q128 truncation retains rounding dust but cannot under-reserve claims.
    294func calculateMaximumClaimableRewardsForActiveDeposits(r *launchpad.RewardManager) int64 {
    295 reward, overflow := u256.Zero().MulOverflow(
    296 r.AccumulatedRewardPerDepositX128(),
    297 u256.NewUintFromInt64(r.ActiveDepositAmount()),
    298 )
    299 if overflow {
    300 panic(errors.New(errOverflow))
    301 }
    302
    303 reward = reward.Sub(reward, r.ActivePriceDebtX128()).Rsh(reward, 128)
    304 totalReward := gnsmath.SafeConvertToInt64(reward)
    305 if totalReward <= r.ActiveClaimedAmount() {
    306 return 0
    307 }
    308
    309 return gnsmath.SafeSubInt64(totalReward, r.ActiveClaimedAmount())
    310}
    311