/lending-protocol-security
Protocol Type Trigger lending (detected when recon finds liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) - Inject Into Breadth agents, depth...
$ npx -y skills add PlamenTSV/plamen --skill lending-protocol-security --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
/lending-protocol-security
Context preview
The summary Claude sees to decide when to auto-load this skill.
Protocol Type Trigger lending (detected when recon finds liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) - Inject Into Breadth agents, depth...
SKILL.md
lending-protocol-security.SKILL.mdname: "lending-protocol-security"
description: "Protocol Type Trigger lending (detected when recon finds liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) - Inject Into Breadth agents, depth..."
Injectable Skill: Lending Protocol Security
> **Protocol Type Trigger**: `lending` (detected when recon finds: liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) > **Inject Into**: Breadth agents, depth-token-flow, depth-edge-case, depth-state-trace > **Language**: Language-agnostic methodology > **Finding prefix**: `[LEND-N]`
Orchestrator Decomposition Guide
When decomposing this skill into depth agent investigation questions, map sections to domains:
- Sections 1, 4: depth-edge-case (health factor boundaries, first borrower)
- Sections 2, 5: depth-state-trace (interest accrual, collateral state, pause mechanics)
- Sections 3, 3b, 3c: depth-token-flow (liquidation flows, bad debt socialization)
- Section 6: depth-external (oracle dependency for pricing)
When This Skill Activates
Recon classifies protocol as `lending` type based on indicators: liquidate, borrow, repay, collateral, lend, loan, LTV, healthFactor, interestRate, debtToken, reserve, utilizationRate, debtShare. This skill adds lending-specific checks that the general ECONOMIC_DESIGN_AUDIT does not cover.
---
1. Health Factor Boundary Analysis
1a. Health Factor Computation
Identify the health factor (HF) formula and trace each input:
- What is the formula? (typically: `HF = (collateralValue * liquidationThreshold) / debtValue`)
- How is `collateralValue` derived? (oracle price * collateral amount * collateral factor)
- How is `debtValue` derived? (oracle price * borrow amount including accrued interest)
- Is interest included in the HF check at the moment of the check, or from a stale snapshot?
Substitute boundary values into the formula: | State | HF Value | Expected Behavior | Actual? | |-------|----------|-------------------|---------| | HF = 1.0 exactly | | Liquidation threshold - which side? | | | HF = 1.0 + 1 wei | | Should NOT be liquidatable | | | HF = 1.0 - 1 wei | | Should be liquidatable | | | HF after max interest accrual | | Worst case between check intervals | | | HF with dust collateral | | Liquidation gas > reward? | |
1b. Check-to-Execution Consistency
- Between HF check and liquidation execution: can any state change (oracle update, interest accrual, collateral deposit) alter the HF?
- If a user's borrow increases their debt: is HF re-checked atomically or can they borrow below HF=1.0?
- Grep every exit-path (withdraw, transfer, finalize_transfer) for the SAME health predicate used at borrow entry. If a DIFFERENT or WEAKER predicate is used on any exit-path, document both predicate names and flag the asymmetry.
1c. Dust Position Economics
- Grep deposit/borrow entry points for minimum amount/value checks (min_borrow, min_deposit, require amount >= X). If NONE found → document "NO_MINIMUM_POSITION" as a finding: attackers can Sybil-create dust positions that cost more to liquidate than they're worth, accumulating bad debt.
- If a minimum exists at creation: grep partial-repay path for the same check. If missing → dust positions can be created by repaying down to near-zero.
Tag: `[BOUNDARY:HF={value} → liquidatable={YES/NO} → operator={>=/>}]`
---
1d. Guard Selector → Post-Transaction Enforcement Completeness
For protocols that use transaction guards or post-transaction hooks with conditional enforcement checks (e.g., post-transaction guard/hook triggered by selector or return value):
1. Enumerate ALL function selectors the guard/hook handles 2. For each selector: does the operation affect HF? (changes collateral amount, debt amount, collateral factor, efficiency/isolation mode, reserve configuration) 3. For each HF-affecting selector: does the guard/hook trigger the post-transaction HF enforcement check? 4. Flag any HF-affecting selector where post-tx enforcement is skipped
| Selector | Function | Affects HF? | Triggers Post-Tx HF Check? | Gap? | |----------|----------|-------------|---------------------------|------|
Tag: `[TRACE:guard_hook_selector={fn} → HF_affecting={YES/NO} → post_tx_check={YES/NO}]`
---
2. Interest Accrual Correctness
2a. Accrual Timing
Identify the interest accrual mechanism and trace when it updates:
- Is interest accrued per-block, per-second, or on-demand (lazy accrual on interaction)?
- For lazy accrual: which functions trigger accrual? (borrow, repay, deposit, withdraw, liquidate)
- Can a user interact without triggering accrual? (view functions used for state-changing decisions)
- Is there a maximum time gap the accrual formula handles correctly? (overflow risk for long-dormant positions)
2b. Index Update Ordering
For index-based interest (where `debt = principal * currentIndex / borrowIndex`):
- Is the global interest index updated BEFORE or AFTER the user's balance change?
- If AFTER: the user's new balance accrues interest from the wrong base
- Trace the exact ordering: `accrueInterest() → updateIndex → updateUserBalance → updateUserIndex`
- If any step is out of order or conditional: flag for depth review
2c. Precision Loss
- Compound interest over many small intervals vs one large interval: is the result equivalent?
- For utilization-rate-based interest: does the utilization rate use pre- or post-operation values?
- Over 365 days of per-second compounding: does accumulated precision error become material? (compute concrete drift using the protocol's actual rate model constants)
2d. Pause-Interest Interaction
- During pause: does interest continue to accrue?
- If interest accrues during pause BUT repayment is blocked: borrowers accumulate debt they cannot repay, potentially becoming liquidatable upon unpause
- If interest does NOT accrue during pause: lenders lose yield for the paused period
Tag: `[TRACE:accrueInterest() → index_update_
Read more
name: "lending-protocol-security" description: "Protocol Type Trigger lending (detected when recon finds liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) - Inject Into Breadth agents, depth..."
Injectable Skill: Lending Protocol Security
> **Protocol Type Trigger**: `lending` (detected when recon finds: liquidate|borrow|repay|collateral|lend|loan|LTV|healthFactor|interestRate|debtToken) > **Inject Into**: Breadth agents, depth-token-flow, depth-edge-case, depth-state-trace > **Language**: Language-agnostic methodology > **Finding prefix**: `[LEND-N]`
Orchestrator Decomposition Guide
When decomposing this skill into depth agent investigation questions, map sections to domains:
- Sections 1, 4: depth-edge-case (health factor boundaries, first borrower)
- Sections 2, 5: depth-state-trace (interest accrual, collateral state, pause mechanics)
- Sections 3, 3b, 3c: depth-token-flow (liquidation flows, bad debt socialization)
- Section 6: depth-external (oracle dependency for pricing)
When This Skill Activates
Recon classifies protocol as `lending` type based on indicators: liquidate, borrow, repay, collateral, lend, loan, LTV, healthFactor, interestRate, debtToken, reserve, utilizationRate, debtShare. This skill adds lending-specific checks that the general ECONOMIC_DESIGN_AUDIT does not cover.
---
1. Health Factor Boundary Analysis
1a. Health Factor Computation
Identify the health factor (HF) formula and trace each input:
- What is the formula? (typically: `HF = (collateralValue * liquidationThreshold) / debtValue`)
- How is `collateralValue` derived? (oracle price * collateral amount * collateral factor)
- How is `debtValue` derived? (oracle price * borrow amount including accrued interest)
- Is interest included in the HF check at the moment of the check, or from a stale snapshot?
Substitute boundary values into the formula: | State | HF Value | Expected Behavior | Actual? | |-------|----------|-------------------|---------| | HF = 1.0 exactly | | Liquidation threshold - which side? | | | HF = 1.0 + 1 wei | | Should NOT be liquidatable | | | HF = 1.0 - 1 wei | | Should be liquidatable | | | HF after max interest accrual | | Worst case between check intervals | | | HF with dust collateral | | Liquidation gas > reward? | |
1b. Check-to-Execution Consistency
- Between HF check and liquidation execution: can any state change (oracle update, interest accrual, collateral deposit) alter the HF?
- If a user's borrow increases their debt: is HF re-checked atomically or can they borrow below HF=1.0?
- Grep every exit-path (withdraw, transfer, finalize_transfer) for the SAME health predicate used at borrow entry. If a DIFFERENT or WEAKER predicate is used on any exit-path, document both predicate names and flag the asymmetry.
1c. Dust Position Economics
- Grep deposit/borrow entry points for minimum amount/value checks (min_borrow, min_deposit, require amount >= X). If NONE found → document "NO_MINIMUM_POSITION" as a finding: attackers can Sybil-create dust positions that cost more to liquidate than they're worth, accumulating bad debt.
- If a minimum exists at creation: grep partial-repay path for the same check. If missing → dust positions can be created by repaying down to near-zero.
Tag: `[BOUNDARY:HF={value} → liquidatable={YES/NO} → operator={>=/>}]`
---
1d. Guard Selector → Post-Transaction Enforcement Completeness
For protocols that use transaction guards or post-transaction hooks with conditional enforcement checks (e.g., post-transaction guard/hook triggered by selector or return value):
1. Enumerate ALL function selectors the guard/hook handles 2. For each selector: does the operation affect HF? (changes collateral amount, debt amount, collateral factor, efficiency/isolation mode, reserve configuration) 3. For each HF-affecting selector: does the guard/hook trigger the post-transaction HF enforcement check? 4. Flag any HF-affecting selector where post-tx enforcement is skipped
| Selector | Function | Affects HF? | Triggers Post-Tx HF Check? | Gap? | |----------|----------|-------------|---------------------------|------|
Tag: `[TRACE:guard_hook_selector={fn} → HF_affecting={YES/NO} → post_tx_check={YES/NO}]`
---
2. Interest Accrual Correctness
2a. Accrual Timing
Identify the interest accrual mechanism and trace when it updates:
- Is interest accrued per-block, per-second, or on-demand (lazy accrual on interaction)?
- For lazy accrual: which functions trigger accrual? (borrow, repay, deposit, withdraw, liquidate)
- Can a user interact without triggering accrual? (view functions used for state-changing decisions)
- Is there a maximum time gap the accrual formula handles correctly? (overflow risk for long-dormant positions)
2b. Index Update Ordering
For index-based interest (where `debt = principal * currentIndex / borrowIndex`):
- Is the global interest index updated BEFORE or AFTER the user's balance change?
- If AFTER: the user's new balance accrues interest from the wrong base
- Trace the exact ordering: `accrueInterest() → updateIndex → updateUserBalance → updateUserIndex`
- If any step is out of order or conditional: flag for depth review
2c. Precision Loss
- Compound interest over many small intervals vs one large interval: is the result equivalent?
- For utilization-rate-based interest: does the utilization rate use pre- or post-operation values?
- Over 365 days of per-second compounding: does accumulated precision error become material? (compute concrete drift using the protocol's actual rate model constants)
2d. Pause-Interest Interaction
- During pause: does interest continue to accrue?
- If interest accrues during pause BUT repayment is blocked: borrowers accumulate debt they cannot repay, potentially becoming liquidatable upon unpause
- If interest does NOT accrue during pause: lenders lose yield for the paused period
Tag: `[TRACE:accrueInterest() → index_update_
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

