fix: Evolution pipeline UUPS upgrade + Foundry PATH (#593)
- Add virtual to Optimizer.calculateParams() for UUPS override - Create OptimizerV3.sol: UUPS-upgradeable optimizer with transpiled Push3 logic - Update deploy-optimizer.sh to deploy OptimizerV3 instead of Optimizer - Add ~/.foundry/bin to PATH in evolve.sh, fitness.sh, deploy-optimizer.sh
This commit is contained in:
parent
6f3601711b
commit
ade7e2033a
5 changed files with 181 additions and 2 deletions
|
|
@ -245,6 +245,7 @@ contract Optimizer is Initializable, UUPSUpgradeable {
|
|||
function calculateParams(OptimizerInput[8] memory inputs)
|
||||
public
|
||||
pure
|
||||
virtual
|
||||
returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth)
|
||||
{
|
||||
// Extract slots 0 and 1 (shift=0 assumed — mantissa IS the value)
|
||||
|
|
|
|||
169
onchain/src/OptimizerV3.sol
Normal file
169
onchain/src/OptimizerV3.sol
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
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.
|
||||
*
|
||||
* @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)
|
||||
*/
|
||||
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)
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
|
||||
uint256 percentagestaked = uint256(uint256(inputs[0].mantissa));
|
||||
uint256 taxrate = uint256(uint256(inputs[1].mantissa));
|
||||
uint256 staked = uint256(((percentagestaked * 100) / 1000000000000000000));
|
||||
|
||||
uint256 r37;
|
||||
uint256 r38;
|
||||
uint256 r39;
|
||||
uint256 r40;
|
||||
|
||||
if ((staked > 91)) {
|
||||
uint256 deltas = uint256((100 - staked));
|
||||
|
||||
// Tax rate index calculation (deep nested if-else chain)
|
||||
uint256 r28;
|
||||
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;
|
||||
} else {
|
||||
r28 = 29;
|
||||
}
|
||||
|
||||
uint256 dup29 = r28;
|
||||
uint256 r32;
|
||||
if ((dup29 >= 14)) {
|
||||
uint256 dup30 = (dup29 + 1);
|
||||
r32 = (dup30 > 29) ? 29 : 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
|
||||
} else {
|
||||
// Bear
|
||||
r37 = 300000000000000000; // AS = 0.3e18
|
||||
r38 = 100; // AW = 100
|
||||
r39 = 300000000000000000; // DD = 0.3e18
|
||||
r40 = 0; // CI = 0
|
||||
}
|
||||
} else {
|
||||
// Bear (staked <= 91%)
|
||||
r37 = 300000000000000000;
|
||||
r38 = 100;
|
||||
r39 = 300000000000000000;
|
||||
r40 = 0;
|
||||
}
|
||||
|
||||
anchorShare = r37;
|
||||
anchorWidth = uint24(r38);
|
||||
discoveryDepth = r39;
|
||||
capitalInefficiency = r40;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
# Foundry tools (forge, cast, anvil)
|
||||
export PATH="${HOME}/.foundry/bin:${PATH}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Paths
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -269,7 +272,7 @@ step "Deploying new Optimizer implementation for diff preview"
|
|||
|
||||
(
|
||||
cd "$ONCHAIN_DIR"
|
||||
forge create src/Optimizer.sol:Optimizer \
|
||||
forge create src/OptimizerV3.sol:OptimizerV3 \
|
||||
--rpc-url "$RPC_URL" \
|
||||
--private-key "$DEPLOYER_KEY" \
|
||||
--json 2>/dev/null \
|
||||
|
|
@ -278,7 +281,7 @@ step "Deploying new Optimizer implementation for diff preview"
|
|||
)
|
||||
|
||||
NEW_IMPL="$(cat /tmp/new-optimizer-impl.txt 2>/dev/null || echo "")"
|
||||
[ -z "$NEW_IMPL" ] && fail "Failed to deploy new Optimizer implementation"
|
||||
[ -z "$NEW_IMPL" ] && fail "Failed to deploy new OptimizerV3 implementation"
|
||||
info "New implementation deployed at: $NEW_IMPL"
|
||||
|
||||
# calculateSentiment is pure — callable on bare (uninitialized) implementation
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
# Foundry tools (forge, cast, anvil)
|
||||
export PATH="${HOME}/.foundry/bin:${PATH}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
FITNESS_SH="$SCRIPT_DIR/fitness.sh"
|
||||
MUTATE_CLI="$SCRIPT_DIR/mutate-cli.ts"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
# Foundry tools (forge, cast, anvil)
|
||||
export PATH="${HOME}/.foundry/bin:${PATH}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
ONCHAIN_DIR="$REPO_ROOT/onchain"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue