ChainScore Labs
LABS
Guides

Stress Testing DeFi Derivatives Protocols

Chainscore © 2025
concepts

Core Concepts for Stress Testing

Understanding the fundamental principles and mechanisms that define the resilience of DeFi derivatives protocols under extreme market conditions.

01

Liquidation Engine

The liquidation engine is the automated system that closes undercollateralized positions to protect protocol solvency.

  • Triggers based on health factor or collateral ratio thresholds.
  • Involves liquidators who are incentivized with a bounty.
  • Must be tested for latency, gas efficiency, and front-running resistance under high volatility to prevent bad debt accumulation.
02

Oracle Resilience

Oracle resilience refers to the protocol's dependency on and defense against price feed manipulation or failure.

  • Tests involve simulating oracle lag, stale data, and flash loan-driven price manipulation attacks.
  • Assesses the impact of using TWAPs or multiple oracle sources.
  • Critical for ensuring accurate collateral valuation and liquidation triggers during market shocks.
03

Funding Rate Mechanism

The funding rate mechanism balances perpetual contract prices with the underlying spot market.

  • Periodically exchanges payments between long and short positions.
  • Stress tests model extreme funding rate scenarios and cascading liquidations.
  • Evaluates the mechanism's ability to prevent unsustainable price premiums or discounts during high leverage and volatility.
04

Insurance & Reserve Funds

Insurance and reserve funds act as a backstop to cover system shortfalls and bad debt.

  • Tests measure the fund's adequacy during correlated market crashes across multiple assets.
  • Simulates drawdown scenarios and the fund's recapitalization mechanisms.
  • Essential for maintaining user confidence and protocol solvency when liquidation engines are overwhelmed.
05

Slippage & Price Impact

Slippage and price impact measure how large trades affect the execution price within the protocol's AMM or order book.

  • Stress tests involve simulating massive position unwinds or liquidations.
  • Quantifies the resulting losses for LPs and the potential for creating toxic order flow.
  • Directly impacts the realizable value of collateral during a crisis.
06

Protocol Parameter Sensitivity

Parameter sensitivity analysis examines how small changes to key variables affect system stability.

  • Variables include initial/maintenance margin, liquidation penalties, and fee structures.
  • Tests identify brittle configurations that could lead to cascading failures.
  • Informs governance on setting robust, adaptive parameters for different market regimes.

Stress Testing Methodology

Process overview

1

Define Protocol Boundaries and Risk Vectors

Identify the core smart contracts and the specific financial risks to test.

Detailed Instructions

Begin by mapping the protocol architecture. Identify the core contracts for the derivative's logic, collateral management, price oracles, and liquidation engine. For a perpetual futures protocol, this includes the vault, market, and funding rate modules. Simultaneously, define the risk vectors to stress. These typically include extreme market volatility (e.g., a 50% price drop in 1 hour), liquidity crunches (withdrawal of 80% of TVL), oracle failure or latency, and cascading liquidations. Document the expected behavior for each component under normal and stressed conditions. This scoping ensures tests are targeted and meaningful.

  • Sub-step 1: Use Etherscan or a block explorer to trace contract interactions and dependencies.
  • Sub-step 2: List all external dependencies, such as Chainlink price feeds (e.g., 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419 for ETH/USD).
  • Sub-step 3: Formalize failure modes in a document, e.g., "If the oracle reports a 40% price deviation, the liquidation system should halt."
solidity
// Example: Checking oracle address in a test setup address public oracle = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419;

Tip: Collaborate with protocol developers to ensure your model of the system matches the actual implementation.

2

Configure the Test Environment with Forked Mainnet

Set up a local or testnet fork to simulate real-world conditions accurately.

Detailed Instructions

Use a development framework like Foundry or Hardhat to fork the main Ethereum network at a specific block. This creates a sandbox with real token balances, prices, and protocol states. The key is to pin the fork to a recent block (e.g., block number 18,500,000) to ensure consistency. Fund test accounts with substantial amounts of relevant assets (e.g., 10,000 WETH and 1,000,000 USDC) using vm.deal or hardhat_setBalance. Impersonate key accounts like the protocol's admin or large liquidity providers using vm.startPrank() to simulate privileged actions. This environment is crucial for testing interactions with live contract logic and dependencies.

  • Sub-step 1: Initialize a Foundry project and configure the fork URL and block number in foundry.toml.
  • Sub-step 2: Use vm.createSelectFork() to spin up the forked chain instance.
  • Sub-step 3: Impersonate a whale account to manipulate large positions within the protocol.
bash
# Foundry command to fork mainnet anvil --fork-url $RPC_URL --fork-block-number 18500000

Tip: Archive node RPC endpoints are required for reliable forking of older blocks.

3

Execute Scenarios with Automated Scripts

Programmatically inject stress events and observe protocol state changes.

