Skip to content

Extend preview_payout to resolve nested splits down to leaf recipients #265

Description

@grantfox-oss

Problem

preview_payout(id, amount) returns one amount per direct recipient:

pub fn preview_payout(env: Env, id: u64, amount: i128) -> Result<Vec<i128>, Error> {
    ...
    Ok(amounts(&env, &split, amount))
}

For a split whose recipients include Recipient::Split(child), the returned vector shows the lump sum routed to the child, not where that money actually lands. It also returns a bare Vec<i128> with no recipient identifiers, so the caller has to zip it against get_split positionally and hope the ordering holds.

Why this matters

Composable routing trees are a headline feature ("a project split that feeds team splits"). But the one function whose entire purpose is "show me what will happen before I sign" stops at the first level. A payer looking at a two-level tree sees "8,000 goes to split #7" and cannot tell whether that means 8,000 to one person or 500 each to sixteen people.

That undermines:

Suggested fix

Add a deep variant, for example preview_payout_deep(id, amount) -> Vec<(Address, i128)>, that recurses through child splits and returns leaf accounts with final amounts. Returning the address alongside the amount also fixes the positional-zip fragility.

Requirements:

  • Bound the recursion depth and document the cap (coordinate with the cycle-rejection work, which needs a depth bound anyway).
  • Preserve the exact rounding behaviour of amounts() at every level, including dust to the last recipient, so preview matches actual (extend the preview_matches_actual_payout test to nested cases).
  • Aggregate correctly if the same address appears as a leaf under multiple branches.

Acceptance criteria

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26enhancementNew feature or requesthelp wantedExtra attention is neededrustPull requests that update rust code

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions