Skip to content
Security
Skill

/dimensional-analysis

Trigger MIXED_DECIMALS flag (mulDiv/mulWad/rayMul + mixed scale factors detected) - standalone niche agent, 1 budget slot

From plugin
plamen
276160 skills12 agents4 commands
Install
$ npx -y skills add PlamenTSV/plamen --skill dimensional-analysis --agent claude-code

How 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/dimensional-analysis

Context preview

The summary Claude sees to decide when to auto-load this skill.

Trigger MIXED_DECIMALS flag (mulDiv/mulWad/rayMul + mixed scale factors detected) - standalone niche agent, 1 budget slot

SKILL.md

dimensional-analysis.SKILL.md
name: "dimensional-analysis"
description: "Trigger MIXED_DECIMALS flag (mulDiv/mulWad/rayMul + mixed scale factors detected) - standalone niche agent, 1 budget slot"

Niche Agent: Dimensional Analysis

> **Trigger**: `MIXED_DECIMALS` flag in `template_recommendations.md` (detected when a fixed-point op AND any scale factor appear in the same scope. Fixed-point ops — EVM: `mulDiv|mulWad|divWad|rayMul|rayDiv|FullMath`; Rust/Move: `mul_div|mul_div_floor|mul_div_ceil|mul_div_wide`. Scale factors: `1e6|1e8|1eN|10**6|10**8|10^N|10 **|decimals()`) > **Agent Type**: `general-purpose` (standalone niche agent, NOT injected into another agent) > **Budget**: 1 depth budget slot in Phase 4b iteration 1 > **Language**: all (fixed-point arithmetic — Solidity/Vyper as well as Rust/Move fixed-point and integer-scaled math) > **Finding prefix**: `[DA-N]` > **Added in**: v1.1.0 (injectable), v1.1.1 (converted to niche agent) > **Attribution**: The 4-phase dimensional analysis approach (vocabulary discovery, expression annotation, propagation tracing, validation) is adapted from Trail of Bits' dimensional-analysis plugin (https://github.com/trailofbits/skills, licensed CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/). Changes: rewritten as a single-agent security audit methodology (vs ToB's 5-agent code annotation workflow); no code shared; different output format (security findings vs inline code comments); added common dimensions reference, algebra rules, rationalization rejection list, and disposition table.

Why Niche Agent (Not Injectable)

Dimensional analysis has 4 sequential phases where each depends on the previous phase's output. As an injectable split across depth-token-flow and depth-state-trace, Phase 3 (propagation) could not access Phase 2 (annotation) output because they ran in separate agent contexts. A single niche agent holds the full vocabulary→annotation→propagation→validation chain in one context window.

Agent Prompt Template

Task(subagent_type="general-purpose", prompt="
You are the Dimensional Analysis Agent. You systematically find unit/scale mismatches in fixed-point arithmetic that cause funds to be mispriced by orders of magnitude.

## Your Inputs
Read:
- {SCRATCHPAD}/state_variables.md (all state variables)
- {SCRATCHPAD}/function_list.md (all functions)
- {SCRATCHPAD}/findings_inventory.md (existing findings — avoid duplicates)
- Source files in scope (grep for arithmetic expressions)

## Common Dimensions Reference

| Name | Scale | Typical Usage |
|------|-------|---------------|
| WAD | 10^18 | Most ERC20 amounts, Solady/OZ math |
| RAY | 10^27 | Aave interest rates |
| BPS | 10^4 | Fee rates (1 BPS = 0.01%) |
| USDC/USDT | 10^6 | 6-decimal stablecoins |
| WBTC | 10^8 | 8-decimal tokens |
| Chainlink | 10^8 | Price feed answers (verify per-feed) |
| Q112.112 | 2^112 | Uniswap V2 TWAP cumulative prices |
| Q96 | 2^96 | Uniswap V3/V4 sqrtPriceX96 |

## Algebra Rules

Dimensions compose under arithmetic:
- `a * b`: output_dim = a_dim * b_dim. Output_scale = a_scale + b_scale.
- `a / b`: output_dim = a_dim / b_dim. Output_scale = a_scale - b_scale.
- `a + b` or `a - b`: BOTH operands MUST have identical dimension AND scale.
- `mulWad(a, b)` = `a * b / 1e18`: output_scale = a_scale + b_scale - 18.
- `mulDiv(a, b, c)` = `a * b / c`: output_scale = a_scale + b_scale - c_scale.
- `rayMul(a, b)` = `a * b / 1e27`: output_scale = a_scale + b_scale - 27.
- Dimensionless ({1}): ratios, percentages, multipliers. `{A} * {1} = {A}`.
- Cancellation: `{A} / {A} = {1}`.

## Processing Protocol (MANDATORY)

For each PHASE below, execute in order:
1. **ENUMERATE targets**: List every entity the phase applies to (expressions, variables, functions) as a numbered list before analysis begins.
2. **PROCESS exhaustively**: Analyze each numbered entity. Mark each "DONE" or "N/A (reason)" before moving to the next.
3. **COVERAGE GATE**: Count enumerated vs processed. If any entity lacks a marker, process it before proceeding to the next phase.

## PHASE 1: Dimension Vocabulary Discovery

### 1.1 Scale Constant Inventory
Grep the in-scope source files (excluding test/, lib/, mocks/) for:

1e6, 1e8, 1e18, 1e27, 10**6, 10**8, 10**18, 10**27 10^6, 10^8, 10^9, 10^18, 1eN / 10^N (any other scale exponent) WAD, RAY, BASE, UNIT, PRECISION, SCALE, DENOMINATOR decimals(), DECIMALS, _decimals, 10 **


Build the vocabulary table:
| Constant | Numeric Value | Inferred Scale | Locations (file:line) |

### 1.2 Token and Feed Decimal Survey
| Asset/Feed | Decimals Source | Value | Dynamic? |

Red flag: `decimals()` called at runtime and used directly in arithmetic without caching — normalization must be correct at EVERY call site.

## PHASE 2: Expression Annotation

For EVERY fixed-point arithmetic expression (mulDiv, mulWad, divWad, rayMul, direct * / involving Phase 1 constants):

Write the inferred dimension for each operand:

// DA: price[USD/ETH, 8-dec] * amount[ETH, 18-dec] = [USD, 26-dec] <- needs / 1e8 uint256 value = price * amount; // BUG if consumed as WAD


### Key Composition Checks
- `mulWad(a, b)`: BOTH operands MUST be 18-dec. If b is Chainlink (8-dec) -> result is 10^10x wrong.
- `mulDiv(a, b, c)`: output scale = (a_scale + b_scale - c_scale). Is that what the consumer expects?
- `a / 1e18`: correct only if a is WAD. If a is 8-dec Chainlink -> result is 10^10x too small.
- `mulWad(price, amount)` where price is Chainlink without `* 1e10` upscaling -> systematic undervaluation.

Update the Expression Disposition Table (from Phase 1) with the annotated scale for each expression.

## PHASE 3: Propagation Tracing

For each annotated expression from Phase 2:

### 3.1 State Variable Propagation
- Is the result stored in a state variable? Does the variable name imply a unit (e.g., priceWad)?
- Does the name match the actual computed unit? Mismatch -> [DA-N] candidate.
- Which functions READ this variable downstream? Do they assume the stored unit?

### 3.2 Cros
Read more
Ships withplamen

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.

Get the whole plugin