Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

market package

Overview

Realm market is a custodial GNOT marketplace for goods listings: sellers list (title, description, price), a buyer purchases by paying the exact price, the marketplace holds the value until the seller claims their proceeds (price minus a transparent, snapshotted protocol fee).

COMPOSITION (per the recorded DISCOVERY / REUSE ANALYSIS): balance accounting is feeledger, coin movement is coinio, free-text render safety is the ecosystem sanitizer p/nt/markdown/sanitize/v0. This realm owns only the listing state machine. Two patterns are adopted from inspected ecosystem marketplaces: non-payable entrypoints REFUSE accidental -send instead of stranding it as surplus (nsmarket/v4's assertNoSend), and admin handoff is 2-STEP (memba_appstore_v2's TransferOwnership/AcceptOwnership), closing the one-step-transfer trade-off carried by earlier realms.

LIFECYCLE (terminal states are frozen; one transition per listing):

Example
 1CreateListing (anyone, no coins) : status Active; the fee bps is
 2                                   SNAPSHOTTED, subject to the
 3                                   seller's own maxFeeBps ceiling
 4Buy (EOA + -send == price)       : Active -> Sold, atomically:
 5                                   proceeds (price - snapshot fee)
 6                                   credit the seller's claimable
 7                                   balance, the fee accrues to the
 8                                   pot, the buyer is recorded
 9CancelListing (seller only)      : Active -> Cancelled (no funds
10                                   are involved; listings hold no
11                                   value)
12Claim / ClaimAll (anyone)        : pays out the caller's own
13                                   claimable proceeds
14WithdrawFees (fee recipient)     : pays out the fee pot

LISTINGS ARE IMMUTABLE: there is no price update — cancel and relist (new id). Together with Buy's EXACT-envelope rule this closes the listing-manipulation race twice over: a cancelled/relisted listing fails Buy's status check, and any price change fails the envelope check — either way the buyer's coins revert with the transaction. Buyers are structurally indifferent to fee changes: they pay the listed price; the fee comes out of the seller's proceeds at the bps snapshotted when the SELLER listed (with the seller's own ceiling — the creation-time fee race is closed the same way grants closes it).

AUTHORIZATION: every identity derives from the crossing entrypoint's cur.Previous().Address(); no function takes a caller identity as a parameter. Sellers may be EOAs or realms (they claim under their own address); buyers must be EOAs (coinio.Receive is the receipt-guaranteed shape). Self-purchase is rejected.

REALM-SELLER CAVEAT (audit Y1): assertNoSend reads the ORIGIN transaction's send envelope, so a realm seller must call CreateListing/CancelListing/Claim* in a transaction whose origin carried no -send — otherwise the guard fails closed even though this realm received nothing. Not third-party triggerable (nobody can attach a send to someone else's transaction); the workaround is a separate transaction.

MONETARY INVARIANT (conservation): listings hold NO value, so with H = ugnot held at the realm address, U = claimable seller proceeds, F = the fee pot, S >= 0 out-of-band surplus:

Example
1H == U + F + S

Buy raises H by exactly price and U+F by exactly price (feeledger guarantees credited + fee == amount); Claim*/WithdrawFees debit the ledger before coinio.Payout moves the identical amount out; any panic aborts the whole transaction; this realm never issues or removes coins. Surplus is recoverable only via SweepDenom (fee recipient), which reserves Liabilities() = U + F.

APPLICATION INVARIANT: status transitions Active -> {Sold, Cancelled} exactly once; Sold if and only if a buyer is recorded; for every sold listing, proceeds + fee == price at the snapshotted bps.

Function

SweepDenom

func SweepDenom(cur realm, denom string)

SweepDenom sends the surplus of a single denomination to the fee recipient. For ugnot only the excess over Liabilities() moves; other denoms move wholly. Only the fee recipient may call it.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/market" -func "SweepDenom" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "pearl-1" -remote "https://rpc.pearl.testnets.gno.land" ADDRESSgnokey query -remote "https://rpc.pearl.testnets.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/market" -func "SweepDenom" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "pearl-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.pearl.testnets.gno.land" call.tx