Skip to content

fix: resolve tranche accounting bugs, gate validation issues, and token owner check omissions - #225

Merged
dcccrypto merged 1 commit into
dcccrypto:mainfrom
v1ktorrr0x:fix-batch-1
Jun 23, 2026
Merged

fix: resolve tranche accounting bugs, gate validation issues, and token owner check omissions#225
dcccrypto merged 1 commit into
dcccrypto:mainfrom
v1ktorrr0x:fix-batch-1

Conversation

@v1ktorrr0x

@v1ktorrr0x v1ktorrr0x commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

1. Account for realized_junior_loss in ReturnInsurance Cap

  • Issue resolved: [M-1] ReturnInsurance cap ignores realized_junior_loss, blocking full physical recovery #220 (M-1)
  • File modified: processor.rs
  • Details: Added pool.realized_junior_loss() to the calculation of outstanding recovery capacity in process_return_insurance. This ensures that paper-forfeited junior losses (bookkeeping settlements) do not artificially lower the physical recovery limit, preventing a shortfall in the vault that could later cause senior LP withdrawals to fail.

2. Invariant Guard for junior_balance in Fee Accrual

3. Factor realized_junior_loss into the DepositJunior Gate

4. SPL Token Owner Check on Vault in ReturnInsurance

5. Named Accessors for StakeDeposit Tranche Flags

Summary by CodeRabbit

  • Bug Fixes

    • Improved account validation and error handling to prevent runtime crashes.
    • Enhanced insurance return calculation logic.
    • Added safeguards against invalid fee accrual scenarios.
  • Security

    • Strengthened token program verification for stake pool operations.
    • Added parameter bounds validation for pool configuration.
  • Chores

    • Updated gitignore configuration.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds is_junior_deposit() and set_junior_deposit() accessor methods to StakeDeposit in state.rs, replacing all raw _reserved[8] reads and writes in processor.rs. Fixes three accounting invariants: accrue_fees_inner guards against junior_balance exceeding total_pool_value; process_deposit_junior computes physical net loss excluding realized_junior_loss; process_return_insurance adds an SPL-token owner check and includes realized_junior_loss in the outstanding-insurance capacity. A *.md glob is added to .gitignore.

Changes

Junior Tranche Accessor and Insurance Accounting Fixes

Layer / File(s) Summary
StakeDeposit junior flag accessors and call-site migration
src/state.rs, src/processor.rs
Adds is_junior_deposit() and set_junior_deposit() to StakeDeposit, replacing all four raw _reserved[8] accesses in process_deposit, process_withdraw, and process_deposit_junior.
accrue_fees, DepositJunior, and ReturnInsurance invariant fixes
src/processor.rs
accrue_fees_inner rejects accrual if junior_balance would exceed total_pool_value; process_deposit_junior gates on physical_net_loss = total_flushed - (total_returned - realized_junior_loss) > 0; process_return_insurance adds SPL-token owner check on vault and sets outstanding = (total_flushed - total_returned) + realized_junior_loss.
Gitignore update
.gitignore
Adds *.md to the ignore rules.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • dcccrypto/percolator-stake#98: Directly overlaps on _reserved[8] junior-flag handling and insurance/fee accounting in processor.rs/state.rs.
  • dcccrypto/percolator-stake#172: Touches the same junior tranche flag in StakeDeposit's reserved slot and the withdraw/reset path that interacts with the new accessors.
  • dcccrypto/percolator-stake#181: Modifies the same junior-side accounting and withdrawal flow in process_withdraw that this PR's flag migration and loss-accounting fixes also affect.

Poem

