harb/onchain/test/mocks/MaliciousOptimizer.sol
johba 2c69963151 feat: Add scenario recording and replay system for invariant debugging
Implements comprehensive fuzzing improvements to find and reproduce invariant violations:

Recording System:
- ScenarioRecorder captures exact trading sequences that violate invariants
- Exports to JSON, replay scripts, and human-readable summaries
- Unique Run IDs (format: YYMMDD-XXXX) for easy communication

Enhanced Fuzzing:
- ImprovedFuzzingAnalysis with larger trades (50-500 ETH) to reach discovery position
- Multiple strategies: Discovery Push, Whale Manipulation, Volatile Swings
- Successfully finds profitable scenarios with 66% success rate

Shell Scripts:
- run-recorded-fuzzing.sh: Automated fuzzing with recording and unique IDs
- replay-scenario.sh: One-command replay of specific scenarios

New Optimizers:
- ExtremeOptimizer: Tests extreme market conditions
- MaliciousOptimizer: Attempts to exploit the protocol

Documentation:
- Updated CLAUDE.md with complete recording workflow
- Enhanced 4-step debugging process
- Quick reference for team collaboration

This system successfully identifies and reproduces the discovery position exploit,
where traders can profit by pushing trades into the unused liquidity at extreme ticks.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 20:31:39 +02:00

62 lines
No EOL
2 KiB
Solidity

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.19;
/**
* @title MaliciousOptimizer
* @notice Intentionally returns parameters that should break the protocol
* @dev Used to find edge cases where the LiquidityManager becomes exploitable
*/
contract MaliciousOptimizer {
uint256 private callCount;
function getOptimalParameters(
uint256, // percentageStaked
uint256, // avgTaxRate
uint256 // sentiment
) external returns (uint256, uint256, uint256, uint256) {
callCount++;
// Return parameters that should cause problems:
// 1. First call: All liquidity in floor (no anchor protection)
if (callCount == 1) {
return (
0, // 0% capital inefficiency (minimum KRAIKEN value)
0, // 0% anchor share (100% to floor)
1, // Minimal width
0 // No discovery
);
}
// 2. Second call: Suddenly switch to all anchor (no floor protection)
if (callCount == 2) {
return (
1e18, // 100% capital inefficiency (maximum KRAIKEN value)
1e18, // 100% anchor share (0% to floor)
100, // Maximum width
0 // No discovery
);
}
// 3. Third call: Create huge discovery position
if (callCount == 3) {
return (
0.5e18, // 50% capital inefficiency
0.1e18, // 10% anchor share
10, // Small width
100e18 // Massive discovery depth
);
}
// 4. Oscillate wildly
return (
callCount % 2 == 0 ? 0 : 1e18,
callCount % 2 == 0 ? 0 : 1e18,
callCount % 2 == 0 ? 1 : 100,
callCount % 2 == 0 ? 0 : 10e18
);
}
function calculateSentiment(uint256, uint256) public pure returns (uint256) {
return 0;
}
}