Manual
Stack · spin · drop
Manual
Rules, mechanics, stack
Catris is guideline-feel Tetris with overflowing cat sprites. Stack cats, clear lines, post the run. Every 15 minutes the highest score takes 60% of the vault pot funded by the 3% letscash.fun trade tax — paid to a contract, never an EOA.
- Play
- catris.xyz/play
- Arena
- catris.xyz/arena
- Launchpad
- letscash.fun
- X / Telegram
- @catrisXYZ
The well
Visible field is 10 × 20 with two hidden spawn rows above. Seven tetrominoes deal from a shuffled bag. A ghost marks the landing row. Hold parks one piece; specials lose their curse when held.
- Field
- 10 columns × 20 rows (+2 hidden)
- Deal
- 7-bag, no triple-repeat of the same cat
- Gravity
- 900 ms at L1, −72 ms per level, floor 70 ms
- Lock delay
- 520 ms, up to 15 resets
- DAS / ARR
- 160 ms delay, 38 ms repeat
Controls
- Left / right
- ← → or A / D
- Soft drop
- ↓ or S · +1 per row
- Hard drop
- Space · +2 per row, locks on landing
- Rotate
- ↑ or Z / X / W
- Hold
- C · once per piece
- Pause
- P
On a phone the same six actions sit under the well. Soft drop is a press-and-hold; the rest are taps.
Scoring
Line clears scale with level. Combos add on top. A small clock bonus ticks while the run is alive.
- Single
- 100 × level
- Double
- 300 × level
- Triple
- 500 × level
- Quad
- 800 × level
- Combo
- +50 × combo × level
- Clock
- +10 every 10 seconds
- Level
- every 10 lines
Black cats
After 120 points a cursed piece can spawn (~16% roll, with a score- scaled cooldown). They are the original specials: same sprite, black fur, a rule that fights you.
- Still
- UNROTATABLE — spin is dead
- Lazy
- UNMOVABLE — no slide left or right
- Pounce
- HARD DROP — slams itself every frame
Hold strips the curse. The next piece from the bag is ordinary again.
Epochs and the arena
A run ends when a cat locks above the well. Post it with a handle. The shared board stores every score. If a wallet is connected the same run is signed with personal_sign (EIP-191) and sent to the keeper for the on-chain board.
- Epoch
- 15 minutes (900 s)
- Winner
- highest posted score in the window
- Prize
- 60% of that epoch’s vault harvest, in ETH
- Drip
- 30% merkle-claimed by $CATRIS holders
- Team
- 10% to the team wallet set at deploy
Stack
Client is TanStack Start + React 19 + Tailwind. The well is a canvas painter: original cat SVGs preloaded as blob URLs, drawn with the js13k overflow math so ears and tails spill the cell. Scores live in Postgres (Neon in prod, PGLite locally). Chain reads go through viem on Robinhood Chain.
- Chain
- Robinhood Chain 4663
- RPC
- https://rpc.mainnet.chain.robinhood.com
- Launch
- letscash.fun · 3% trade tax
- Factory
- 0x5bd1Fbe78a78fe8236fa00CF48fbEBA74ae34661
- Hook
- 0x75A54357D9C78a2Db19004a5FDc76c50F9242AEC
- Ticker
- CATRIS
Fee flow
Traders pay the 3% tax in ETH on the Uniswap v4 pool that letscash.fun opens at launch. No bonding curve. The creator stream is handed to the vault.
trade $CATRIS → 3% letscash.fun tax → hook claim → Vault 60 / 30 / 10 → epoch winner ETH, holder drip, team
Contracts
Two helpers, Solidity 0.8.24, Remix, 200 optimizer runs. Vault holds the pot and the split. Board holds epochs and signed scores. A 15-minute keeper harvests the creator stream, posts the winner, and publishes the drip merkle root.
CatrisVault(teamWallet)— letscash.fun creator stream recipient. DownloadCatrisBoard— no constructor args. Download- Vault:
setBot(keeperEOA), thensetMetadata("https://catris.xyz", "catrisXYZ", "https://github.com/catrisXYZ", "https://t.me/catrisXYZ"). - Board:
setBot(keeperEOA),setVault(VAULT_CA). - Launch on letscash.fun/launch: name Catris, symbol CATRIS, fee 3%, pair ETH. Then hand the creator stream to
VAULT_CAwithupdateCreatorand callsetTokenCA(TOKEN_CA)on the vault.
Keeper and site env
Bot source: epoch-bot.mjs + package.json. Env: RPC_URL, BOT_PRIVATE_KEY, VAULT_CA, BOARD_CA, TOKEN_CA, MIN_CLAIM_ETH. Fund the keeper with ~0.1 ETH for gas.
After deploy set VITE_VAULT_CA, VITE_BOARD_CA, VITE_TOKEN_CA, VITE_KEEPER_URL. Until those exist the arcade still runs — scores live on the shared board, chain writes wait for the keeper.
- Empty escrow no longer reverts — the keeper can poke
claimFromEscrowevery epoch. - Reentrancy lock on prize, drip, team, and escrow pulls.
- Score signatures are
personal_sign, the message wallets actually produce.