Cosmic Bull

Realm on pearl-1

revshare

gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/revshare

realmfactory-applicationrevenue

RenderedSourceCall builderState

curated

Team revenue realm that IS a subscription provider: creates plans on the live subscriptions realm as the provider (admin-gated), pulls accrued revenue across the realm boundary via permissionless Pull (ClaimAll cross-call, measured held-delta), and splits it among weighted members (<=20, weights 1..10000) into pull-claimable feeledger balances, rounding dust to the highest-weight member. Conservation Held == UsersTotal + S; the downstream receivable is accounted, not custodied. Factory benchmark #7 (economic composition).

Identity

Import pathgno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/revshare
Kindrealm (/r/)
Chainpearl-1
Namespaceg1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3
Realm addressg1ccm649r4y542awaafhnl4v8ukuyhqqjmrtdwge confirmed against the realm itself

Provenance

chain-attested
Deployed at height662,737
Deploy transactiona59b13509186fd244bc7c26316bed7b3accb5edd1345cff2106a6ff9bee74cd3 look it up on the RPC
Deployerg1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3
Gas used33,482,374
Storage32,207 bytes, deposit 3220700ugnot
Files on chaingnomod.toml revshare.gno
Deployed bytesrevshare.gno — 16,794 bytes
sha25633529d65b8d7635ba2b1e09aa92462a137959263abbbcabfda717121a4872014

Do not take the hash above on trust. $download returns the bytes pearl-1 is actually running; this command fetches them and prints their digest, which should equal the one in the table:

curl -sS 'https://pearl.testnets.gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/revshare$download&file=revshare.gno' | shasum -a 256

Expected: 33529d65b8d7635ba2b1e09aa92462a137959263abbbcabfda717121a4872014 — 16,794 bytes. This was checked for all 23 packages while building this site's architecture record; every one matched. Use curl: pearl's edge answers Python's default user-agent with HTTP 403.

API

chain-derived 22 exported functions.

Every function below deep-links to gnoweb's call builder, which generates a ready-to-run gnokey maketx call for it:

AcceptAdminAddMemberBalanceOfClaimClaimAllCreatePlanHeldMemberCountMemberWeightNumPlansPlanIDPullPulledReceivableRemoveMemberRenderRetirePlanSetWeightSweepDenomTotalWeightTransferAdminUsersTotal

Overview

Package revshare is a team revenue realm that IS a subscription provider. The live subscriptions realm supports realm providers but warns, in its own frozen header, that a realm provider "must expose its own crossing path to Claim, or what it earns is stranded." revshare is that crossing path, plus the one thing a team needs on top of it: pulled revenue is split among weighted members into pull-claimable balances.

THE ECONOMIC COMPOSITION, PRECISELY:

