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/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/fishtoken

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
fishtoken
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt
Files
2 (gnomod.toml)
Exported functions
23
Module
gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/fishtoken
gno
0.9
This realm implements a recognized token.FISH →

Files (2)

  • gnomod.tomltoml
  • fishtoken.gnogno
fishtoken.gnogno
1// Package fishtoken is the unreleased GnoFish FISH ledger.2// Init mints a fixed supply once. No later call can mint.3// While transfers are closed, a normal wallet cannot send FISH, so it cannot4// fund a pool or sell through a market. The deploy wallet opens transfers.5// The five treasury wallets, the deploy wallet, and a reward realm the deploy6// wallet has granted may still send. This realm has no pool and no trade.7// Public-sale FISH is minted to the deploy wallet. fishtoken-1.8package fishtoken910import (11	"chain"12	"chain/runtime/unsafe"13	"strconv"1415	"gno.land/p/nt/grc20/v0"16	"gno.land/p/nt/seqid/v0"17)1819const (20	unit            int64 = 1_000_00021	supplyWhole     int64 = 100_000_00022	seasonWhole     int64 = 43_000_00023	liquidityWhole  int64 = 20_000_00024	ecosystemWhole  int64 = 15_000_00025	communityWhole  int64 = 12_000_00026	teamWhole       int64 = 5_000_00027	saleWhole       int64 = 5_000_00028)2930var (31	seasonAddr    = address("g1m6z3l9q577dltj73ym8fu0068peupqg468r5xe")32	liquidityAddr = address("g1lepzz7lehwfnwng0ddxaglz2kzmsf6pyy5f6tw")33	ecosystemAddr = address("g1p4cylgemajmw93e9a0nr0fmph60gee2yhkn2kz")34	communityAddr = address("g1dpklfykp2mrhcwccek54scv43kamtxlszya2z8")35	teamAddr      = address("g15ejerz2n0xn5x94zezhquvwvp98m3jgkcwdrya")36)3738var (39	token     *grc20.Token40	ledger    *grc20.PrivateLedger41	seq       seqid.ID42	inited    bool43	open      bool44	admin     address45	mover     map[address]bool46	payer     map[address]bool47)4849// Init mints the fixed supply once. The caller is the deploy wallet and receives the public-sale FISH. No coins.50func Init(cur realm) {51	caller := requireUser(cur)52	takeExact(0)53	if inited {54		panic("fishtoken: init")55	}56	if !distinct(caller, seasonAddr, liquidityAddr, ecosystemAddr, communityAddr, teamAddr) {57		panic("fishtoken: addr")58	}59	tok, led := grc20.NewToken("FISH", "FISH", 6, seq.Next(), cur)60	credit(led, seasonAddr, seasonWhole*unit)61	credit(led, liquidityAddr, liquidityWhole*unit)62	credit(led, ecosystemAddr, ecosystemWhole*unit)63	credit(led, communityAddr, communityWhole*unit)64	credit(led, teamAddr, teamWhole*unit)65	credit(led, caller, saleWhole*unit)66	if tok.TotalSupply() != supplyWhole*unit {67		panic("fishtoken: supply")68	}69	token = tok70	ledger = led71	admin = caller72	open = false73	mover = map[address]bool{74		caller:        true,75		seasonAddr:    true,76		liquidityAddr: true,77		ecosystemAddr: true,78		communityAddr: true,79		teamAddr:      true,80	}81	payer = map[address]bool{}82	inited = true83	chain.Emit("Init", "admin", caller.String(), "supply", strconv.FormatInt(supplyWhole*unit, 10))84}8586// SetTransfers opens or closes ordinary wallet sends. The deploy wallet only. No coins.87func SetTransfers(cur realm, next bool) {88	caller := requireUser(cur)89	takeExact(0)90	requireReady()91	requireAdmin(caller)92	open = next93	chain.Emit("SetTransfers", "open", strconv.FormatBool(next))94}9596// GrantMover lets that wallet send FISH while transfers are closed. The deploy wallet only. No coins.97func GrantMover(cur realm, who address) {98	caller := requireUser(cur)99	takeExact(0)100	requireReady()101	requireAdmin(caller)102	if !who.IsValid() {103		panic("fishtoken: addr")104	}105	mover[who] = true106	chain.Emit("GrantMover", "who", who.String())107}108109// RevokeMover removes that wallet from the closed-transfer list. The deploy wallet only. No coins.110func RevokeMover(cur realm, who address) {111	caller := requireUser(cur)112	takeExact(0)113	requireReady()114	requireAdmin(caller)115	if !who.IsValid() {116		panic("fishtoken: addr")117	}118	delete(mover, who)119	chain.Emit("RevokeMover", "who", who.String())120}121122// GrantDistributor lets that realm pay FISH to users while transfers are closed. The deploy wallet only. No coins.123func GrantDistributor(cur realm, who address) {124	caller := requireUser(cur)125	takeExact(0)126	requireReady()127	requireAdmin(caller)128	if !who.IsValid() {129		panic("fishtoken: addr")130	}131	payer[who] = true132	chain.Emit("GrantDistributor", "who", who.String())133}134135// RevokeDistributor removes that reward realm. The deploy wallet only. No coins.136func RevokeDistributor(cur realm, who address) {137	caller := requireUser(cur)138	takeExact(0)139	requireReady()140	requireAdmin(caller)141	if !who.IsValid() {142		panic("fishtoken: addr")143	}144	delete(payer, who)145	chain.Emit("RevokeDistributor", "who", who.String())146}147148// TransferAdmin hands the switch to next. Balances stay where they are. No coins.149func TransferAdmin(cur realm, next address) {150	caller := requireUser(cur)151	takeExact(0)152	requireReady()153	requireAdmin(caller)154	if !next.IsValid() {155		panic("fishtoken: admin")156	}157	admin = next158	mover[next] = true159	chain.Emit("TransferAdmin", "next", next.String())160}161162// Transfer sends FISH from the caller to to.163// A closed ledger rejects an ordinary wallet. Listed wallets and granted reward realms may still send.164func Transfer(cur realm, to address, amount int64) {165	caller := cur.Previous().Address()166	if cur.Previous().IsUserCall() {167		takeExact(0)168	}169	requireReady()170	requireAmount(amount, to)171	if !mayMove(cur, caller, caller) {172		panic("fishtoken: closed")173	}174	must(ledger.CallerTeller().Transfer(0, cur, to, amount))175	chain.Emit("Send", "to", to.String(), "amount", strconv.FormatInt(amount, 10))176}177178// Approve sets the spender allowance. It does not move FISH and does not open trading. No coins from an EOA.179func Approve(cur realm, spender address, amount int64) {180	if cur.Previous().IsUserCall() {181		takeExact(0)182	} else if !payer[cur.Previous().Address()] {183		panic("fishtoken: closed")184	}185	requireReady()186	if amount < 0 || !spender.IsValid() {187		panic("fishtoken: amount")188	}189	must(ledger.CallerTeller().Approve(0, cur, spender, amount))190	chain.Emit("Approve", "spender", spender.String(), "amount", strconv.FormatInt(amount, 10))191}192193// TransferFrom sends FISH using the caller's allowance.194// While closed, only a granted reward realm may pull, and only from its own balance or from a listed wallet.195func TransferFrom(cur realm, owner, to address, amount int64) {196	caller := cur.Previous().Address()197	if cur.Previous().IsUserCall() {198		takeExact(0)199	}200	requireReady()201	requireAmount(amount, to)202	if !mayMove(cur, caller, owner) {203		panic("fishtoken: closed")204	}205	must(ledger.CallerTeller().TransferFrom(0, cur, owner, to, amount))206	chain.Emit("SendFrom", "owner", owner.String(), "to", to.String(), "amount", strconv.FormatInt(amount, 10))207}208209func TransfersOpen() bool { return open }210func IsMover(who address) bool {211	return mover[who]212}213func IsDistributor(who address) bool { return payer[who] }214func Version() string                { return "fishtoken-1" }215func Admin() address                 { return admin }216217func Name() string {218	requireReady()219	return token.GetName()220}221222func Symbol() string {223	requireReady()224	return token.GetSymbol()225}226227func Decimals() int {228	requireReady()229	return token.GetDecimals()230}231232func TotalSupply() int64 {233	requireReady()234	return token.TotalSupply()235}236237func BalanceOf(who address) int64 {238	requireReady()239	return token.BalanceOf(who)240}241242func Allowance(owner, spender address) int64 {243	requireReady()244	return token.Allowance(owner, spender)245}246247func TokenID() string {248	requireReady()249	return token.ID()250}251252func Render(path string) string {253	if path != "" {254		return "# FISH\n\nUnknown path.\n"255	}256	if !inited {257		return "# FISH\n\nNot opened.\n"258	}259	state := "closed"260	if open {261		state = "open"262	}263	return "# FISH\n\nFixed supply. Transfers are " + state + ". A closed ledger does not fund a pool and does not trade. Listed wallets and granted reward realms can still send. Public-sale FISH was minted to the deploy wallet.\n"264}265266func mayMove(cur realm, caller, from address) bool {267	if open {268		return true269	}270	if cur.Previous().IsUserCall() {271		return from == caller && mover[caller]272	}273	if !payer[caller] {274		return false275	}276	return from == caller || mover[from]277}278279func requireAdmin(caller address) {280	if caller != admin {281		panic("fishtoken: admin")282	}283}284285func requireAmount(amount int64, to address) {286	if amount <= 0 || !to.IsValid() {287		panic("fishtoken: amount")288	}289}290291func credit(led *grc20.PrivateLedger, who address, amount int64) {292	if err := led.Mint(who, amount); err != nil {293		panic(err)294	}295}296297func must(err error) {298	if err != nil {299		panic(err)300	}301}302303func requireReady() {304	if !inited || token == nil || ledger == nil {305		panic("fishtoken: init")306	}307}308309func requireUser(cur realm) address {310	if !cur.Previous().IsUserCall() {311		panic("fishtoken: eoa")312	}313	return cur.Previous().Address()314}315316func takeExact(n int64) {317	sent := unsafe.OriginSend()318	if n == 0 {319		if len(sent) != 0 {320			panic("fishtoken: payment")321		}322		return323	}324	panic("fishtoken: payment")325}326327func distinct(xs ...address) bool {328	for i, a := range xs {329		if !a.IsValid() {330			return false331		}332		for j := 0; j < i; j++ {333			if xs[j] == a {334				return false335			}336		}337	}338	return true339}340

Functions

  • Admin() string

  • 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(who string) int64

  • Decimals() int

  • GrantDistributor(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}, who string)

  • GrantMover(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}, who string)

  • 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})

  • IsDistributor(who string) bool

  • IsMover(who string) bool

  • Name() string

  • Render(path string) string

  • RevokeDistributor(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}, who string)

  • RevokeMover(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}, who string)

  • SetTransfers(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 bool)

  • Symbol() string

  • TokenID() string

  • TotalSupply() 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}, owner string, to string, amount int64)

  • TransfersOpen() bool

  • 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.