/overflow-safety
Trigger Pattern Always required for Soroban audits - Inject Into Breadth agents, depth-edge-case
$ npx -y skills add PlamenTSV/plamen --skill overflow-safety --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/overflow-safety
Context preview
The summary Claude sees to decide when to auto-load this skill.
Trigger Pattern Always required for Soroban audits - Inject Into Breadth agents, depth-edge-case
SKILL.md
overflow-safety.SKILL.mdname: "overflow-safety"
description: "Trigger Pattern Always required for Soroban audits - Inject Into Breadth agents, depth-edge-case"
OVERFLOW_SAFETY Skill (Soroban)
> **Trigger Pattern**: Always required for Soroban audits > **Inject Into**: Breadth agents, depth-edge-case > **Finding prefix**: `[OF-N]` > **Rules referenced**: R10, R14
Soroban contracts are compiled Rust. Rust's overflow behavior depends on the build profile: in debug builds, overflows panic; in release builds (used for deployment), overflows silently wrap by default unless `overflow-checks = true` is set. Silent wrapping in financial arithmetic is a critical vulnerability.
1. Profile Check
Before tracing any arithmetic, inspect `Cargo.toml` for the release profile overflow setting:
| File | `[profile.release]` Present? | `overflow-checks` Setting | Safe? | |------|------------------------------|--------------------------|-------| | `Cargo.toml` | YES/NO | `true` / `false` / MISSING | Only if `true` |
**Interpretation**:
- `overflow-checks = true` → all integer arithmetic panics on overflow in release builds. The codebase is safe from silent wrapping.
- `overflow-checks = false` or missing → overflows silently wrap in release. **Proceed to Section 2.**
- If the file does not exist or does not contain `[profile.release]`: treat as `false` (Rust default for release).
**Finding threshold**: If `overflow-checks` is not `true`, the entire overflow safety of the contract depends on manual use of checked/saturating arithmetic. This is a configuration-level finding regardless of whether Section 2 finds specific overflow sites.
2. Arithmetic Trace (if `overflow-checks` is false/missing)
If the profile check from Section 1 found that overflow protection is NOT enabled, trace ALL arithmetic operations in financial paths:
| Location | Expression | Operand Types | Max Realistic Value | Overflow Possible? | Impact if Wrapped | |----------|-----------|--------------|--------------------|--------------------|------------------| | `{file:line}` | `{a + b}` | `u64 / i128 / u32` | `{estimate}` | YES/NO | `{balance wraps to 0, share inflates, etc.}` |
**Financial paths to prioritize**:
- Token balance calculations (`balance + amount`, `total_supply + mint_amount`)
- Share/ratio calculations (`shares * price / precision`)
- Fee calculations (`amount * fee_bps / 10000`)
- Interest accrual (`principal * rate * time`)
- Reward distributions (`rewards_per_token * user_balance`)
**Wrapping arithmetic consequences**:
- `u128` overflows near `2^128 ≈ 3.4 × 10^38` — practically unreachable for balances
- `i128` overflows near `2^127 ≈ 1.7 × 10^38` — practically unreachable for balances
- `u64` overflows near `1.8 × 10^19` — reachable with large token amounts in 6-decimal tokens
- `u32` overflows near `4.3 × 10^9` — reachable in ledger numbers, timestamps, counts
3. Checked Arithmetic Patterns
Identify all financial arithmetic and classify whether safe arithmetic methods are used:
| Location | Operation | Method Used | Safe? | |----------|-----------|-------------|-------| | `{file:line}` | `{description}` | `+` / `checked_add` / `saturating_add` / `wrapping_add` | Only `checked_*` or `saturating_*` |
**Safe methods**:
- `checked_add(b)` → returns `Option<T>`, panics or propagates None on overflow
- `checked_mul(b)` → returns `Option<T>`
- `saturating_add(b)` → clamps at MAX (safe for balances where MAX means "very rich")
- `checked_div(b)` → also catches division by zero
**Unsafe methods**:
- `+`, `-`, `*` without `overflow-checks = true` → silent wrapping in release
- `wrapping_add`, `wrapping_sub`, `wrapping_mul` → explicitly wraps (intentionally unsafe for most contexts)
- `/` → panics on divide-by-zero regardless of overflow-checks (covered in Section 5)
**Flag any unchecked arithmetic where**:
- Operands are user-controlled (amounts, durations, counts)
- The result feeds into a balance, share count, or reward calculation
4. i128 Boundary Analysis
Soroban's native token and SEP-41 tokens frequently use `i128` for amounts. Check operations near the boundaries:
| Location | Operation | Uses `i128`? | Near-Boundary Risk | Checked? | |----------|-----------|-------------|-------------------|---------| | `{file:line}` | `{expression}` | YES/NO | YES/NO | YES/NO |
**Specific checks**:
- Share calculations: `shares = (amount * total_shares) / total_assets` — if `total_shares` is near `i128::MAX`, multiplication overflows before division
- Cumulative reward trackers: `reward_per_token_stored += rewards * PRECISION / total_supply` — accumulation can overflow over time
- Negative balance checks: `i128` allows negative values; verify contracts reject negative amount parameters via explicit `require!(amount > 0)`
- Cast safety: `u128 as i128` silently truncates if the `u128` value exceeds `i128::MAX`
5. Division Precision
Soroban has no floating-point arithmetic. All division truncates toward zero (integer division). Incorrect division ordering causes precision loss or incorrect results:
| Location | Expression | Division-Before-Multiplication? | Precision Loss Estimate | Impact | |----------|-----------|--------------------------------|------------------------|--------| | `{file:line}` | `{a / b * c}` | YES → FLAG | `{up to b-1 units lost}` | `{financial impact}` |
**Anti-pattern** (division before multiplication):
// BAD: (amount / total_supply) loses precision before multiplying by rewards
let user_share = (user_balance / total_supply) * total_rewards;
**Correct pattern** (multiplication before division):
// GOOD: multiply first to preserve precision
let user_share = (user_balance * total_rewards) / total_supply;
**Additional checks**:
- Division by zero: verify all divisors are checked for zero before use. `require!(total_supply > 0)` before `x / total_supply`
- Rounding direction: does truncation favor the protocol (rounding down on user withdrawals) or systematically favo
Read more
name: "overflow-safety" description: "Trigger Pattern Always required for Soroban audits - Inject Into Breadth agents, depth-edge-case"
OVERFLOW_SAFETY Skill (Soroban)
> **Trigger Pattern**: Always required for Soroban audits > **Inject Into**: Breadth agents, depth-edge-case > **Finding prefix**: `[OF-N]` > **Rules referenced**: R10, R14
Soroban contracts are compiled Rust. Rust's overflow behavior depends on the build profile: in debug builds, overflows panic; in release builds (used for deployment), overflows silently wrap by default unless `overflow-checks = true` is set. Silent wrapping in financial arithmetic is a critical vulnerability.
1. Profile Check
Before tracing any arithmetic, inspect `Cargo.toml` for the release profile overflow setting:
| File | `[profile.release]` Present? | `overflow-checks` Setting | Safe? | |------|------------------------------|--------------------------|-------| | `Cargo.toml` | YES/NO | `true` / `false` / MISSING | Only if `true` |
**Interpretation**:
- `overflow-checks = true` → all integer arithmetic panics on overflow in release builds. The codebase is safe from silent wrapping.
- `overflow-checks = false` or missing → overflows silently wrap in release. **Proceed to Section 2.**
- If the file does not exist or does not contain `[profile.release]`: treat as `false` (Rust default for release).
**Finding threshold**: If `overflow-checks` is not `true`, the entire overflow safety of the contract depends on manual use of checked/saturating arithmetic. This is a configuration-level finding regardless of whether Section 2 finds specific overflow sites.
2. Arithmetic Trace (if `overflow-checks` is false/missing)
If the profile check from Section 1 found that overflow protection is NOT enabled, trace ALL arithmetic operations in financial paths:
| Location | Expression | Operand Types | Max Realistic Value | Overflow Possible? | Impact if Wrapped | |----------|-----------|--------------|--------------------|--------------------|------------------| | `{file:line}` | `{a + b}` | `u64 / i128 / u32` | `{estimate}` | YES/NO | `{balance wraps to 0, share inflates, etc.}` |
**Financial paths to prioritize**:
- Token balance calculations (`balance + amount`, `total_supply + mint_amount`)
- Share/ratio calculations (`shares * price / precision`)
- Fee calculations (`amount * fee_bps / 10000`)
- Interest accrual (`principal * rate * time`)
- Reward distributions (`rewards_per_token * user_balance`)
**Wrapping arithmetic consequences**:
- `u128` overflows near `2^128 ≈ 3.4 × 10^38` — practically unreachable for balances
- `i128` overflows near `2^127 ≈ 1.7 × 10^38` — practically unreachable for balances
- `u64` overflows near `1.8 × 10^19` — reachable with large token amounts in 6-decimal tokens
- `u32` overflows near `4.3 × 10^9` — reachable in ledger numbers, timestamps, counts
3. Checked Arithmetic Patterns
Identify all financial arithmetic and classify whether safe arithmetic methods are used:
| Location | Operation | Method Used | Safe? | |----------|-----------|-------------|-------| | `{file:line}` | `{description}` | `+` / `checked_add` / `saturating_add` / `wrapping_add` | Only `checked_*` or `saturating_*` |
**Safe methods**:
- `checked_add(b)` → returns `Option<T>`, panics or propagates None on overflow
- `checked_mul(b)` → returns `Option<T>`
- `saturating_add(b)` → clamps at MAX (safe for balances where MAX means "very rich")
- `checked_div(b)` → also catches division by zero
**Unsafe methods**:
- `+`, `-`, `*` without `overflow-checks = true` → silent wrapping in release
- `wrapping_add`, `wrapping_sub`, `wrapping_mul` → explicitly wraps (intentionally unsafe for most contexts)
- `/` → panics on divide-by-zero regardless of overflow-checks (covered in Section 5)
**Flag any unchecked arithmetic where**:
- Operands are user-controlled (amounts, durations, counts)
- The result feeds into a balance, share count, or reward calculation
4. i128 Boundary Analysis
Soroban's native token and SEP-41 tokens frequently use `i128` for amounts. Check operations near the boundaries:
| Location | Operation | Uses `i128`? | Near-Boundary Risk | Checked? | |----------|-----------|-------------|-------------------|---------| | `{file:line}` | `{expression}` | YES/NO | YES/NO | YES/NO |
**Specific checks**:
- Share calculations: `shares = (amount * total_shares) / total_assets` — if `total_shares` is near `i128::MAX`, multiplication overflows before division
- Cumulative reward trackers: `reward_per_token_stored += rewards * PRECISION / total_supply` — accumulation can overflow over time
- Negative balance checks: `i128` allows negative values; verify contracts reject negative amount parameters via explicit `require!(amount > 0)`
- Cast safety: `u128 as i128` silently truncates if the `u128` value exceeds `i128::MAX`
5. Division Precision
Soroban has no floating-point arithmetic. All division truncates toward zero (integer division). Incorrect division ordering causes precision loss or incorrect results:
| Location | Expression | Division-Before-Multiplication? | Precision Loss Estimate | Impact | |----------|-----------|--------------------------------|------------------------|--------| | `{file:line}` | `{a / b * c}` | YES → FLAG | `{up to b-1 units lost}` | `{financial impact}` |
**Anti-pattern** (division before multiplication):
// BAD: (amount / total_supply) loses precision before multiplying by rewards let user_share = (user_balance / total_supply) * total_rewards;
**Correct pattern** (multiplication before division):
// GOOD: multiply first to preserve precision let user_share = (user_balance * total_rewards) / total_supply;
**Additional checks**:
- Division by zero: verify all divisors are checked for zero before use. `require!(total_supply > 0)` before `x / total_supply`
- Rounding direction: does truncation favor the protocol (rounding down on user withdrawals) or systematically favo
Autonomous Web3 security auditor for Claude Code and OpenAI Codex CLI. Orchestrates 18-100 AI agents across 40+ phases to produce audit reports with verified PoC exploits — for smart contracts and L1 node-client infrastructure.
Repo: PlamenTSV/plamen
Other skills on plamen.
- /ability-analysis
Trigger Pattern Always (Aptos Move) - foundational security check - Inject Into Breadth agents, depth agents
Open skill - /bit-shift-safety
Trigger Pattern Always (Aptos Move) - Move VM aborts on shift = bit width - Inject Into Breadth agents, depth-edge-case
Open skill - /centralization-risk
Trigger Protocol has privileged roles (admin, operator, governance, resource account owner) - Covers Single points of failure, privilege escalation, external governance dependen...
Open skill - /cross-chain-timing
Trigger Pattern wormhole|layerzero|ccip|bridge|cross_chain|vaa|guardian|emitter|relay|remote_chain|payload|nonce.sequence - Inject Into Breadth agents, depth-external
Open skill - /dependency-audit
Trigger EXTERNAL_LIB flag detected (protocol uses third-party Move dependencies) - Used by Breadth agents, depth-external
Open skill - /economic-design-audit
Trigger Pattern MONETARY_PARAMETER flag (required) - Inject Into Breadth agents (merged via M4 hierarchy)
Open skill

