Merge pull request 'fix: fix: Fitness metric should measure ETH only, not token value (#670)' (#677) from fix/issue-670 into master

This commit is contained in:
johba 2026-03-13 10:39:17 +01:00
commit 8b1d1ce146

View file

@ -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