From b7cf8fb6d6cb897c2e4b1a75a3dcfec2f1bb0da6 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Thu, 19 Dec 2024 19:54:28 +0900 Subject: [PATCH] GSW-1845 refactor: assert too many emission amount --- _deploy/r/gnoswap/gns/errors.gno | 3 +- _deploy/r/gnoswap/gns/gns.gno | 39 +++++-- _deploy/r/gnoswap/gns/gns_test.gno | 10 +- _deploy/r/gnoswap/gns/halving_test.gno | 101 +++++++++--------- .../tests/gns_calculate_and_mint_test.gnoA | 37 ++++--- .../minted_and_left_emission_amount_test.gnoA | 25 +++-- _deploy/r/gnoswap/gns/tests/z1_filetest.gno | 42 +++++--- _deploy/r/gnoswap/gns/tests/z2_filetest.gno | 53 ++++----- _deploy/r/gnoswap/gns/tests/z3_filetest.gno | 54 +++------- _deploy/r/gnoswap/gns/tests/z4_filetest.gno | 93 ++++++++++++++++ 10 files changed, 292 insertions(+), 165 deletions(-) create mode 100644 _deploy/r/gnoswap/gns/tests/z4_filetest.gno diff --git a/_deploy/r/gnoswap/gns/errors.gno b/_deploy/r/gnoswap/gns/errors.gno index 55eb28cd1..2f4480fd2 100644 --- a/_deploy/r/gnoswap/gns/errors.gno +++ b/_deploy/r/gnoswap/gns/errors.gno @@ -7,7 +7,8 @@ import ( ) var ( - errNoPermission = errors.New("[GNOSWAP-GNS-001] caller has no permission") + errNoPermission = errors.New("[GNOSWAP-GNS-001] caller has no permission") + errTooManyEmission = errors.New("[GNOSWAP-GNS-002] too many emission reward") ) func addDetailToError(err error, detail string) string { diff --git a/_deploy/r/gnoswap/gns/gns.gno b/_deploy/r/gnoswap/gns/gns.gno index 43c5bf80b..f647460a8 100644 --- a/_deploy/r/gnoswap/gns/gns.gno +++ b/_deploy/r/gnoswap/gns/gns.gno @@ -31,6 +31,8 @@ var ( leftEmissionAmount uint64 mintedEmissionAmount uint64 lastMintedHeight int64 + + burnAmount uint64 ) func init() { @@ -56,15 +58,15 @@ func MintGns(address pusers.AddressOrName) uint64 { // skip minting process if following conditions are met // - if gns for current block is already minted - // - if last minted height is same as last height to mint ( 12 years passed ) - if lastMintedHeight == currentHeight || lastMintedHeight == GetEndHeight() { + // - if last minted height is same or later than emission end height + if lastMintedHeight == currentHeight || lastMintedHeight >= GetEndHeight() { return 0 } assertShouldNotBeHalted() assertCallerIsEmission() - // calculate gns amount to mint, and the mint to the target address + // calculate gns amount to mint amountToMint := calculateAmountToMint(lastMintedHeight+1, currentHeight) // update @@ -84,6 +86,8 @@ func Burn(from pusers.AddressOrName, amount uint64) { owner.AssertCallerIsOwner() fromAddr := users.Resolve(from) checkErr(privateLedger.Burn(fromAddr, amount)) + + burnAmount += amount } func TotalSupply() uint64 { @@ -153,37 +157,38 @@ func calculateAmountToMint(fromHeight, toHeight int64) uint64 { totalAmountToMint := uint64(0) - for i := fromYear; i <= toYear; i++ { - yearEndHeight := GetHalvingYearBlock(i) + for year := fromYear; year <= toYear; year++ { + yearEndHeight := GetHalvingYearEndBlock(year) mintUntilHeight := i64Min(yearEndHeight, toHeight) // how many blocks to calculate blocks := uint64(mintUntilHeight-fromHeight) + 1 // amount of gns to mint for each block for current year - singleBlockAmount := GetAmountPerBlockPerHalvingYear(i) + singleBlockAmount := GetAmountPerBlockPerHalvingYear(year) // amount of gns to mint for current year yearAmountToMint := singleBlockAmount * blocks // if last block of halving year, handle left emission amount if isLastBlockOfHalvingYear(mintUntilHeight) { - yearAmountToMint += handleLeftEmissionAmount(i, yearAmountToMint) + yearAmountToMint += handleLeftEmissionAmount(year, yearAmountToMint) } totalAmountToMint += yearAmountToMint - setHalvingYearMintAmount(i, GetHalvingYearMintAmount(i)+yearAmountToMint) + setHalvingYearMintAmount(year, GetHalvingYearMintAmount(year)+yearAmountToMint) // update fromHeight for next year (if necessary) fromHeight = mintUntilHeight + 1 } + assertTooManyEmission(totalAmountToMint) return totalAmountToMint } // isLastBlockOfHalvingYear returns true if the current block is the last block of a halving year. func isLastBlockOfHalvingYear(height int64) bool { year := GetHalvingYearByHeight(height) - lastBlock := GetHalvingYearBlock(year) + lastBlock := GetHalvingYearEndBlock(year) return height == lastBlock } @@ -219,6 +224,11 @@ func GetLeftEmissionAmount() uint64 { return leftEmissionAmount } +// GetBurnAmount returns the amount of GNS that has been burned. +func GetBurnAmount() uint64 { + return burnAmount +} + // GetMintedEmissionAmount returns the amount of GNS that has been minted by the emission contract. // It does not include initial minted amount. func GetMintedEmissionAmount() uint64 { @@ -236,3 +246,14 @@ func setLeftEmissionAmount(amount uint64) { func setMintedEmissionAmount(amount uint64) { mintedEmissionAmount = amount } + +// assertTooManyEmission asserts if the amount of gns to mint is too many. +// It checks if the amount of gns to mint is greater than the left emission amount or the total emission amount. +func assertTooManyEmission(amount uint64) { + if amount > GetLeftEmissionAmount() || (amount+GetMintedEmissionAmount()) > MAX_EMISSION_AMOUNT { + panic(addDetailToError( + errTooManyEmission, + ufmt.Sprintf("amount: %d", amount), + )) + } +} diff --git a/_deploy/r/gnoswap/gns/gns_test.gno b/_deploy/r/gnoswap/gns/gns_test.gno index 870d507e6..758d94b03 100644 --- a/_deploy/r/gnoswap/gns/gns_test.gno +++ b/_deploy/r/gnoswap/gns/gns_test.gno @@ -34,14 +34,14 @@ func TestIsLastBlockOfHalvingYear(t *testing.T) { want bool }, 0, 24) - for i := int64(1); i <= 12; i++ { + for i := HALVING_START_YEAR; i <= HALVING_END_YEAR; i++ { tests = append(tests, struct { name string height int64 want bool }{ name: fmt.Sprintf("last block of halving year %d", i), - height: GetHalvingYearBlock(i), + height: GetHalvingYearEndBlock(i), want: true, }) @@ -51,7 +51,7 @@ func TestIsLastBlockOfHalvingYear(t *testing.T) { want bool }{ name: fmt.Sprintf("not last block of halving year %d", i), - height: GetHalvingYearBlock(i) - 1, + height: GetHalvingYearEndBlock(i) - 1, want: false, }) } @@ -120,13 +120,13 @@ func TestSkipIfEmissionEnded(t *testing.T) { func TestGetterSetter(t *testing.T) { t.Run("last minted height", func(t *testing.T) { - value := int64(1234) + value := int64(123) setLastMintedHeight(value) uassert.Equal(t, value, GetLastMintedHeight()) }) t.Run("left emission amount", func(t *testing.T) { - value := uint64(123456) + value := uint64(0) setLeftEmissionAmount(value) uassert.Equal(t, value, GetLeftEmissionAmount()) }) diff --git a/_deploy/r/gnoswap/gns/halving_test.gno b/_deploy/r/gnoswap/gns/halving_test.gno index 233a941b6..2450d01fd 100644 --- a/_deploy/r/gnoswap/gns/halving_test.gno +++ b/_deploy/r/gnoswap/gns/halving_test.gno @@ -16,22 +16,22 @@ var ( ) var FIRST_BLOCK_OF_YEAR = []int64{ - startHeight, - startHeight + BLOCK_PER_YEAR*1, - startHeight + BLOCK_PER_YEAR*2, - startHeight + BLOCK_PER_YEAR*3, - startHeight + BLOCK_PER_YEAR*4, - startHeight + BLOCK_PER_YEAR*5, - startHeight + BLOCK_PER_YEAR*6, - startHeight + BLOCK_PER_YEAR*7, - startHeight + BLOCK_PER_YEAR*8, - startHeight + BLOCK_PER_YEAR*9, - startHeight + BLOCK_PER_YEAR*10, - startHeight + BLOCK_PER_YEAR*11, + startHeight + (BLOCK_PER_YEAR * 0) + 1, + startHeight + (BLOCK_PER_YEAR * 1) + 2, + startHeight + (BLOCK_PER_YEAR * 2) + 3, + startHeight + (BLOCK_PER_YEAR * 3) + 4, + startHeight + (BLOCK_PER_YEAR * 4) + 5, + startHeight + (BLOCK_PER_YEAR * 5) + 6, + startHeight + (BLOCK_PER_YEAR * 6) + 7, + startHeight + (BLOCK_PER_YEAR * 7) + 8, + startHeight + (BLOCK_PER_YEAR * 8) + 9, + startHeight + (BLOCK_PER_YEAR * 9) + 10, + startHeight + (BLOCK_PER_YEAR * 10) + 11, + startHeight + (BLOCK_PER_YEAR * 11) + 12, } var FIRST_TIMESTAMP_OF_YEAR = []int64{ - startTimestamp, + startTimestamp + consts.TIMESTAMP_YEAR*0, startTimestamp + consts.TIMESTAMP_YEAR*1, startTimestamp + consts.TIMESTAMP_YEAR*2, startTimestamp + consts.TIMESTAMP_YEAR*3, @@ -60,45 +60,6 @@ var END_TIMESTAMP_OF_YEAR = []int64{ startTimestamp + consts.TIMESTAMP_YEAR*12, } -func TestSetAvgBlockTimeInMsByAdmin(t *testing.T) { - t.Run("panic if caller is not admin", func(t *testing.T) { - uassert.PanicsWithMessage(t, - "caller(g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm) has no permission", - func() { - SetAvgBlockTimeInMsByAdmin(1) - }, - ) - }) - - t.Run("success if caller is admin", func(t *testing.T) { - std.TestSkipHeights(1) - std.TestSetRealm(adminRealm) - SetAvgBlockTimeInMsByAdmin(2) - uassert.Equal(t, GetAvgBlockTimeInMs(), int64(2)) - }) -} - -func TestSetAvgBlockTimeInMs(t *testing.T) { - t.Run("panic if caller is not governance contract", func(t *testing.T) { - uassert.PanicsWithMessage(t, - "caller(g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm) has no permission", - func() { - SetAvgBlockTimeInMs(3) - }, - ) - }) - - t.Run("success if caller is governance contract", func(t *testing.T) { - std.TestSkipHeights(3) - std.TestSetRealm(govRealm) - SetAvgBlockTimeInMs(4) - uassert.Equal(t, GetAvgBlockTimeInMs(), int64(4)) - }) - - // reset to default for further test - setAvgBlockTimeInMs(consts.SECOND_IN_MILLISECOND * consts.BLOCK_GENERATION_INTERVAL) -} - func TestGetAmountByHeight(t *testing.T) { for year := HALVING_START_YEAR; year <= HALVING_END_YEAR; year++ { firstBlockOfYear := FIRST_BLOCK_OF_YEAR[year-1] @@ -173,3 +134,39 @@ func TestGetHalvingInfo(t *testing.T) { halving := jsonStr.MustKey("halvings").MustArray() uassert.Equal(t, len(halving), 12) } + +func TestSetAvgBlockTimeInMsByAdmin(t *testing.T) { + t.Run("panic if caller is not admin", func(t *testing.T) { + uassert.PanicsWithMessage(t, + "caller(g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm) has no permission", + func() { + SetAvgBlockTimeInMsByAdmin(1) + }, + ) + }) + + t.Run("success if caller is admin", func(t *testing.T) { + std.TestSkipHeights(1) + std.TestSetRealm(adminRealm) + SetAvgBlockTimeInMsByAdmin(2) + uassert.Equal(t, GetAvgBlockTimeInMs(), int64(2)) + }) +} + +func TestSetAvgBlockTimeInMs(t *testing.T) { + t.Run("panic if caller is not governance contract", func(t *testing.T) { + uassert.PanicsWithMessage(t, + "caller(g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm) has no permission", + func() { + SetAvgBlockTimeInMs(3) + }, + ) + }) + + t.Run("success if caller is governance contract", func(t *testing.T) { + std.TestSkipHeights(3) + std.TestSetRealm(govRealm) + SetAvgBlockTimeInMs(4) + uassert.Equal(t, GetAvgBlockTimeInMs(), int64(4)) + }) +} diff --git a/_deploy/r/gnoswap/gns/tests/gns_calculate_and_mint_test.gnoA b/_deploy/r/gnoswap/gns/tests/gns_calculate_and_mint_test.gnoA index a5cfd9931..f6a912020 100644 --- a/_deploy/r/gnoswap/gns/tests/gns_calculate_and_mint_test.gnoA +++ b/_deploy/r/gnoswap/gns/tests/gns_calculate_and_mint_test.gnoA @@ -18,44 +18,45 @@ var ( func TestCalculateAmountToMint(t *testing.T) { t.Run("1 block for same year 01", func(t *testing.T) { amount := calculateAmountToMint(GetLastMintedHeight()+1, GetLastMintedHeight()+1) - uassert.Equal(t, amountPerBlockPerHalvingYear[1], amount) + uassert.Equal(t, amountPerBlockPerHalvingYear[0], amount) }) t.Run("2 block for same year 01", func(t *testing.T) { - amount := calculateAmountToMint(GetLastMintedHeight()+1, GetLastMintedHeight()+2) - uassert.Equal(t, amountPerBlockPerHalvingYear[2]*2, amount) + amount := calculateAmountToMint(GetLastMintedHeight()+2, GetLastMintedHeight()+3) + uassert.Equal(t, amountPerBlockPerHalvingYear[1]*2, amount) }) t.Run("entire block for year 01 + 1 block for year 02", func(t *testing.T) { - calculateAmountToMint(halvingYearBlock[1], halvingYearBlock[1]+1) + minted := calculateAmountToMint(GetLastMintedHeight()+4, GetHalvingYearBlock(2)) // minted all amount for year 01 - uassert.Equal(t, GetHalvingYearAmount(1), GetHalvingYearMintAmount(1)) + uassert.Equal(t, GetHalvingYearMaxAmount(1), GetHalvingYearMintAmount(1)) // minted 1 block for year 02 - uassert.Equal(t, amountPerBlockPerHalvingYear[2], GetHalvingYearMintAmount(2)) + uassert.Equal(t, amountPerBlockPerHalvingYear[1], GetHalvingYearMintAmount(2)) }) t.Run("entire block for 12 years", func(t *testing.T) { - calculateAmountToMint(halvingYearBlock[1], halvingYearBlock[12]) + calculateAmountToMint(GetHalvingYearBlock(1), GetHalvingYearBlock(12)) for year := int64(1); year <= 12; year++ { - uassert.Equal(t, GetHalvingYearAmount(year), GetHalvingYearMintAmount(year)) + uassert.Equal(t, GetHalvingYearMaxAmount(year), GetHalvingYearMintAmount(year)) } }) t.Run("no emission amount for after 12 years", func(t *testing.T) { - amount := calculateAmountToMint(halvingYearBlock[12], halvingYearBlock[12]+1) + amount := calculateAmountToMint(GetHalvingYearBlock(12), GetHalvingYearBlock(12)+1) uassert.Equal(t, uint64(0), amount) }) // clear for further test - halvingYearMintAmount = make(map[int64]uint64) + halvingYearMintAmount = []uint64{} } func TestMintGns(t *testing.T) { t.Run("panic for swap is halted", func(t *testing.T) { std.TestSetRealm(adminRealm) + std.TestSkipHeights(123) // pass some block to bypass last block check common.SetHaltByAdmin(true) // set halt uassert.PanicsWithMessage(t, "[GNOSWAP-COMMON-002] halted || gnoswap halted", func() { MintGns(a2u(consts.ADMIN)) @@ -72,20 +73,21 @@ func TestMintGns(t *testing.T) { t.Run("do not mint for same block", func(t *testing.T) { std.TestSetRealm(emissionRealm) + std.TestSkipHeights(-123) // revert height to get caught by last block check mintedAmount := MintGns(a2u(consts.ADMIN)) uassert.Equal(t, uint64(0), mintedAmount) }) t.Run("mint by year, until emission ends", func(t *testing.T) { for year := int64(1); year <= 12; year++ { - std.TestSkipHeights(BLOCK_PER_YEAR) + skipUntilLastHeightOfHalvingYear(t, year) std.TestSetRealm(emissionRealm) mintedAmount := MintGns(a2u(consts.ADMIN)) - uassert.Equal(t, halvingYearAmount[year], mintedAmount) - uassert.Equal(t, halvingYearAmount[year], halvingYearMintAmount[year]) - uassert.Equal(t, halvingYearAccuAmount[year], MintedEmissionAmount()) + uassert.Equal(t, GetHalvingYearMaxAmount(year), mintedAmount) + uassert.Equal(t, GetHalvingYearMaxAmount(year), GetHalvingYearMintAmount(year)) + uassert.Equal(t, GetHalvingYearAccuAmount(year), GetMintedEmissionAmount()) } }) @@ -97,3 +99,10 @@ func TestMintGns(t *testing.T) { uassert.Equal(t, uint64(0), mintedAmount) }) } + +func skipUntilLastHeightOfHalvingYear(t *testing.T, year int64) { + t.Helper() + + lastHeight := GetHalvingYearEndBlock(year) + std.TestSkipHeights(lastHeight - std.GetHeight()) +} diff --git a/_deploy/r/gnoswap/gns/tests/minted_and_left_emission_amount_test.gnoA b/_deploy/r/gnoswap/gns/tests/minted_and_left_emission_amount_test.gnoA index aee171e6b..9a47d2187 100644 --- a/_deploy/r/gnoswap/gns/tests/minted_and_left_emission_amount_test.gnoA +++ b/_deploy/r/gnoswap/gns/tests/minted_and_left_emission_amount_test.gnoA @@ -20,7 +20,7 @@ func TestCheckInitialData(t *testing.T) { }) t.Run("mintedAmount", func(t *testing.T) { - uassert.Equal(t, uint64(0), MintedEmissionAmount()) + uassert.Equal(t, uint64(0), GetMintedEmissionAmount()) }) t.Run("leftEmissionAmount", func(t *testing.T) { @@ -31,7 +31,7 @@ func TestCheckInitialData(t *testing.T) { func TestMintAndCheckRelativeData(t *testing.T) { // before mint oldTotalSupply := TotalSupply() - oldMintedAmount := MintedEmissionAmount() + oldMintedAmount := GetMintedEmissionAmount() oldLeftEmissionAmount := GetLeftEmissionAmount() // mint @@ -49,7 +49,7 @@ func TestMintAndCheckRelativeData(t *testing.T) { }) t.Run("increment of mintedAmount", func(t *testing.T) { - uassert.Equal(t, oldMintedAmount+mintAmountFor10Blocks, MintedEmissionAmount()) + uassert.Equal(t, oldMintedAmount+mintAmountFor10Blocks, GetMintedEmissionAmount()) }) t.Run("decrement of leftEmissionAmount", func(t *testing.T) { @@ -60,8 +60,9 @@ func TestMintAndCheckRelativeData(t *testing.T) { func TestBurnAndCheckRelativeData(t *testing.T) { // before burn oldTotalSupply := TotalSupply() - oldMintedAmount := MintedEmissionAmount() + oldMintedAmount := GetMintedEmissionAmount() oldLeftEmissionAmount := GetLeftEmissionAmount() + oldBurnAmount := GetBurnAmount() // burn burnAmount := uint64(100000000) @@ -75,15 +76,23 @@ func TestBurnAndCheckRelativeData(t *testing.T) { uassert.Equal(t, oldTotalSupply-burnAmount, TotalSupply()) }) - t.Run("decrement of mintedAmount", func(t *testing.T) { - uassert.Equal(t, oldMintedAmount-burnAmount, MintedEmissionAmount()) + t.Run("same for mintedAmount", func(t *testing.T) { + // it is already `minted` amount, therefore it is not affected by burn + uassert.Equal(t, oldMintedAmount, GetMintedEmissionAmount()) }) - t.Run("totalSupply should be same with (INITIAL_MINT_AMOUNT) + (mintedEmissionAmount)", func(t *testing.T) { - uassert.Equal(t, TotalSupply(), INITIAL_MINT_AMOUNT+MintedEmissionAmount()) + t.Run("totalSupply should be same or less than inital mint + acutal mint amount", func(t *testing.T) { + // burn does affect totalSupply + uassert.True(t, TotalSupply() <= INITIAL_MINT_AMOUNT+GetMintedEmissionAmount()) }) t.Run("same for leftEmissionAmount", func(t *testing.T) { + // leftEmissionAmount gets affected by only mint uassert.Equal(t, oldLeftEmissionAmount, GetLeftEmissionAmount()) }) + + t.Run("increment of burnAmount", func(t *testing.T) { + // `burn` only increments burnAmount + uassert.Equal(t, oldBurnAmount+burnAmount, GetBurnAmount()) + }) } diff --git a/_deploy/r/gnoswap/gns/tests/z1_filetest.gno b/_deploy/r/gnoswap/gns/tests/z1_filetest.gno index 674fd31b3..c88626cf6 100644 --- a/_deploy/r/gnoswap/gns/tests/z1_filetest.gno +++ b/_deploy/r/gnoswap/gns/tests/z1_filetest.gno @@ -35,33 +35,47 @@ func skip50Blocks() { uassert.Equal(t, std.GetHeight(), int64(173)) std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) - gns.MintGns(a2u(user01Addr)) // 14269406 * 50 = 713470300 - uassert.Equal(t, uint64(713470300), gns.MintedEmissionAmount()) + mintedAmount := gns.MintGns(a2u(user01Addr)) // 14269406 * 50 = 713470300) + uassert.Equal(t, uint64(713470300), gns.GetMintedEmissionAmount()) } func blockTime2500ms() { std.TestSetRealm(std.NewUserRealm(consts.ADMIN)) gns.SetAvgBlockTimeInMsByAdmin(2500) - std.TestSkipHeights(1) + // for block time 2.5s, amount per block is 17836759 + + // first halving year end block = 15768122 + // first halving year end timestamp = 1234567990 + + // 50 block minted from L#38 + // > current height = 173 + // > current timestamp = 1234568140 + + // 1266103890 - 1234567990 = 31535900 // timestamp left for current halving year + // 31535900000 / 2500(new block avg time/ms) = 12614360 // number of block left for current halving year - // for block time 2.5s - // amount per block is 17836757 + // 713470300 // already minted amount + + // first halving year should mint 225000000000000 + // 225000000000000 - 713470300 = 224999286529700 + // 224999286529700 / 12614360 = 17836759 std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) - gns.MintGns(a2u(user01Addr)) // 17836757 - uassert.Equal(t, uint64(713470300+17836757), gns.MintedEmissionAmount()) // 731307057 + std.TestSkipHeights(1) + mintedAmount := gns.MintGns(a2u(user01Addr)) // 17836757 + uassert.Equal(t, uint64(713470300+17836757), gns.GetMintedEmissionAmount()) // 731307057 } func reachAlmostFirstHalving() { - // current height = 174 - // next halving = 12614533 - // 12614533 - 174 = 12614359 - std.TestSkipHeights(12614358) + firstEnds := gns.GetHalvingYearEndBlock(1) + blockLeftUntilEnd := firstEnds - std.GetHeight() + + std.TestSkipHeights(blockLeftUntilEnd - 1) // 1 block left until first halving year ends std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) - uassert.Equal(t, uint64(224999969664063), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(224999969664063), gns.GetMintedEmissionAmount()) // 224999969664063 - 731307057 = 224999238357006 // 224999238357006 / 12614358 = 17836757 } @@ -72,7 +86,7 @@ func reachExactFirstHalving() { gns.MintGns(a2u(user01Addr)) // minted all amount for first halving year - uassert.Equal(t, uint64(225000000000000), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(225000000000000), gns.GetMintedEmissionAmount()) year := gns.GetHalvingYearByHeight(std.GetHeight()) uassert.Equal(t, int64(1), year) @@ -89,7 +103,7 @@ func startSecondHalving() { std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) - uassert.Equal(t, uint64(225000000000000+14269406), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(225000000000000+14269406), gns.GetMintedEmissionAmount()) } func a2u(addr std.Address) pusers.AddressOrName { diff --git a/_deploy/r/gnoswap/gns/tests/z2_filetest.gno b/_deploy/r/gnoswap/gns/tests/z2_filetest.gno index 31b612bcc..6b51fba23 100644 --- a/_deploy/r/gnoswap/gns/tests/z2_filetest.gno +++ b/_deploy/r/gnoswap/gns/tests/z2_filetest.gno @@ -36,37 +36,40 @@ func skip50Blocks() { std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) // 14269406 * 50 = 713470300 - uassert.Equal(t, uint64(713470300), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(713470300), gns.GetMintedEmissionAmount()) } func blockTime4000ms() { std.TestSetRealm(std.NewUserRealm(consts.ADMIN)) gns.SetAvgBlockTimeInMsByAdmin(4000) - std.TestSkipHeights(1) - - // for block time 4s - // amount per block is 28538812 + // for block time 4s, amount per block is 28538812 std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) - gns.MintGns(a2u(user01Addr)) // 28538812 - uassert.Equal(t, uint64(713470300+28538812), gns.MintedEmissionAmount()) // 742009112 + std.TestSkipHeights(1) + mintedAmount := gns.MintGns(a2u(user01Addr)) // 28538812 + uassert.Equal(t, uint64(713470300+28538812), gns.GetMintedEmissionAmount()) // 742009112 firstYearAmountPerBlock := gns.GetAmountPerBlockPerHalvingYear(1) uassert.Equal(t, uint64(28538812), firstYearAmountPerBlock) - uassert.Equal(t, int64(7884148), gns.GetHalvingYearBlock(1)) - // FORMULA - // orig_start = 123 - // orig_1year = 15768123 ( 123 + 1 year block(15768000) ) - // 50 block mined from L#37 - // current = 173 - // 15768123 - 173 = 15767950 // number of block left to next halving + // next halving year start/end block + uassert.Equal(t, int64(7884149), gns.GetHalvingYearBlock(2)) + uassert.Equal(t, int64(15768149), gns.GetHalvingYearEndBlock(2)) + + // orig year01 start block = 123 + // 50 block mined from L#38 + // current block = 173 + // current timestamp = 1234567990 + // orig year01 end timestamp = 1266103890 + + // 1266103890 - 1234567990 = 31535900 // timestamp left for current halving year + // 31535900000(ms) / 4000(ms) = 7883975 // number of block left for current halving year - // 15767950 * 2 = 31535900 // number of timestamp left to next halving - // > before change, block time was 2s (2000ms) + // 173 + 7883975 = 7884148 // end block of current halving year + // 7884148 + 1 = 7884149 // start block of next halving year - // 31535900 / 4 = 7883975 // based on 4s block, number of block left to next halving - // current(173) + above left(7883975) = 7884148 + // 7884000 // based on 4s block, how many block in a year + // 7884149 + 7884000 = 15768149 // end block of next halving year } func reachFirstHalving() { @@ -79,7 +82,7 @@ func reachFirstHalving() { gns.MintGns(a2u(user01Addr)) // minted all amount for first halving year - uassert.Equal(t, uint64(225000000000000), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(225000000000000), gns.GetMintedEmissionAmount()) year := gns.GetHalvingYearByHeight(std.GetHeight()) uassert.Equal(t, int64(1), year) @@ -96,20 +99,20 @@ func startSecondHalving() { std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) - uassert.Equal(t, uint64(225000000000000+14269406), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(225000000000000+14269406), gns.GetMintedEmissionAmount()) } func reachSecondHalving() { - // current := 7884149 - // nextHalving := 15768148 - // 15768148 - 7884149 = 7883999 + blockLeftUntilEndOfYear02 := gns.GetHalvingYearEndBlock(2) - std.GetHeight() - std.TestSkipHeights(7883999) + std.TestSkipHeights(int64(blockLeftUntilEndOfYear02)) std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) // minted all amount until second halving - uassert.Equal(t, uint64(225000000000000*2), gns.MintedEmissionAmount()) + year01Max := gns.GetHalvingYearMaxAmount(1) + year02Max := gns.GetHalvingYearMaxAmount(2) + uassert.Equal(t, year01Max+year02Max, gns.GetMintedEmissionAmount()) } func a2u(addr std.Address) pusers.AddressOrName { diff --git a/_deploy/r/gnoswap/gns/tests/z3_filetest.gno b/_deploy/r/gnoswap/gns/tests/z3_filetest.gno index cba842238..2337485cc 100644 --- a/_deploy/r/gnoswap/gns/tests/z3_filetest.gno +++ b/_deploy/r/gnoswap/gns/tests/z3_filetest.gno @@ -37,52 +37,34 @@ func skip50Blocks() { std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) // 14269406 * 50 = 713470300 - uassert.Equal(t, uint64(713470300), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(713470300), gns.GetMintedEmissionAmount()) } func blockTime4000ms() { std.TestSetRealm(std.NewUserRealm(consts.ADMIN)) gns.SetAvgBlockTimeInMsByAdmin(4000) - std.TestSkipHeights(1) - - // for block time 4s - // amount per block is 28538812 + // for block time 4s, amount per block is 28538812 + std.TestSkipHeights(1) std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) - gns.MintGns(a2u(user01Addr)) // 28538812 - uassert.Equal(t, uint64(713470300+28538812), gns.MintedEmissionAmount()) // 742009112 - - firstYearAmountPerBlock := gns.GetAmountPerBlockPerHalvingYear(1) - uassert.Equal(t, uint64(28538812), firstYearAmountPerBlock) - uassert.Equal(t, int64(7884148), gns.GetHalvingYearBlock(1)) - // FORMULA - // orig_start = 123 - // orig_1year = 15768123 ( 123 + 1 year block(15768000) ) + gns.MintGns(a2u(user01Addr)) // 28538812 + uassert.Equal(t, uint64(713470300+28538812), gns.GetMintedEmissionAmount()) // 742009112 - // 50 block mined from L#37 - // current = 173 - // 15768123 - 173 = 15767950 // number of block left to next halving - - // 15767950 * 2 = 31535900 // number of timestamp left to next halving - // > before change, block time was 2s (2000ms) - - // 31535900 / 4 = 7883975 // based on 4s block, number of block left to next halving - // current(173) + above left(7883975) = 7884148 + // next halving year start/end block + uassert.Equal(t, int64(7884149), gns.GetHalvingYearBlock(2)) + uassert.Equal(t, int64(15768149), gns.GetHalvingYearEndBlock(2)) } func reachAboutHalfOfFirstHalving() { - // current := 174 - // nextHalving := 7884148 - // 7884148 - 174 = 7883974 - // 7883974 / 2 = 3941987 + // current block = 174 + // next halving year start block = 7884148 + // 7884148 - 174 = 7883974 // block left to next halving - std.TestSkipHeights(3941987) + std.TestSkipHeights(3941987) // 7883974 / 2 std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) - // minted about 50% amount for first halving year - uassert.Equal(t, uint64(112500367908556), gns.MintedEmissionAmount()) - + // stil in first halving year year := gns.GetHalvingYearByHeight(std.GetHeight()) uassert.Equal(t, int64(1), year) } @@ -94,16 +76,14 @@ func blockTime3000ms() { } func reachFirstHalving() { - // current := 3942162 - // nextHalving := 11826135 - // 11826135 - 3942162 = 7883973 + blockLeftUntilEndOfYear01 := gns.GetHalvingYearEndBlock(1) - std.GetHeight() + std.TestSkipHeights(blockLeftUntilEndOfYear01) - std.TestSkipHeights(7883973) std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) // minted all amount for first halving year - uassert.Equal(t, uint64(225000000000000), gns.MintedEmissionAmount()) + uassert.Equal(t, gns.GetHalvingYearMaxAmount(1), gns.GetMintedEmissionAmount()) // we're at the end of first halving year year := gns.GetHalvingYearByHeight(std.GetHeight()) @@ -121,7 +101,7 @@ func startSecondHalving() { std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) gns.MintGns(a2u(user01Addr)) - uassert.Equal(t, uint64(225000000000000+14269406), gns.MintedEmissionAmount()) + uassert.Equal(t, uint64(225000000000000+14269406), gns.GetMintedEmissionAmount()) } func a2u(addr std.Address) pusers.AddressOrName { diff --git a/_deploy/r/gnoswap/gns/tests/z4_filetest.gno b/_deploy/r/gnoswap/gns/tests/z4_filetest.gno new file mode 100644 index 000000000..f4ea61add --- /dev/null +++ b/_deploy/r/gnoswap/gns/tests/z4_filetest.gno @@ -0,0 +1,93 @@ +// reach all having years and minted all amount +// and then no gns will be minted + +// PKGPATH: gno.land/r/gnoswap/v1/gns_test +package gns_test + +import ( + "std" + "testing" + + "gno.land/p/demo/testutils" + "gno.land/p/demo/uassert" + "gno.land/p/demo/ufmt" + pusers "gno.land/p/demo/users" + + "gno.land/r/gnoswap/v1/consts" + "gno.land/r/gnoswap/v1/gns" +) + +var t *testing.T + +var ( + user01Addr = testutils.TestAddress("user01Addr") + user01Realm = std.NewUserRealm(user01Addr) +) + +func main() { + reachAlmostEndOfEmission() + skip50Blocks() + moreBlocksAfterEmissionEnds() +} + +func reachAlmostEndOfEmission() { + endHeight := gns.GetEndHeight() + untilEnds := endHeight - std.GetHeight() + std.TestSkipHeights(untilEnds - 10) // 10 blocks before end of emission + + std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) + minted := gns.MintGns(a2u(user01Addr)) + + // minted all amount for year 01 ~ 11 + for year := int64(1); year <= 11; year++ { + uassert.Equal( + t, + gns.GetHalvingYearMaxAmount(year), + gns.GetHalvingYearMintAmount(year), + ufmt.Sprintf("shoud been minted max amount for year %d", year), + ) + } + + // we're at the end of last halving year + year := gns.GetHalvingYearByHeight(std.GetHeight()) + uassert.Equal(t, int64(12), year) +} + +func skip50Blocks() { + // 10 block left until emission ends + // skipping 50 blocks will reach the end of emission + // and it should mint for only 10 blocks + + std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) + std.TestSkipHeights(50) + gns.MintGns(a2u(user01Addr)) + + // total supply + totalSupply := gns.TotalSupply() + uassert.Equal(t, gns.MAXIMUM_SUPPLY, totalSupply) + + // minted amount + mintedAmount := gns.GetMintedEmissionAmount() + uassert.Equal(t, gns.MAX_EMISSION_AMOUNT, mintedAmount) +} + +func moreBlocksAfterEmissionEnds() { + std.TestSetRealm(std.NewCodeRealm(consts.EMISSION_PATH)) + std.TestSkipHeights(10) + + // no gns will be minted after emission ends + minted := gns.MintGns(a2u(user01Addr)) + uassert.Equal(t, uint64(0), minted) + + // total supply + totalSupply := gns.TotalSupply() + uassert.Equal(t, gns.MAXIMUM_SUPPLY, totalSupply) + + // minted amount + mintedAmount := gns.GetMintedEmissionAmount() + uassert.Equal(t, gns.MAX_EMISSION_AMOUNT, mintedAmount) +} + +func a2u(addr std.Address) pusers.AddressOrName { + return pusers.AddressOrName(addr) +}