PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/nym-wizards001/drop

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
drop
Namespace
nym-wizards001
Files
2 (gnomod.toml)
Exported functions
53
Module
gno.land/r/nym-wizards001/drop
gno
0.9
This realm implements a recognized token.WIZ →

Files (2)

  • gnomod.tomltoml
  • drop.gnogno
drop.gnogno
1// Package drop is the wizards token, symbol WIZ, version 4: the meme token and its genesis claim.2//3// Supply is 10_000_000_000 WIZ. Decimals are 6, so one WIZ is4// tokenUnit base units and the mint is 10_000_000_000_000_000.5//   - 75% airdrop, pro-rata to each wallet's genesis GNOT, paid from here6//   - 15% liquidity, minted once to the pinned wallet g17xukdzx4w0q4tmendmsjy2luxk7lvfzv39nfkl7//   - 7% liquidity incentives, minted once to the bound GovDAO realm8//   - 3% community development, plus the pro-rata remainder, minted once9//     to that same GovDAO realm10//11// A leaf is "g1...:<amount>". Claim pays that full amount once. The12// deployer sets the claim start. The window is 90 days. Unclaimed airdrop13// is burned. Claim attaches no GNOT. Any attached coins revert.14// This realm has no withdraw. It cannot move the liquidity sleeve or the15// GovDAO balance after Seal. GovDAO spends the incentive sleeve and the16// community sleeve separately.17// GovDAO lives in gno.land/r/nym-wizards001/gov. Holders vote there.18// The realm does not recompute GNOT weights.19// SetTradeOpen stores the instant other wallets may transfer. Until that20// instant, only the liquidity wallet, the airdrop escrow, and GovDAO may21// move WIZ through Transfer or TransferFrom. Claim and Seal move the22// ledger directly and stay available. After SetPool, tokens that leave23// that pool share one buy cap for a short window. The liquidity wallet24// is never capped, so it can add liquidity during the window.25package drop2627import (28	"chain"29	"chain/runtime/unsafe"30	"crypto/merkle"31	"encoding/hex"32	"math"33	"strconv"34	"time"3536	"gno.land/p/nt/grc20/v0"37	"gno.land/p/nt/avl/v0"38	"gno.land/p/nt/ownable/v0"39	"gno.land/p/nt/ufmt/v0"40)4142const (43	// tokenDecimals is the GRC20 display scale. One WIZ is tokenUnit base units.44	tokenDecimals = 645	// tokenUnit is 10^tokenDecimals.46	tokenUnit int64 = 1_000_00047	// wholeSupply is the mint in whole WIZ. mintSupply is the same mint in base units.48	// TotalSupply() is the circulating supply and shrinks when leftover airdrop is burned.49	wholeSupply int64 = 10_000_000_00050	mintSupply  int64 = wholeSupply * tokenUnit51	// CommunityBps is 3% of supply. The pro-rata remainder is added on top.52	CommunityBps int64 = 30053	// IncentiveBps is the liquidity-incentive sleeve, 7% of supply.54	IncentiveBps int64 = 70055	// LiquidityBps is the liquidity sleeve, 15% of supply.56	LiquidityBps int64 = 1_50057	// BpsBasis is 100%.58	BpsBasis int64 = 10_0005960	// ClaimWindow is the claim period after the deployer-set start: 90 days.61	ClaimWindow int64 = 90 * 24 * 60 * 6062	// VoteWindow is the longest a GovDAO ballot may lock a balance.63	// gno.land/r/nym-wizards001/gov uses the same duration.64	VoteWindow int64 = 7 * 24 * 60 * 6065	// quorumBps is the yes-vote floor, measured against the sealed airdrop budget.66	quorumBps int64 = 1_0006768	// BuyCapWindow is how long buys that leave the pool stay capped.69	BuyCapWindow int64 = 10 * 6070	// BuyCapBucket is one slice of that window. The cap resets each slice.71	BuyCapBucket int64 = 6072	// BuyCapPerBucket is 1% of the liquidity sleeve. Divide before multiply so the product fits in int64.73	BuyCapPerBucket int64 = mintSupply / BpsBasis * LiquidityBps / 1007475	tokenVersion = "4"7677	maxProofAunts = 10078	hashLen       = 3279)8081// hold is the largest ballot still locking an address.82type hold struct {83	amount int6484	until  int6485}8687var (88	// publisher is the addpkg signer. Captured once, when this package is initialized.89	publisher = unsafe.OriginCaller()9091	token     *grc20.Token92	ledger    *grc20.PrivateLedger93	admin     *ownable.Ownable94	adminAddr address9596	escrow address97	gov    address9899	sealed         bool100	root           []byte101	eligible       int102	allocated      int64103	communitySent  int64104	liquidityTo    address105	liquiditySent  int64106	incentiveSent  int64107	airdropLeft    int64108	claimStart     int64109	tradeOpen      int64110	burned         bool111	claimed        avl.Tree112	claimedSupply  int64113	locks          avl.Tree114115	// pair is the pool. Buys are transfers that leave it.116	pair      address117	pairSetAt int64118	buyBucket int64119	buySpent  int64120)121122// liquidityRecipient is the only wallet Seal may pay the 15% sleeve.123var liquidityRecipient = address("g17xukdzx4w0q4tmendmsjy2luxk7lvfzv39nfkl")124125// Version is the token book. Version 4 sends liquidity to the named address126// and sends incentive plus community to the bound GovDAO.127func Version() string { return tokenVersion }128129// Init binds the addpkg signer as admin. Any other caller panics.130func Init(cur realm) {131	mustUser(cur)132	mustNoPayment()133	if token != nil {134		panic("already initialized")135	}136	caller := cur.Previous().Address()137	// A deployed package records the addpkg signer in publisher.138	// The test VM leaves that address empty; the first Init caller is recorded.139	if !publisher.IsValid() {140		publisher = caller141	}142	if caller != publisher {143		panic("deployer")144	}145	admin = ownable.NewWithAddress(caller)146	adminAddr = caller147	escrow = cur.Address()148	token, ledger = grc20.NewToken("wizards", "WIZ", tokenDecimals, 0, cur)149	chain.Emit("Init", "admin", caller.String(), "version", tokenVersion)150}151152// TransferAdmin moves the admin seat. Admin cannot move funds.153func TransferAdmin(cur realm, next address) {154	mustAdmin(cur)155	mustNoPayment()156	if err := admin.TransferOwnership(0, cur, next); err != nil {157		panic(err.Error())158	}159	adminAddr = next160}161162// SetGov binds the GovDAO. The caller must be that realm, and the163// transaction signer must be this token's admin. One call, before Seal.164// Seal sends both the incentive sleeve and the community sleeve there.165func SetGov(cur realm) {166	mustCurrent(cur)167	mustNoPayment()168	if token == nil {169		panic("not initialized")170	}171	if sealed {172		panic("sealed")173	}174	if gov.IsValid() {175		panic("gov set")176	}177	prev := cur.Previous()178	if prev.IsUserCall() || prev.IsUserRun() {179		panic("gov")180	}181	if unsafe.OriginCaller() != adminAddr {182		panic("admin")183	}184	caller := prev.Address()185	if !caller.IsValid() || caller == escrow {186		panic("gov")187	}188	gov = caller189	chain.Emit("SetGov", "gov", caller.String())190}191192// Seal mints the whole supply, commits the eligible-set Merkle root, and193// sends the sleeves out. airdropTotal is the sum of the leaf amounts,194// at most the 75% pool. Integer dust is added to the community mint.195// liquidityTo must be liquidityRecipient. Any other address panics.196// Incentive and community both go to the realm bound with SetGov.197func Seal(cur realm, rootHex string, eligibleCount int, airdropTotal int64, liquidityToArg address) {198	mustAdmin(cur)199	mustNoPayment()200	if sealed {201		panic("already sealed")202	}203	if eligibleCount <= 0 {204		panic("eligible count")205	}206	decoded, err := hex.DecodeString(rootHex)207	if err != nil || len(decoded) != hashLen {208		panic("root")209	}210	communityAmt, incentiveAmt, liqAmt, pool := sleeves()211	if airdropTotal <= 0 || airdropTotal > pool {212		panic("allocated")213	}214	if !gov.IsValid() {215		panic("gov")216	}217	if liquidityToArg != liquidityRecipient || liquidityToArg == escrow || liquidityToArg == gov {218		panic("recipient")219	}220	communityAmt += pool - airdropTotal221222	mustMint(escrow, communityAmt+incentiveAmt+liqAmt+airdropTotal)223	mustTransfer(escrow, liquidityToArg, liqAmt)224	mustTransfer(escrow, gov, incentiveAmt)225	mustTransfer(escrow, gov, communityAmt)226227	root = append([]byte(nil), decoded...)228	eligible = eligibleCount229	allocated = airdropTotal230	communitySent = communityAmt231	liquidityTo = liquidityToArg232	liquiditySent = liqAmt233	incentiveSent = incentiveAmt234	airdropLeft = airdropTotal235	sealed = true236237	chain.Emit(238		"Seal",239		"root", hex.EncodeToString(root),240		"eligible", strconv.Itoa(eligibleCount),241		"allocated", strconv.FormatInt(airdropTotal, 10),242		"community", strconv.FormatInt(communityAmt, 10),243		"liquidity", strconv.FormatInt(liqAmt, 10),244		"incentive", strconv.FormatInt(incentiveAmt, 10),245		"liquidityTo", liquidityToArg.String(),246		"gov", gov.String(),247	)248}249250// SetClaimStart opens claims at start (unix seconds). The deployer may251// call it once. start must be in the future. Claims run for ClaimWindow.252func SetClaimStart(cur realm, start int64) {253	mustAdmin(cur)254	mustNoPayment()255	if !sealed {256		panic("not sealed")257	}258	if claimStart != 0 {259		panic("claim start set")260	}261	if start <= time.Now().Unix() || start > math.MaxInt64-ClaimWindow {262		panic("claim start")263	}264	claimStart = start265	chain.Emit(266		"SetClaimStart",267		"start", strconv.FormatInt(start, 10),268		"end", strconv.FormatInt(start+ClaimWindow, 10),269	)270}271272// SetTradeOpen stores the instant public transfers open. One call.273// The instant has to be in the future. Until it arrives, Transfer and274// TransferFrom move tokens only for the liquidity wallet, the airdrop275// escrow, and the bound GovDAO.276func SetTradeOpen(cur realm, start int64) {277	mustAdmin(cur)278	mustNoPayment()279	if tradeOpen != 0 {280		panic("trade open set")281	}282	if start <= time.Now().Unix() {283		panic("trade open")284	}285	tradeOpen = start286	chain.Emit("SetTradeOpen", "start", strconv.FormatInt(start, 10))287}288289// SetPool registers the pool once. The buy cap starts at this call.290// The liquidity wallet cannot be the pool. That wallet sends tokens291// into the pool, and those sends are not buys.292func SetPool(cur realm, market address) {293	mustAdmin(cur)294	mustNoPayment()295	if pair.IsValid() {296		panic("pool")297	}298	if !market.IsValid() || market == escrow || market == gov || market == liquidityRecipient {299		panic("pool")300	}301	pair = market302	pairSetAt = time.Now().Unix()303	buyBucket = 0304	buySpent = 0305	chain.Emit(306		"SetPool",307		"pool", market.String(),308		"start", strconv.FormatInt(pairSetAt, 10),309	)310}311312// Claim pays the caller's full sealed amount. Attaching coins reverts.313// There is no withdraw.314func Claim(cur realm, index int, amount int64, auntsHex string) {315	var to address316	claim(cur, index, amount, auntsHex, to)317}318319// ClaimTo pays the caller's full sealed amount to another address.320// The caller must still be the leaf. An invalid to pays the caller.321// to cannot be this realm. Attaching coins reverts. There is no withdraw.322func ClaimTo(cur realm, index int, amount int64, auntsHex string, to address) {323	claim(cur, index, amount, auntsHex, to)324}325326func claim(cur realm, index int, amount int64, auntsHex string, to address) {327	mustUser(cur)328	mustNoPayment()329	if !sealed {330		panic("not sealed")331	}332	if !claimOpen() {333		panic("claim closed")334	}335	if amount <= 0 || amount > allocated {336		panic("amount")337	}338	caller := cur.Previous().Address()339	key := caller.String()340	dest := to341	if !dest.IsValid() {342		dest = caller343	}344	if dest == escrow {345		panic("recipient")346	}347	if index < 0 || index >= eligible {348		panic("index")349	}350	aunts, err := hex.DecodeString(auntsHex)351	if err != nil || len(aunts)%hashLen != 0 || len(aunts)/hashLen > maxProofAunts {352		panic("bad proof")353	}354	if !merkle.VerifySimpleProof(root, leafData(key, amount), index, eligible, aunts) {355		panic("bad proof")356	}357	if claimed.Has(key) {358		panic("already claimed")359	}360	if airdropLeft < amount {361		panic("airdrop empty")362	}363	airdropLeft -= amount364	claimedSupply += amount365	claimed.Set(key, amount)366	mustTransfer(escrow, dest, amount)367	chain.Emit(368		"Claim",369		"leaf", key,370		"to", dest.String(),371		"index", strconv.Itoa(index),372		"amount", strconv.FormatInt(amount, 10),373	)374}375376// BurnUnclaimed destroys the airdrop budget still here after the window.377// Anyone may call it. A second call reverts. GovDAO cannot recover it.378// The sleeves already sent are not burned.379func BurnUnclaimed(cur realm) {380	mustCurrent(cur)381	if cur.Address() != escrow {382		panic("escrow")383	}384	mustNoPayment()385	if !sealed {386		panic("not sealed")387	}388	if burned {389		panic("already burned")390	}391	if claimStart == 0 || time.Now().Unix() < claimStart+ClaimWindow {392		panic("claim open")393	}394	left := airdropLeft395	airdropLeft = 0396	burned = true397	if left > 0 {398		mustBurn(escrow, left)399	}400	chain.Emit("BurnUnclaimed", "amount", strconv.FormatInt(left, 10))401}402403// NoteVote locks the signing caller's current balance until until.404// Only the bound GovDAO may call it. until cannot pass VoteWindow.405func NoteVote(cur realm, until int64) {406	mustCurrent(cur)407	mustNoPayment()408	if !gov.IsValid() || cur.Previous().Address() != gov {409		panic("gov")410	}411	now := time.Now().Unix()412	if until <= now || until > now+VoteWindow {413		panic("lock")414	}415	voter := unsafe.OriginCaller()416	if !voter.IsValid() || voter == gov || voter == escrow {417		panic("voter")418	}419	weight := BalanceOf(voter)420	if weight <= 0 {421		panic("vote weight")422	}423	key := voter.String()424	amt := weight425	end := until426	if v := locks.Get(key); v != nil {427		prev, ok := v.(*hold)428		if !ok || prev == nil {429			panic("lock")430		}431		if now < prev.until {432			if prev.amount > amt {433				amt = prev.amount434			}435			if prev.until > end {436				end = prev.until437			}438		}439	}440	locks.Set(key, &hold{amount: amt, until: end})441	chain.Emit(442		"NoteVote",443		"voter", voter.String(),444		"weight", strconv.FormatInt(amt, 10),445		"until", strconv.FormatInt(end, 10),446	)447}448449func Transfer(cur realm, to address, amount int64) {450	mustCurrent(cur)451	mustToken()452	mustNoPayment()453	caller := cur.Previous().Address()454	mustTradable(caller)455	mustUnlocked(caller, amount)456	mustBuyCap(caller, amount)457	teller := ledger.ImpersonateTeller(caller)458	if err := teller.Transfer(0, cur, to, amount); err != nil {459		panic(err.Error())460	}461}462463func Approve(cur realm, spender address, amount int64) {464	mustCurrent(cur)465	mustToken()466	mustNoPayment()467	caller := cur.Previous().Address()468	teller := ledger.ImpersonateTeller(caller)469	if err := teller.Approve(0, cur, spender, amount); err != nil {470		panic(err.Error())471	}472}473474func TransferFrom(cur realm, from, to address, amount int64) {475	mustCurrent(cur)476	mustToken()477	mustNoPayment()478	mustTradable(from)479	mustUnlocked(from, amount)480	mustBuyCap(from, amount)481	caller := cur.Previous().Address()482	teller := ledger.ImpersonateTeller(caller)483	if err := teller.TransferFrom(0, cur, from, to, amount); err != nil {484		panic(err.Error())485	}486}487488func Name() string {489	mustToken()490	return token.GetName()491}492493func Symbol() string {494	mustToken()495	return token.GetSymbol()496}497498func Decimals() int {499	mustToken()500	return token.GetDecimals()501}502503func Supply() int64 { return TotalSupply() }504505func TotalSupply() int64 {506	mustToken()507	return token.TotalSupply()508}509510func GetName() string   { return Name() }511func GetSymbol() string { return Symbol() }512func GetDecimals() int  { return Decimals() }513514func BalanceOf(owner address) int64 {515	mustToken()516	return token.BalanceOf(owner)517}518519func Allowance(owner, spender address) int64 {520	mustToken()521	return token.Allowance(owner, spender)522}523524func Admin() address { return adminAddr }525526func Escrow() address       { return escrow }527func Gov() address          { return gov }528func Sealed() bool          { return sealed }529func Eligible() int         { return eligible }530func Allocated() int64      { return allocated }531func CommunitySent() int64  { return communitySent }532// LiquidityRecipient is the only address Seal accepts for the 15% sleeve.533func LiquidityRecipient() address { return liquidityRecipient }534535func Pool() address       { return pair }536func PoolSetAt() int64    { return pairSetAt }537func BuySpent() int64     { return buySpent }538func LiquidityTo() address { return liquidityTo }539func LiquiditySent() int64 { return liquiditySent }540func IncentiveSent() int64 { return incentiveSent }541func AirdropLeft() int64    { return airdropLeft }542func ClaimStart() int64     { return claimStart }543func TradeOpen() int64      { return tradeOpen }544545func ClaimEnd() int64 {546	if claimStart == 0 {547		return 0548	}549	return claimStart + ClaimWindow550}551552func Burned() bool { return burned }553func Claimed() int { return claimed.Size() }554555// ClaimsStarted reports whether the claim window has opened.556func ClaimsStarted() bool { return claimsStarted() }557558func Quorum() int64 {559	if !sealed {560		return 0561	}562	// Floor on whole WIZ, then scale. allocated * quorumBps can overflow,563	// and dividing the base amount first would keep a fraction the 0-decimal book dropped.564	whole := allocated / tokenUnit565	return whole * quorumBps / BpsBasis * tokenUnit566}567568// ClaimedSupply is the sum of leaves already paid. Burns and transfers do not change it.569func ClaimedSupply() int64 { return claimedSupply }570571// Publisher is the only address allowed to call Init.572func Publisher() address { return publisher }573574func RootHex() string {575	if len(root) == 0 {576		return ""577	}578	return hex.EncodeToString(root)579}580581func HasClaimed(owner address) bool {582	if !owner.IsValid() {583		return false584	}585	return claimed.Has(owner.String())586}587588func ClaimedOf(owner address) int64 {589	if !owner.IsValid() {590		return 0591	}592	return claimedOf(owner.String())593}594595// Render shows the version-4 split and the claim window.596func Render(path string) string {597	if token == nil {598		return "# WIZ\n\nNot initialized.\n"599	}600	out := "# WIZ\n\n"601	out += ufmt.Sprintf("* **Version**: %s\n", tokenVersion)602	out += ufmt.Sprintf("* **Symbol**: %s\n", token.GetSymbol())603	out += ufmt.Sprintf("* **Decimals**: %d\n", token.GetDecimals())604	out += ufmt.Sprintf("* **One WIZ**: %d base units\n", tokenUnit)605	out += ufmt.Sprintf("* **Total supply**: %d WIZ\n", token.TotalSupply()/tokenUnit)606	out += ufmt.Sprintf("* **Total supply base**: %d\n", token.TotalSupply())607	out += "* **Airdrop**: 75%, pro-rata to genesis GNOT, 100% unlocked at claim\n"608	out += "* **Claim fee**: none\n"609	out += "* **Claim recipient**: the caller, or another address in the same call\n"610	out += "* **Claim window**: 90 days from the deployer start\n"611	out += "* **Unclaimed**: burned after the window\n"612	out += "* **Liquidity**: 15%, sent once at seal to the named address\n"613	out += "* **Incentives**: 7%, sent once at seal to GovDAO\n"614	out += "* **Community development**: 3% plus the pro-rata remainder, sent once at seal to GovDAO\n"615	out += "* **GovDAO**: a separate realm. Holders vote there on incentive and community, separately\n"616	out += "* **No withdraw**\n"617	out += ufmt.Sprintf("* **Trade open**: %d\n", tradeOpen)618	out += "* **Before trade open**: only the liquidity wallet, the airdrop escrow, and GovDAO can transfer\n"619	out += ufmt.Sprintf("* **Buy cap**: %d WIZ may leave the pool every %d seconds, for %d seconds after the pool is registered\n", BuyCapPerBucket/tokenUnit, BuyCapBucket, BuyCapWindow)620	out += "* **Liquidity add**: the liquidity wallet is not capped\n"621	if pair.IsValid() {622		out += ufmt.Sprintf("* **Pool**: %s\n", pair.String())623		out += ufmt.Sprintf("* **Buy cap ends**: %d\n", pairSetAt+BuyCapWindow)624	}625	if !sealed {626		out += "\nRoot is not sealed.\n"627		return out628	}629	out += ufmt.Sprintf("\n* **Eligible**: %d\n", eligible)630	out += ufmt.Sprintf("* **Airdrop budget left**: %d base units\n", airdropLeft)631	out += ufmt.Sprintf("* **Community sent**: %d base units\n", communitySent)632	out += ufmt.Sprintf("* **Liquidity sent**: %d base units\n", liquiditySent)633	out += ufmt.Sprintf("* **Incentive sent**: %d base units\n", incentiveSent)634	out += ufmt.Sprintf("* **Claim start**: %d\n", claimStart)635	out += ufmt.Sprintf("* **Claim end**: %d\n", ClaimEnd())636	out += ufmt.Sprintf("* **Burned**: %t\n", burned)637	out += ufmt.Sprintf("* **Root**: %s\n", hex.EncodeToString(root))638	out += ufmt.Sprintf("* **Claimed supply**: %d base units\n", claimedSupply)639	return out640}641642func leafData(bech32 string, amount int64) []byte {643	return []byte(bech32 + ":" + strconv.FormatInt(amount, 10))644}645646func sleeves() (community, incentive, liquidity, pool int64) {647	// Divide first. mintSupply * LiquidityBps does not fit in int64.648	community = mintSupply / BpsBasis * CommunityBps649	incentive = mintSupply / BpsBasis * IncentiveBps650	liquidity = mintSupply / BpsBasis * LiquidityBps651	pool = mintSupply - community - incentive - liquidity652	return653}654655func claimOpen() bool {656	if claimStart == 0 {657		return false658	}659	now := time.Now().Unix()660	return now >= claimStart && now < claimStart+ClaimWindow661}662663func claimsStarted() bool {664	return claimStart != 0 && time.Now().Unix() >= claimStart665}666667func mustCurrent(cur realm) {668	if !cur.IsCurrent() {669		panic("realm")670	}671}672673func mustUser(cur realm) {674	mustCurrent(cur)675	if !cur.Previous().IsUserCall() {676		panic("user call only")677	}678}679680// mustTradable panics while public transfers are closed.681// The liquidity wallet, the airdrop escrow, and GovDAO stay able to move tokens.682// Claim and Seal do not call this.683func mustTradable(from address) {684	if from == liquidityRecipient || (escrow.IsValid() && from == escrow) || (gov.IsValid() && from == gov) {685		return686	}687	if tradeOpen == 0 || time.Now().Unix() < tradeOpen {688		panic("trade closed")689	}690}691692// mustUnlocked panics when amount would push owner's balance under the693// largest weight they already cast on a ballot that is still open.694// An amount above the balance is left to the token transfer.695// mustBuyCap limits tokens leaving the registered pool during the short window.696// The liquidity wallet is exempt. A transfer that does not leave the pool is not a buy.697func mustBuyCap(from address, amount int64) {698	if amount <= 0 || from == liquidityRecipient || !pair.IsValid() || from != pair {699		return700	}701	now := time.Now().Unix()702	if pairSetAt <= 0 || now < pairSetAt {703		panic("buy cap")704	}705	if now >= pairSetAt+BuyCapWindow {706		return707	}708	bucket := (now - pairSetAt) / BuyCapBucket709	if bucket != buyBucket {710		buyBucket = bucket711		buySpent = 0712	}713	if amount > BuyCapPerBucket || buySpent > BuyCapPerBucket-amount {714		panic("buy cap")715	}716	buySpent += amount717}718719func mustUnlocked(owner address, amount int64) {720	if amount <= 0 {721		return722	}723	bal := BalanceOf(owner)724	if amount > bal {725		return726	}727	if bal-amount < voteLock(owner) {728		panic("vote lock")729	}730}731732func voteLock(owner address) int64 {733	if !owner.IsValid() {734		return 0735	}736	v := locks.Get(owner.String())737	if v == nil {738		return 0739	}740	h, ok := v.(*hold)741	if !ok || h == nil {742		panic("lock")743	}744	if time.Now().Unix() >= h.until {745		return 0746	}747	return h.amount748}749750func mustNoPayment() {751	if len(unsafe.OriginSend()) != 0 {752		panic("unexpected payment")753	}754}755756func mustAdmin(cur realm) {757	if admin == nil || token == nil {758		panic("not initialized")759	}760	mustUser(cur)761	admin.AssertOwnedBy(cur.Previous().Address())762}763764func mustToken() {765	if token == nil {766		panic("not initialized")767	}768}769770func claimedOf(key string) int64 {771	v := claimed.Get(key)772	if v == nil {773		return 0774	}775	n, ok := v.(int64)776	if !ok {777		panic("claimed amount")778	}779	return n780}781782func mustMint(to address, amount int64) {783	if err := ledger.Mint(to, amount); err != nil {784		panic(err.Error())785	}786}787788func mustTransfer(from, to address, amount int64) {789	if err := ledger.Transfer(from, to, amount); err != nil {790		panic(err.Error())791	}792}793794func mustBurn(from address, amount int64) {795	if err := ledger.Burn(from, amount); err != nil {796		panic(err.Error())797	}798}799

