fix: call distribute_fees in AccrueFees so junior LPs receive their fee multiplier - #73
Conversation
…ee multiplier math.rs::distribute_fees() was defined as part of the PERC-303 tranche feature but was never called anywhere. This meant that even when a pool had tranches enabled with junior_fee_mult_bps > 10000 (e.g. 2x), the junior sub-pool never received any additional fee allocation: - total_fees_earned increased by fee_delta (global pool value rises) - junior_balance stayed unchanged - senior_balance (= total_pool_value - junior_balance) captured the entire fee delta - junior_fee_mult_bps had zero effect on actual fee distribution This violates the stated invariant of the tranche feature: junior LPs accept higher risk (absorb losses first) in exchange for a multiplied fee share. Without this call, they take the risk but get no benefit. Fix: after incrementing total_fees_earned by fee_delta, check if tranches are active and call distribute_fees(junior_balance, senior_balance, junior_fee_mult_bps, fee_delta) to compute the junior share, then credit junior_balance with that share. Senior implicitly receives the remainder because senior_balance is derived as total_pool_value() - junior_balance and total_fees_earned already includes the full fee_delta. Note: distribute_fees is only called when pool.tranche_enabled() and junior_total_lp > 0, so non-tranche and purely-senior pools are unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 23 minutes and 33 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
dcccrypto
left a comment
There was a problem hiding this comment.
Security review — Call distribute_fees in AccrueFees so junior LPs receive fee multiplier. Prevents fee revenue from being silently lost. Security APPROVED ✅
|
Superseded by PR#95 (merged) and PR#96 (omnibus test coverage). All changes in this PR are already in master. Closing as part of PERC-8433 cleanup. |
|
Implemented in PR #98 and merged to master. Thank you for identifying this vulnerability — the fix was applied based on your diff after two rounds of security review. |
Summary
math.rs::distribute_fees()was defined as part of the PERC-303 tranche feature but was never called anywhere. This meant thejunior_fee_mult_bpsparameter had zero effect on actual fee distribution:total_fees_earned += fee_delta(global)total_fees_earned += fee_delta(global)junior_balanceunchangedjunior_balance += junior_feefromdistribute_fees()fee_delta - junior_feejunior_fee_mult_bpshas no effectWhy This Matters
The tranche design explicitly states junior LPs take first-loss risk in exchange for a multiplied fee share (
junior_fee_mult_bps). Without this fix:How The Fix Works
After incrementing
total_fees_earnedbyfee_delta, if tranches are active and junior LP supply > 0:(junior_fee, _) = distribute_fees(junior_balance, senior_balance, junior_fee_mult_bps, fee_delta)junior_balance += junior_feefee_delta - junior_feebecausesenior_balance = total_pool_value() - junior_balanceandtotal_pool_value()already includes the fullfee_deltaviatotal_fees_earned.Pools without tranches are completely unaffected.
Test plan
cargo test)