- Analysis: parameter sweep scripts, adversarial testing, 2D frontier maps - Research: KRAIKEN_RESEARCH_REPORT, SECURITY_REVIEW, STORAGE_LAYOUT - FuzzingBase: consolidated fuzzing helper, BackgroundLP simulation - Sweep results: CSV data for full 4D sweep (1050 combos), bull-bear, AS sweep, VWAP fix validation - Code quality: .gitignore for fuzz CSVs, gas snapshot, updated docs - Remove dead analysis helpers (CSVHelper, CSVManager, ScenarioRecorder) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.3 KiB
3.3 KiB
Storage Layout Verification: Optimizer → OptimizerV3 UUPS Upgrade
Date: 2026-02-13 Result: SAFE — storage layout is identical
Inheritance Chain (C3 Linearization)
Both contracts share the same inheritance:
Optimizer/OptimizerV3 → Initializable → UUPSUpgradeable → ERC1967Upgrade
Storage Slot Map
OpenZeppelin Infrastructure (Slot 0)
| Offset | Type | Variable | Size |
|---|---|---|---|
| 0 | uint8 |
_initialized |
1 byte |
| 0 | bool |
_initializing |
1 byte (packed) |
ERC1967Upgrade uses named constant slots (not sequential):
_IMPLEMENTATION_SLOT=0x360894...— proxy implementation pointer_ADMIN_SLOT=0xb53127...— proxy admin address_ROLLBACK_SLOT=0x4910fd...— upgrade rollback check
These do not conflict with sequential storage.
Contract State Variables
| Slot | Type | Variable | Optimizer.sol | OptimizerV3.sol |
|---|---|---|---|---|
| 1 | Kraiken (address) |
kraiken |
Line 37 | Line 29 |
| 2 | Stake (address) |
stake |
Line 38 | Line 30 |
Both contracts declare the same two state variables in the same order with the same types.
Comparison
Optimizer.sol (V1) OptimizerV3.sol
───────────────────── ─────────────────────
Slot 0: _initialized, _initializing Slot 0: _initialized, _initializing
Slot 1: Kraiken private kraiken Slot 1: Kraiken private kraiken
Slot 2: Stake private stake Slot 2: Stake private stake
- No new state variables added in V3
- No variables removed or reordered
- No type changes
- No
__gaparrays needed (both are final implementations, not base contracts)
Function Signature Compatibility
| Function | Optimizer | OptimizerV3 | Compatible |
|---|---|---|---|
initialize(address,address) |
Yes | Yes | Yes |
getLiquidityParams() → (uint256,uint256,uint24,uint256) |
Yes | Yes | Yes |
_authorizeUpgrade(address) |
Yes | Yes | Yes |
calculateSentiment(uint256,uint256) |
Yes | No (removed) | N/A (internal) |
isBullMarket(uint256,uint256) |
No | Yes (new) | N/A (additive) |
The critical external interface (getLiquidityParams) is identical. New functions are additive and don't affect storage.
Upgrade Path
1. Deploy OptimizerV3 implementation contract
2. Call UUPSUpgradeable(proxy).upgradeTo(newImpl)
3. No re-initialization needed (storage persists)
4. Verify: call getLiquidityParams() through proxy → returns V3 binary bear/bull params
The UpgradeOptimizer.sol script at script/UpgradeOptimizer.sol implements this correctly and includes post-upgrade verification.
OptimizerV2 (Intermediate Version)
OptimizerV2.sol also has identical storage layout (same two variables: kraiken, stake). The full upgrade chain Optimizer → OptimizerV2 → OptimizerV3 is safe at every step.
Conclusion
UUPS Upgrade: APPROVED
- Storage layout: identical across all optimizer versions
- Proxy infrastructure: preserved (initialization flags, admin slot)
- No re-initialization required
- The only change is the algorithm inside
getLiquidityParams()— from sentiment-score interpolation to direct 2D binary mapping