Skip to content

Commit

Permalink
update test
Browse files Browse the repository at this point in the history
  • Loading branch information
notJoon committed Jan 2, 2025
1 parent ca5c0bb commit 1906bd8
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 50 deletions.
43 changes: 31 additions & 12 deletions launchpad/deposit.gno
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import (
"time"

"gno.land/p/demo/avl"
"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ufmt"
u256 "gno.land/p/gnoswap/uint256"
"gno.land/r/gnoswap/v1/common"
"gno.land/r/gnoswap/v1/consts"

"gno.land/r/gnoswap/v1/gns"
"gno.land/r/gnoswap/v1/gov/xgns"

pusers "gno.land/p/demo/users"
)

var (
Expand All @@ -31,16 +28,16 @@ func init() {
// DepositStore stores deposit-related metadata
type DepositStore struct {
// all deposits
deposits *avl.Tree // key: deposit ID, value: *Deposit
deposits *avl.Tree // deposit ID -> *Deposit

// deposits by project
depositsByProject *avl.Tree // key: <project ID, tier>, value: []string(depositIds)
depositsByProject *avl.Tree // project ID + tier -> []string(depositIds)

// deposits by user
depositsByUser *avl.Tree // key: user address, value: []string(depositIds)
depositsByUser *avl.Tree // user address -> []string(depositIds)

// deposits by user & project
depositsByUserProject *avl.Tree // key: <user address, project ID>, value: []string(depositIds)
depositsByUserProject *avl.Tree // user address + project ID -> []string(depositIds)
}

func NewDepositStore() *DepositStore {
Expand Down Expand Up @@ -89,6 +86,10 @@ func (ds *DepositStore) AddDeposit(projectId string, user std.Address, amount ui
return "", ufmt.Errorf("tier(%s) is not active", tier)
}

if alreadyDepositedSameTier(ds, user, projectId, tier) {
return "", ufmt.Errorf("already deposited in the same project(%s) tier(%s)", projectId, tier)
}

depositId := generateDepositId(projectId, tier, user)

// calculate claimable height & time
Expand Down Expand Up @@ -131,6 +132,24 @@ func (ds *DepositStore) AddDeposit(projectId string, user std.Address, amount ui
return depositId, nil
}

func alreadyDepositedSameTier(ds *DepositStore, user std.Address, projectId, tier string) bool {
userProjectKey := ufmt.Sprintf("%s:%s", user.String(), projectId)
value, exists := ds.depositsByUserProject.Get(userProjectKey)
if !exists {
return false
}

depositIds := value.([]string)
for _, id := range depositIds {
deposit, _ := ds.GetDeposit(id)
if deposit.tier == tier {
return true
}
}

return false
}

func (ds *DepositStore) GetDeposit(depositId string) (*Deposit, error) {
value, exists := ds.deposits.Get(depositId)
if !exists {
Expand Down Expand Up @@ -194,6 +213,11 @@ func (ds *DepositStore) CollectDeposit(depositId string, user std.Address) (uint
return 0, errors.New("deposit already collected")
}

// update deposit
dpst.depositCollectHeight = uint64(std.GetHeight())
dpst.depositCollectTime = uint64(time.Now().Unix())
ds.deposits.Set(depositId, dpst)

project, exists := projects[dpst.projectId]
if !exists {
return 0, ufmt.Errorf("project(%s) not found", dpst.projectId)
Expand All @@ -204,11 +228,6 @@ func (ds *DepositStore) CollectDeposit(depositId string, user std.Address) (uint
return 0, errors.New("cannot collect from active tier")
}

// update deposit
dpst.depositCollectHeight = uint64(std.GetHeight())
dpst.depositCollectTime = uint64(time.Now().Unix())
ds.deposits.Set(depositId, dpst)

// upadte project stats
ds.updateProjectStats(dpst, project, tier, false)

Expand Down
142 changes: 142 additions & 0 deletions launchpad/deposit_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package launchpad

import (
"std"
"testing"
"time"

"gno.land/p/demo/avl"
"gno.land/p/demo/testutils"
"gno.land/p/demo/uassert"
)

func TestDepositStore(t *testing.T) {
setupTestProject := func() (*DepositStore, *Project, std.Address) {
ds := &DepositStore{
deposits: avl.NewTree(),
depositsByProject: avl.NewTree(),
depositsByUser: avl.NewTree(),
depositsByUserProject: avl.NewTree(),
}

testAddr := testutils.TestAddress("test")

project := &Project{
id: "test:1",
name: "Test Project",
tokenPath: "test/token",
depositAmount: 1000000,
recipient: testAddr,
startHeight: 90,
endHeight: 10000,
tier30: Tier{
id: "test:1:30",
collectWaitDuration: 100,
tierAmount: 300000,
startHeight: 100,
endHeight: 3100,
actualDepositAmount: 0,
},
tier90: Tier{
id: "test:1:90",
collectWaitDuration: 200,
tierAmount: 300000,
startHeight: 100,
endHeight: 6100,
actualDepositAmount: 0,
},
tier180: Tier{
id: "test:1:180",
collectWaitDuration: 300,
tierAmount: 400000,
startHeight: 100,
endHeight: 9100,
actualDepositAmount: 0,
},
}

projects[project.id] = *project

return ds, project, testAddr
}

t.Run("AddDeposit - Pass", func(t *testing.T) {
ds, project, testAddr := setupTestProject()

depositId, err := ds.AddDeposit(project.id, testAddr, 1000, "30")
uassert.NoError(t, err)

deposit, err := ds.GetDeposit(depositId)
uassert.NoError(t, err)

uassert.Equal(t, deposit.amount, uint64(1000))
uassert.Equal(t, deposit.tier, "30")
uassert.Equal(t, deposit.depositor, testAddr)
})

t.Run("AddDeposit - Fail - Not Found Project", func(t *testing.T) {
ds, _, testAddr := setupTestProject()

_, err := ds.AddDeposit("invalid:1", testAddr, 1000, "30")
uassert.Error(t, err)
})

t.Run("GetUserDeposits - Check user deposits", func(t *testing.T) {
ds, project, testAddr := setupTestProject()

_, err1 := ds.AddDeposit(project.id, testAddr, 1000, "30")
_, err2 := ds.AddDeposit(project.id, testAddr, 2000, "90")
uassert.NoError(t, err1)
uassert.NoError(t, err2)

deposits, err := ds.GetUserDeposits(testAddr)
uassert.NoError(t, err)

uassert.Equal(t, len(deposits), 2)

totalAmount := uint64(0)
for _, d := range deposits {
totalAmount += d.amount
}

uassert.Equal(t, totalAmount, uint64(3000))
})

t.Run("CollectDeposit - Fail - Unauthorized", func(t *testing.T) {
ds, project, testAddr := setupTestProject()
unauthorizedAddr := testutils.TestAddress("unauthorized")

depositId, _ := ds.AddDeposit(project.id, testAddr, 1000, "30")

_, err := ds.CollectDeposit(depositId, unauthorizedAddr)
uassert.Error(t, err)
})

t.Run("Check Index Consistency", func(t *testing.T) {
ds, project, testAddr := setupTestProject()
depositId, _ := ds.AddDeposit(project.id, testAddr, 1000, "30")

projectKey := project.id + ":30"
value, exists := ds.depositsByProject.Get(projectKey)
uassert.True(t, exists)

depositIds := value.([]string)
uassert.Equal(t, len(depositIds), 1)
uassert.Equal(t, depositIds[0], depositId)

value, exists = ds.depositsByUser.Get(testAddr.String())
uassert.True(t, exists)

depositIds = value.([]string)
uassert.Equal(t, len(depositIds), 1)
uassert.Equal(t, depositIds[0], depositId)

userProjectKey := testAddr.String() + ":" + project.id
value, exists = ds.depositsByUserProject.Get(userProjectKey)
uassert.True(t, exists)

depositIds = value.([]string)
uassert.Equal(t, len(depositIds), 1)
uassert.Equal(t, depositIds[0], depositId)
})
}
11 changes: 0 additions & 11 deletions launchpad/project.gno
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package launchpad

import (
"std"
u256 "gno.land/p/gnoswap/uint256"
"gno.land/p/demo/avl"
)
Expand All @@ -17,13 +16,3 @@ type ProjectStore struct {
// 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)
// }
Loading

0 comments on commit 1906bd8

Please sign in to comment.