fix: address review feedback on PositionTracker and StrategyExecutor
- Fix fee attribution: distribute fees only to positions whose tick range contains the active tick at close time (in-range weight), not by raw liquidity. FLOOR is priced far below current tick and rarely earns fees; the old approach would over-credit it and corrupt capital-efficiency and net-P&L numbers. Fallback to raw-liquidity weighting with a WARN log when no position is in range. - Warn on first-close skip: when _closePosition finds no open record (first recenter, before any tracking), log [TRACKER][WARN] instead of silently returning so the gap is visible in reports. - Add tick range assertion: require() that the incoming close snapshot tick range matches the stored open record — a mismatch would mean IL is computed across different ranges (apples vs oranges). - Fix finalBlock accuracy: logSummary now calls tracker.logFinalSummary(tracker.lastNotifiedBlock()) instead of lastRecenterBlock, so the summary reflects the actual last replay block rather than potentially hundreds of blocks early. - Initialize lastRecenterBlock = block.number in StrategyExecutor constructor to defer the first recenter attempt by recenterInterval blocks and document the invariant. - Extract shared FormatLib: _str(uint256) and _istr(int256) were copy-pasted in both PositionTracker and StrategyExecutor. Extracted to FormatLib.sol internal library; both contracts now use `using FormatLib`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cfcf750084
commit
cf8e7ee6ee
3 changed files with 159 additions and 106 deletions
33
onchain/script/backtesting/FormatLib.sol
Normal file
33
onchain/script/backtesting/FormatLib.sol
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
/**
|
||||
* @title FormatLib
|
||||
* @notice Shared integer-to-string formatting helpers for backtesting log output.
|
||||
* Extracted to avoid copy-pasting the same logic across PositionTracker
|
||||
* and StrategyExecutor.
|
||||
*/
|
||||
library FormatLib {
|
||||
/// @notice Format an unsigned integer as a decimal string.
|
||||
function str(uint256 v) internal pure returns (string memory) {
|
||||
if (v == 0) return "0";
|
||||
uint256 tmp = v;
|
||||
uint256 len;
|
||||
while (tmp != 0) {
|
||||
len++;
|
||||
tmp /= 10;
|
||||
}
|
||||
bytes memory buf = new bytes(len);
|
||||
while (v != 0) {
|
||||
buf[--len] = bytes1(uint8(48 + v % 10));
|
||||
v /= 10;
|
||||
}
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
/// @notice Format a signed integer as a decimal string (prefixed with '-' if negative).
|
||||
function istr(int256 v) internal pure returns (string memory) {
|
||||
if (v >= 0) return str(uint256(v));
|
||||
return string.concat("-", str(uint256(-v)));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue