PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

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

Realm
Open in gnoweb ↗

Overview

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

Files (19)

  • README.mdmarkdown
  • gnomod.tomltoml
  • counter.gnogno
  • deposit.gnogno
  • doc.gnogno
  • errors.gnogno
  • getter_utils.gnogno
  • getter.gnogno
  • project_condition.gnogno
  • project_tier.gnogno
  • project.gnogno
  • proxy.gnogno
  • render.gnogno
  • reward_manager.gnogno
  • reward_state.gnogno
  • state.gnogno
  • store.gnogno
  • types.gnogno
  • upgrade.gnogno
  • project.gnogno
    1package launchpad23import (4	ufmt "gno.land/p/nt/ufmt/v0"5)67// Project represents a launchpad project.8

    Functions

    • CollectDepositGns(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, depositID string) (int64, interface {Error func() string})

    • CollectEmissionReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

    • CollectProtocolFee(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

    • CollectProtocolFeeReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, tokenPath string)

    • CollectRewardByDepositId(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, depositID string) int64

    • CreateProject(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, tokenPath string, recipient string, depositAmount int64, conditionTokens string, conditionAmounts string, tier30Ratio int64, tier90Ratio int64, tier180Ratio int64, startTime int64) string

    • DefaultDeposit() struct{depositor .uverse.address; id string; projectID string; tier int64; depositAmount int64; withdrawnHeight int64; withdrawnTime int64; createdHeight int64; createdAt int64; endTime int64}

    • DepositGns(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, targetProjectTierID string, depositAmount int64, referrer string) string

    • GetCurrentDepositId() int64

    • GetDeposit(depositId string) (struct{depositor .uverse.address; id string; projectID string; tier int64; depositAmount int64; withdrawnHeight int64; withdrawnTime int64; createdHeight int64; createdAt int64; endTime int64}, interface {Error func() string})

    • GetDepositAmount(depositId string) (int64, interface {Error func() string})

    • GetDepositCount() int

    • GetDepositCreatedAt(depositId string) (int64, interface {Error func() string})

    • GetDepositCreatedHeight(depositId string) (int64, interface {Error func() string})

    • GetDepositEndTime(depositId string) (int64, interface {Error func() string})

    • GetDepositProjectID(depositId string) (string, interface {Error func() string})

    • GetDepositProjectTierID(depositId string) (string, interface {Error func() string})

    • GetDepositTier(depositId string) (int64, interface {Error func() string})

    • GetDepositWithdrawnHeight(depositId string) (int64, interface {Error func() string})

    • GetDepositWithdrawnTime(depositId string) (int64, interface {Error func() string})

    • GetImplementationPackagePath() string

    • GetProjectActiveStatus(projectId string) (bool, interface {Error func() string})

    • GetProjectCondition(projectId string, tokenPath string) (*gno.land/r/gnoswap/launchpad.ProjectCondition, interface {Error func() string})

    • GetProjectCreatedAt(projectId string) (int64, interface {Error func() string})

    • GetProjectCreatedHeight(projectId string) (int64, interface {Error func() string})

    • GetProjectDepositAmount(projectId string) (int64, interface {Error func() string})

    • GetProjectName(projectId string) (string, interface {Error func() string})

    • GetProjectRecipient(projectId string) (string, interface {Error func() string})

    • GetProjects() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

    • GetProjectTier(projectId string, tier int64) (*gno.land/r/gnoswap/launchpad.ProjectTier, interface {Error func() string})

    • GetProjectTierDistributeAmountPerSecondX128(projectId string, tier int64) (*gno.land/p/gnoswap/uint256/v1.Uint, interface {Error func() string})

    • GetProjectTierEndTime(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierRewardAccumulatedDistributeAmount(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardAccumulatedRewardPerDepositX128(projectTierId string) (*gno.land/p/gnoswap/uint256/v1.Uint, interface {Error func() string})

    • GetProjectTierRewardAccumulatedTime(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardClaimableDuration(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardDistributeAmountPerSecondX128(projectTierId string) (*gno.land/p/gnoswap/uint256/v1.Uint, interface {Error func() string})

    • GetProjectTierRewardDistributeEndTime(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardDistributeStartTime(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardManager(projectTierId string) (*gno.land/r/gnoswap/launchpad.RewardManager, interface {Error func() string})

    • GetProjectTierRewardManagerCount() int

    • GetProjectTierRewards(projectId string, tier int64) *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

    • GetProjectTierRewardTotalClaimedAmount(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTierRewardTotalDistributeAmount(projectTierId string) (int64, interface {Error func() string})

    • GetProjectTiersRatios(projectId string) (map[int64]int64, interface {Error func() string})

    • GetProjectTierStartTime(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalCollectedAmount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalDepositAmount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalDepositCount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalDistributeAmount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalWithdrawAmount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTierTotalWithdrawCount(projectId string, tier int64) (int64, interface {Error func() string})

    • GetProjectTokenPath(projectId string) (string, interface {Error func() string})

    • GetRewardState(projectTierId string, depositId string) (*gno.land/r/gnoswap/launchpad.RewardState, interface {Error func() string})

    • GetTotalGNSStakedAmount() int64

    • MakeDeposit(depositID string, projectID string, tier int64, depositor string, depositAmount int64, createdHeight int64, createdTime int64, endTime int64) struct{depositor .uverse.address; id string; projectID string; tier int64; depositAmount int64; withdrawnHeight int64; withdrawnTime int64; createdHeight int64; createdAt int64; endTime int64}

    • MakeProjectID(tokenPath string, createdHeight int64) string

    • MakeProjectTierID(projectID string, duration int64) string

    • NewBPTreeN(fanout int) *gno.land/p/nt/bptree/v0.BPTree

    • NewCounter() *gno.land/r/gnoswap/launchpad.Counter

    • NewLaunchpadStore(kvStore interface {AddAuthorizedCaller func(int, .uverse.realm, .uverse.address, gno.land/p/gnoswap/store/v1.Permission) .uverse.error; Delete func(int, .uverse.realm, string) .uverse.error; Get func(string) (interface {}, .uverse.error); GetAddress func(string) (.uverse.address, .uverse.error); GetAllKeys func() ([]string, .uverse.error); GetAuthorizedCallers func() (map[.uverse.address]gno.land/p/gnoswap/store/v1.Permission, .uverse.error); GetBPTree func(string) (*gno.land/p/nt/bptree/v0.BPTree, .uverse.error); GetBool func(string) (bool, .uverse.error); GetDomainAddress func() .uverse.address; GetInt64 func(string) (int64, .uverse.error); GetString func(string) (string, .uverse.error); GetUint64 func(string) (uint64, .uverse.error); Has func(string) bool; IsWriteAuthorized func(.uverse.address) bool; RemoveAuthorizedCaller func(int, .uverse.realm, .uverse.address) .uverse.error; Set func(int, .uverse.realm, string, interface {}) .uverse.error; UpdateAuthorizedCaller func(int, .uverse.realm, .uverse.address, gno.land/p/gnoswap/store/v1.Permission) .uverse.error}) 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}

    • NewProject(name string, tokenPath string, depositAmount int64, recipient string, createdHeight int64, createdAt int64) *gno.land/r/gnoswap/launchpad.Project

    • NewProjectCondition(tokenPath string, minimumAmount int64) *gno.land/r/gnoswap/launchpad.ProjectCondition

    • NewProjectConditionsWithError(conditionTokens string, conditionAmounts string) ([]*gno.land/r/gnoswap/launchpad.ProjectCondition, interface {Error func() string})

    • NewProjectTier(projectID string, tierDuration int64, totalDistributeAmount int64, startTime int64, endTime int64) *gno.land/r/gnoswap/launchpad.ProjectTier

    • NewRewardManager(totalDistributeAmount int64, distributeStartTime int64, distributeEndTime int64, rewardCollectableDuration int64) *gno.land/r/gnoswap/launchpad.RewardManager

    • NewRewardState(accumulatedRewardPerDepositX128 *gno.land/p/gnoswap/uint256/v1.Uint, depositAmount int64, distributeStartTime int64, distributeEndTime int64, claimableTime int64) *gno.land/r/gnoswap/launchpad.RewardState

    • RegisterInitializer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, initializer func(int, .uverse.realm, gno.land/r/gnoswap/launchpad.ILaunchpadStore) gno.land/r/gnoswap/launchpad.ILaunchpad)

    • Render(path string) string

    • TransferLeftFromProjectByAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, projectID string, recipient string) int64

    • UpgradeImpl(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, packagePath string)

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

    Rendered

    RenderedRawgnoweb ↗
    //
    9// This struct contains the necessary data and methods to manage and distribute
    10// rewards for a specific project.
    11//
    12// Fields:
    13// - id (string): The unique identifier for the project, formatted as "{tokenPath}:{createdHeight}".
    14// - name (string): The name of the project.
    15// - tokenPath (string): The path of the token associated with the project.
    16// - depositAmount (int64): The total amount of tokens deposited for the project.
    17// - recipient (address): The address to receive the project's rewards.
    18// - conditions (map[string]*ProjectCondition): A map of token paths to their associated conditions.
    19// - tiers (map[int64]*ProjectTier): A map of tier durations to their associated tiers.
    20// - tiersRatios (map[int64]int64): A map of tier durations to their associated ratios.
    21// - createdHeight (int64): The block height at which the project was created.
    22// - createdAt (int64): The Unix timestamp at which the project was created.
    23type Project struct {
    24 id string // 'tokenPath:createdHeight'
    25 name string
    26 tokenPath string
    27 depositAmount int64
    28 recipient address // string
    29 conditions map[string]*ProjectCondition // tokenPath -> Condition
    30 tiers map[int64]*ProjectTier
    31 tiersRatios map[int64]int64
    32 createdHeight int64
    33 createdAt int64
    34}
    35
    36// ID returns the project identifier in "{tokenPath}:{createdHeight}" form.
    37//
    38// Returns:
    39// - id: unique identifier assigned to this project.
    40func (p *Project) ID() string {
    41 return p.id
    42}
    43
    44// SetID replaces the project's identifier.
    45//
    46// Parameters:
    47// - id: project identifier to store, normally in "{tokenPath}:{createdHeight}" form.
    48func (p *Project) SetID(id string) {
    49 p.id = id
    50}
    51
    52// Name returns the project's human-readable name.
    53//
    54// Returns:
    55// - name: stored project name.
    56func (p *Project) Name() string {
    57 return p.name
    58}
    59
    60// SetName replaces the project's human-readable name.
    61//
    62// Parameters:
    63// - name: project name to store.
    64func (p *Project) SetName(name string) {
    65 p.name = name
    66}
    67
    68// TokenPath returns the token path whose tokens are distributed as project rewards.
    69//
    70// Returns:
    71// - tokenPath: configured project reward-token path.
    72func (p *Project) TokenPath() string {
    73 return p.tokenPath
    74}
    75
    76// SetTokenPath replaces the project's reward-token path.
    77//
    78// Parameters:
    79// - tokenPath: token path to store as the project's reward token.
    80func (p *Project) SetTokenPath(tokenPath string) {
    81 p.tokenPath = tokenPath
    82}
    83
    84// DepositAmount returns the total reward-token allocation configured for the project.
    85//
    86// Returns:
    87// - amount: project reward-token allocation.
    88func (p *Project) DepositAmount() int64 {
    89 return p.depositAmount
    90}
    91
    92// SetDepositAmount replaces the project's total reward-token allocation.
    93//
    94// Parameters:
    95// - amount: total reward-token amount allocated to the project.
    96func (p *Project) SetDepositAmount(amount int64) {
    97 p.depositAmount = amount
    98}
    99
    100// Recipient returns the address authorized to receive the project's rewards.
    101//
    102// Returns:
    103// - recipient: configured project recipient address.
    104func (p *Project) Recipient() address {
    105 return p.recipient
    106}
    107
    108// SetRecipient replaces the address authorized to receive project rewards.
    109//
    110// Parameters:
    111// - recipient: address to store as the project recipient.
    112func (p *Project) SetRecipient(recipient address) {
    113 p.recipient = recipient
    114}
    115
    116// Conditions returns a copy of the project's token deposit conditions.
    117//
    118// Returns:
    119// - conditions: map from token path to cloned condition values; mutations do not alter project state.
    120func (p *Project) Conditions() map[string]*ProjectCondition {
    121 conditions := make(map[string]*ProjectCondition)
    122
    123 for tokenPath, condition := range p.conditions {
    124 conditions[tokenPath] = condition.Clone()
    125 }
    126
    127 return conditions
    128}
    129
    130// SetConditions replaces the project's token deposit conditions.
    131// The map and its entries are retained in the project realm for later mutation.
    132//
    133// Parameters:
    134// - conditions: map from required token path to its deposit condition.
    135func (p *Project) SetConditions(conditions map[string]*ProjectCondition) {
    136 owned := make(map[string]*ProjectCondition, len(conditions))
    137 for tokenPath, condition := range conditions {
    138 owned[tokenPath] = condition
    139 }
    140 p.conditions = owned
    141}
    142
    143// SetCondition replaces one token-path deposit condition in the project-owned map.
    144//
    145// Parameters:
    146// - tokenPath: token path whose condition is replaced.
    147// - condition: required balance condition for that token path.
    148func (p *Project) SetCondition(tokenPath string, condition *ProjectCondition) {
    149 p.conditions[tokenPath] = condition
    150}
    151
    152// Tiers returns a copy of the project's configured duration-to-tier map.
    153//
    154// Returns:
    155// - tiers: map from tier duration in seconds to cloned tier values.
    156func (p *Project) Tiers() map[int64]*ProjectTier {
    157 tiers := make(map[int64]*ProjectTier)
    158
    159 for duration, tier := range p.tiers {
    160 tiers[duration] = tier.Clone()
    161 }
    162
    163 return tiers
    164}
    165
    166// SetTiers replaces the project's tier map with a project-owned map.
    167//
    168// Parameters:
    169// - tiers: map from tier duration in seconds to its tier configuration.
    170func (p *Project) SetTiers(tiers map[int64]*ProjectTier) {
    171 owned := make(map[int64]*ProjectTier, len(tiers))
    172 for duration, tier := range tiers {
    173 owned[duration] = tier
    174 }
    175 p.tiers = owned
    176}
    177
    178// TiersRatios returns reward allocation ratios keyed by tier duration.
    179//
    180// Returns:
    181// - ratios: map from tier duration in seconds to its allocation ratio.
    182func (p *Project) TiersRatios() map[int64]int64 {
    183 return p.tiersRatios
    184}
    185
    186// SetTiersRatios replaces the project's tier allocation ratios.
    187//
    188// Parameters:
    189// - tiersRatios: map from tier duration in seconds to its reward allocation ratio.
    190func (p *Project) SetTiersRatios(tiersRatios map[int64]int64) {
    191 p.tiersRatios = tiersRatios
    192}
    193
    194// CreatedHeight returns the block height at which the project was created.
    195//
    196// Returns:
    197// - height: project creation block height.
    198func (p *Project) CreatedHeight() int64 {
    199 return p.createdHeight
    200}
    201
    202// SetCreatedHeight replaces the project's creation block height.
    203//
    204// Parameters:
    205// - height: block height to store as the project creation height.
    206func (p *Project) SetCreatedHeight(height int64) {
    207 p.createdHeight = height
    208}
    209
    210// CreatedAt returns the Unix timestamp at which the project was created.
    211//
    212// Returns:
    213// - time: project creation Unix timestamp.
    214func (p *Project) CreatedAt() int64 {
    215 return p.createdAt
    216}
    217
    218// SetCreatedAt replaces the project's creation timestamp.
    219//
    220// Parameters:
    221// - time: Unix timestamp to store as the project creation time.
    222func (p *Project) SetCreatedAt(time int64) {
    223 p.createdAt = time
    224}
    225
    226// GetTier returns a copy of the project's tier for one duration.
    227//
    228// Parameters:
    229// - duration: tier duration in seconds.
    230//
    231// Returns:
    232// - tier: cloned tier configuration for the duration, or nil when absent.
    233// - err: non-nil when no tier is configured for duration.
    234func (p *Project) GetTier(duration int64) (*ProjectTier, error) {
    235 tier, exists := p.tiers[duration]
    236 if !exists {
    237 return nil, ufmt.Errorf("tier(%d) not found", duration)
    238 }
    239
    240 return tier.Clone(), nil
    241}
    242
    243// SetTier replaces one duration entry in the project-owned tier map.
    244//
    245// Parameters:
    246// - duration: tier duration in seconds used as the map key.
    247// - tier: tier configuration to store for duration.
    248func (p *Project) SetTier(duration int64, tier *ProjectTier) {
    249 p.tiers[duration] = tier
    250}
    251
    252// IsRecipient reports whether recipient matches the project's configured recipient address.
    253//
    254// Parameters:
    255// - recipient: address to compare with the configured project recipient.
    256//
    257// Returns:
    258// - matches: true when recipient is the configured project recipient.
    259func (p *Project) IsRecipient(recipient address) bool {
    260 return p.recipient == recipient
    261}
    262
    263// NewProject creates a project with empty conditions, tiers, and tier-ratio maps.
    264//
    265// Parameters:
    266// - name: human-readable project name.
    267// - tokenPath: token path whose tokens are distributed as project rewards.
    268// - depositAmount: total reward-token amount allocated to the project.
    269// - recipient: address authorized to receive project rewards.
    270// - createdHeight: block height at which the project is created.
    271// - createdAt: Unix timestamp at which the project is created.
    272//
    273// Returns:
    274// - project: initialized project with an ID derived from tokenPath and createdHeight.
    275func NewProject(
    276 name string,
    277 tokenPath string,
    278 depositAmount int64,
    279 recipient address,
    280 createdHeight int64,
    281 createdAt int64,
    282) *Project {
    283 return &Project{
    284 id: MakeProjectID(tokenPath, createdHeight),
    285 name: name,
    286 tokenPath: tokenPath,
    287 depositAmount: depositAmount,
    288 recipient: recipient,
    289 conditions: make(map[string]*ProjectCondition),
    290 tiers: make(map[int64]*ProjectTier),
    291 tiersRatios: make(map[int64]int64),
    292 createdHeight: createdHeight,
    293 createdAt: createdAt,
    294 }
    295}
    296
    297// Clone returns a deep-enough copy of the project for independent map and nested
    298// condition/tier mutation; scalar fields are copied directly.
    299//
    300// Returns:
    301// - clone: project copy with independently allocated condition, tier, and ratio maps.
    302func (p Project) Clone() *Project {
    303 conditions := make(map[string]*ProjectCondition)
    304 for k, v := range p.conditions {
    305 conditions[k] = v.Clone()
    306 }
    307
    308 tiers := make(map[int64]*ProjectTier)
    309 for k, v := range p.tiers {
    310 tiers[k] = v.Clone()
    311 }
    312
    313 tiersRatios := make(map[int64]int64)
    314 for k, v := range p.tiersRatios {
    315 tiersRatios[k] = v
    316 }
    317
    318 return &Project{
    319 id: p.id,
    320 name: p.name,
    321 tokenPath: p.tokenPath,
    322 depositAmount: p.depositAmount,
    323 recipient: p.recipient,
    324 conditions: conditions,
    325 tiers: tiers,
    326 tiersRatios: tiersRatios,
    327 createdHeight: p.createdHeight,
    328 createdAt: p.createdAt,
    329 }
    330}
    331
    332// MakeProjectID combines a token path and creation height into a project identifier.
    333//
    334// Parameters:
    335// - tokenPath: token path associated with the project.
    336// - createdHeight: block height at which the project was created.
    337//
    338// Returns:
    339// - projectID: identifier in "{tokenPath}:{createdHeight}" form.
    340func MakeProjectID(tokenPath string, createdHeight int64) string {
    341 return ufmt.Sprintf("%s:%d", tokenPath, createdHeight)
    342}
    343

    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.