Skip to content

Commit

Permalink
Merge branch 'refactor-launchpad' of https://github.com/gnoswap-labs/…
Browse files Browse the repository at this point in the history
…gnoswap into refactor-launchpad
  • Loading branch information
onlyhyde committed Jan 8, 2025
2 parents dab5b78 + cc5dbb2 commit 189add5
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 220 deletions.
8 changes: 7 additions & 1 deletion launchpad/_helper_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ import (

"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/testutils"
"gno.land/p/demo/ufmt"
pusers "gno.land/p/demo/users"
"gno.land/r/demo/users"
"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"
)

var (
adminAddr = consts.ADMIN
adminUser = common.AddrToUser(adminAddr)
adminRealm = std.NewUserRealm(adminAddr)
)

// MockXGNSToken implements basic functionality for testing xgns token
type MockXGNSToken struct {
token *grc20.Token
Expand Down
178 changes: 91 additions & 87 deletions launchpad/deposit.gno
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ func isTierActive(tier Tier, height uint64) bool {
// createDeposit creates a new deposit entry
func createDeposit(info ProjectTierInfo, amount uint64) (Deposit, error) {
depositor := std.PrevRealm().Addr()
depositId := ufmt.Sprintf("%s:%s:%s:%d",
info.Project.id,
info.TierStr,
depositor.String(),
depositId := ufmt.Sprintf("%s:%s:%s:%d",
info.Project.id,
info.TierStr,
depositor.String(),
info.Height,
)

Expand Down Expand Up @@ -127,7 +127,7 @@ func updateDepositIndices(deposit Deposit, state *DepositState) {
state.DepositsByUser[deposit.depositor] = []string{}
}
state.DepositsByUser[deposit.depositor] = append(
state.DepositsByUser[deposit.depositor],
state.DepositsByUser[deposit.depositor],
deposit.id,
)

Expand All @@ -139,7 +139,7 @@ func updateDepositIndices(deposit Deposit, state *DepositState) {
state.DepositsByProject[deposit.projectId][deposit.tier] = []string{}
}
state.DepositsByProject[deposit.projectId][deposit.tier] = append(
state.DepositsByProject[deposit.projectId][deposit.tier],
state.DepositsByProject[deposit.projectId][deposit.tier],
deposit.id,
)

Expand All @@ -151,7 +151,7 @@ func updateDepositIndices(deposit Deposit, state *DepositState) {
state.DepositsByUserProject[deposit.depositor][deposit.projectId] = []string{}
}
state.DepositsByUserProject[deposit.depositor][deposit.projectId] = append(
state.DepositsByUserProject[deposit.depositor][deposit.projectId],
state.DepositsByUserProject[deposit.depositor][deposit.projectId],
deposit.id,
)
}
Expand Down Expand Up @@ -188,7 +188,7 @@ func DepositGns(targetProjectTierId string, amount uint64) string {

en.MintAndDistributeGns()

project = projects[projectId] // get updates project
project = projects[projectId] // get updates project
tier = getTier(project, tierStr) // get updates tier

// Update gov_staker to calculate project's recipient's reward
Expand Down Expand Up @@ -289,7 +289,7 @@ func processDepositCollection(
}

tier := getTier(project, dpst.tier)
if isTierActive(tier, height) || dpst.depositCollectHeight != 0 {
if !isPassedClaimableHeight(dpst, height) || dpst.depositCollectHeight != 0 {
continue
}

Expand Down Expand Up @@ -372,94 +372,94 @@ func processCollectedDeposits(dpsts []string, pid string) uint64 {
}

func validateDepositCollection(depositId string, caller std.Address) (Deposit, Project, error) {
deposit, exists := deposits[depositId]
if !exists {
return Deposit{}, Project{}, errors.New("deposit not found")
}
deposit, exists := deposits[depositId]
if !exists {
return Deposit{}, Project{}, errors.New("deposit not found")
}

project, exists := projects[deposit.projectId]
if !exists {
return Deposit{}, Project{}, errors.New("project not found")
}
project, exists := projects[deposit.projectId]
if !exists {
return Deposit{}, Project{}, errors.New("project not found")
}

if _, exists := depositsByUserByProject[caller]; !exists {
return Deposit{}, Project{}, errors.New("no deposits for this user")
}
if _, exists := depositsByUserByProject[caller]; !exists {
return Deposit{}, Project{}, errors.New("no deposits for this user")
}

return deposit, project, nil
return deposit, project, nil
}

// receive deposit and project as an pointer to avoid copying
func processDeposit(deposit *Deposit, project *Project, height uint64) (uint64, error) {
tier := getTier(*project, deposit.tier)
if isTierActive(tier, height) {
return 0, errors.New("tier is still active")
}

if deposit.depositCollectHeight != 0 {
return 0, errors.New("deposit already collected")
}

// Update deposit status
deposit.depositCollectHeight = height
deposit.depositCollectTime = uint64(time.Now().Unix())
deposits[deposit.id] = *deposit

// Update project tier
tier.actualDepositAmount -= deposit.amount
tier.actualParticipant--

// Update project
*project = setTier(*project, deposit.tier, tier)
project.stats.actualDeposit -= deposit.amount
project.stats.actualParticipant--
projects[deposit.projectId] = *project

return deposit.amount, nil
tier := getTier(*project, deposit.tier)
if isTierActive(tier, height) {
return 0, errors.New("tier is still active")
}

if deposit.depositCollectHeight != 0 {
return 0, errors.New("deposit already collected")
}

// Update deposit status
deposit.depositCollectHeight = height
deposit.depositCollectTime = uint64(time.Now().Unix())
deposits[deposit.id] = *deposit

// Update project tier
tier.actualDepositAmount -= deposit.amount
tier.actualParticipant--

// Update project
*project = setTier(*project, deposit.tier, tier)
project.stats.actualDeposit -= deposit.amount
project.stats.actualParticipant--
projects[deposit.projectId] = *project

return deposit.amount, nil
}

func CollectDepositGnsByDepositId(depositId string) uint64 {
common.IsHalted()
caller := std.PrevRealm().Addr()

// Validate deposit collection request
deposit, project, err := validateDepositCollection(depositId, caller)
if err != nil {
return 0
}

en.MintAndDistributeGns()

project = projects[deposit.projectId] // get updated project

// Process deposit collection
height := uint64(std.GetHeight())
amount, err := processDeposit(&deposit, &project, height)
if err != nil {
return 0
}

// Update gov_staker contract
gs.SetAmountByProjectWallet(project.recipient, amount, false)

// Emit collection event
prevAddr, prevRealm := getPrev()
std.Emit(
"CollectDepositGnsByDepositId",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"depositId", depositId,
"amount", ufmt.Sprintf("%d", amount),
)

// Process token transfers if amount > 0
if amount > 0 {
xgns.Burn(a2u(consts.LAUNCHPAD_ADDR), amount)
gns.Transfer(a2u(caller), amount)
return amount
}

return 0
caller := std.PrevRealm().Addr()

// Validate deposit collection request
deposit, project, err := validateDepositCollection(depositId, caller)
if err != nil {
return 0
}

en.MintAndDistributeGns()

project = projects[deposit.projectId] // get updated project

// Process deposit collection
height := uint64(std.GetHeight())
amount, err := processDeposit(&deposit, &project, height)
if err != nil {
return 0
}

// Update gov_staker contract
gs.SetAmountByProjectWallet(project.recipient, amount, false)

// Emit collection event
prevAddr, prevRealm := getPrev()
std.Emit(
"CollectDepositGnsByDepositId",
"prevAddr", prevAddr,
"prevRealm", prevRealm,
"depositId", depositId,
"amount", ufmt.Sprintf("%d", amount),
)

// Process token transfers if amount > 0
if amount > 0 {
xgns.Burn(a2u(consts.LAUNCHPAD_ADDR), amount)
gns.Transfer(a2u(caller), amount)
return amount
}

return 0
}

func getProjectIdFromTierId(tierId string) string {
Expand Down Expand Up @@ -499,7 +499,7 @@ func checkDepositConditions(project Project) {
if condition.minAmount == 0 {
continue
}

// check balance
var balance uint64
if condition.tokenPath == consts.GOV_XGNS_PATH {
Expand Down Expand Up @@ -573,3 +573,7 @@ func setTier(project Project, tierStr string, tier Tier) Project {

return project
}

func isPassedClaimableHeight(deposit Deposit, height uint64) bool {
return deposit.claimableHeight <= height
}
15 changes: 10 additions & 5 deletions launchpad/deposit_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package launchpad

import (
"std"
"strings"
"testing"
"time"

"gno.land/p/demo/testutils"
"gno.land/p/demo/uassert"
"gno.land/p/demo/ufmt"

"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"
"gno.land/r/gnoswap/v1/gov/xgns"

"gno.land/r/gnoswap/v1/gns"
)

// Mock data structs
Expand Down Expand Up @@ -320,21 +321,24 @@ func TestDepositGns(t *testing.T) {

t.Run("Fail with insufficient balance", func(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(testAddr))
mockTeller.balance = 500 // Less than required deposit amount

defer func() {
r := recover()
if r != nil {
t.Fatalf("Recovered from panic: %v", r)
t.Logf("Recovered from panic: %v", r)
}
}()

DepositGns(project.id+":30", 1000)
})

t.Run("Success with sufficient balance", func(t *testing.T) {
// transfer enough gns
std.TestSetRealm(adminRealm)
gns.Transfer(common.AddrToUser(testAddr), 1000)

std.TestSetRealm(std.NewUserRealm(testAddr))
mockTeller.balance = 2000 // More than required deposit amount
gns.Approve(common.AddrToUser(consts.LAUNCHPAD_ADDR), 1000)

depositId := DepositGns(project.id+":30", 1000)
deposit := deposits[depositId]
Expand Down Expand Up @@ -403,6 +407,7 @@ func TestMultipleDeposits(t *testing.T) {
CurrentTime: uint64(time.Now().Unix()),
}

std.TestSetRealm(std.NewUserRealm(testAddr))
deposit, _ := createDeposit(info, 100)
deposits[deposit.id] = deposit
updateDepositIndices(deposit, state)
Expand Down
Loading

0 comments on commit 189add5

Please sign in to comment.