Detailed Instructions

Write automated scripts that sequentially apply stress. Start by simulating a large position opening at high leverage (e.g., 25x). Then, trigger the primary stressor, such as manipulating the oracle price via vm.mockCall to simulate a flash crash. Observe the liquidation cascade: check if liquidators are incentivized correctly, if the liquidation function reverts due to congestion, and if bad debt accumulates. Measure key metrics before, during, and after the event: total collateral locked, open interest, funding rate, and protocol-owned bad debt. Use Foundry's vm.roll() to simulate the passage of time for funding period tests.

  • Sub-step 1: Deploy a test contract that calls the protocol to open a large leveraged position.
  • Sub-step 2: Use a mock oracle to drop the reported price by 35% in a single block.
  • Sub-step 3: Call the liquidatePosition function and record gas usage and success/failure.
solidity
// Example: Mocking a Chainlink price drop in Foundry vm.mockCall( oracleAddress, abi.encodeWithSelector(AggregatorV3Interface.latestRoundData.selector), abi.encode(0, 150000000000, 0, block.timestamp, 0) // $1,500 price );

Tip: Log all transaction hashes and contract state changes to a file for later analysis.

4

Analyze Failure Points and Resource Exhaustion

Identify where the protocol breaks, focusing on gas, liquidity, and logic limits.

Detailed Instructions

Post-execution, analyze the data for breaking points. Did the gas cost for liquidations exceed the block gas limit? Did the collateral pool become insolvent? Check for oracle manipulation susceptibility by testing minimum update intervals. Examine the health of the insurance or treasury fund after absorbing losses. A critical metric is the maximum extractable value (MEV) available to liquidators; if it's negative, liquidations won't occur. Look for reverts in core functions and analyze error messages. Use trace calls to see if internal state updates completed correctly or left the system in an inconsistent state.

  • Sub-step 1: Query the protocol's bad debt variable after the stress test concludes.
  • Sub-step 2: Use Ethpector or Tenderly to trace a failed liquidation and identify the revert reason.
  • Sub-step 3: Calculate the gas used in critical functions during peak congestion.
solidity
// Querying a hypothetical bad debt variable uint256 badDebt = vault.badDebt(); require(badDebt == 0, "Protocol has accrued bad debt");

Tip: Compare gas usage against current network conditions (e.g., 30M gas block limit) to assess feasibility.

5

Document Findings and Recommend Mitigations

Synthesize results into a report that outlines vulnerabilities and proposed solutions.

Detailed Instructions

Compile all observations into a structured report. For each identified failure mode, provide a severity assessment (High, Medium, Low) based on likelihood and impact. Detail the exact steps to reproduce the issue. Propose concrete mitigation strategies. For example, if liquidations failed due to gas costs, recommend a circuit breaker or a partial liquidation mechanism. If oracle latency was an issue, suggest adding a multi-oracle system with a staleness check. Include code snippets for potential fixes. The report should enable developers to prioritize and implement changes that enhance the protocol's economic security and resilience.

  • Sub-step 1: Create a table summarizing each vulnerability, its trigger, and outcome.
  • Sub-step 2: For a high-severity finding, draft a pseudo-code patch for the vulnerable function.
  • Sub-step 3: Suggest parameter adjustments, like increasing the minimum collateral ratio from 110% to 120%.
solidity
// Example: A simple circuit breaker modifier modifier circuitBreaker() { require(!tradingPaused, "Trading halted"); _; }

Tip: Frame recommendations in the context of trade-offs, such as between safety and capital efficiency.

Testing by Protocol Type

Core Testing Focus for Perps

Funding rate mechanisms and liquidation engines are the primary attack vectors. Stress tests must simulate extreme volatility to validate the funding payment calculations that maintain the peg to the underlying index price. The liquidation logic, including the health factor calculation and the auction or keeper-based process, must be tested under high gas price scenarios to prevent cascading failures.

Key Attack Scenarios

  • Funding rate manipulation: Simulate low-liquidity conditions where a large position can skew the premium index, triggering unsustainable funding payments for one side.
  • Oracle latency exploitation: Test the protocol's behavior when oracle updates are delayed during a flash crash, potentially allowing underwater positions to avoid liquidation.
  • Liquidation congestion: Model network congestion to see if keepers are incentivized to liquidate positions when gas costs exceed potential profits, risking protocol insolvency.

Example: dYdX or GMX

A robust test would involve creating a market with skewed open interest, then simulating a 30% price drop in 3 blocks. The test must verify that the liquidation system correctly identifies and processes all undercollateralized positions before the protocol's insurance fund is depleted, and that the funding rate adjusts appropriately to rebalance the market.

Tools and Frameworks

Comparison of tools for load generation and protocol simulation.

Tool / MetricGanache (Fork)Foundry / ForgeTenderly SimulationsChaos Mesh

