This post summarizes the iCKB contracts security review published in ickb/contracts. The review keeps evolving with the tests, so the report is the source of truth. Any question or feedback is more than welcomed
Review period: 2026-05-01 to 2026-11-02.
Reviewed contracts commit:454cfa9, the last commit that changed the contracts. The deployed code is immutable.
Executable test evidence: the scripts/tests/** suite, 252 tests that run the release binaries, including the fuzzer, the exhaustive search and the chain replay.
Scope:iCKB Logic, Owned Owner, Limit Order, and the shared utils crate.
Prior external audit:Scalebit (2024-09-10), which reported three issues: two informational and one minor.
Results
The review confirmed one live issue, the known Limit Order confusion attack (LO-01). limit_order runs only when a transaction creates or spends a master cell or spends an order. A transaction that only creates order cells runs no check, because CKB does not execute output locks. Anyone can therefore create phantom orders pointing at no master, or fake orders pointing at the live master of someone else. A fake order can trick the owner into melting it with their master, which strands their real order. The stack SDK mitigates this client-side with a best-effort heuristic: it rejects orders that differ from the original mint order and ranks the rest by progress, as described in the whitepaper.
No other live issue:
iCKB Logic deposits can be created without the script running, because output locks don’t execute, and are later accepted as pool deposits. They mint no iCKB, so their value is effectively burned: whoever later withdraws one gains only its occupied capacity. A separately funded aggregate-deposit path is accepted too, but it costs its user more than it returns. No test shows theft, duplicated principal, or a profit path beyond assets the caller already controls.
Limit Order value conservation, minimum match and the binding of real orders to their master hold as designed.
Owned Owner preserves its pairing rules under locks that sign the whole transaction. The remaining cases need a lock that does not sign the whole transaction, which no current iCKB integration uses.
All other candidates are blocked paths, generic CKB model constraints, or boundary cases relevant only to future integrations.
The appendix keeps the case-by-case traces by attack class, each linked to the test that reproduces it.
Test harness. 231 tests now run against the release binaries. Every cell is checked for realistic occupied capacity, and the harness mirrors two node rules the scripts can’t see: the capacity balance and the DAO lock-size rule. Golden vectors computed by the Rust code of the contracts are shared with the TypeScript oracle in the stack.
Receiptless deposits are now documented in the report and the whitepaper: they mint no iCKB, so the whitepaper calls them a donation to the pool.
Whitepaper corrections. Independent reviews of the whitepaper fixed the Limit Order minimum-match rule, the description of the SDK order resolution, the accounting in the exit example and a few smaller points.
Great update.
This appendix is almost exactly the kind of scenario map I would need before turning iCKB into a CellScript maturity benchmark. The attack-class structure, traces, expected results, and links to concrete tests make it much easier.
Hey all~ @ArthurZhang, glad the scenario map helped!
iCKB safety has always been my priority. With all the recent LLM incidents, I went back to the contracts. I was already pretty sure there was no issue (but you never know), so I threw at them every technique I could think of, fuzzing first and foremost!!
Right now, the greater concern I have is over the continuous reporting of vulnerabilities and breaches: PHP, Node.js, Binance, even the Linux kernel itself, all in ten days of October.
The time correlation is pretty telling: AI is what enables the speed of these developments, on both sides.
So once again I put that same speed on our side: I just want to be sure we’re doing our best to keep the contracts as safe as possible. They can’t be changed on chain, so I tried hard to make them accept something they shouldn’t. They held every single time!!
Same bytes: anyone can rebuild the contracts from source and get exactly the bytes running on chain.
Millions of attempts: 12 million random transactions plus every small combination of tricky cells (37.8 million more), each checked against the four protocol rules: over 50 hours of computing. Not a single break.
Real network rules: the tests now apply the same checks a CKB node runs. Every real iCKB transaction so far passes them.
Testing the tests: of the 231 planted bugs that still compiled, the tests catch 229. The other two change nothing.
A lying node can’t steal: since stack#66, the iCKB SDK checks what a node says before signing. A lying node can only make a transaction fail.
Bottom line: the iCKB contracts hold up, with nothing new found!! The one known limitation is still the fake limit order trick, which the iCKB Stack guards against. The report has the details and how to repeat every check. The appendix still maps every scenario to the section that traces it.