Skip to content

Conversation

@2501babe
Copy link
Member

@2501babe 2501babe commented Oct 2, 2025

NOTE presently based on #87

i rewrote Split from scratch to fix #1 plus some other bugs with minimum delegation. i also tried to make it more readable. Split has gone through several layers of changes which caused it to accumulate a lot of cruft, particularly because it originally ignored delegation, worked with lamports exclusively, and never used stake history

current Split tries match once on source stake and share code for both the Initialized and Stake cases in the unified validate_split_amount() function and then do more work for the Stake case after. it ends up being quite difficult to understand because:

  • when Stake is deactivated it should actually follow the same logic as Initialized, not the logic for Stake
  • logic for the full split is woven into all the same math as the partial split
  • there are many duplicated or "just in case" balance checks, particularly involving rent-exemption because feature_set::rent_exempt_split_destinations was added in a minimally invasive way
  • the math overall is extremely indirect. it starts with source/dest/split lamps and "additional required" (minimum delegation), calculates minimums from rent and additional, source remaining from source and split, then uses these to try to calculate stake delta and split stake amounts. all through this, these values are combined and compared haphazardly to check various error conditions

i find Split the most difficult stake operation to reason about. in rewriting process_split(), i decided to:

  • check signers up front for all cases
  • handle the full split, partial split inactive, and partial split active/activating cases separately, with their own math and update logic
  • tolerate matching on stake states as convenient rather than forcing the code to be structured around a single match

this results in a function that has a bit more boilerplate but none of the difficult calculations of the orginal Split

i also made it an error to split 0 from Uninitialized. i dont see any good reason to allow it

this soft-depends on #82 and #87, we could change it if either of those fail to land but i assume they will both land first. it was a total rewrite of Split, so we definitely want more review care and possibly a scoped audit, so this should be merged after we cut the next stake program release

closes #1

@2501babe 2501babe self-assigned this Oct 2, 2025
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.

Splitting a deactivated stake wrongly takes delegation into account

1 participant