components : subscriptions (live realm — the revenue machine and the upstream custodian), feeledger (member balance accounting, fee cap 0), coinio (payouts, held-balance reads, reserve-protected sweep). value boundaries : B1 subscriber EOA -> subscriptions (plan price, origin envelope; governed by subscriptions' own H == U + F). B2 subscriptions -> revshare (banker send: ClaimAll pays the caller, and the caller is this realm). B3 revshare -> member EOA (coinio.Payout on Claim/ClaimAll). who owns which state : subscriptions owns plans, subs and the provider's claimable balance (revshare's RECEIVABLE); revshare owns the member table, weights, and the member balances in its own ledger. No state is shared; the only coupling is the crossing calls and the coins that move over B2. who controls funds : upstream, only a claim by this realm can move its receivable (provider-keyed ledger). Here, member balances move only to their owner (pull claims); the admin can NEVER touch earned balances — sweep reserves them, weight changes affect only FUTURE distributions. identity propagation : downstream sees cur.Previous() = THIS realm on every crossing call, so the plan provider and the claim beneficiary are the realm address by construction — no admin or member identity ever reaches the downstream realm. conservation : Held == UsersTotal + S (surplus above the Liabilities() reserve, recoverable only by SweepDenom). Distribution is exact: shares are floor(amountw/W) via the overflow-free split (A/W)w + ((A%W)*w)/W, and the remainder goes to the highest-weight member (ties: lowest address) — fee_split's deterministic dust policy, so no residual pool exists. Cross-boundary: lifetime Pulled equals the sum of all distributions, and the downstream receivable is NOT part of Held. ordering : Pull refuses BEFORE the downstream call (no members configured = refuse), claims downstream, MEASURES the arrival as a held-balance delta, then distributes exactly what arrived. State-after-call: the only local mutations happen after the boundary, on measured coins. downstream abort : "nothing to claim" (or any downstream panic) aborts the whole Pull — no local state exists yet to corrupt, by ordering AND by VM atomicity. There is no recover anywhere in this realm, and none may be added. replay : a second Pull finds a zero downstream balance and aborts there. Distribution credits are driven by the measured delta, so a replayed Pull cannot double-count even in principle. trust : revshare does not trust the downstream reply beyond "it did not abort" — it distributes the measured balance delta, not a reported amount. Downstream validates nothing about this caller; the provider ledger is keyed by address. terminal states : plans retire downstream (provider-only, exposed here admin-gated); members can be removed (earned balances survive removal and stay claimable); the realm itself has no terminal state — a team that walks away leaves only pull-claimable balances. adversarial callers : Pull is permissionless — it can only move the receivable into member balances at the fixed weights, so a stranger's Pull is a free favor. Plan creation/retirement is admin-gated (the downstream per-provider plan quota is a griefable resource). Members trust the admin for FUTURE weights only, never for earned balances. All entrypoints refuse coin-carrying transactions (the downstream assertNoSend reads the origin envelope; ours matches).

One team per deploy: subscriptions keeps ONE claimable balance per provider address, so a multi-team router behind one realm address could not attribute revenue at the boundary. This is a measured constraint of the downstream API, not a choice.

Imports

Constants and variables

MaxMembers bounds the distribution loop; MaxWeight bounds a single weight. Together they cap totalWeight at 200,000, which makes the remainder step of the split ((A%W)*w) provably overflow-free for any int64 coin amount — the conservation math cannot trap.

const (
	MaxMembers = 20
	MaxWeight  = int64(10000)
)

Denom is the only asset this realm accounts.

const Denom = "ugnot"

Functions

AcceptAdmin

func AcceptAdmin(cur realm)

Crossing function. Callable from a transaction via MsgCall, and from another realm as AcceptAdmin(cross(cur), ...).

AcceptAdmin completes the handover; only the staged successor may. The sweeper role moves with the admin.

AddMember

func AddMember(cur realm, a address, weight int64)

Crossing function. Callable from a transaction via MsgCall, and from another realm as AddMember(cross(cur), ...).

AddMember adds a weighted member. Weight changes never touch earned balances; they shape future pulls only.

BalanceOf

func BalanceOf(a address) int64

Claim

func Claim(cur realm, amount int64)

Crossing function. Callable from a transaction via MsgCall, and from another realm as Claim(cross(cur), ...).

Claim sends amount ugnot of the caller's earned balance to the caller.

ClaimAll

func ClaimAll(cur realm)

Crossing function. Callable from a transaction via MsgCall, and from another realm as ClaimAll(cross(cur), ...).

ClaimAll sends the caller's entire earned balance to the caller.

CreatePlan

func CreatePlan(cur realm, title, description string, price, periodBlocks, maxFeeBps int64) int64

Crossing function. Callable from a transaction via MsgCall, and from another realm as CreatePlan(cross(cur), ...).

CreatePlan creates a subscription plan THROUGH this realm, making the realm the plan's provider downstream. Admin only: the per-provider plan quota downstream is a griefable resource.

Held

func Held() int64

MemberCount

func MemberCount() int64

MemberWeight

func MemberWeight(a address) int64

NumPlans

func NumPlans() int64

PlanID

func PlanID(i int64) int64

Pull

func Pull(cur realm) int64

Crossing function. Callable from a transaction via MsgCall, and from another realm as Pull(cross(cur), ...).

Pull claims this realm's entire accrued provider balance from the subscriptions realm and distributes it to the members by weight. Permissionless: pulling can only move the receivable into member balances at the fixed weights, so anyone may crank it. Refuses BEFORE the downstream call when no member could receive the funds.

Pulled

func Pulled() int64

Receivable

func Receivable() int64

Receivable reads this realm's accrued, not-yet-pulled provider balance inside the subscriptions realm — the other side of value boundary B2. It is deliberately NOT part of Held or of the local conservation equation.

RemoveMember

func RemoveMember(cur realm, a address)

Crossing function. Callable from a transaction via MsgCall, and from another realm as RemoveMember(cross(cur), ...).

RemoveMember removes a member from future distributions. The member's earned balance is untouched and stays claimable forever.

Render

func Render(path string) string

RetirePlan

func RetirePlan(cur realm, planID int64)

Crossing function. Callable from a transaction via MsgCall, and from another realm as RetirePlan(cross(cur), ...).

RetirePlan retires one of this realm's plans downstream. Admin only.

SetWeight

func SetWeight(cur realm, a address, weight int64)

Crossing function. Callable from a transaction via MsgCall, and from another realm as SetWeight(cross(cur), ...).

SetWeight changes a member's weight for future distributions.

SweepDenom

func SweepDenom(cur realm, denom string)

Crossing function. Callable from a transaction via MsgCall, and from another realm as SweepDenom(cross(cur), ...).

SweepDenom recovers out-of-band coins to the sweeper. For the accounting denom the reserve is the full ledger liability — member balances are structurally unsweepable. Sweeper only.

TotalWeight

func TotalWeight() int64

TransferAdmin

func TransferAdmin(cur realm, successor address)

Crossing function. Callable from a transaction via MsgCall, and from another realm as TransferAdmin(cross(cur), ...).

TransferAdmin stages a two-step admin handover.

UsersTotal

func UsersTotal() int64

Doc text is reproduced as vm/qdoc returns it. The node markdown-escapes doc comments, so a bracket or angle bracket may carry a backslash the committed source does not have. The source itself is at source and in this repository.

Dependencies

chain-attested
Importschain, chain/runtime/unsafe, gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/coinio, gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/feeledger, gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/subscriptions, strconv
First-party dependenciesgno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/coinio, gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/feeledger, gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/subscriptions
Used bynone

Known limitations

Recorded by the people who built and deployed it. This list is deliberately not empty where honesty costs something.

curated

Source and records

Source filepearl/r/revshare/revshare.gno at commit 4fc6c79cd480 in the project repository (not public — the digest command above is the check that needs no repository)
Matches the deployed bytesyes — byte-identical
Recordscatalog/applications.md#revshare
pearl/DEPLOYMENT.md