Security model
The game runs in a browser, so the client is treated as hostile. Anything it sends can be forged from a console or a patched bundle. The design goal is that forging it buys an attacker almost nothing.
The core defence#
A client sends which of its keys are held, and nothing else:
{ "t": "i", "seq": 42, "l": false, "r": true, "j": false, "k": true }
There is no code path where a client-supplied position, score, clock or effect reaches the world. This is structural, not a filter: extra fields can be added to the JSON and nothing reads them.
Attack classes tested and blocked#
Three adversarial suites run against a live server (cheating/minting/identity, forcing an opponent out, scale and protocol abuse). All probes are currently blocked.
| Class | Examples | Why it fails |
|---|---|---|
| Forging game state | Teleporting, moving the ball, awarding goals, granting power-ups, self-reporting a result | Positions, score and effects are computed server-side only; there is no handler for them. |
| Forging money | Minting balances, staking arbitrary amounts, negative amounts | Stake must be a current tier; amounts must be positive safe integers; funds live on-chain. |
| Identity abuse | Acting before identifying, playing as the opponent's seat, one account on two clients | Every command needs a valid signature (or signed session token); seat is bound to the connection; a new login evicts the old one. |
| Input flooding | Sending 1000 inputs to move faster | Input and message rates are capped, sequence numbers must strictly increase, and the clock runs on server time. |
| Protocol abuse | Oversized or deeply nested frames, hostile identity strings | Malformed or oversized frames are dropped before they are parsed. |
| Resource exhaustion | Socket swarms, identity churn, room spam, join-code guessing | Rate limits and caps on connections, logins and room creation. |
Wallet sign-in#
- Identity is a wallet address proven by a signature. In strict mode every page refresh would need one, so after a successful sign-in the server issues a 24-hour HMAC-signed session token bound to your address and its expiry.
- A forged, tampered, expired or wrong-secret token is rejected, and the token is cleared on disconnect.
- Before queueing the server also checks your on-chain token balance and allowance, so a broke wallet cannot occupy a match slot.
Review without confiscation#
Automated checks may flag suspicious play for human review. Flags never take money: a false positive would rob an honest player, so detection never changes a payout.
Independent review#
The escrow contract should pass an independent third-party audit before it holds meaningful value. Until then, treat it as unaudited code and stake accordingly.