Functions

  • Admin() string

  • AirdropLeft() int64

  • Allocated() int64

  • Allowance(owner string, spender string) int64

  • Approve(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, spender string, amount int64)

  • BalanceOf(owner string) int64

  • Burned() bool

  • BurnUnclaimed(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • BuySpent() int64

  • Claim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, index int, amount int64, auntsHex string)

  • Claimed() int

  • ClaimedOf(owner string) int64

  • ClaimedSupply() int64

  • ClaimEnd() int64

  • ClaimsStarted() bool

  • ClaimStart() int64

  • ClaimTo(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, index int, amount int64, auntsHex string, to string)

  • CommunitySent() int64

  • Decimals() int

  • Eligible() int

  • Escrow() string

  • GetDecimals() int

  • GetName() string

  • GetSymbol() string

  • Gov() string

  • HasClaimed(owner string) bool

  • IncentiveSent() int64

  • Init(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • LiquidityRecipient() string

  • LiquiditySent() int64

  • LiquidityTo() string

  • Name() string

  • NoteVote(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, until int64)

  • Pool() string

  • PoolSetAt() int64

  • Publisher() string

  • Quorum() int64

  • Render(path string) string

  • RootHex() string

  • Seal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, rootHex string, eligibleCount int, airdropTotal int64, liquidityToArg string)

  • Sealed() bool

  • SetClaimStart(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, start int64)

  • SetGov(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • SetPool(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, market string)

  • SetTradeOpen(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, start int64)

  • Supply() int64

  • Symbol() string

  • TotalSupply() int64

  • TradeOpen() int64

  • Transfer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, amount int64)

  • TransferAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, next string)

  • TransferFrom(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, from string, to string, amount int64)

  • Version() string

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.