Kakarot — disclosed vulnerability reports and payouts
Every publicly disclosed and closed bug bounty report we hold for Kakarot, with our own summary of each finding and a link to the original disclosure.
- Reports indexed
- 8
- Total paid
- $0
- Critical
- 0
- Largest payout
- $0
This page collects the 8 closed, publicly disclosed Kakarot reports indexed on Coin Buggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.
The findings concentrate in Logic error, Reentrancy, Integer overflow / underflow, across EVM-Solidity, Other. Reading a single protocol end to end is the fastest way to see which assumptions its codebase repeatedly gets wrong, which is usually a better predictor of where the next finding lives than the category alone.
Use the vulnerability class links below to compare these findings against the same bug class in other protocols.
What reviewers look for
- Logic error findings disclosed against Kakarot
- Reentrancy findings disclosed against Kakarot
- Integer overflow / underflow findings disclosed against Kakarot
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Kakarot: No way to cancel `l1 -< l2` messages
Kakarot's L1KakarotMessaging contract provides only send and consume functions for L1->L2 traffic, with no way to cancel an already-submitted message. If a message cannot be delivered or the contract misbehaves, the messaging fee paid by the user is permanently stranded with no recovery path. The Kakarot team initially disputed severity on the grounds that only fees are at risk, but the contest judge upheld medium severity on the basis that fee loss still constitutes a value leak. Kakarot confirmed cancellation functionality will be implemented, modeled on Starknet's time-limited message-cancellation flow.
Kakarot: Reentrancy check in `account_contract` can be easily circumvented
Kakarot, a Cairo-based zk-EVM running on Starknet, guarded its account_contract.execute_starknet_call against reentrancy by only blocking calls to Kakarot's own address when the selector was anything other than the harmless get_starknet_address getter. An attacker who already holds a not-yet-executed signed transaction could front-run its execution to store the transaction's effects on Starknet first, then have the account_contract invoke itself or another account_contract through the call-cairo precompile, re-entering the Kakarot EVM. Because Kakarot commits execution effects only at the very end via Starknet.commit instead of incrementally (check-effect-interaction not followed), the reentrant execution runs against cached, not-yet-committed state, threatening EVM state integrity. Exploitation likelihood is low since the entry is whitelisted, but the judge upheld Medium severity and the protocol mitigated by moving the guard to Kakarot.eth_call in PR 1582.
Kakarot: `RIPEMD160` precompile crashes with a Cairo exception for some input lengths
Kakarot's Cairo implementation of the EVM RIPEMD160 precompile crashes for certain input lengths. In the finish() routine the local dict pointer x is reassigned to a freshly created default dict while the start pointer still references the segment of the original dict, so default_dict_finalize fails with a 'cannot subtract two relocatable values with different segment indexes' error during dict squashing. Any L2 contract invoking the precompile with an input in the vulnerable range triggers a Cairo exception and cannot execute — a targeted denial of service for contracts that rely on RIPEMD160. The finding reproduces with both a Solidity e2e test and an independent Cairo hypothesis test, and was corroborated by multiple other researchers. It was a fun, well-scoped precompile correctness bug in a zkEVM context.
Kakarot: Prover can cheat in `felt_to_bytes_little` due to value underflow
Kakarot's Cairo routine `felt_to_bytes_little()` in bytes.cairo converts a felt into a minimal byte array, but its termination is driven by a prover-controlled hint: the loop keeps emitting bytes until `value` underflows to zero. Because the verifier checks only that the loop eventually stops at a code offset whose table entry is zero — and there are many zero-valued offsets in the code segment — a malicious prover can forge a near-arbitrary byte sequence that does not correspond to the true minimal encoding of the input felt. This spoofed output flows into every caller of the conversion, notably `get_create_address()` and `get_create2_address()`, enabling an attacker to deploy L2 contracts from a forged sender address. The author supplied a patched-hint PoC producing a 135-byte forged output for the input felt 1, and the protocol confirmed the mitigation of adding range checks on `value`.
Kakarot: Missing constraint in `default_dict_copy`
Kakarot's CairoZero account implementation creates persistent dictionaries (transient_storage, storage, valid_jumpdests) with default_dict_new but never pairs them with the default_dict_finalize constraint that pins the first entry's prev_value to the intended default. Because dict_squash only validates the internal read/write consistency of the access log, and default_dict_copy derives the copied dictionary's default from a prover-supplied first prev_value, a malicious prover can fabricate arbitrary initial dictionary values that still pass squashing. This breaks the soundness of the EVM-execution proof, letting reads of uninitialized keys return attacker-chosen values instead of 0. Maintainers initially confirmed at high severity, then a Zellic review challenged it, and it was ultimately re-confirmed valid and mitigated via PR #1592, which finalizes the copied dictionary with default value 0.
Kakarot: `ExponentiationImpl::pow()` returns `0` for `0^0`
Kakarot's Cairo `ExponentiationImpl::pow()` in `math.cairo` returns 0 for the input `0^0` when the conventional mathematical result is 1. The root cause is an ordering error: the function early-returns zero when the base is zero without first checking whether the exponent is also zero, so the special `0^0` case is never reached. The function is not invoked with a `0^0` argument anywhere in the current in-scope code, so there is no reachable exploit today, but the finding was accepted as a valid medium-severity specification defect because it violates a mathematical convention relied on by binomial expansion, power series, and combinatorial formulas, potentially producing wrong results in future callers. Kakarot confirmed the medium severity and mitigated it by fixing `pow` in the SSJ repository, with the mitigation subsequently confirmed.