- Add PositionTracker.sol: tracks position lifecycle (open/close per recenter), records tick ranges, liquidity, entry/exit blocks/timestamps, token amounts (via LiquidityAmounts math), fees (proportional to liquidity share), IL (LP exit value − HODL value at exit price), and net P&L per position. Aggregates total fees, cumulative IL, net P&L, rebalance count, Anchor time-in-range, and capital efficiency accumulators. Logs with [TRACKER][TYPE] prefix; emits cumulative P&L every 500 blocks. - Modify StrategyExecutor.sol: add IUniswapV3Pool + token0isWeth to constructor (creates PositionTracker internally), call tracker.notifyBlock() on every block for time-in-range, and call tracker.recordRecenter() on each successful recenter. logSummary() now delegates to tracker.logFinalSummary(). - Modify BacktestRunner.s.sol: pass sp.pool and token0isWeth to StrategyExecutor constructor; log tracker address. - forge fmt: reformat all backtesting scripts and affected src/test files to project style (number_underscore=thousands, multiline_func_header=all). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a491ecb7d9
commit
cfcf750084
12 changed files with 666 additions and 244 deletions
|
|
@ -1,14 +1,15 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { IUniswapV3MintCallback } from "@uniswap-v3-core/interfaces/callback/IUniswapV3MintCallback.sol";
|
||||
import { IUniswapV3SwapCallback } from "@uniswap-v3-core/interfaces/callback/IUniswapV3SwapCallback.sol";
|
||||
import { IUniswapV3Pool } from "@uniswap-v3-core/interfaces/IUniswapV3Pool.sol";
|
||||
import { TickMath } from "@aperture/uni-v3-lib/TickMath.sol";
|
||||
import { Vm } from "forge-std/Vm.sol";
|
||||
import { console2 } from "forge-std/console2.sol";
|
||||
import { MockToken } from "./MockToken.sol";
|
||||
import { StrategyExecutor } from "./StrategyExecutor.sol";
|
||||
import { TickMath } from "@aperture/uni-v3-lib/TickMath.sol";
|
||||
import { IUniswapV3Pool } from "@uniswap-v3-core/interfaces/IUniswapV3Pool.sol";
|
||||
import { IUniswapV3MintCallback } from "@uniswap-v3-core/interfaces/callback/IUniswapV3MintCallback.sol";
|
||||
import { IUniswapV3SwapCallback } from "@uniswap-v3-core/interfaces/callback/IUniswapV3SwapCallback.sol";
|
||||
|
||||
import { Vm } from "forge-std/Vm.sol";
|
||||
import { console2 } from "forge-std/console2.sol";
|
||||
|
||||
/**
|
||||
* @title EventReplayer
|
||||
|
|
@ -107,13 +108,7 @@ contract EventReplayer is IUniswapV3MintCallback, IUniswapV3SwapCallback {
|
|||
_replayWithStrategy(eventsFile, totalEvents, strategyExecutor);
|
||||
}
|
||||
|
||||
function _replayWithStrategy(
|
||||
string memory eventsFile,
|
||||
uint256 totalEvents,
|
||||
StrategyExecutor strategyExecutor
|
||||
)
|
||||
internal
|
||||
{
|
||||
function _replayWithStrategy(string memory eventsFile, uint256 totalEvents, StrategyExecutor strategyExecutor) internal {
|
||||
uint256 idx = 0;
|
||||
|
||||
// Track the last Swap event's expected state for drift measurement.
|
||||
|
|
@ -178,9 +173,8 @@ contract EventReplayer is IUniswapV3MintCallback, IUniswapV3SwapCallback {
|
|||
if (absDrift > maxDrift) maxDrift = absDrift;
|
||||
// Log sqrtPrice deviation when it exceeds ~0.01% (filters rounding noise).
|
||||
if (finalSqrtPrice != lastExpectedSqrtPrice) {
|
||||
uint256 priceDelta = finalSqrtPrice > lastExpectedSqrtPrice
|
||||
? uint256(finalSqrtPrice - lastExpectedSqrtPrice)
|
||||
: uint256(lastExpectedSqrtPrice - finalSqrtPrice);
|
||||
uint256 priceDelta =
|
||||
finalSqrtPrice > lastExpectedSqrtPrice ? uint256(finalSqrtPrice - lastExpectedSqrtPrice) : uint256(lastExpectedSqrtPrice - finalSqrtPrice);
|
||||
if (lastExpectedSqrtPrice > 0 && priceDelta * 10_000 > uint256(lastExpectedSqrtPrice)) {
|
||||
console2.log(" final sqrtPrice divergence:", priceDelta);
|
||||
}
|
||||
|
|
@ -392,14 +386,7 @@ contract EventReplayer is IUniswapV3MintCallback, IUniswapV3SwapCallback {
|
|||
/**
|
||||
* @notice Emit a progress line and accumulate drift statistics for one checkpoint.
|
||||
*/
|
||||
function _logCheckpoint(
|
||||
uint256 idx,
|
||||
uint256 totalEvents,
|
||||
int24 expectedTick,
|
||||
uint160 expectedSqrtPrice
|
||||
)
|
||||
internal
|
||||
{
|
||||
function _logCheckpoint(uint256 idx, uint256 totalEvents, int24 expectedTick, uint160 expectedSqrtPrice) internal {
|
||||
(uint160 currentSqrtPrice, int24 currentTick,,,,,) = pool.slot0();
|
||||
int256 diff = int256(currentTick) - int256(expectedTick);
|
||||
uint256 absDrift = diff >= 0 ? uint256(diff) : uint256(-diff);
|
||||
|
|
@ -425,9 +412,8 @@ contract EventReplayer is IUniswapV3MintCallback, IUniswapV3SwapCallback {
|
|||
|
||||
// Log sqrtPrice deviation when it exceeds ~0.01% (filters rounding noise).
|
||||
if (currentSqrtPrice != expectedSqrtPrice) {
|
||||
uint256 priceDelta = currentSqrtPrice > expectedSqrtPrice
|
||||
? uint256(currentSqrtPrice - expectedSqrtPrice)
|
||||
: uint256(expectedSqrtPrice - currentSqrtPrice);
|
||||
uint256 priceDelta =
|
||||
currentSqrtPrice > expectedSqrtPrice ? uint256(currentSqrtPrice - expectedSqrtPrice) : uint256(expectedSqrtPrice - currentSqrtPrice);
|
||||
if (expectedSqrtPrice > 0 && priceDelta * 10_000 > uint256(expectedSqrtPrice)) {
|
||||
console2.log(" sqrtPrice divergence:", priceDelta);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue