Repository navigation
fix(H1/H2): high-water-mark performance fee + minimum term - #13
Merged
Merged
Conversation
Audit H1/H2: the performance fee was charged on (nav - protectedAmount), i.e. NAV above the 90% floor, so a flat term (nav 100 vs floor 90) or a losing term (nav 95) still minted a 'performance' fee; and because every new term re-strikes the floor at 0.9x current nav with no minimum term, a keeper could loop settleTerm->startTerm to mint ~perfBps*(1-P) of NAV per cycle indefinitely. Fix: the performance fee is now charged only on the rise in navPerShare above a per-share high-water mark, which then ratchets up. Flat/losing terms and re-struck terms where navPerShare has not advanced pay zero, and gains are never double-charged across terms. HWM is seeded at the first startTerm's entry price. Also added a 7-day MIN_TERM_DURATION in the controller as anti-churn defense-in-depth. Composes with the H3 per-share design (deposits never move navPerShare, so the basis is clean). Regression tests: no fee on flat/losing terms, HWM holds across terms, min-term blocks 1-second churn. 116 -> 120.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audit findings H1 & H2 (High) — stacked on #12 (merge #12 first)
H1: the performance fee was charged on
nav - protectedAmount, whereprotectedAmountis the 90% floor, not principal or a high-water mark. So a flat term (NAV 100 vs floor 90) paid a fee on 10, and a losing term (NAV 95) still paid a 'performance' fee on 5.H2: every new term re-strikes the floor at
0.9 x current nav, so immediately afterstartTermthe vault always showsnav > protectedAmount. With no minimum term, a keeper could loopsettleTerm -> startTermand mint~perfBps x (1-P)of NAV in fee shares every cycle, with no market move.Fix (one mechanism for both)
Switch to a proper per-share high-water mark:
navPerShareabovehighWaterPerShareWad, which then ratchets up. Flat/losing terms and re-struck terms where navPerShare has not advanced pay zero; cross-term gains are never double-charged. HWM is seeded at the firststartTerm's entry price.navPerShare, so the per-share fee basis is clean.MIN_TERM_DURATIONinCPPIController.startTerm(well below the 12-month product term) so a compromised keeper cannot loop tiny terms even setting the fee aside.Tests
Existing perf-fee test rewritten to assert the fee is 10% of real profit (not nav-above-floor). New regressions: no fee on a flat term, no fee on a losing term, HWM holds across terms (no double-charge), and min-term blocks a 1-second churn. Suite 116 -> 120.