marginal price views

This commit is contained in:
tim
2025-09-20 16:18:41 -04:00
parent 10d432070d
commit cd663105f4
3 changed files with 97 additions and 0 deletions

View File

@@ -778,6 +778,51 @@ library LMSRStabilized {
return e_i_acc.div(Z);
}
/// @notice Marginal price of `base` in terms of `quote` (p_quote / p_base) as Q64.64
/// @dev Returns exp((q_quote - q_base) / b). Indices must be valid and b > 0.
function price(State storage s, uint256 baseTokenIndex, uint256 quoteTokenIndex) internal view returns (int128) {
require(baseTokenIndex < s.nAssets && quoteTokenIndex < s.nAssets, "LMSR: idx");
int128 b = _computeB(s);
require(b > int128(0), "LMSR: b<=0");
// Use reciprocal of b to avoid repeated divisions
int128 invB = ABDKMath64x64.div(ONE, b);
// Marginal price p_quote / p_base = exp((q_quote - q_base) / b)
return _exp(s.qInternal[quoteTokenIndex].sub(s.qInternal[baseTokenIndex]).mul(invB));
}
/// @notice Price of one unit of the LP size-metric (S = sum q_i) denominated in `quote` asset (Q64.64)
/// @dev Computes: poolPrice_quote = (1 / S) * sum_j q_j * exp((q_j - q_quote) / b)
function poolPrice(State storage s, uint256 quoteTokenIndex) internal view returns (int128) {
require(quoteTokenIndex < s.nAssets, "LMSR: idx");
// Compute b and ensure positivity
int128 b = _computeB(s);
require(b > int128(0), "LMSR: b<=0");
// Compute total size metric S = sum q_i
int128 S = _computeSizeMetric(s.qInternal);
require(S > int128(0), "LMSR: size zero");
// Precompute reciprocal of b
int128 invB = ABDKMath64x64.div(ONE, b);
// Accumulate weighted exponentials: sum_j q_j * exp((q_j - q_quote) / b)
int128 acc = int128(0);
uint256 n = s.nAssets;
for (uint256 j = 0; j < n; ) {
// factor = exp((q_j - q_quote) / b)
int128 factor = _exp(s.qInternal[j].sub(s.qInternal[quoteTokenIndex]).mul(invB));
// term = q_j * factor
int128 term = s.qInternal[j].mul(factor);
acc = acc.add(term);
unchecked { j++; }
}
// pool price in units of quote = (1 / S) * acc
return acc.div(S);
}
/* --------------------
Slippage -> b computation & resize-triggered rescale
-------------------- */