Security testing

How we test the contracts, what each test covered, and a test you can run yourself.

Every change to the contracts or the app runs the contract test suites first. On top of that we attack the contracts on purpose, and we publish what we tested so you can check it rather than take our word for it.

Red-team test, 2 November 2026

We ran kaspa-redteam, an open-source tool by Kaspero Labs, against 16 transactions of the live mainnet contracts. The tool takes a valid transaction, changes it the way an attacker would, and asks Kaspa’s own consensus code (rusty-kaspa 2.1.0) whether the changed transaction would be accepted. A finding means consensus accepted a change it should have refused.

What was attackedTransactions
Curve buys and sells2
Pool buys and sells, and a liquidity withdrawal4
Creator fee claims, from a curve and from a pool2
Token lock releases: one release, two at once, the last one, all at the end, after a waiting period, 100 releases, at a high network fee8

The transactions were built by the same transaction builder the app uses for your trades, with throwaway test keys and made-up coins, so they can never be broadcast. Their contract programs are the live ones: the pack checks each one against our public SDK on npm and, for the lock, against a real mainnet lock release read from api.kaspa.org.

What it found

AttackResult
Send a payout to the attackerRefused on every transaction
Pay a payout less, or shorten a later oneRefused on every transaction
Two contract coins share one set of payoutsRefused on every transaction
Put an attacker’s coin in front of the contractRefused on every transaction
Send the contract’s value to the minerRefused on every transaction
Keep what is left overFlagged, explained below
  • Trades and fee claims: the “leftover” is the network fee, paid from the sender’s own wallet coin. The tool counts that coin as the attacker’s, so the attacker only keeps their own fee.
  • Lock releases: anyone may send a due release, and each release may spend up to 0.2 KAS of the lock’s deposit on its network fee; whoever sends it may keep what the fee does not use. The tokens and 1 KAS always go to the beneficiary. This is known, shown on the lock’s Review screen, and kept on purpose: it lets anyone, not only Kasseal, send a release (see Token locks).

No new issue was found.

Run it yourself

Download the test pack. It holds a step-by-step README, the 16 transactions (no private keys), the script that checks which contracts they spend, a script that runs the whole test, and our exact output to compare with yours. You need git, Rust 1.94 or later and Node 22 or later.

  1. Build kaspa-redteam at the version we ran, commit eaa79c890a4fc00aa6c8ac12a1208aa8e6d6d23f (v0.15.0).
  2. Run node check-contracts.mjs baselines/*.json: it must end with “Every contract input is a mainnet program.”
  3. Run the tool on each file, kaspa-redteam --baseline baselines/pool.json -v and so on, and compare with expected/.

./run.sh in the pack does all three.

What this test does not cover

The tool cannot yet test transactions that create a new contract (a launch, a graduation, a pool’s setup, a lock’s creation), transactions where your signature sits inside the token program’s data (adding liquidity, splitting a holding), or a lock extension, which only its beneficiary can sign. Our own tests cover these: the contract test suites on every change, a mutation fuzzer of the curve and pool (19 October 2026) and a stress test of the locks (29 October 2026).