SweepStuckRake
Ask AI
SweepStuckRake is the LAST RESORT for a booked rake the raffle will not take, and it exists so that pendingPot is not a place money can enter and never leave. It transfers the whole booked amount to the raffle's address by PLAIN wugnot.Transfer and returns it. PERMISSIONLESS, and only once the batch's YOUNGEST CLAIM has stood for pendingGraceBlocks (pendingSince, finding D-4 — it is not, and cannot be, a measure of delivery having been attempted and refused).
WHY IT CANNOT BE REFUSED, which is the only property that makes it a real exit: a plain GRC20 transfer runs no raffle code. FlushPot goes through raffle.FundPot and can therefore be refused by anything in the raffle — that is exactly the state this function is for. This one cannot be.
AND IT DROPS THE EARNED ENTRIES WITH THE MONEY, WHICH IS THE OTHER HALF OF THE COST (finding 15). The money on this path becomes the raffle's ops pot, so there is no prize left for an entry to be an entry in, and an entry with no rake behind it is a thing this realm's own invariant refuses. So players who earned entries in a batch that reached this function get nothing for them. It takes three weeks of the raffle refusing EVERY caller, the drop is in this function's event, and any player could have prevented it at any moment by flushing — for between 10,378,157 gas (a two-holder batch, measured 2026-09-30) and 351,725,503 (a FULL 128-holder batch against a week grown to 100,096 ticket indices). Read maxPendingEntryHolders for where each figure comes from and why only the first is reproducible by running this package.
THE FULL-BATCH END OF THAT RANGE IS THE ONE THAT APPLIES HERE, and citing only the cheap end was a real misstatement, corrected 2026-09-30. This paragraph is about a batch that has been accumulating for three weeks of refusals, i.e. the regime in which the batch is as large as maxPendingEntryHolders allows — so quoting a two-holder figure understated the mitigation's cost by more than thirty times in exactly the paragraph where it is dearest. (The figure said ~1.1M until 2026-09-29 and was stale by finding 15 — see maxPendingEntryHolders and AUDIT-2026-09-28.md finding 19. The argument every version of it supports is unchanged: at 11.7% of a block it is still one affordable transaction available to anybody at any height. AUDIT-duel-2026-09-27.md addendum 2, findings D-4 and D-6.)
WHERE IT LANDS, AND THE HONEST COST OF THAT. An unattributed arrival at the raffle is swept by its sweepDonations into its OPS pot, not into any week's prize — the raffle says why: crediting an unattributed arrival to a prize pot would break the identity that makes its refunds safe. So this money reaches the house rather than the players, and the 80/20 split is therefore NOT preserved on this path. That is stated plainly because it is the one place in this change where the split moves: it takes three weeks of the raffle refusing EVERY caller for it to happen, it emits its own event, and it is the alternative to the money never leaving at all.
AND THE DESTINATION IS THE RAFFLE, NOT r/splash/ops, DELIBERATELY. gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/ops does not exist — the ops constant in this file is a package-derived address with no code at it — so routing a NEW stream there would be creating exactly the "money in, no way out" shape that six of this product's findings have had. The raffle's ops pot has an exit (WithdrawOps), and whether THAT exit's destination is reachable is a pre-existing question about r/splash/ops which is the owner's and is not made worse here.
THE COST OF HAVING A WINDOW AT ALL, RECORDED RATHER THAN LEFT TO BE FOUND: after 21 days in which nobody bothered to call FlushPot — even with the raffle perfectly willing — any caller may move the booked rake to the raffle's ops pot instead of its prize pot. That is a value shift from the players to the house, it costs the caller gas and gains them nothing personally, and it is preventable by anyone at any time by simply flushing — for 10,378,157 gas at two holders and 351,725,503 at a FULL 128-holder batch, which is the end of the range that applies after three weeks of accumulation (see maxPendingEntryHolders for each figure's provenance; corrected from a bare "~8.6M" on 2026-09-30 and from "~1.1M" on 2026-09-29, findings D-4, D-6 and 19). It is accepted because the alternatives are worse: no window makes this a free diversion available on the first block, and no function at all leaves the balance with a single exit that another realm can hold shut for ever. AUDIT-2026-09-28.md finding 14.
Panics if there is nothing booked, or if the window has not elapsed.
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/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/arcade/duel" -func "SweepStuckRake" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "onyx-1" -remote "https://rpc.onyx.testnets.gno.land" ADDRESSgnokey query -remote "https://rpc.onyx.testnets.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/arcade/duel" -func "SweepStuckRake" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "onyx-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.onyx.testnets.gno.land" call.tx