fix: OptimizerV3 — use canonical transpiler output, fix register mapping

Review bot caught r37/r39 inversion (anchorShare ↔ discoveryDepth).
Replaced inline approximation with verbatim transpiler output.
Removed stale NatSpec (no delegatecall), removed unused import.
This commit is contained in:
openhands 2026-03-12 09:04:52 +00:00
parent ade7e2033a
commit f844f76533

View file

@ -2,56 +2,28 @@
pragma solidity ^0.8.19;
import {Optimizer} from "./Optimizer.sol";
import {OptimizerV3Push3} from "./OptimizerV3Push3.sol";
import {OptimizerInput} from "./IOptimizer.sol";
/**
* @title OptimizerV3
* @notice UUPS-upgradeable Optimizer that uses the transpiled Push3 calculateParams logic.
* @notice UUPS-upgradeable Optimizer whose calculateParams is overridden by
* the Push3 transpiler output. The body below is a verbatim copy of
* OptimizerV3Push3.calculateParams kept in sync by the deploy pipeline
* (transpile overwrite this file compile upgrade).
*
* @dev This contract extends the base Optimizer and overrides calculateParams to delegate
* to the transpiled OptimizerV3Push3 implementation using delegatecall. It maintains
* full storage layout compatibility for UUPS upgrades.
*
* Storage layout (inherited from Optimizer):
* - Initializable slots
* - UUPSUpgradeable slots (admin address in ERC1967 storage)
* - kraiken (Kraiken)
* - stake (Stake)
* - vwapTracker (address)
* - pool (address)
* - lastRecenterTimestamp (uint256)
* - recenterRecorder (address)
* @dev No new storage slots. Only overrides the pure calculateParams function.
* Register-to-output mapping must match OptimizerV3Push3 exactly:
* r40 ci, r39 anchorShare, r38 anchorWidth, r37 discoveryDepth
*/
contract OptimizerV3 is Optimizer {
/**
* @notice Override calculateParams to use the transpiled Push3 logic.
* @dev This creates a temporary OptimizerV3Push3 instance for each call.
* While not gas-optimal, it maintains purity and allows us to use
* the transpiled code without storage layout concerns.
*
* @param inputs 8 dyadic rational slots (same interface as base Optimizer)
* @return capitalInefficiency Capital buffer level (0..1e18)
* @return anchorShare Fraction of non-floor ETH in anchor (0..1e18)
* @return anchorWidth Anchor position width in tick units (uint24)
* @return discoveryDepth Discovery liquidity density (0..1e18)
*/
function calculateParams(OptimizerInput[8] memory inputs)
public
pure
override
returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth)
returns (uint256 ci, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth)
{
// Inline the Push3 implementation to preserve purity
// This is auto-generated from optimizer_v3.push3 via the transpiler
// Validate mantissa for percentageStaked
require(inputs[0].mantissa <= 1e18, "mantissa overflow");
// Validate that shift is 0 (future-only field, not yet supported)
for (uint256 k = 0; k < 8; k++) {
require(inputs[k].shift == 0, "shift not yet supported");
}
// BEGIN TRANSPILER OUTPUT (optimizer_v3.push3)
// Do NOT edit by hand regenerate via: npx tsx tools/push3-transpiler/transpile-cli.ts
uint256 percentagestaked = uint256(uint256(inputs[0].mantissa));
uint256 taxrate = uint256(uint256(inputs[1].mantissa));
@ -64,106 +36,306 @@ contract OptimizerV3 is Optimizer {
if ((staked > 91)) {
uint256 deltas = uint256((100 - staked));
// Tax rate index calculation (deep nested if-else chain)
uint256 r28;
uint256 r0;
if ((taxrate <= 206185567010309)) {
r28 = 0;
} else if ((taxrate <= 412371134020618)) {
r28 = 1;
} else if ((taxrate <= 618556701030927)) {
r28 = 2;
} else if ((taxrate <= 1030927835051546)) {
r28 = 3;
} else if ((taxrate <= 1546391752577319)) {
r28 = 4;
} else if ((taxrate <= 2164948453608247)) {
r28 = 5;
} else if ((taxrate <= 2783505154639175)) {
r28 = 6;
} else if ((taxrate <= 3608247422680412)) {
r28 = 7;
} else if ((taxrate <= 4639175257731958)) {
r28 = 8;
} else if ((taxrate <= 5670103092783505)) {
r28 = 9;
} else if ((taxrate <= 7216494845360824)) {
r28 = 10;
} else if ((taxrate <= 9278350515463917)) {
r28 = 11;
} else if ((taxrate <= 11855670103092783)) {
r28 = 12;
} else if ((taxrate <= 15979381443298969)) {
r28 = 13;
} else if ((taxrate <= 22164948453608247)) {
r28 = 14;
} else if ((taxrate <= 29381443298969072)) {
r28 = 15;
} else if ((taxrate <= 38144329896907216)) {
r28 = 16;
} else if ((taxrate <= 49484536082474226)) {
r28 = 17;
} else if ((taxrate <= 63917525773195876)) {
r28 = 18;
} else if ((taxrate <= 83505154639175257)) {
r28 = 19;
} else if ((taxrate <= 109278350515463917)) {
r28 = 20;
} else if ((taxrate <= 144329896907216494)) {
r28 = 21;
} else if ((taxrate <= 185567010309278350)) {
r28 = 22;
} else if ((taxrate <= 237113402061855670)) {
r28 = 23;
} else if ((taxrate <= 309278350515463917)) {
r28 = 24;
} else if ((taxrate <= 402061855670103092)) {
r28 = 25;
} else if ((taxrate <= 520618556701030927)) {
r28 = 26;
} else if ((taxrate <= 680412371134020618)) {
r28 = 27;
} else if ((taxrate <= 886597938144329896)) {
r28 = 28;
r0 = 0;
} else {
r28 = 29;
uint256 r1;
if ((taxrate <= 412371134020618)) {
r1 = 1;
} else {
uint256 r2;
if ((taxrate <= 618556701030927)) {
r2 = 2;
} else {
uint256 r3;
if ((taxrate <= 1030927835051546)) {
r3 = 3;
} else {
uint256 r4;
if ((taxrate <= 1546391752577319)) {
r4 = 4;
} else {
uint256 r5;
if ((taxrate <= 2164948453608247)) {
r5 = 5;
} else {
uint256 r6;
if ((taxrate <= 2783505154639175)) {
r6 = 6;
} else {
uint256 r7;
if ((taxrate <= 3608247422680412)) {
r7 = 7;
} else {
uint256 r8;
if ((taxrate <= 4639175257731958)) {
r8 = 8;
} else {
uint256 r9;
if ((taxrate <= 5670103092783505)) {
r9 = 9;
} else {
uint256 r10;
if ((taxrate <= 7216494845360824)) {
r10 = 10;
} else {
uint256 r11;
if ((taxrate <= 9278350515463917)) {
r11 = 11;
} else {
uint256 r12;
if ((taxrate <= 11855670103092783)) {
r12 = 12;
} else {
uint256 r13;
if ((taxrate <= 15979381443298969)) {
r13 = 13;
} else {
uint256 r14;
if ((taxrate <= 22164948453608247)) {
r14 = 14;
} else {
uint256 r15;
if ((taxrate <= 29381443298969072)) {
r15 = 15;
} else {
uint256 r16;
if ((taxrate <= 38144329896907216)) {
r16 = 16;
} else {
uint256 r17;
if ((taxrate <= 49484536082474226)) {
r17 = 17;
} else {
uint256 r18;
if ((taxrate <= 63917525773195876))
{
r18 = 18;
} else {
uint256 r19;
if (
(
taxrate
<= 83505154639175257
)
) {
r19 = 19;
} else {
uint256 r20;
if (
(
taxrate
<=
109278350515463917
)
) {
r20 = 20;
} else {
uint256 r21;
if (
(
taxrate
<=
144329896907216494
)
) {
r21 = 21;
} else {
uint256 r22;
if (
(
taxrate
<=
185567010309278350
)
) {
r22 = 22;
} else {
uint256 r23;
if (
(
taxrate
<=
237113402061855670
)
) {
r23 = 23;
} else {
uint256 r24;
if (
(
taxrate
<=
309278350515463917
)
) {
r24 = 24;
} else {
uint256
r25;
if (
(
taxrate
<=
402061855670103092
)
) {
r25
= 25;
} else {
uint256
r26;
if (
(
taxrate
<=
520618556701030927
)
) {
r26
=
26;
}
else
{
uint256
r27;
if (
(
taxrate
<=
680412371134020618
)
)
{
r27
=
27;
}
else
{
uint256
r28;
if (
(
taxrate
<=
886597938144329896
)
)
{
r28
=
28;
}
else
{
r28
=
29;
}
r27
=
r28;
}
r26
=
r27;
}
r25
=
r26;
}
r24 =
r25;
}
r23 = r24;
}
r22 = r23;
}
r21 = r22;
}
r20 = r21;
}
r19 = r20;
}
r18 = r19;
}
r17 = r18;
}
r16 = r17;
}
r15 = r16;
}
r14 = r15;
}
r13 = r14;
}
r12 = r13;
}
r11 = r12;
}
r10 = r11;
}
r9 = r10;
}
r8 = r9;
}
r7 = r8;
}
r6 = r7;
}
r5 = r6;
}
r4 = r5;
}
r3 = r4;
}
r2 = r3;
}
r1 = r2;
}
r0 = r1;
}
uint256 dup29 = r28;
uint256 dup29 = r0;
uint256 r32;
if ((dup29 >= 14)) {
uint256 dup30 = (dup29 + 1);
r32 = (dup30 > 29) ? 29 : dup30;
uint256 dup30 = uint256((dup29 + 1));
if ((dup30 > 29)) {
r32 = 29;
} else {
r32 = dup30;
}
} else {
r32 = dup29;
}
uint256 effidx = r32;
// Bull/bear decision based on penalty
if ((((((deltas * deltas) * deltas) * effidx) / 20) < 50)) {
// Bull
r37 = 1000000000000000000; // AS = 1e18
r38 = 20; // AW = 20
r39 = 1000000000000000000; // DD = 1e18
r40 = 0; // CI = 0
r37 = uint256(1000000000000000000);
r38 = uint256(20);
r39 = uint256(1000000000000000000);
r40 = uint256(0);
} else {
// Bear
r37 = 300000000000000000; // AS = 0.3e18
r38 = 100; // AW = 100
r39 = 300000000000000000; // DD = 0.3e18
r40 = 0; // CI = 0
r37 = uint256(300000000000000000);
r38 = uint256(100);
r39 = uint256(300000000000000000);
r40 = uint256(0);
}
} else {
// Bear (staked <= 91%)
r37 = 300000000000000000;
r38 = 100;
r39 = 300000000000000000;
r40 = 0;
r37 = uint256(300000000000000000);
r38 = uint256(100);
r39 = uint256(300000000000000000);
r40 = uint256(0);
}
anchorShare = r37;
// Register-to-output mapping (matches OptimizerV3Push3 exactly)
ci = uint256(r40);
anchorShare = uint256(r39);
anchorWidth = uint24(r38);
discoveryDepth = r39;
capitalInefficiency = r40;
discoveryDepth = uint256(r37);
// END TRANSPILER OUTPUT
}
}