Primary Use Case

Local mainnet fork for replay

Smart contract testing & fuzzing

Gas estimation & transaction simulation

Kubernetes-based chaos engineering

Max TPS (Theoretical)

~100-150 (single instance)

Limited by local hardware

API rate-limited

Infrastructure-dependent

State Management

In-memory snapshot

In-memory / anvil state

Cloud-based ephemeral forks

Live pod injection

Custom Transaction Scripting

Manual via web3 libs

Native via Solidity/DScript

REST API & SDK calls

YAML manifest definitions

Network Fault Injection

Manual node stop/start

vm.rollback, vm.mockCall

Simulate revert conditions & mempool

Pod kill, network latency, I/O faults

Integration Complexity

Low (standard RPC)

Medium (requires test setup)

Low (web3 provider wrapper)

High (K8s cluster required)

Cost for Heavy Load

Free (local compute)

Free (local compute)

Tiered pricing per simulation

Free (self-hosted), cloud service fees

risk_scenarios

Critical Risk Scenarios to Model

Effective stress testing requires simulating extreme but plausible market events to evaluate protocol solvency and liquidation mechanisms under duress.

01

Volatility Shock & Oracle Failure

Black Swan volatility combined with oracle lag or manipulation. Simulate a 50%+ price drop in a major collateral asset within minutes while oracles report stale data. This tests the robustness of price feeds, the safety margins of perpetual futures, and the speed of liquidation cascades before positions can be updated.

02

Liquidity Crunch & Slippage

Extreme slippage in underlying AMMs or lending pools during mass liquidations. Model a scenario where the primary DEX for a collateral asset experiences 20%+ slippage, rendering liquidation bots unprofitable and causing bad debt to accumulate. This validates the protocol's reliance on deep, resilient liquidity sources.

03

Funding Rate Manipulation

Sustained negative funding attacks on perpetual contracts. Test a scenario where a large actor intentionally drives funding rates deeply negative to extract value from longs, potentially destabilizing the equilibrium between long and short positions and testing the protocol's funding rate caps and circuit breakers.

04

Counterparty Concentration Risk

Single-point failure from a dominant trader or LP. Model the insolvency of a whale holding 30% of open interest or providing critical liquidity. This assesses the impact on the protocol's insurance fund, the potential for socialized losses, and the effectiveness of position size limits and diversification incentives.

05

Smart Contract & Economic Exploit

Logic flaw discovery during market stress. Simulate a scenario where an attacker identifies a vulnerability in the margin accounting or fee distribution mechanism during high volatility. This tests the protocol's pause mechanisms, governance response time, and the sufficiency of treasury reserves for covering exploited funds.

06

Cross-Protocol Contagion

Cascading failure from a correlated DeFi protocol. Model the depegging of a major stablecoin or the insolvency of a large lending protocol that shares collateral assets. This evaluates the isolation of risk modules and the impact of correlated liquidations across the interconnected DeFi ecosystem on your derivatives vaults.

Analyzing Results and Reporting

Process for interpreting test data and creating actionable reports.

1

Aggregate and Normalize Test Data

Collect outputs from all test scenarios into a unified dataset.

Detailed Instructions

