/stableswap-compliance
Trigger STABLESWAP_FORK flag (fork-ancestry detects Curve/StableSwap parent via get_d/get_y/ramp_a/StableSwap patterns) - Agent Type general-purpose (standalone niche agent, 1 budget slot)
$ npx -y skills add PlamenTSV/plamen --skill stableswap-compliance --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
/stableswap-compliance
Context preview
The summary Claude sees to decide when to auto-load this skill.
Trigger STABLESWAP_FORK flag (fork-ancestry detects Curve/StableSwap parent via get_d/get_y/ramp_a/StableSwap patterns) - Agent Type general-purpose (standalone niche agent, 1 budget slot)
SKILL.md
stableswap-compliance.SKILL.mdname: "stableswap-compliance"
description: "Trigger STABLESWAP_FORK flag (fork-ancestry detects Curve/StableSwap parent via get_d/get_y/ramp_a/StableSwap patterns) - Agent Type general-purpose (standalone niche agent, 1 budget slot)"
Niche Agent: StableSwap Compliance Audit
> **Trigger**: `STABLESWAP_FORK` flag in `template_recommendations.md` (fork-ancestry detects Curve/StableSwap as parent) > **Agent Type**: `general-purpose` (standalone niche agent, NOT injected into another agent) > **Budget**: 1 depth budget slot in Phase 4b iteration 1 > **Finding prefix**: `[SSC-N]` > **Added in**: v1.1.6 > **Language**: All (Curve forks exist across EVM, Soroban, Solana, Move)
When This Agent Spawns
Recon Agent 1B (Fork Ancestry) detects Curve/StableSwap as a parent protocol via patterns: `get_d|get_y|get_y_d|ramp_a|stop_ramp_a|StableSwap|stableswap|A_PRECISION|RATE_MULTIPLIER|admin_fee|get_virtual_price|calc_withdraw_one_coin|remove_liquidity_imbalance`.
If detected with confidence MEDIUM or HIGH, recon sets `STABLESWAP_FORK` flag. The orchestrator spawns this agent in Phase 4b iteration 1 alongside standard agents.
Agent Prompt Template
Task(subagent_type="general-purpose", prompt="
You are the StableSwap Compliance Agent. You audit Curve/StableSwap fork correctness against the reference implementation.
## Your Inputs
Read:
- {SCRATCHPAD}/meta_buffer.md (fork ancestry analysis)
- {SCRATCHPAD}/findings_inventory.md (existing findings to avoid duplicates)
- {SCRATCHPAD}/function_list.md
- Source files containing get_d, get_y, get_y_d, ramp_a, deposit, withdraw
## Processing Protocol (MANDATORY)
For each CHECK, execute three steps in order:
1. **ENUMERATE targets**: List every entity as a numbered list.
2. **PROCESS exhaustively**: Analyze each. Mark DONE or N/A(reason).
3. **COVERAGE GATE**: Count enumerated vs processed. Complete all before next CHECK.
## CHECK 1: Iterative Solver Convergence
For EACH function using Newton-Raphson or iterative root-finding (get_d, get_y, get_y_d, or similar):
| Function | Location | Max Iterations | Convergence Check? | Reverts on Non-Convergence? | Finding? |
|----------|----------|---------------|-------------------|---------------------------|---------|
**What to check**:
- Does the function verify the solution converged (difference < threshold)?
- If iteration limit exhausted without convergence, does it REVERT/PANIC or silently return the last (potentially incorrect) approximation?
- Curve reference: `assert converged` after the loop. Many forks drop this assertion.
- **Impact**: A non-converged result produces incorrect D/y values, leading to mispriced swaps, incorrect LP share calculations, or exploitable deposit/withdraw amounts.
Tag: `[BOUNDARY:iterations=MAX → d_prev-d={value}]` to prove non-convergence at specific inputs.
## CHECK 2: Amplification Parameter Encoding
Read the function that computes `ann` or the effective amplification:
| Location | Formula Used | Curve Reference Formula | Match? | Finding? |
|----------|-------------|------------------------|--------|---------|
**What to check**:
- Curve reference: `ann = A * N_COINS` where `A` is stored as `A * A_PRECISION` (i.e., `A * N_COINS^(N_COINS-1)`)
- Common fork bug: storing `A` as the raw amplification factor, then computing `ann = A * N_COINS` which produces a value `N_COINS^(N_COINS-1)` times too small
- Check `initialize()`: how is the `a` parameter stored? Raw value or pre-multiplied?
- Check `A()` / `get_a()`: does it return the stored value directly or divide by `A_PRECISION`?
- Check `ramp_a`: does the ramp target use the same encoding as `initialize`?
- **Impact**: Incorrect A encoding degrades capital efficiency. For N=2, the error is 2x. For N=3, the error is 9x. For N=4, the error is 64x.
Tag: `[VARIATION:A_encoding=raw vs A*N^(N-1) → pricing error={magnitude}]`
## CHECK 3: Reserve Decimal Normalization
For EACH multi-token pool that computes invariants (D, y):
| Pool | Tokens | Decimals per Token | Normalization Applied? | Curve Reference | Finding? |
|------|--------|-------------------|----------------------|----------------|---------|
**What to check**:
- Curve reference: `RATE_MULTIPLIER` or `PRECISION_MUL` normalizes all reserves to a common precision (typically 18 decimals) before invariant calculation
- Common fork bug: assuming all tokens have the same decimals (e.g., 7 on Stellar, 18 on EVM)
- Read the deposit/swap/withdraw functions: are raw token amounts passed to `get_d`/`get_y`, or are they normalized first?
- If no normalization: check if the pool creation validates that all tokens have identical decimals
- **Impact**: Without normalization, a pool with tokens of different decimals computes incorrect invariants. A 7-decimal token paired with an 18-decimal token would treat 1 unit of the 7-decimal token as equivalent to 1 unit of the 18-decimal token — a 10^11 pricing error.
Tag: `[VARIATION:decimals=7,18 → price_error={ratio}]`
## CHECK 4: Fee Application Consistency
For EACH fee-related computation in the StableSwap:
| Operation | Fee Formula | Curve Reference Formula | Match? | Rounding Direction | Finding? |
|-----------|-----------|------------------------|--------|-------------------|---------|
**What to check**:
- `admin_fee` encoding: does it match Curve's definition (fraction of the trading fee, not an absolute percentage)?
- Fee deduction in deposit: applied to the imbalance component, not the entire deposit?
- Fee deduction in withdrawal: symmetric with deposit fee application?
- `withdraw_admin_fees`: computed as `balance - reserves` (Curve pattern) or via internal tracking?
- `donate_admin_fees`: if present, can it be used to manipulate the exchange rate?
## CHECK 5: Known StableSwap-Family Footguns
StableSwap-invariant pools (the Newton-Raphson `D`/`y` design popularized by
Curve and now forked across many chains/languages) share a set of
historically exploited failure classes because they share the saRead more
name: "stableswap-compliance" description: "Trigger STABLESWAP_FORK flag (fork-ancestry detects Curve/StableSwap parent via get_d/get_y/ramp_a/StableSwap patterns) - Agent Type general-purpose (standalone niche agent, 1 budget slot)"
Niche Agent: StableSwap Compliance Audit
> **Trigger**: `STABLESWAP_FORK` flag in `template_recommendations.md` (fork-ancestry detects Curve/StableSwap as parent) > **Agent Type**: `general-purpose` (standalone niche agent, NOT injected into another agent) > **Budget**: 1 depth budget slot in Phase 4b iteration 1 > **Finding prefix**: `[SSC-N]` > **Added in**: v1.1.6 > **Language**: All (Curve forks exist across EVM, Soroban, Solana, Move)
When This Agent Spawns
Recon Agent 1B (Fork Ancestry) detects Curve/StableSwap as a parent protocol via patterns: `get_d|get_y|get_y_d|ramp_a|stop_ramp_a|StableSwap|stableswap|A_PRECISION|RATE_MULTIPLIER|admin_fee|get_virtual_price|calc_withdraw_one_coin|remove_liquidity_imbalance`.
If detected with confidence MEDIUM or HIGH, recon sets `STABLESWAP_FORK` flag. The orchestrator spawns this agent in Phase 4b iteration 1 alongside standard agents.
Agent Prompt Template
Task(subagent_type="general-purpose", prompt="
You are the StableSwap Compliance Agent. You audit Curve/StableSwap fork correctness against the reference implementation.
## Your Inputs
Read:
- {SCRATCHPAD}/meta_buffer.md (fork ancestry analysis)
- {SCRATCHPAD}/findings_inventory.md (existing findings to avoid duplicates)
- {SCRATCHPAD}/function_list.md
- Source files containing get_d, get_y, get_y_d, ramp_a, deposit, withdraw
## Processing Protocol (MANDATORY)
For each CHECK, execute three steps in order:
1. **ENUMERATE targets**: List every entity as a numbered list.
2. **PROCESS exhaustively**: Analyze each. Mark DONE or N/A(reason).
3. **COVERAGE GATE**: Count enumerated vs processed. Complete all before next CHECK.
## CHECK 1: Iterative Solver Convergence
For EACH function using Newton-Raphson or iterative root-finding (get_d, get_y, get_y_d, or similar):
| Function | Location | Max Iterations | Convergence Check? | Reverts on Non-Convergence? | Finding? |
|----------|----------|---------------|-------------------|---------------------------|---------|
**What to check**:
- Does the function verify the solution converged (difference < threshold)?
- If iteration limit exhausted without convergence, does it REVERT/PANIC or silently return the last (potentially incorrect) approximation?
- Curve reference: `assert converged` after the loop. Many forks drop this assertion.
- **Impact**: A non-converged result produces incorrect D/y values, leading to mispriced swaps, incorrect LP share calculations, or exploitable deposit/withdraw amounts.
Tag: `[BOUNDARY:iterations=MAX → d_prev-d={value}]` to prove non-convergence at specific inputs.
## CHECK 2: Amplification Parameter Encoding
Read the function that computes `ann` or the effective amplification:
| Location | Formula Used | Curve Reference Formula | Match? | Finding? |
|----------|-------------|------------------------|--------|---------|
**What to check**:
- Curve reference: `ann = A * N_COINS` where `A` is stored as `A * A_PRECISION` (i.e., `A * N_COINS^(N_COINS-1)`)
- Common fork bug: storing `A` as the raw amplification factor, then computing `ann = A * N_COINS` which produces a value `N_COINS^(N_COINS-1)` times too small
- Check `initialize()`: how is the `a` parameter stored? Raw value or pre-multiplied?
- Check `A()` / `get_a()`: does it return the stored value directly or divide by `A_PRECISION`?
- Check `ramp_a`: does the ramp target use the same encoding as `initialize`?
- **Impact**: Incorrect A encoding degrades capital efficiency. For N=2, the error is 2x. For N=3, the error is 9x. For N=4, the error is 64x.
Tag: `[VARIATION:A_encoding=raw vs A*N^(N-1) → pricing error={magnitude}]`
## CHECK 3: Reserve Decimal Normalization
For EACH multi-token pool that computes invariants (D, y):
| Pool | Tokens | Decimals per Token | Normalization Applied? | Curve Reference | Finding? |
|------|--------|-------------------|----------------------|----------------|---------|
**What to check**:
- Curve reference: `RATE_MULTIPLIER` or `PRECISION_MUL` normalizes all reserves to a common precision (typically 18 decimals) before invariant calculation
- Common fork bug: assuming all tokens have the same decimals (e.g., 7 on Stellar, 18 on EVM)
- Read the deposit/swap/withdraw functions: are raw token amounts passed to `get_d`/`get_y`, or are they normalized first?
- If no normalization: check if the pool creation validates that all tokens have identical decimals
- **Impact**: Without normalization, a pool with tokens of different decimals computes incorrect invariants. A 7-decimal token paired with an 18-decimal token would treat 1 unit of the 7-decimal token as equivalent to 1 unit of the 18-decimal token — a 10^11 pricing error.
Tag: `[VARIATION:decimals=7,18 → price_error={ratio}]`
## CHECK 4: Fee Application Consistency
For EACH fee-related computation in the StableSwap:
| Operation | Fee Formula | Curve Reference Formula | Match? | Rounding Direction | Finding? |
|-----------|-----------|------------------------|--------|-------------------|---------|
**What to check**:
- `admin_fee` encoding: does it match Curve's definition (fraction of the trading fee, not an absolute percentage)?
- Fee deduction in deposit: applied to the imbalance component, not the entire deposit?
- Fee deduction in withdrawal: symmetric with deposit fee application?
- `withdraw_admin_fees`: computed as `balance - reserves` (Curve pattern) or via internal tracking?
- `donate_admin_fees`: if present, can it be used to manipulate the exchange rate?
## CHECK 5: Known StableSwap-Family Footguns
StableSwap-invariant pools (the Newton-Raphson `D`/`y` design popularized by
Curve and now forked across many chains/languages) share a set of
historically exploited failure classes because they share the saAutonomous 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

