sportula · the basket a patron handed out each morning

Every lamport, or the gap.

A fee stream is easy to publish and hard to check. Every lamport that arrives is either assigned to somewhere, with the transaction that moved it, or it is a gap  and the gap is printed at the same size as the rest.

$SPORcontract address

3k9HP28q6kxuCDpWES6eCUzfZykdtaiadBF1Z22ipump

What a launch in this category actually is

No launchpad here creates a coin.

Pressing launch signs one transaction. pump.fun’s CreateV2 makes the mint; then, in the same transaction, a fee-sharing config names who receives the creator fee and at what share. That is the whole product.

Decoded from a live launch, not from documentation. Launching cost the creator 0.0155 SOL.

CreateV2                     <- pump.fun makes the mint
CreateFeeSharingConfig
MigrateBondingCurveCreator
UpdateFeeSharesV2            <- names the recipient
DistributeCreatorFeesV2

Not our figures — theirs

Their own published totals, put through this rule.

to holders3,272.9581reserved683.3917costs392.476no destination207.7414
arrived4,556.56740217
distributed3,272.958196681
pot683.39172694
protocol392.476012176
with no name207.741466373

The three destinations add to 4,348.825935797. 207.741466373 SOL of what arrived is in none of them.

Not an accusation — subtraction. The point is that their system permits money to have no destination, so nobody, including them, was ever forced to write the sentence that would explain it.

Four questions a published total does not answer

what arrived

The fee stream lands in one wallet. Almost nobody publishes what actually reached it, as opposed to what was earned in theory.

what left

Every payout is a transaction. A total with no transactions behind it is a row in a database, and it looks identical to one that is true.

what stayed

Money that has not moved has no signature. That is not suspicious — it is the reason “reserved” needs a date instead.

what was left over

Every stream has a remainder. Rounding is real. What is not real is a remainder nobody ever has to name.

Four destinations, four different proofs

Each one proves itself differently.

HOLDERSmust carry the transaction that moved it
COSTSmust carry the transaction that moved it
RESERVEDmust carry a date
RESIDUEmust carry what happens to it next

Read out of the launch transactions themselves

Four launches. One address. All of it.

launches decoded

distinct recipients

%

of the fee, every time

The share is a 32-byte address followed by a u16 of basis points. Every one we read said 10 27 — ten thousand, which is all of it. See the register.

The rule, not a policy

A report cannot exist while one lamport has no destination.

declare const CLOSED: unique symbol;   // never exported

type Basket =
  | { state: "CLOSED"; received; allocations; closed: Closed }
  | ...

An object literal cannot supply a key it cannot write down. Nothing outside one file can name that symbol, so nothing outside can build a seal — and the only function that returns one checks the sum first, as bigint.

Two checkers, because a type cannot count

/ 6

the shape

Five cheats written out as real TypeScript and refused, plus one control that must compile. No as, no @ts-expect-error — both suppress the error the case exists to provoke.

/ 13

the sum

A basket can be perfectly well-typed and still be wrong by two hundred SOL. Two of these add up the figures printed on this page, because a display that does not reconcile is the same failure wearing a nicer font.

Both suites carry a control case that must pass. Two suites in this workspace have already been green while testing nothing — in one, every rejection was really a bad import path. How they work.

Something the tool could not do, found by running it

A wallet can never disagree with itself.

In, out and balance always reconcile. That is arithmetic, not virtue — and a tool that manufactured a shortfall out of them would be inventing exactly the kind of figure this project objects to.

So a gap only appears where a claim is set against what moved. The audit reads the chain on one side and takes an operator’s published totals on the other — and labels every one of them “their published figure, not a transaction”.

In the same size type as everything else

It reads a window

The most recent 250 signatures, and it stops after 12 seconds whether or not it got them all. Both numbers travel with every figure.

It does not know why money left

Direction and amount are facts on the chain. Purpose is not, and this will not guess at one.

It cannot price anything

No feed, no dollars. Everything is SOL and lamports, because that is what was actually read.

A gap is not an allegation

It is subtraction. Most gaps have ordinary explanations — the point is that the report never had to contain one.

Open a basket. Ours, or anyone else's.

It reads nothing but the chain, so it works on any wallet a fee stream lands in. An instrument that only runs on its author’s own numbers is a brochure.