sentio.
sentio.

Security scanner for Solana programs

sentio scans your Anchor programs for critical vulnerabilities — missing owner checks, unsafe account patterns, and more. Zero config. CLI-first.

$cargo install sentio-cli
sentio scan
$ sentio scan
══ FINDING 1: SW016 init_if_needed usage (manual review) ══
Severity: medium
Location: ./ralli-bet/programs/ralli-bet/src/instructions/create_lineV2.rs:27:1
Matched Because:
Account `line_pointer` uses `init_if_needed`; review for re-initialization or state-reset risk.
25 pub player_line: Account<'info, PlayerLine>,
26
27> #[account(
28 init_if_needed,
29 payer = admin,
Guidance: Prefer #[account(init, ...)] when possible. If init_if_needed is necessary, confirm the account cannot be abused to reset state.
══ FINDING 2: SW002 Missing owner check ══
Severity: critical
Location: ./ralli-bet/programs/ralli-bet/src/instructions/resolve_game_batch.rs:40:1
Matched Because:
Account `treasury` has no owner constraint and no owner guard in instruction logic; any program-owned account can be passed.
38 pub game_vault: Box<InterfaceAccount<'info, TokenAccount>>,
39
40> /// CHECK: Treasury account to receive fees
41 #[account(mut)]
42 pub treasury: AccountInfo<'info>,
Guidance: Add #[account(owner = expected_program::ID)] or verify account.owner explicitly in the instruction handler.
── Summary ──
Total findings: 3
Critical: 2
Medium: 1

What sentio catches

Rules targeting real Solana exploit patterns.

SW001critical
Missing signer check

Authority-like accounts lacking signer validation.

SW002critical
Missing owner check

Accounts without owner or address constraints.

SW003critical
Arbitrary CPI target

Raw CPI calls missing program ID verification.

SW005high
Unchecked arithmetic

Unprotected math operations on account fields.

SW006critical
Type cosplay — missing discriminator check

Deserialization without discriminator validation.

SW008high
Missing post-CPI account reload

Account writes after CPI without reload().

SW009high
Missing token account mint check

Mutable token accounts lacking mint constraints.

SW010critical
Missing token account owner check

Token accounts without authority validation.

SW011high
AccountInfo used as data account

Untyped AccountInfo where typed Account is needed.

SW012high
Missing seeds + bump on PDA

PDAs with seeds but no bump verification.

SW013high
PDA seed references unvalidated account

PDA seeds referencing unconstrained accounts.

SW014high
PDA bump may not be canonical

Caller-supplied bumps instead of canonical derivation.

SW016high
init_if_needed usage (manual review)

Accounts risking silent reinitialization.

SW018low
Missing realloc::zero = true

Realloc operations leaving stale data in memory.

SW020critical
AccountInfo used as CPI target program

Untyped program accounts in CPI contexts.

SW021high
PDA seed collision risk

Adjacent variable-length seed elements that can collide under different splits.

SW022high
Manual account closure without close constraint

Accounts closed by hand instead of Anchor's close constraint.

SW023critical
Unvalidated remaining_accounts forwarded to CPI

remaining_accounts passed into CPI without ownership or program checks.

SW024high
Division by zero

Division or modulo on values that may be zero at runtime.

SW025medium
unwrap() / expect() in instruction handler

Panic paths in handlers that can halt the program unexpectedly.

SW026high
create_program_address used instead of find_program_address

Non-canonical PDA derivation that may not match find_program_address.

SW027low
Missing event emission on state change

State-changing instructions that never emit an Anchor event.

SW001critical
Missing signer check

Authority-like accounts lacking signer validation.

SW002critical
Missing owner check

Accounts without owner or address constraints.

SW003critical
Arbitrary CPI target

Raw CPI calls missing program ID verification.

SW005high
Unchecked arithmetic

Unprotected math operations on account fields.

SW006critical
Type cosplay — missing discriminator check

Deserialization without discriminator validation.

SW008high
Missing post-CPI account reload

Account writes after CPI without reload().

SW009high
Missing token account mint check

Mutable token accounts lacking mint constraints.

SW010critical
Missing token account owner check

Token accounts without authority validation.

SW011high
AccountInfo used as data account

Untyped AccountInfo where typed Account is needed.

SW012high
Missing seeds + bump on PDA

PDAs with seeds but no bump verification.

SW013high
PDA seed references unvalidated account

PDA seeds referencing unconstrained accounts.

SW014high
PDA bump may not be canonical

Caller-supplied bumps instead of canonical derivation.

SW016high
init_if_needed usage (manual review)

Accounts risking silent reinitialization.

SW018low
Missing realloc::zero = true

Realloc operations leaving stale data in memory.

SW020critical
AccountInfo used as CPI target program

Untyped program accounts in CPI contexts.

SW021high
PDA seed collision risk

Adjacent variable-length seed elements that can collide under different splits.

SW022high
Manual account closure without close constraint

Accounts closed by hand instead of Anchor's close constraint.

SW023critical
Unvalidated remaining_accounts forwarded to CPI

remaining_accounts passed into CPI without ownership or program checks.

SW024high
Division by zero

Division or modulo on values that may be zero at runtime.

SW025medium
unwrap() / expect() in instruction handler

Panic paths in handlers that can halt the program unexpectedly.

SW026high
create_program_address used instead of find_program_address

Non-canonical PDA derivation that may not match find_program_address.

SW027low
Missing event emission on state change

State-changing instructions that never emit an Anchor event.

SW001critical
Missing signer check

Authority-like accounts lacking signer validation.

SW002critical
Missing owner check

Accounts without owner or address constraints.

SW003critical
Arbitrary CPI target

Raw CPI calls missing program ID verification.

SW005high
Unchecked arithmetic

Unprotected math operations on account fields.

SW006critical
Type cosplay — missing discriminator check

Deserialization without discriminator validation.

SW008high
Missing post-CPI account reload

Account writes after CPI without reload().

SW009high
Missing token account mint check

Mutable token accounts lacking mint constraints.

SW010critical
Missing token account owner check

Token accounts without authority validation.

SW011high
AccountInfo used as data account

Untyped AccountInfo where typed Account is needed.

SW012high
Missing seeds + bump on PDA

PDAs with seeds but no bump verification.

SW013high
PDA seed references unvalidated account

PDA seeds referencing unconstrained accounts.

SW014high
PDA bump may not be canonical

Caller-supplied bumps instead of canonical derivation.

SW016high
init_if_needed usage (manual review)

Accounts risking silent reinitialization.

SW018low
Missing realloc::zero = true

Realloc operations leaving stale data in memory.

SW020critical
AccountInfo used as CPI target program

Untyped program accounts in CPI contexts.

SW021high
PDA seed collision risk

Adjacent variable-length seed elements that can collide under different splits.

SW022high
Manual account closure without close constraint

Accounts closed by hand instead of Anchor's close constraint.

SW023critical
Unvalidated remaining_accounts forwarded to CPI

remaining_accounts passed into CPI without ownership or program checks.

SW024high
Division by zero

Division or modulo on values that may be zero at runtime.

SW025medium
unwrap() / expect() in instruction handler

Panic paths in handlers that can halt the program unexpectedly.

SW026high
create_program_address used instead of find_program_address

Non-canonical PDA derivation that may not match find_program_address.

SW027low
Missing event emission on state change

State-changing instructions that never emit an Anchor event.