From ff7ab269010dc7d50ccf2abf78e5a5427060695d Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Fri, 27 Dec 2024 11:57:54 +0900 Subject: [PATCH] save --- launchpad/deposit.gno | 45 ++++++++++++++++++++++++ launchpad/project.gno | 29 +++++++++++++++ launchpad/reward.gno | 82 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 launchpad/deposit.gno create mode 100644 launchpad/project.gno create mode 100644 launchpad/reward.gno diff --git a/launchpad/deposit.gno b/launchpad/deposit.gno new file mode 100644 index 000000000..7780d4a3d --- /dev/null +++ b/launchpad/deposit.gno @@ -0,0 +1,45 @@ +package launchpad + + +import ( + "std" + + u256 "gno.land/p/gnoswap/uint256" + "gno.land/p/demo/avl" +) + +// DepositStore stores deposit-related metadata +type DepositStore struct { + // all deposits + deposits *avl.Tree // key: deposit ID, value: *Deposit + + // deposits by project + depositsByProject *avl.Tree // key: , value: []string(depositIds) + + // deposits by user + depositsByUser *avl.Tree // key: user address, value: []string(depositIds) + + // deposits by user & project + depositsByUserProject *avl.Tree // key: , value: []string(depositIds) +} + +// DepositManager implements the deposit manager +type DepositManager interface { + // AddDeposit adds a deposit to the store + AddDeposit(projectId string, user std.Address, amount uint64, tier string) (string, error) + + // GetDeposit returns the deposit by depositId + GetDeposit(depositId string) (*Deposit, error) + + // GetUserDeposits retrieves all of the user's deposits + GetUserDeposits(user std.Address) ([]*Deposit, error) + + // GetProjectDeposits retrieves all of the project's deposits + GetProjectDeposits(projectId string) ([]*Deposit, error) + + // CollectDeposit collects the deposit + CollectDeposit(depositId string, user std.Address) (uint64, error) + + // UpdateDepositReward updates the deposit's reward + UpdateDepositReward(depositId string, reward *u256.Uint) error +} \ No newline at end of file diff --git a/launchpad/project.gno b/launchpad/project.gno new file mode 100644 index 000000000..f66936527 --- /dev/null +++ b/launchpad/project.gno @@ -0,0 +1,29 @@ +package launchpad + +import ( + "std" + u256 "gno.land/p/gnoswap/uint256" + "gno.land/p/demo/avl" +) + +// ProjectStore stores project-related metadata +type ProjectStore struct { + // all projects + projects *avl.Tree // key: project ID, value: *Project + + // project information by tier + projectsByTier *avl.Tree // key: tier, value: []string(projectIds) + + // project information by status + projectsByStatus *avl.Tree // key: status, value: []string(projectIds) +} + +type ProjectManager interface { + CreateProject(name string, tokenPath string, recipient std.Address, params ProjectParams) (string, error) + GetProject(projectId string) (*Project, error) + UpdateProject(projectId string, params ProjectParams) error + GetProjectTiers(projectId string) (map[string]*Tier, error) // TODO: change type + IsProjectActive(projectId string) bool + GetProjectsByTier(tier string) ([]*Project, error) + GetProjectsByStatus(status ProjectStatus) ([]*Project, error) +} \ No newline at end of file diff --git a/launchpad/reward.gno b/launchpad/reward.gno new file mode 100644 index 000000000..9efd514ab --- /dev/null +++ b/launchpad/reward.gno @@ -0,0 +1,82 @@ +package launchpad + +import ( + "gno.land/p/demo/avl" + "gno.land/p/demo/ufmt" + + u256 "gno.land/p/gnoswap/uint256" +) + +var ( + rewardStore = NewRewardStore() // TODO: init? +) + +// RewardStore stores reward-related metadata +type RewardStore struct { + accumulatedRewards *avl.Tree // key: project ID, value: *u256.Uint + lastCalculatedHeight *avl.Tree // key: project ID, value: uint64 + rewardSnapshots *avl.Tree // key: , value: *RewardSnapshot +} + +func NewRewardStore() *RewardStore { + return &RewardStore{ + accumulatedRewards: avl.NewTree(), + lastCalculatedHeight: avl.NewTree(), + rewardSnapshots: avl.NewTree(), + } +} + +type RewardSnapshot struct { + Height uint64 + AccumulatedRewards *u256.Uint + TierRewards *avl.Tree // key: tier, value: *u256.Uint +} + +func (rs *RewardStore) CalculateRewards(pid string, height uint64) (*u256.Uint, error) { + lastHeight, exists := rs.lastCalculatedHeight.Get(pid) + if !exists { + lastHeight = uint64(0) + } + + lstHeight := lastHeight.(uint64) + if height <= lstHeight { + // return cached value if height already calculated + rwd, exists := rs.accumulatedRewards.Get(pid) + if !exists { + return u256.NewUint(0), nil + } + return rwd.(*u256.Uint), nil + } + + project, exists := projects[pid] // TODO: avl later + if !exists { + return nil, ufmt.Errorf("project(%s) not found", pid) + } + + // not started yet + if project.startHeight > height { + return u256.Zero(), nil + } + + // calculate rewards + totalReward := calculateProjectReward(&project, lstHeight, height) + + // update accumulated rewards + rs.accumulatedRewards.Set(pid, totalReward) + rs.lastCalculatedHeight.Set(pid, height) + + return totalReward, nil +} + +// func calculateProjectReward(proj *Project, startHeight, endHeight uint64) *u256.Uint { +// totalReward := u256.Zero() + +// tiers := []struct{ +// tier *Tier +// ratio uint64 +// }{ +// {&proj.tier30, proj.tier30Ratio}, +// {&proj.tier90, proj.tier90Ratio}, +// {&proj.tier180, proj.tier180Ratio}, +// } +// }