Consolidate logs from your load generators, blockchain nodes (e.g., local Geth/Erigon), and monitoring dashboards (Grafana, Tenderly). The key is to normalize timestamps to a single source (like the test coordinator's clock) to correlate events. Extract critical metrics: transaction success/failure rates, average gas used per function call, block inclusion latency, and the protocol's internal state (e.g., oracle price staleness, cumulative PnL). For derivative-specific tests, track the funding rate deviation and liquidation efficiency under load. Store this data in a structured format (CSV, Parquet) or a time-series database (InfluxDB) for analysis.

  • Sub-step 1: Parse RPC logs for transaction receipts and calculate success rates per scenario.
  • Sub-step 2: Extract gas usage metrics and correlate with specific contract functions like executeTrade or updateFundingRate.
  • Sub-step 3: Query node metrics for mempool depth and block gas used percentage during peak load.
python
# Example: Parsing transaction receipts from a test log import json success_count = 0 total_tx = 0 with open('tx_receipts.json') as f: for line in f: receipt = json.loads(line) total_tx += 1 if receipt.get('status') == '0x1': success_count += 1 print(f"Success Rate: {success_count/total_tx:.2%}")

Tip: Use a unique nonce or transaction tag in your test client to easily filter and group transactions by test scenario.

2

Identify Performance Bottlenecks and Failures

Analyze the normalized data to locate system limits and failure modes.

Detailed Instructions

Systematically review the aggregated data to pinpoint bottlenecks. Look for inflection points where metrics degrade, such as a drop in TPS when simulated open interest reaches a specific threshold. Analyze failure modes: are transactions reverting due to slippage tolerance, insufficient margin, or hitting gas limits? Examine contract event logs for errors like PriceStale or LiquidationInsufficient. A critical failure mode for derivatives is oracle latency causing incorrect mark prices; check the timestamp delta between price updates and trade executions. Use visualization (e.g., plotting latency vs. load) to identify non-linear scaling. Document any state corruption, such as an incorrect cumulative funding payment that doesn't reset after a cycle.

  • Sub-step 1: Graph transaction latency against concurrent user count to find the throughput ceiling.
  • Sub-step 2: Filter for reverted transactions and group by revert reason string from trace calls.
  • Sub-step 3: Calculate the deviation between the test oracle feed and the protocol's internal price during high-frequency trades.
javascript
// Example: Filtering for specific revert reasons in Hardhat traces const receipts = await provider.send("eth_getTransactionReceipt", [txHash]); if (receipts.status === '0x0') { const trace = await network.provider.send("debug_traceTransaction", [txHash]); const revertReason = trace.structLogs.find(log => log.op === 'REVERT'); console.log("Revert Opcode Data:", revertReason); }

Tip: Correlate high gas prices with periods of network congestion to distinguish protocol limits from base-layer issues.

3

Benchmark Against Requirements and Prior Runs

Compare observed performance with predefined targets and historical data.

Detailed Instructions

Evaluate the results against the success criteria defined in your test plan, such as "99% of liquidations must execute within 5 blocks under 500 TPS." Create a comparison table showing target vs. actual for key performance indicators (KPIs): throughput, latency, and cost (gas). For regression analysis, compare metrics with results from previous test runs or a known baseline (e.g., mainnet fork state). This highlights improvements or degradations. Pay special attention to economic security benchmarks; for example, ensure the protocol's solvency was maintained and that the insurance fund or liquidity pool did not become undercollateralized during stress. Calculate the maximum drawdown or value at risk (VaR) observed during the test.

  • Sub-step 1: Tabulate KPIs: Target TPS, Actual TPS, Max Latency, 95th Percentile Gas Cost.
  • Sub-step 2: Overlay current and historical latency distributions on the same chart to spot regressions.
  • Sub-step 3: Verify that all invariant checks (e.g., total assets >= total liabilities) held true throughout the test duration.
solidity
// Example: An invariant check that could be logged during the test function checkSolvencyInvariant() public view returns (bool) { uint256 totalCollateral = vault.totalAssets(); uint256 totalDebt = perpsMarket.totalOpenInterestNotional(); // Assume a 1:1 collateralization requirement for simplicity return totalCollateral >= totalDebt; }

Tip: Automate this benchmarking step in your CI/CD pipeline to fail builds if performance degrades beyond a threshold.

4

Compile Findings into an Actionable Report

Synthesize analysis into a structured document for stakeholders and developers.

Detailed Instructions

Create a final report that translates raw data into actionable insights. Structure it with an executive summary, methodology, detailed results, and prioritized recommendations. The summary should state whether the protocol met its stress test goals. In the results section, use clear visualizations: graphs of load vs. latency, tables of failure rates, and screenshots of dashboard alerts. For each identified issue (e.g., "Oracle update function gas cost exceeds block limit under congestion"), provide a root cause analysis and a severity rating (Critical, High, Medium). Recommendations must be specific: "Optimize the updatePrice function by caching external calls" or "Increase the keeper incentive for liquidations by 15%." Include raw data appendices or links to queryable databases for auditability.

  • Sub-step 1: Draft the executive summary, clearly stating pass/fail status against primary objectives.
  • Sub-step 2: Create a dedicated section for critical failures with trace IDs and block numbers for reproducibility.
  • Sub-step 3: List recommendations with clear owners (e.g., Smart Contract Team, DevOps) and estimated effort.
markdown
## Example Report Section: Critical Finding **Title:** Liquidation Bot Timeout Under Network Congestion **Severity:** High **Observation:** 40% of liquidation calls reverted with 'out of gas' when base fee > 150 gwei. **Root Cause:** The `liquidatePosition` function performs redundant storage reads. **Recommendation:** Refactor to use memory variables for repeated state access. Assign to: Smart Contract Team. Effort: S (1-2 days).

Tip: Use a consistent report template across all stress tests to enable longitudinal tracking of protocol resilience.

Frequently Asked Questions

Stress testing focuses on liquidation cascades and oracle manipulation. A cascade occurs when a price drop triggers liquidations, forcing the sale of collateral and depressing prices further, potentially causing protocol insolvency. Funding rate arbitrage exploits can drain protocol reserves if funding mechanisms are flawed. Testing must also simulate extreme volatility and network congestion to assess how delayed transactions affect position management and margin calls. For example, a 40% single-day price drop in a volatile asset like AVAX should not collapse a well-designed perpetual futures protocol.