🐇 Hoppity-hop through reserved bytes no more,
A named accessor guards the junior door.
The phantom loss that snuck through the gate —
Now realized_junior_loss sets the record straight!
The vault gets its owner check, tidy and right,
No senior left bricked on a fee-accrual night. 🌙

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: resolve tranche accounting bugs, gate validation issues, and token owner check omissions' accurately summarizes the main changes: accounting fixes, validation improvements, and security checks.
Description check ✅ Passed The PR description provides detailed explanations of all five issues resolved with file references and fix details, but lacks explicit testing checklist completion and math-verification confirmation.
Linked Issues check ✅ Passed The PR addresses all five linked issues (#220, #221, #222, #223, #224) with specific implementation details for each fix: accounting formulas, invariant guards, gate logic, owner checks, and accessor methods.
Out of Scope Changes check ✅ Passed Changes are tightly scoped to the five documented issues. The .gitignore update is a minor cleanup unrelated to the core fixes but does not compromise the scope of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/processor.rs (1)

1293-1296: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Unmigrated raw _reserved[8] access.

This full-withdrawal reset path still uses direct byte access instead of the new accessor. For consistency with the PR's stated goal of replacing all raw _reserved[8] accesses:

♻️ Suggested fix
     if deposit_mut.lp_amount == 0 {
         deposit_mut.is_initialized = 0;
-        deposit_mut._reserved[8] = 0;
+        deposit_mut.set_junior_deposit(false);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/processor.rs` around lines 1293 - 1296, In the full-withdrawal reset path
within the conditional block where deposit_mut.lp_amount equals zero, replace
the direct raw byte access assignment to deposit_mut._reserved[8] = 0 with the
new accessor method that was introduced in this PR for setting reserved values.
Search the codebase for other instances of this accessor method to ensure
consistency in how reserved fields are being accessed and modified throughout
the deposit mutation logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitignore:
- Around line 7-8: The `*.md` pattern in .gitignore is too broad and will
exclude all markdown files in the repository, including critical documentation
files currently tracked such as README.md, .github/pull_request_template.md, and
files in the docs/ directory. Either remove this pattern entirely from the
.gitignore file if no generated markdown files need to be ignored, or replace it
with a more specific path-based glob pattern such as `dist/**/*.md` or
`target/**/*.md` to only target generated markdown artifacts in specific
directories.

---

Nitpick comments:
In `@src/processor.rs`:
- Around line 1293-1296: In the full-withdrawal reset path within the
conditional block where deposit_mut.lp_amount equals zero, replace the direct
raw byte access assignment to deposit_mut._reserved[8] = 0 with the new accessor
method that was introduced in this PR for setting reserved values. Search the
codebase for other instances of this accessor method to ensure consistency in
how reserved fields are being accessed and modified throughout the deposit
mutation logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ced50dd2-6aac-4f3f-9f1a-9ab236a28a65

📥 Commits

Reviewing files that changed from the base of the PR and between 5f6ffa7 and 1fa06a8.

📒 Files selected for processing (3)
  • .gitignore
  • src/processor.rs
  • src/state.rs

Comment thread .gitignore
Comment on lines +7 to +8
*.md

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# List all tracked .md files to understand what would be ignored
git ls-files '*.md'

Repository: dcccrypto/percolator-stake

Length of output: 229


Remove *.md from .gitignore or narrow the pattern to specific directories.

Adding *.md to .gitignore will exclude critical documentation files currently tracked in the repository: README.md, .github/pull_request_template.md, and all files in docs/ (ARCHITECTURE.md, AUDIT.md, KANI-DEEP-ANALYSIS.md, KANI-PROOF-ANALYSIS.md, WRAPPER-HARDENING.md).

Either remove this pattern or replace it with a path-specific glob if targeting only generated markdown artifacts (e.g., dist/**/*.md or target/**/*.md).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.gitignore around lines 7 - 8, The `*.md` pattern in .gitignore is too broad
and will exclude all markdown files in the repository, including critical
documentation files currently tracked such as README.md,
.github/pull_request_template.md, and files in the docs/ directory. Either
remove this pattern entirely from the .gitignore file if no generated markdown
files need to be ignored, or replace it with a more specific path-based glob
pattern such as `dist/**/*.md` or `target/**/*.md` to only target generated
markdown artifacts in specific directories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants