This commit is contained in:
Jakob Notland 2026-03-17 08:53:55 +01:00
parent 5d18524fa3
commit b46271d6bd

View file

@ -528,8 +528,7 @@ mod tests {
// Before fix: end.timestamp = trade_ts (2h after creation)
let period_short = PoolPeriod::new(start.clone(), end_unclamped).unwrap();
let apy_inflated =
APYAggregator::aggregate_apy(std::iter::once(period_short), Some(creation_ts))
.unwrap();
APYAggregator::aggregate_apy(std::iter::once(period_short), Some(creation_ts)).unwrap();
// After fix: end.timestamp = window_end (10 days after creation)
let end_clamped = PoolSnapshot {
@ -538,8 +537,7 @@ mod tests {
};
let period_full = PoolPeriod::new(start, end_clamped).unwrap();
let apy_correct =
APYAggregator::aggregate_apy(std::iter::once(period_full), Some(creation_ts))
.unwrap();
APYAggregator::aggregate_apy(std::iter::once(period_full), Some(creation_ts)).unwrap();
// The inflated APY should be dramatically higher than the corrected one.
// Rough expectation: inflated ≈ 200x the correct value given 10 days vs 2 hours.
@ -569,8 +567,7 @@ mod tests {
// Active pool: real fee income throughout the window.
let active_start = PoolSnapshot::dummy(window_start - 3600, 1_000_000, 500_000);
let active_end = PoolSnapshot::dummy(window_end - 3600, 1_001_000, 499_501);
let active =
PoolPeriod::new(active_start, active_end).unwrap();
let active = PoolPeriod::new(active_start, active_end).unwrap();
let apy_active_only =
APYAggregator::aggregate_apy(std::iter::once(active.clone()), Some(window_start))
.unwrap();
@ -586,11 +583,9 @@ mod tests {
// duration = 0 → PoolPeriod::new is still valid (start == end allowed), but
// the aggregator skips zero-duration periods.
let dormant = PoolPeriod::new(dormant_start, dormant_end).unwrap();
let apy_with_dormant = APYAggregator::aggregate_apy(
vec![active, dormant].into_iter(),
Some(window_start),
)
.unwrap();
let apy_with_dormant =
APYAggregator::aggregate_apy(vec![active, dormant].into_iter(), Some(window_start))
.unwrap();
// The pre-window dormant pool contributes nothing; APY should be unchanged.
assert_eq!(
@ -621,13 +616,10 @@ mod tests {
let last_trade_snap = PoolSnapshot::dummy(last_trade_ts, 1_001_000, 499_501);
// Without fix: end.timestamp = last_trade_ts (5 days short of window_end)
let period_unclamped =
PoolPeriod::new(start.clone(), last_trade_snap.clone()).unwrap();
let apy_unclamped = APYAggregator::aggregate_apy(
std::iter::once(period_unclamped),
Some(window_start),
)
.unwrap();
let period_unclamped = PoolPeriod::new(start.clone(), last_trade_snap.clone()).unwrap();
let apy_unclamped =
APYAggregator::aggregate_apy(std::iter::once(period_unclamped), Some(window_start))
.unwrap();
// With fix: end.timestamp = window_end (5 extra days included)
let end_clamped = PoolSnapshot {
@ -645,7 +637,10 @@ mod tests {
"clamped APY ({apy_clamped}) should be lower than unclamped ({apy_unclamped})"
);
// Both should be positive — there was real fee income
assert!(apy_clamped > dec!(0), "APY should be positive, got {apy_clamped}");
assert!(
apy_clamped > dec!(0),
"APY should be positive, got {apy_clamped}"
);
// The difference should be meaningful (5/30 ≈ 17% longer duration)
assert!(
apy_unclamped > apy_clamped * dec!(1.1),