Realm detail
padv23
gno.land/r/g1mv0052e7r6s09f5t9xsqf00nj3tqsgt9dg52jr/gnomemepad/padv23
Indexed deployment identity with independently loaded latest RPC source, functions, and Render.
Indexed deployment
Identity
- Package path
- gno.land/r/g1mv0052e7r6s09f5t9xsqf00nj3tqsgt9dg52jr/gnomemepad/padv23
- Block
- 213869
- Deployed (UTC)
- Transaction
- 82yFU8nSGG1a5zAbc/6tourVOiVmc+1q5X+t73fRDSo=
Latest RPC state
Source
package padv23
import (
"chain"
"strconv"
"strings"
"time"
"gno.land/p/gnoswap/consts"
u256 "gno.land/p/gnoswap/uint256"
"gno.land/r/gnoland/wugnot"
"gno.land/r/gnoswap/gns"
gnspool "gno.land/r/gnoswap/pool"
"gno.land/r/gnoswap/position"
"gno.land/r/gnoswap/router"
)
// Sapphire Gnoswap registry keys / role addresses (sapphire-1).
const (
wugnotTokenKey = "gno.land/r/gnoland/wugnot.wugnot"
gnsTokenKey = "gno.land/r/gnoswap/gns.GNS"
gnoswapPoolAddrStr = "g1dexaf6aqkkyr9yfy9d5up69lsn7ra80af34g5v"
gnoswapRouterAddrStr = "g1vc883gshu5z7ytk5cdynhc8c2dh67pdp4cszkp"
)
// listFund tracks assets pulled from the listing caller for refund / LP ugnot reimburse.
type listFund struct {
ok bool
caller address
pulledLpWugnot int64 // reimbursed as ugnot after successful list
pulledFeeWugnot int64 // leftover WUGNOT refunded after list; full refund on fail
pulledGns int64 // CreatePool fee; consumed on success
}
// tryListOnGnoswap seeds a Gnoswap CL pool with remaining meme tokens + raised-sized
// WUGNOT as LP. CreatePool fee (fixed GNS amount) is paid from:
// 1) pre-funded GNS on pad (preferred - immune to GNOT/GNS price moves), else
// 2) ExactOut WUGNOT->GNS using SURPLUS inventory only (above raised), so LP depth
// stays equal to raised even when GNS is expensive.
//
// Returns true on success. Soft failure sets l.GnoswapNote and returns false
// (caller keeps internal CPMM). Does not pull from user - see prepareCallerListFunding.
func tryListOnGnoswap(cur realm, l *Launch, raisedUgnot, remainingTokens int64) bool {
if raisedUgnot <= 0 || remainingTokens <= 0 {
l.GnoswapNote = "list skip: empty capital"
return false
}
padAddr := cur.Address()
wBal := wugnot.BalanceOf(padAddr)
if wBal < raisedUgnot {
l.GnoswapNote = "list skip: need WUGNOT inventory >= raised for LP; have " +
strconv.FormatInt(wBal, 10) + " need " + strconv.FormatInt(raisedUgnot, 10)
return false
}
feeNeed := gnspool.GetPoolCreationFee()
if feeNeed <= 0 {
feeNeed = 100_000_000 // 100 GNS default (6 decimals)
}
// --- GNS for CreatePool fee ---
// Require GNS already on pad. Do NOT Approve+router ExactOut mid-list:
// realm spender frame often panics "insufficient allowance" and reverts the tx.
// UI: gns.Transfer(pad, feeNeed) then RetryListGnoswap.
gnsBal := gns.BalanceOf(padAddr)
feeWugnot := int64(0)
if gnsBal < feeNeed {
l.GnoswapNote = "list skip: need " + strconv.FormatInt(feeNeed, 10) +
" GNS base units on pad (Transfer GNS then RetryList). have " +
strconv.FormatInt(gnsBal, 10) +
". No mid-list WUGNOT->GNS swap (avoids allowance panic)."
return false
}
liqWugnot := raisedUgnot
if wugnot.BalanceOf(padAddr) < liqWugnot {
l.GnoswapNote = "list skip: WUGNOT below raised after fee path"
return false
}
// LP token amount: prefer PoolToken already sized in graduate() to curve spot.
// Defensive resize if Virtuals are somehow still set (pre-graduate test paths):
// tokensForLP = raisedUgnot * VirtualToken / VirtualUgnot
liqTokens := remainingTokens
if l.VirtualUgnot > 0 && l.VirtualToken > 0 && liqWugnot > 0 {
needed := liqWugnot * l.VirtualToken / l.VirtualUgnot
if needed > 0 && needed < remainingTokens {
liqTokens = needed
}
}
if liqTokens <= 0 {
l.GnoswapNote = "list skip: zero LP tokens at curve spot"
return false
}
// Mint LP slice + leftover inventory (LeftoverTokens set at graduate) onto pad.
mintAmt := remainingTokens
if l.LeftoverTokens > 0 {
mintAmt = remainingTokens + l.LeftoverTokens
}
if mintAmt < liqTokens {
mintAmt = liqTokens
}
addBal(l, padAddr, mintAmt)
tokenKey := adenaKeyFromTokenID(l.TokenID, l.Symbol)
if tokenKey == "" {
l.GnoswapNote = "list skip: empty token registry key"
return false
}
// Sort token0 < token1 (Gnoswap pool key order) BEFORE sqrtPrice + CreatePool + Mint.
// CreatePool reorders tokens and INVERTS sqrtPriceX96 when args are out of order
// (newSqrt = Q192/oldSqrt). If we pass unsorted keys with a price already computed
// for the sorted pair, the pool is born with inverted price -> Mint only takes a
// tiny sliver of one side (e.g. ~4 GNOT of a 10k WUGNOT raise). Always call
// CreatePool(t0, t1, fee, sqrt) with the same sorted pair as Mint.
t0, t1 := wugnotTokenKey, tokenKey
amt0, amt1 := liqWugnot, liqTokens
if strings.Compare(t0, t1) > 0 {
t0, t1 = t1, t0
amt0, amt1 = amt1, amt0
}
sqrtPrice := computeSqrtPriceX96(amt0, amt1)
if sqrtPrice == "" || sqrtPrice == "0" {
l.GnoswapNote = "list skip: bad sqrtPriceX96"
return false
}
poolAddr := address(gnoswapPoolAddrStr)
gns.Approve(cross(cur), poolAddr, feeNeed)
wugnot.Approve(cross(cur), poolAddr, liqWugnot)
if err := l.ledger.Approve(padAddr, poolAddr, liqTokens); err != nil {
l.GnoswapNote = "list skip: token approve failed: " + err.Error()
return false
}
// CRITICAL: sorted (t0,t1) + matching sqrtPrice (do NOT pass original unsorted keys)
gnspool.CreatePool(cross(cur), t0, t1, GnoswapFeeTier, sqrtPrice)
tickLower, tickUpper := alignedFullRangeTicks(GnoswapTickSpacing)
deadline := time.Now().Unix() + 600
posID, liqStr, a0, a1 := position.Mint(
cross(cur),
t0,
t1,
GnoswapFeeTier,
tickLower,
tickUpper,
strconv.FormatInt(amt0, 10),
strconv.FormatInt(amt1, 10),
"0",
"0",
deadline,
padAddr, // permanent lock: pad owns position NFT
"",
)
// Actual WUGNOT deposited (whichever side is WUGNOT after sort)
used0, _ := strconv.ParseInt(a0, 10, 64)
used1, _ := strconv.ParseInt(a1, 10, 64)
wugnotUsed := int64(0)
if t0 == wugnotTokenKey {
wugnotUsed = used0
} else if t1 == wugnotTokenKey {
wugnotUsed = used1
}
// Sanity: if Mint took << intended LP WUGNOT, mark note (still listed - pool exists)
if wugnotUsed > 0 && liqWugnot > 0 && wugnotUsed*2 < liqWugnot {
// keep going but surface under-deposit for ops
chain.Emit("ListUnderDeposit",
"id", l.ID,
"wantWugnot", strconv.FormatInt(liqWugnot, 10),
"gotWugnot", strconv.FormatInt(wugnotUsed, 10),
)
}
poolPath := t0 + ":" + t1 + ":" + strconv.FormatUint(uint64(GnoswapFeeTier), 10)
l.GnoswapListed = true
l.GnoswapPoolPath = poolPath
l.GnoswapPositionID = posID
l.ListVenue = VenueGnoswap
l.FeeWugnotSpent = feeWugnot
if wugnotUsed > 0 {
l.LiqWugnotUsed = wugnotUsed
} else {
l.LiqWugnotUsed = liqWugnot
}
// Release Create-time GNS escrow (fee left pad via CreatePool).
consumeListFeeEscrow(l)
leftoverTok := l.LeftoverTokens
if leftoverTok < 0 {
leftoverTok = 0
}
if remLeft := remainingTokens - liqTokens; remLeft > leftoverTok {
leftoverTok = remLeft
}
l.GnoswapNote = "listed pool=" + poolPath + " pos=" + strconv.FormatUint(posID, 10) +
" liq=" + liqStr + " a0=" + a0 + " a1=" + a1 +
" wugnotUsed=" + strconv.FormatInt(wugnotUsed, 10) +
" feeWugnot=" + strconv.FormatInt(feeWugnot, 10) +
" lpTokens=" + strconv.FormatInt(liqTokens, 10) +
" leftoverTokens=" + strconv.FormatInt(leftoverTok, 10)
chain.Emit("GnoswapListed",
"id", l.ID,
"poolPath", poolPath,
"positionId", strconv.FormatUint(posID, 10),
"feeWugnot", strconv.FormatInt(feeWugnot, 10),
"liqWugnot", strconv.FormatInt(liqWugnot, 10),
"wugnotUsed", strconv.FormatInt(wugnotUsed, 10),
"lpTokens", strconv.FormatInt(liqTokens, 10),
"leftoverTokens", strconv.FormatInt(leftoverTok, 10),
"tokens", strconv.FormatInt(remainingTokens, 10),
)
return true
}
// prepareCallerListFunding fills pad inventory shortfall from the EOA caller via TransferFrom.
//
// padv14+ WUGNOT raise: Buy already TransferFrom WUGNOT to pad, so wBal >= raised
// at graduate in the normal case - only GNS fee (or small fee WUGNOT budget) may be short.
//
// Legacy ugnot-raise pads: wugnot.Deposit is EOA-only; caller wraps temp LP then reimbursed.
func prepareCallerListFunding(cur realm, l *Launch, raisedUgnot int64) listFund {
caller := cur.Previous().Address()
padA := cur.Address()
out := listFund{ok: true, caller: caller}
if raisedUgnot <= 0 {
l.GnoswapNote = "list skip: empty raise"
out.ok = false
return out
}
feeNeed := gnspool.GetPoolCreationFee()
if feeNeed <= 0 {
feeNeed = 100_000_000
}
wBal := wugnot.BalanceOf(padA)
if wBal < raisedUgnot {
short := raisedUgnot - wBal
if !pullWugnotFrom(cur, caller, padA, short) {
l.GnoswapNote = "list skip: need temp WUGNOT wrap " +
strconv.FormatInt(short, 10) +
" ugnot units (Deposit+Approve pad). LP reimbursed from pad ugnot after list. " +
"Fee: " + strconv.FormatInt(feeNeed, 10) + " GNS or WUGNOT ExactOut budget."
out.ok = false
return out
}
out.pulledLpWugnot = short
wBal += short
}
gnsBal := gns.BalanceOf(padA)
if gnsBal < feeNeed {
gShort := feeNeed - gnsBal
if pullGnsFrom(cur, caller, padA, gShort) {
out.pulledGns = gShort
} else {
// No GNS from caller - pull modest WUGNOT surplus for ExactOut -> GNS.
// Do NOT pull full GnoswapMaxFeeWugnot (5000 GNOT) - that causes
// InsufficientCoins for normal wallets. MaxFee still caps ExactOut spend.
surplus := wBal - raisedUgnot
if surplus < 1 {
feeBudget := listFeeWugnotPull()
if !pullWugnotFrom(cur, caller, padA, feeBudget) {
l.GnoswapNote = "list skip: need GNS fee " +
strconv.FormatInt(feeNeed, 10) +
" (Approve pad) OR WUGNOT fee budget " +
strconv.FormatInt(feeBudget, 10) +
" ugnot for ExactOut. Prefer holding 100 GNS."
// Roll back LP pull.
if out.pulledLpWugnot > 0 {
safeWugnotTransfer(cur, caller, out.pulledLpWugnot)
out.pulledLpWugnot = 0
}
out.ok = false
return out
}
out.pulledFeeWugnot = feeBudget
}
}
}
return out
}
// listFeeWugnotPull is the WUGNOT amount pulled from the listing caller for
// ExactOut -> GNS when they do not hold CreatePool fee in GNS.
// Kept well below GnoswapMaxFeeWugnot so List does not demand 5k+ GNOT wrap.
func listFeeWugnotPull() int64 {
const defaultPull int64 = 1_500_000_000 // 1500 GNOT - enough for ~100 GNS at <=15 GNOT/GNS
if GnoswapMaxFeeWugnot > 0 && GnoswapMaxFeeWugnot < defaultPull {
return GnoswapMaxFeeWugnot
}
return defaultPull
}
// pullWugnotFrom is intentionally a no-op pull.
//
// GRC20 TransferFrom from a realm often panics "insufficient allowance" even when
// Allowance(owner, pad) is set (spender frame resolves to EOA, not pad). Soft-fail
// instead so list can fall back to notes / surplus / pre-funded pad inventory.
//
// UI must pre-fund pad via wugnot.Transfer(pad, amount) and gns.Transfer(pad, fee)
// before RetryListGnoswap - never rely on Approve+TransferFrom in the same flow.
func pullWugnotFrom(cur realm, from, to address, amount int64) bool {
if amount <= 0 {
return true
}
// Already on pad? treat as satisfied without TransferFrom.
if wugnot.BalanceOf(to) >= amount && from != to {
// Not a full check for "raised" accounting - prepareCallerListFunding
// already compared pad balance to raised before calling shortfall pulls.
}
_ = cur
_ = from
_ = to
return false
}
func pullGnsFrom(cur realm, from, to address, amount int64) bool {
if amount <= 0 {
return true
}
_ = cur
_ = from
_ = to
// Never TransferFrom GNS either (same spender-frame issue).
return false
}
func safeWugnotTransfer(cur realm, to address, amount int64) {
if amount <= 0 {
return
}
have := wugnot.BalanceOf(cur.Address())
if have < amount {
amount = have
}
if amount > 0 {
wugnot.Transfer(cross(cur), to, amount)
}
}
func safeGnsTransfer(cur realm, to address, amount int64) {
if amount <= 0 {
return
}
have := gns.BalanceOf(cur.Address())
if have < amount {
amount = have
}
if amount > 0 {
gns.Transfer(cross(cur), to, amount)
}
}
func refundCallerListFunding(cur realm, fund listFund) {
if !fund.caller.IsValid() {
return
}
safeWugnotTransfer(cur, fund.caller, fund.pulledLpWugnot+fund.pulledFeeWugnot)
safeGnsTransfer(cur, fund.caller, fund.pulledGns)
}
// settleCallerListFunding returns unused fee-budget WUGNOT to the caller.
// LP shortfall pull is rare on WUGNOT-raise pads (raised already on pad); if it
// happened, reimburse in WUGNOT from any leftover pad balance after list.
func settleCallerListFunding(cur realm, fund listFund) {
if !fund.caller.IsValid() {
return
}
if fund.pulledLpWugnot > 0 {
safeWugnotTransfer(cur, fund.caller, fund.pulledLpWugnot)
}
// Leftover fee-budget WUGNOT (ExactOut may not consume full maxIn).
if fund.pulledFeeWugnot > 0 {
safeWugnotTransfer(cur, fund.caller, fund.pulledFeeWugnot)
}
}
// listOnGnoswapWithFunding is the full auto path: pull inventory from caller if needed,
// CreatePool+Mint, reimburse LP ugnot / refund on failure.
func listOnGnoswapWithFunding(cur realm, l *Launch, raisedUgnot, remainingTokens int64) bool {
fund := prepareCallerListFunding(cur, l, raisedUgnot)
if !fund.ok {
return false
}
ok := tryListOnGnoswap(cur, l, raisedUgnot, remainingTokens)
if ok {
settleCallerListFunding(cur, fund)
if fund.pulledLpWugnot > 0 || fund.pulledFeeWugnot > 0 || fund.pulledGns > 0 {
chain.Emit("ListFunding",
"id", l.ID,
"caller", fund.caller.String(),
"lpWugnot", strconv.FormatInt(fund.pulledLpWugnot, 10),
"feeWugnot", strconv.FormatInt(fund.pulledFeeWugnot, 10),
"gns", strconv.FormatInt(fund.pulledGns, 10),
)
}
return true
}
refundCallerListFunding(cur, fund)
return false
}
// listNeedOf: poolU|wHave|wNeedLp|gnsHave|gnsNeed|feeGns|feeWugnotBudget|padAddr
func listNeedOf(l *Launch) string {
poolU := int64(0)
if l != nil && l.Status == StatusGraduated && !l.GnoswapListed {
poolU = l.PoolUgnot
}
padA := padAddr
wHave := wugnot.BalanceOf(padA)
gnsHave := gns.BalanceOf(padA)
feeGns := gnspool.GetPoolCreationFee()
if feeGns <= 0 {
feeGns = 100_000_000
}
wNeed := poolU - wHave
if wNeed < 0 {
wNeed = 0
}
gNeed := feeGns - gnsHave
if gNeed < 0 {
gNeed = 0
}
feeBud := listFeeWugnotPull()
// If GNS already covered, fee WUGNOT budget need is 0 for the wizard.
if gNeed == 0 {
feeBud = 0
} else if wHave > poolU {
// Existing surplus reduces fee budget to pull
surp := wHave - poolU
if surp >= feeBud {
feeBud = 0
} else {
feeBud = feeBud - surp
}
}
return strconv.FormatInt(poolU, 10) + "|" +
strconv.FormatInt(wHave, 10) + "|" +
strconv.FormatInt(wNeed, 10) + "|" +
strconv.FormatInt(gnsHave, 10) + "|" +
strconv.FormatInt(gNeed, 10) + "|" +
strconv.FormatInt(feeGns, 10) + "|" +
strconv.FormatInt(feeBud, 10) + "|" +
padA.String()
}
// ListNeed is the public query for the Token list wizard (default venue).
func ListNeed(id string) string {
return listNeedOf(mustLaunch(id))
}
// ListNeedFor is venue-aware; only gnoswap has a Need adapter today.
func ListNeedFor(id, venueId string) string {
l := mustLaunch(id)
vid := normalizeVenueID(venueId)
if vid != VenueGnoswap {
poolU := int64(0)
if l != nil && l.Status == StatusGraduated && !l.GnoswapListed {
poolU = l.PoolUgnot
}
return strconv.FormatInt(poolU, 10) + "|0|0|0|0|0|0|" + padAddr.String()
}
return listNeedOf(l)
}
// ListedOf reports whether the launch is listed on any venue.
func ListedOf(id string) bool {
l := mustLaunch(id)
return l.GnoswapListed || l.ListVenue != ""
}
// ListPoolPathOf returns the pool path after listing.
func ListPoolPathOf(id string) string {
return mustLaunch(id).GnoswapPoolPath
}
// ListNoteOf returns the listing status note.
func ListNoteOf(id string) string {
return mustLaunch(id).GnoswapNote
}
func swapWugnotForGNS(cur realm, amountOutGNS, maxInWugnot int64) (spent int64, ok bool) {
if amountOutGNS <= 0 || maxInWugnot <= 0 {
return 0, false
}
routerAddr := address(gnoswapRouterAddrStr)
before := wugnot.BalanceOf(cur.Address())
if before < maxInWugnot {
maxInWugnot = before
}
if maxInWugnot <= 0 {
return 0, false
}
wugnot.Approve(cross(cur), routerAddr, maxInWugnot)
route := wugnotTokenKey + ":" + gnsTokenKey + ":" + strconv.FormatUint(uint64(GnoswapFeeTier), 10)
deadline := time.Now().Unix() + 600
inStr, outStr := router.ExactOutSwapRoute(
cross(cur),
wugnotTokenKey,
gnsTokenKey,
strconv.FormatInt(amountOutGNS, 10),
route,
"100",
strconv.FormatInt(maxInWugnot, 10),
deadline,
"",
)
_ = outStr
spentIn, err := strconv.ParseInt(inStr, 10, 64)
if err != nil || spentIn <= 0 {
after := wugnot.BalanceOf(cur.Address())
if after >= before {
return 0, false
}
return before - after, true
}
return spentIn, true
}
func computeSqrtPriceX96(amount0, amount1 int64) string {
if amount0 <= 0 || amount1 <= 0 {
return ""
}
a0 := u256.MustFromDecimal(strconv.FormatInt(amount0, 10))
a1 := u256.MustFromDecimal(strconv.FormatInt(amount1, 10))
num := u256.Zero().Mul(a1, consts.Q192())
ratio := u256.Zero().Div(num, a0)
sqrt := u256Sqrt(ratio)
if sqrt.Lt(consts.MinSqrtRatio()) {
return consts.MinSqrtRatio().ToString()
}
if sqrt.Gte(consts.MaxSqrtRatio()) {
return u256.Zero().Sub(consts.MaxSqrtRatio(), u256.One()).ToString()
}
return sqrt.ToString()
}
func u256Sqrt(x *u256.Uint) *u256.Uint {
if x == nil || x.IsZero() {
return u256.Zero()
}
if x.Eq(u256.One()) {
return u256.One()
}
lo := u256.Zero()
hi := u256.Zero().Add(x, u256.One())
cap128 := u256.Zero().Lsh(u256.One(), 128)
if hi.Gt(cap128) {
hi = cap128.Clone()
}
for lo.Lt(u256.Zero().Sub(hi, u256.One())) {
mid := u256.Zero().Div(u256.Zero().Add(lo, hi), u256.NewUint(2))
if mid.IsZero() {
lo = u256.One()
continue
}
sq, overflow := u256.Zero().MulOverflow(mid, mid)
if overflow || sq.Gt(x) {
hi = mid
} else {
lo = mid
}
}
return lo
}
func alignedFullRangeTicks(spacing int32) (int32, int32) {
if spacing <= 0 {
spacing = 60
}
tl := (GnoswapMinTick / spacing) * spacing
tu := (GnoswapMaxTick / spacing) * spacing
if tl >= tu {
tl = -spacing
tu = spacing
}
return tl, tu
}
// GnoswapListedOf reports whether a launch was auto-listed on Gnoswap.
func GnoswapListedOf(id string) bool {
return mustLaunch(id).GnoswapListed
}
// GnoswapPoolPathOf returns the Gnoswap pool path after listing (or empty).
func GnoswapPoolPathOf(id string) string {
return mustLaunch(id).GnoswapPoolPath
}
// GnoswapNoteOf returns the listing status note.
func GnoswapNoteOf(id string) string {
return mustLaunch(id).GnoswapNote
}
Latest RPC state
Exported functions
- ListNeed(id string) string
- ListNeedFor(id string, venueId string) string
- ListedOf(id string) bool
- ListPoolPathOf(id string) string
- ListNoteOf(id string) string
- GnoswapListedOf(id string) bool
- GnoswapPoolPathOf(id string) string
- GnoswapNoteOf(id string) string
- DefaultListVenue() string
- SetDefaultListVenue(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}, venueId string)
- SetListVenue(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}, id string, label string, enabled bool, feeAssetHint string)
- ListVenues() string
- ListVenueOf(id string) 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})
- SetGraduationThreshold(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}, ugnot int64)
- GraduationThresholdLive() int64
- SetListFeeGns(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}, gns int64)
Latest RPC state · Realm Render
gnomemepad
Meme launchpad - WUGNOT bonding curve -> remaining tokens + raised WUGNOT seed Gnoswap LP (auto-list).
- Launches: 0
- Protocol treasury:
g1mv0052e7r6s09f5t9xsqf00nj3tqsgt9dg52jr - Protocol fees pending (claim/push): 0 ugnot
- Protocol fees paid (lifetime): 0 ugnot
Markets
No launches yet. Call Create with name, symbol, uri and bond.