Cairo Scanner Skill

SkillFiles & storage

Use when the user wants to audit Cairo smart contracts for security vulnerabilities, scan Starknet contracts for felt overflow, storage collision, or account abstraction issues, review Cairo 2.x contracts for component architecture flaws, or analyze STARK-based protocols for cryptographic and computational errors.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Cairo Scanner Skill skill

What this skill tells your AI

The instructions your AI receives, as published by 0x-shashi/web3-audit-skills in skills/cairo-scanner/SKILL.md and read by ahel’s review.

Purpose

Analyze Cairo smart contracts deployed on Starknet for security vulnerabilities. Cairo's unique computational model — based on field elements (felts), STARK proofs, and native account abstraction — creates attack surfaces that don't exist on EVM chains.

Cairo Security Model

PropertyCairo/StarknetEVM/Solidity
Integer typeFelt252 (field element, $0$ to $P-1$ where $P = 2^{251} + 17 \cdot 2^{192} + 1$)uint256, int256
ArithmeticModular (wraps around $P$)Checked (reverts in Solidity 0.8+)
DivisionModular inverse (not integer division)Integer truncation
Account modelAll accounts are smart contracts (native AA)EOAs + smart contracts
Upgradesreplace_class_syscall (instant)Proxy patterns (delegatecall)
StoragePedersen hash-based addressesSequential slots (keccak256)
L1 interactionL1-L2 messaging via Starknet Core on EthereumBridges required
ProvingSTARK proofs for L1 verificationNo proofs needed

Detection Capabilities

Critical — Direct Fund Loss

VulnerabilityDescriptionDetection Signal
Felt overflow wrappingArithmetic on felt252 wraps around $P$, enabling underflow/overflowFelt252 used for balances or amounts without range checks
Unprotected replace_class_syscallAnyone can upgrade the contract logicreplace_class_syscall without assert_only_owner or equivalent
L1-L2 message replaySame L1→L2 message consumed multiple timesMissing nonce or message hash tracking in l1_handler
Account validation bypassCustom __validate__ skips critical checks__validate__ returns success without signature verification
Storage collisionTwo different state variables map to same storage slotCustom storage_address_from_base with colliding inputs

High — Significant Impact

VulnerabilityDescriptionDetection Signal
Reentrancy via call_contract_syscallExternal contract call re-enters before state updatecall_contract_syscall before storage writes
Missing caller validationExternal function callable by anyoneget_caller_address() not checked in sensitive functions
Felt252 comparison pitfallsComparing felts that represent "negative" numbers (near $P$)< or > on felts where semantic negativity matters
Component storage isolation failureComponents sharing storage addressesOverlapping #[storage] declarations across components
Incorrect modular divisionUsing / operator expecting integer divisiona / b on felt252 produces modular inverse, not truncation

Medium — Conditional Impact

VulnerabilityDescriptionDetection Signal
Unbounded storage growthMaps or arrays without size limitsMap<K, V> without pruning mechanism
Missing eventsState changes without event emissionwrite to storage without emit
Library dispatch trustUsing library_call_syscall with unchecked class hashExternal class hash in library call
Paymaster manipulationTransaction fee payment logic exploitableCustom __validate__ with fee token handling
Felt-to-u256 conversion errorsIncorrect type casting between felt and uint typesfelt252.into() or TryInto::<u256> without bounds

Cairo-Specific Pitfalls

Felt Arithmetic Is Modular

// DANGEROUS: Felt subtraction wraps around P
let balance: felt252 = 100;
let amount: felt252 = 200;
let result = balance - amount;
// result is NOT -100, it is P - 100 (a very large number)
// Any comparison result > 0 will be TRUE

// SAFE: Use u256 for amounts
let balance: u256 = 100;
let amount: u256 = 200;
assert(balance >= amount, 'Insufficient balance'); // Correctly reverts

Division Is Not Integer Division

// UNEXPECTED: Felt division is modular inverse
let a: felt252 = 7;
let b: felt252 = 2;
let result = a / b;
// result is NOT 3 (integer truncation)
// result is the felt252 x such that x * 2 ≡ 7 (mod P)
// This is (P + 7) / 2 = a very large number

// SAFE: Use u256 for integer division
let a: u256 = 7;
let b: u256 = 2;
let result = a / b; // result is 3 (integer truncation, as expected)

Resources

