Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import (
)

var (
blockTimeSeconds int64 = 5
secondsInDay int64 = 24 * 60 * 60
skipBlocks180Day int64 = 180 * secondsInDay / blockTimeSeconds

adminAddr, _ = access.GetAddress(prbac.ROLE_ADMIN.String())
adminRealm = testing.NewUserRealm(adminAddr)

Expand Down Expand Up @@ -68,9 +72,9 @@ func main() {
println()

println("[SCENARIO] 5. Skip blocks to end project")
println("[INFO] Project duration is 180 days (7776000 blocks at 5 sec/block)")
println("[INFO] Skipping remaining blocks to end project")
testing.SkipHeights(7776000)
ufmt.Printf("[INFO] Project duration is 180 days (%d blocks at %d sec/block)\n", skipBlocks180Day, blockTimeSeconds)
println("[INFO] Skipping 180 days worth of blocks to ensure project ended")
testing.SkipHeights(skipBlocks180Day)
println()

println("[SCENARIO] 6. Depositors collect final rewards after project ends")
Expand Down Expand Up @@ -258,8 +262,8 @@ func transferRemainingRewards(projectId string) {
// [INFO] Reward collected: 5000096
//
// [SCENARIO] 5. Skip blocks to end project
// [INFO] Project duration is 180 days (7776000 blocks at 5 sec/block)
// [INFO] Skipping remaining blocks to end project
// [INFO] Project duration is 180 days (3110400 blocks at 5 sec/block)
// [INFO] Skipping 180 days worth of blocks to ensure project ended
//
// [SCENARIO] 6. Depositors collect final rewards after project ends
// [INFO] Alice collecting final reward
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import (
)

var (
blockTimeSeconds int64 = 5
secondsInDay int64 = 24 * 60 * 60
skipBlocks180Day int64 = 180 * secondsInDay / blockTimeSeconds
endProjectGraceBlocks int64 = 6

adminAddr, _ = access.GetAddress(prbac.ROLE_ADMIN.String())
adminRealm = testing.NewUserRealm(adminAddr)

Expand All @@ -39,8 +44,8 @@ func main() {

// [SCENARIO] 2. Skip blocks to end project
println("[SCENARIO] 2. Skip blocks to end project")
println("[INFO] Skipping 7776000 + 6 blocks to end project")
testing.SkipHeights(7776000 + 6) // End project
println("[INFO] Skipping 180 days plus grace blocks to end project")
testing.SkipHeights(skipBlocks180Day + endProjectGraceBlocks) // End project
println()

// [SCENARIO] 3. Refund ended project without deposit
Expand Down Expand Up @@ -153,7 +158,7 @@ func refundEndedProjectWithoutDeposit() {
// [EXPECTED] Tier 180 amount: 700000000
//
// [SCENARIO] 2. Skip blocks to end project
// [INFO] Skipping 7776000 + 6 blocks to end project
// [INFO] Skipping 180 days plus grace blocks to end project
//
// [SCENARIO] 3. Refund ended project without deposit
// [INFO] Checking project status before refund
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ import (
)

var (
blockTimeSeconds int64 = 5
secondsInDay int64 = 24 * 60 * 60
skipBlocks180Day int64 = 180 * secondsInDay / blockTimeSeconds

adminAddr, _ = access.GetAddress(prbac.ROLE_ADMIN.String())
adminRealm = testing.NewUserRealm(adminAddr)

Expand Down Expand Up @@ -67,10 +71,11 @@ func main() {
depositGns(aliceAddr, projectTier30Id, int64(1_000_000))
println()

println("[SCENARIO] 3. Skip to end all tiers (180+ days) with NO collect/withdraw")
println("[SCENARIO] 3. Skip to end all tiers (180 days) with NO collect/withdraw")
ufmt.Printf("[INFO] Skipping %d blocks (%d days at %d sec/block)\n", skipBlocks180Day, int64(180), blockTimeSeconds)
println("[INFO] No deposit/collect/withdraw events trigger reward manager update")
println("[INFO] Reward manager will be updated during admin refund calculation")
testing.SkipHeights(7776000)
testing.SkipHeights(skipBlocks180Day)
println()

println("[SCENARIO] 4. Verify launchpad balance before admin refund")
Expand Down Expand Up @@ -229,7 +234,8 @@ func collectReward(addr address) {
// [INFO] Alice approving launchpad to spend GNS
// [INFO] Deposit created with ID: 1
//
// [SCENARIO] 3. Skip to end all tiers (180+ days) with NO collect/withdraw
// [SCENARIO] 3. Skip to end all tiers (180 days) with NO collect/withdraw
// [INFO] Skipping 3110400 blocks (180 days at 5 sec/block)
// [INFO] No deposit/collect/withdraw events trigger reward manager update
// [INFO] Reward manager will be updated during admin refund calculation
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ var (

max_timeout int64 = 9999999999
maxInt64 int64 = 9223372036854775807

blockTimeSeconds int64 = 5
warmupPenaltyDurationSeconds int64 = 1800 + 3600 + 7200
)

func main() {
Expand All @@ -71,7 +74,7 @@ func main() {
stakeTime := stakePosition(positionId)
println()

println("[SCENARIO] 5. Skip time within warmup period")
println("[SCENARIO] 5. Skip one hour within warmup period")
skipTimeWithinWarmup()
println()

Expand Down Expand Up @@ -175,9 +178,10 @@ func stakePosition(positionId uint64) int64 {
}

func skipTimeWithinWarmup() {
println("[INFO] skip 1 hour (3600 blocks) - staying within warmup period")
testing.SkipHeights(3600) // 1 hour = half of warmup period

blocksToSkip := int64(3600) / blockTimeSeconds
println("[INFO] skip 1 hour (720 blocks) - staying within warmup period")
testing.SkipHeights(blocksToSkip)

currentTime := time.Now().Unix()
ufmt.Printf("[EXPECTED] current time advanced to: %d\n", currentTime)
}
Expand All @@ -188,7 +192,10 @@ func collectRewardsAndVerifyPenalty(positionId uint64, stakeTime int64) {
println("[INFO] check time since stake")
currentTime := time.Now().Unix()
timeSinceStake := currentTime - stakeTime
ufmt.Printf("[INFO] time since stake: %d seconds (warmup period: 7200 seconds)\n", timeSinceStake)
ufmt.Printf("[INFO] time since stake: %d seconds (warmup penalty period: %d seconds)\n", timeSinceStake, warmupPenaltyDurationSeconds)
if timeSinceStake >= warmupPenaltyDurationSeconds {
panic("collection should happen during warmup penalty period")
}

println("[INFO] record balances before collection")
userGnsBefore := gns.BalanceOf(adminUser)
Expand All @@ -200,7 +207,9 @@ func collectRewardsAndVerifyPenalty(positionId uint64, stakeTime int64) {
ufmt.Printf("[INFO] devOps GNS before: %d\n", devOpsGnsBefore)

println("[INFO] collect rewards during warmup period")
sr.CollectReward(cross, positionId)
internalRewardToUserStr, internalWarmupPenaltyStr, _, _ := sr.CollectReward(cross, positionId)
internalRewardToUser := mustParseInt64(internalRewardToUserStr)
internalWarmupPenalty := mustParseInt64(internalWarmupPenaltyStr)

println("[INFO] check balances after collection")
userGnsAfter := gns.BalanceOf(adminUser)
Expand All @@ -210,29 +219,45 @@ func collectRewardsAndVerifyPenalty(positionId uint64, stakeTime int64) {
userReward := userGnsAfter - userGnsBefore
communityReward := communityGnsAfter - communityGnsBefore
devOpsReward := devOpsGnsAfter - devOpsGnsBefore

ufmt.Printf("[EXPECTED] user reward (reduced by warmup): %d GNS\n", userReward)
ufmt.Printf("[EXPECTED] community pool penalty: %d GNS\n", communityReward)
communityEmissionReward := communityReward - internalWarmupPenalty

ufmt.Printf("[EXPECTED] user reward (reduced by warmup and fee): %d GNS\n", userReward)
ufmt.Printf("[EXPECTED] warmup penalty: %d GNS\n", internalWarmupPenalty)
ufmt.Printf("[EXPECTED] community pool total increase: %d GNS\n", communityReward)
ufmt.Printf("[EXPECTED] community pool emission distribution: %d GNS\n", communityEmissionReward)
ufmt.Printf("[EXPECTED] devOps reward: %d GNS\n", devOpsReward)

println("[INFO] verify total distribution")
totalDistributed := userReward + communityReward
ufmt.Printf("[EXPECTED] total distributed (user + penalty): %d GNS\n", totalDistributed)
totalDistributed := userReward + internalWarmupPenalty
ufmt.Printf("[EXPECTED] total distributed (user + warmup penalty): %d GNS\n", totalDistributed)

if totalDistributed == 0 {
panic("total distributed should be positive - rewards should have been generated")
}

if timeSinceStake < 7200 {
if communityReward == 0 {
panic("community pool should receive penalty during warmup period")
}
ufmt.Printf("[VERIFIED] warmup penalty correctly applied - community pool received: %d GNS\n", communityReward)

if userReward != internalRewardToUser {
panic("user balance delta should match CollectReward return value")
}


if internalWarmupPenalty == 0 {
panic("community pool should receive penalty during warmup period")
}
if communityReward < internalWarmupPenalty {
panic("community pool increase should include at least the warmup penalty")
}
ufmt.Printf("[VERIFIED] warmup penalty correctly applied - penalty amount: %d GNS\n", internalWarmupPenalty)

println("[INFO] warmup period penalty test completed successfully")
}

func mustParseInt64(value string) int64 {
parsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
panic(err)
}
return parsed
}

func positionIdFrom(positionId any) grc721.TokenID {
if positionId == nil {
panic("positionId is nil")
Expand Down Expand Up @@ -275,22 +300,25 @@ func positionIdFrom(positionId any) grc721.TokenID {
// [INFO] approve and stake position
// [EXPECTED] position staked at time: 1234567905
//
// [SCENARIO] 5. Skip time within warmup period
// [INFO] skip 1 hour (3600 blocks) - staying within warmup period
// [EXPECTED] current time advanced to: 1234585910
// [SCENARIO] 5. Skip one hour within warmup period
// [INFO] skip 1 hour (720 blocks) - staying within warmup period
// [EXPECTED] current time advanced to: 1234571510
//
// [SCENARIO] 6. Collect rewards during warmup and verify penalty
// [INFO] check time since stake
// [INFO] time since stake: 18005 seconds (warmup period: 7200 seconds)
// [INFO] time since stake: 3605 seconds (warmup penalty period: 12600 seconds)
// [INFO] record balances before collection
// [INFO] user GNS before: 100000000000000
// [INFO] community GNS before: 5351025
// [INFO] devOps GNS before: 21404109
// [INFO] collect rewards during warmup period
// [INFO] check balances after collection
// [EXPECTED] user reward (reduced by warmup): 32496112018 GNS
// [EXPECTED] community pool penalty: 20415949365 GNS
// [EXPECTED] devOps reward: 25692065503 GNS
// [EXPECTED] user reward (reduced by warmup and fee): 3666456126 GNS
// [EXPECTED] warmup penalty: 5785796862 GNS
// [EXPECTED] community pool total increase: 7098582207 GNS
// [EXPECTED] community pool emission distribution: 1312785345 GNS
// [EXPECTED] devOps reward: 5144120863 GNS
// [INFO] verify total distribution
// [EXPECTED] total distributed (user + penalty): 52912061383 GNS
// [EXPECTED] total distributed (user + warmup penalty): 9452252988 GNS
// [VERIFIED] warmup penalty correctly applied - penalty amount: 5785796862 GNS
// [INFO] warmup period penalty test completed successfully
Loading