diff --git a/onchain/test/FitnessEvaluator.t.sol b/onchain/test/FitnessEvaluator.t.sol index 20cdf40..2fc5052 100644 --- a/onchain/test/FitnessEvaluator.t.sol +++ b/onchain/test/FitnessEvaluator.t.sol @@ -43,7 +43,6 @@ import { UUPSUpgradeable } from "@openzeppelin/proxy/utils/UUPSUpgradeable.sol"; import { IERC20 } from "@openzeppelin/token/ERC20/IERC20.sol"; import { IUniswapV3Factory } from "@uniswap-v3-core/interfaces/IUniswapV3Factory.sol"; import { IUniswapV3Pool } from "@uniswap-v3-core/interfaces/IUniswapV3Pool.sol"; -import { FullMath } from "@aperture/uni-v3-lib/FullMath.sol"; import { LiquidityAmounts } from "@aperture/uni-v3-lib/LiquidityAmounts.sol"; import { TickMath } from "@aperture/uni-v3-lib/TickMath.sol"; import { UniswapHelpers } from "../src/helpers/UniswapHelpers.sol"; @@ -561,8 +560,9 @@ contract FitnessEvaluator is Test { // ─── Score computation ──────────────────────────────────────────────────── /** - * @notice Compute lm_eth_total = free ETH + free WETH + sum(position ETH values). - * Mirrors AttackRunner._logSnapshot's lm_eth_total calculation. + * @notice Compute lm_eth_total = free ETH + free WETH + sum(WETH in each position). + * Only counts real ETH reserves — KRK token value is excluded to prevent + * evolution from gaming the metric by inflating token price through positioning. */ function _computeLmEthTotal() internal view returns (uint256) { (uint160 sqrtPriceX96,,,,,,) = pool.slot0(); @@ -576,16 +576,16 @@ contract FitnessEvaluator is Test { return lmEthFree + lmWethFree - + _positionEthValue(sqrtPriceX96, fLo, fHi, fLiq) - + _positionEthValue(sqrtPriceX96, aLo, aHi, aLiq) - + _positionEthValue(sqrtPriceX96, dLo, dHi, dLiq); + + _positionEthOnly(sqrtPriceX96, fLo, fHi, fLiq) + + _positionEthOnly(sqrtPriceX96, aLo, aHi, aLiq) + + _positionEthOnly(sqrtPriceX96, dLo, dHi, dLiq); } /** - * @notice ETH-equivalent value of a Uniswap V3 position at the current price. - * Copied verbatim from AttackRunner._positionEthValue. + * @notice WETH-only component of a Uniswap V3 position at the current price. + * Ignores KRK token value entirely — counts only the actual ETH backing. */ - function _positionEthValue( + function _positionEthOnly( uint160 sqrtPriceX96, int24 tickLower, int24 tickUpper, @@ -601,21 +601,7 @@ contract FitnessEvaluator is Test { (uint256 amount0, uint256 amount1) = LiquidityAmounts.getAmountsForLiquidity(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, liquidity); - uint256 ethAmount = token0isWeth ? amount0 : amount1; - uint256 krkAmount = token0isWeth ? amount1 : amount0; - - if (krkAmount == 0 || sqrtPriceX96 == 0) return ethAmount; - - uint256 krkInEth; - if (token0isWeth) { - // token0=WETH, token1=KRK: 1 KRK = 2^192 / sqrtP^2 WETH - krkInEth = FullMath.mulDiv(FullMath.mulDiv(krkAmount, 1 << 96, sqrtPriceX96), 1 << 96, sqrtPriceX96); - } else { - // token0=KRK, token1=WETH: 1 KRK = sqrtP^2 / 2^192 WETH - krkInEth = FullMath.mulDiv(FullMath.mulDiv(krkAmount, sqrtPriceX96, 1 << 96), sqrtPriceX96, 1 << 96); - } - - return ethAmount + krkInEth; + return token0isWeth ? amount0 : amount1; } // ─── Utilities ────────────────────────────────────────────────────────────