ResourceDescription
Cairo PatternsVulnerability patterns specific to Cairo language and Starknet
Starknet SecurityStarknet architecture security: sequencer, proofs, upgrades
Messaging SecurityL1-L2 messaging: message replay, nonce handling, proof finalization

Workflows

WorkflowDescription
Cairo AuditStep-by-step audit workflow for Cairo contracts on Starknet

Notable Starknet Security Incidents

IncidentRoot CauseImpact
Various DeFi exploits on Starknet testnetFelt overflow in token balancesFund inflation
L1→L2 message replay in early bridgesMissing consumed message trackingDouble-spending
Account contract vulnerabilitiesInsufficient __validate__ logicTransaction forging

Integration with Other Skills

SkillConnection
starknet-scanner/Shares Cairo language patterns; this skill focuses on language, starknet-scanner focuses on chain
chain-guides/starknet.mdChain-level context for Starknet architecture
patterns/Cross-reference with general vulnerability categories (reentrancy, access control)
exploit-forensics/Limited Starknet exploits but growing as ecosystem matures

Error Code Reference

Common Cairo/Starknet errors encountered during audits. Cairo errors manifest as felt252 values in transaction reverts.

Cairo Language Errors

Error PatternError SourceMeaning
felt252 overflowArithmetic operationResult exceeds field prime P (≈ 2^251 + 17·2^192 + 1) — wraps silently
index out of boundsArray accessArray index exceeds length — causes execution failure
Option::unwrap on NoneOption handlingAttempted to unwrap an empty Option — missing existence check
assertion failedassert() macroContract invariant violation — check assert conditions
'Entry not found'StorageMap accessKey does not exist in LegacyMap/Map — missing default handling
u256_sub OverflowSubtraction underflowUnsigned subtraction result would be negative
u256_add OverflowAddition overflowAddition exceeds u256 max value
Division by zeroDivision operationDenominator is zero — missing zero-check

Starknet Contract Errors

Error PatternError SourceMeaning
'Caller is not the owner'OZ OwnableMissing ownership — check access control
'Caller is the zero address'OZ OwnableZero address caller — validate caller identity
'ERC20: insufficient balance'OZ ERC20Token balance too low
'ERC20: insufficient allowance'OZ ERC20Approval not set or insufficient
'ERC20: approve to zero address'OZ ERC20Invalid spender address
'ERC721: invalid token ID'OZ ERC721Token does not exist
'Contract already initialized'Initializable patternRe-initialization attempt — check initializer guard
'ENTRYPOINT_NOT_FOUND'Starknet OSCalled selector doesn't exist on contract
'UNINITIALIZED_CONTRACT'Starknet OSClass not declared or deployed
'TRANSACTION_FAILED'Starknet sequencerGeneric failure — check inner error for details

Felt Arithmetic Audit Concerns

IssueRiskDetection
Felt overflow wrappingArithmetic wraps mod P instead of revertingFlag all felt252 math ops — prefer u256/u128 for financial math
Felt comparison edge cases< and > comparisons are mod P, not natural orderingCheck comparisons on felt252 values — may produce unexpected results
Integer to felt truncationConverting large u256 to felt252 silently truncatesFlag all into() / try_into() conversions between types
Storage key collisionLegacyMap keys hash via Pedersen — potential collision with crafted inputsVerify map key uniqueness assumptions

Troubleshooting

IssueLikely CauseSolution
Scanner misses felt overflow issuesAnalyzing code as if integers revert on overflowCairo felt252 wraps mod P — flag all felt arithmetic in financial logic
False positives on storage accessScanner flags all LegacyMap reads as riskyVerify if default value (0) is safe for the use case
Account abstraction patterns not detectedScanner uses EVM mental modelLoad starknet-scanner/ for account abstraction-specific checks
Component architecture flaws missedScanner doesn't understand Cairo componentsManually review component trait implementations and storage conflicts
Missed reentrancy via L1 handlerScanner only checks external functionsInclude #[l1_handler] functions in reentrancy analysis
Cairo version mismatch warningsPattern written for Cairo 1.x, contract uses 2.xVerify syntax patterns match target Cairo version; update detection rules

Signals

GitHub stars
60
Forks
10
Last commit
Feb 2026
Advanced
Catalog kind
skill
Gateway key
cairo-scanner
Source
github.com/0x-shashi/web3-audit-skills