reserve.gno
2.36 Kb · 53 lines
1package guardians
2
3import (
4 "chain"
5 "gno.land/p/nt/ufmt/v0"
6)
7
8// The approved genesis list contains 369 independent one-token claims.
9// The Merkle manifest must be checked against this value before activation.
10const allowlistReservedSupply = int64(369)
11
12var (
13 allowlistMintedSupply int64
14 allowlistReserveReleased bool
15)
16
17func AllowlistReservedSupply() int64 { return allowlistReservedSupply }
18func AllowlistMintedSupply() int64 { return allowlistMintedSupply }
19func AllowlistReserveReleased() bool { return allowlistReserveReleased }
20func AllowlistUnclaimedSupply() int64 { return allowlistReservedSupply - allowlistMintedSupply }
21func AllowlistReserveRemaining() int64 {
22 if allowlistReserveReleased { return 0 }
23 return AllowlistUnclaimedSupply()
24}
25func PublicMintableSupply() int64 {
26 return maxSupply - token.TotalSupply() - AllowlistReserveRemaining()
27}
28
29// This one-way administrator action releases only the still-unclaimed stock.
30// It does NOT change the proof root, free price, or individual free entitlement.
31// No timer, public mint, or claim can trigger this release automatically.
32func ReleaseAllowlistReserve(cur realm) {
33 assertAdmin(cur.Previous().Address())
34 if !saleConfigured || revealState != revealStateCommitted {
35 panic("guardians: reserve release is not available")
36 }
37 if allowlistReserveReleased { panic("guardians: reserve already released") }
38 released := AllowlistReserveRemaining()
39 allowlistReserveReleased = true
40 chain.Emit("AllowlistReserveReleased", "released", ufmt.Sprintf("%d", released), "freeEntitlementsPreserved", "true")
41}
42
43func assertReserveCapacity(freeQuantity, paidQuantity int) {
44 if freeQuantity < 0 || paidQuantity < 0 { panic("guardians: invalid reserved allocation") }
45 if int64(freeQuantity) > AllowlistUnclaimedSupply() { panic("guardians: whitelist allocation exhausted") }
46 if token.TotalSupply()+int64(freeQuantity+paidQuantity) > maxSupply { panic("guardians: max supply reached") }
47 // A free claim consumes one reserved slot and one supply slot together.
48 // A paid mint must never consume the slots that remain protected afterwards.
49 protectedAfter := AllowlistReserveRemaining()
50 if !allowlistReserveReleased { protectedAfter -= int64(freeQuantity) }
51 remainingAfter := maxSupply-token.TotalSupply()-int64(freeQuantity+paidQuantity)
52 if remainingAfter < protectedAfter { panic("guardians: remaining supply is reserved for whitelist claims") }
53}