Cairo Development Skills

The Cairo skill family provides comprehensive coverage for Cairo smart contract development on Starknet. These skills are organized into five focused areas that follow the natural development workflow.

Skill Overview

SkillPurposeWhen to Use
cairo-contractsContract structure, storage, events, OZ componentsWriting new contracts
cairo-testingsnforge patterns, cheatcodes, fuzzing, fork testingAfter writing contract logic
cairo-securitySecurity patterns from 50+ audits, DeFi pitfallsReview pass before deployment
cairo-optimizationGas optimization, BoundedInt, storage packingPost-test optimization pass
cairo-deploysncast deployment, verification, multicallFinal deployment to network

Installation

# Install all Cairo skills
npx skills add keep-starknet-strange/starknet-agentic/skills/cairo-contracts
npx skills add keep-starknet-strange/starknet-agentic/skills/cairo-testing
npx skills add keep-starknet-strange/starknet-agentic/skills/cairo-security
npx skills add keep-starknet-strange/starknet-agentic/skills/cairo-optimization
npx skills add keep-starknet-strange/starknet-agentic/skills/cairo-deploy

# Or clone the repo
git clone https://github.com/keep-starknet-strange/starknet-agentic.git

Cairo Contracts Skill

Reference for writing Cairo smart contracts with proper structure, storage, events, interfaces, and OpenZeppelin v3 components.

Contracts Coverage

  • Contract skeleton with storage, events, constructors
  • Interface definitions with #[starknet::interface] trait pattern
  • Storage management (basic types, Maps, composite key tuples)
  • Events with indexed/non-indexed fields
  • Components using the Mixin pattern (OZ v3)
  • Common OZ components: Ownable, Upgradeable, ERC20, AccessControl, Pausable, ReentrancyGuard

Contract Skeleton

#[starknet::contract]
mod MyContract {
    use starknet::ContractAddress;
    use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess};

    #[storage]
    struct Storage {
        owner: ContractAddress,
        balances: Map<ContractAddress, u256>,
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        Transfer: Transfer,
    }

    #[derive(Drop, starknet::Event)]
    struct Transfer {
        #[key]
        from: ContractAddress,
        #[key]
        to: ContractAddress,
        amount: u256,
    }

    #[constructor]
    fn constructor(ref self: ContractState, owner: ContractAddress) {
        self.owner.write(owner);
    }
}

Cairo Testing Skill

Reference for testing Cairo smart contracts with snforge (Starknet Foundry).

Testing Coverage

  • Test setup with contract_state_for_testing()
  • Contract deployment using declare, deploy, and dispatchers
  • Cheatcodes: start_cheat_caller_address, start_cheat_block_timestamp
  • Expected failures with #[should_panic]
  • Event testing with spy_events()
  • Fuzzing with #[fuzzer(runs: N, seed: N)]
  • Fork testing against mainnet/testnet state

Basic Test Pattern

use snforge_std::{declare, ContractClassTrait, DeclareResultTrait};
use snforge_std::{start_cheat_caller_address, stop_cheat_caller_address};

#[test]
fn test_transfer() {
    // Deploy contract
    let contract = declare("MyContract").unwrap().contract_class();
    let (contract_address, _) = contract.deploy(@array![owner.into()]).unwrap();

    // Create dispatcher
    let dispatcher = IMyContractDispatcher { contract_address };

    // Cheat caller address
    start_cheat_caller_address(contract_address, owner);
    dispatcher.transfer(recipient, 100);
    stop_cheat_caller_address(contract_address);

    // Assert
    assert(dispatcher.balance_of(recipient) == 100, 'Balance mismatch');
}

Cairo Security Skill

Comprehensive security patterns and vulnerabilities sourced from 50+ public audits.

Critical Patterns

The security skill covers patterns that have caused real exploits, including the $10M zkLend exploit and multiple Code4rena critical findings.

Top 10 Critical Patterns

  1. felt252 division is modular inverse, NOT floor division — Never use felt252 for financial math
  2. Map.read() returns zero on missing keys — No panic, always validate
  3. felt252 arithmetic wraps silently — Use u256/u128 for financial operations
  4. Floor division rounding favors the actor — Burn UP against user, mint DOWN
  5. Empty market initialization + flash loan = catastrophic — Lock minimum liquidity
  6. OZ embedded impls leak privileged selectors to session keys — Block self-calls
  7. SNIP-9 execute_from_outside needs nonce + caller + time bounds — Missing any enables replay
  8. Starknet v0.14.0 killed v0/v1/v2 transactions — Time-dependent logic must recalibrate
  9. __validate__ must be lightweight — No storage writes, no external calls
  10. Checks-effects-interactions is not optional — Update state before external calls

Pre-Deployment Checklist

The skill includes a 41-item pre-deployment checklist covering:

  • Access control and initialization
  • Reentrancy and state ordering
  • Precision and rounding
  • Nonces and replay protection
  • Storage collisions
  • Paymaster and gas considerations
  • Time-dependent logic

Cairo Optimization Skill

Post-test gas optimization pass with 11 rules sourced from audit findings and production profiling.

Core Optimization Rules

BoundedInt for Gas Savings

BoundedInt<MIN, MAX> encodes value constraints at compile-time, enabling 2-5x gas savings on limb assembly operations:

use core::integer::BoundedInt;

// Declare a type that can only hold values 0-255
type Byte = BoundedInt<0, 255>;

// Operations are bounds-checked at compile time

BoundedInt Calculator

The skill includes a bounded_int_calc.py CLI tool for computing bounds when refactoring arithmetic operations.

Cairo Deploy Skill

Guide for deploying Cairo contracts to Starknet using sncast (Starknet Foundry).

Deployment Workflow

Declare the Contract

sncast --profile sepolia declare --contract-name MyContract

Returns a class hash for deployment.

Deploy with Constructor Args

sncast --profile sepolia deploy \
  --class-hash 0x123... \
  --constructor-calldata 0xOWNER_ADDRESS

Verify on Explorer

# Voyager
sncast --profile sepolia verify \
  --contract-address 0x456... \
  --contract-name MyContract \
  --verifier voyager

sncast.toml Configuration

[sncast.sepolia]
account = "deployer"
url = "https://starknet-sepolia.public.blastapi.io"

[sncast.mainnet]
account = "deployer"
url = "https://starknet-mainnet.public.blastapi.io"

Calldata Encoding

TypeEncoding
felt252Direct hex value
ContractAddress0x-prefixed address
u256Two felts: [low, high]
bool0 or 1
ByteArrayLength + chunks + pending word + pending len

Attribution

The Cairo optimization patterns are originally authored by feltroidprime and integrated with permission. Security patterns are sourced from 50+ public audits including Nethermind, ConsenSys Diligence, Code4rena, ChainSecurity, and Cairo Security Clan.

Next Steps