Skip to content

Protocol Fee Engine with Multi-Party Payout Splits & Treasury Accounting #39

Closed

Description

@meshackyaro

Description

This issue aims to address the implementation of Protocol Fee Engine with Multi-Party Payout Splits & Treasury Accounting.

The core objective is to: Add a configurable, governance-bounded fee engine to the escrow contract that splits every payout across worker, protocol treasury, and optional referrer in exact integer arithmetic, with per-token treasury accounting and provable no-dust/no-loss invariants.

By completing this feature, we will ensure that the GuildWorkman protocol maintains its high standards for security, usability, and decentralized logic. This issue requires careful attention to the Smart Contract architecture and adherence to the existing project conventions.

When picking up this issue, please ensure you document any new dependencies or architectural decisions made during development.

Component

Smart Contracts (Soroban)

Difficulty

⚫ Very Hard

Current state

escrow::confirm_completion, cancel_appointment, and resolve_dispute all transfer the entire appointment.amount to exactly one recipient. There is no protocol revenue path, no treasury, and no notion of a referrer or guild cut — so the protocol currently cannot sustain itself, and every future fee change would be a breaking rewrite of the payout paths.

The hard part here is not the split; it is the arithmetic and the invariants. Payouts are i128 token units, fee rates are basis points, and every rounding decision must be deliberate and provable: no path may ever pay out more than was escrowed, and no path may leave stranded dust in the contract.

Tasks

  • Review the existing Soroban workspace under soroban-contracts/contracts/
  • Implement the contract logic for: Protocol Fee Engine with Multi-Party Payout Splits & Treasury Accounting
  • Define fee configuration in basis points with a hard-coded maximum the governance/admin path cannot exceed
  • Apply the split consistently across confirm_completion, resolve_dispute, and the cancel/refund path (a cancellation must define whether fees are charged at all — document the choice)
  • Implement per-token treasury accounting with an explicit withdrawal path and its own authorization
  • Use checked integer arithmetic throughout; pick and document a deterministic rounding policy, assigning the remainder to a single named party so totals always reconcile exactly
  • Support an optional referrer/guild share that is absent for most appointments without changing the settlement path
  • Write comprehensive unit and integration tests, including adversarial edge cases — 1-unit amounts, i128::MAX-adjacent amounts, zero-fee and max-fee configs, and a property/invariant test asserting sum(payouts) == amount for randomized inputs
  • Add caching for cargo dependencies in CI
  • Run cargo fmt --check and cargo clippy -- -D warnings
  • Run cargo test and soroban contract build to verify the optimized WASM build

Acceptance Criteria

  • Feature accurately implements the objective: Add a configurable, governance-bounded fee engine to the escrow contract that splits every payout across worker, protocol treasury, and optional referrer in exact integer arithmetic, with per-token treasury accounting and provable no-dust/no-loss invariants.
  • For every payout path, the sum of all transferred amounts equals the escrowed amount exactly — no overpayment, no stranded dust
  • Fee rates cannot be set above the documented protocol maximum, by admin or by anyone else
  • Treasury balances are tracked per token and are withdrawable only through the authorized path
  • Fee behaviour on cancellation and on dispute resolution is documented and tested, not incidental
  • Any PR that introduces compiler or clippy warnings is automatically blocked
  • Contract logic is covered by tests exercising success, failure, and attack paths
  • Storage layout and authorization are documented and reviewed for safety
  • Code is properly reviewed and approved by codeowners

Estimated Time

4-5 days

Activity

  1. Chigybillionz commented on Aug 19, 2026

    @Chigybillionz
    Contributor

    Hi, I’m interested in this task and can handle the implementation. Assign it to me and I’ll get started.

  2. cyb3ralee commented on Aug 19, 2026

    @cyb3ralee

    I would like to take this pls 🙌

  3. Meet-hybrid commented on Aug 20, 2026

    @Meet-hybrid

    I would like to contribute to this issue. I have experience with JavaScript/TypeScript, React, backend APIs, testing, Git, and software architecture. I will follow the acceptance criteria, add tests, and provide a focused pull request.

  4. CillaSam commented on Aug 25, 2026

    @CillaSam

    I’d like to take on this issue and implement the Protocol Fee Engine and treasury accounting in the Soroban escrow contracts.

    My approach would be to first review the existing escrow architecture and settlement flows, then introduce a small, reusable fee calculation layer with:

    Governance-controlled basis-point fees with a hard maximum.
    Worker, treasury, and optional referrer splits using checked i128 arithmetic.
    Deterministic rounding with the remainder assigned explicitly so sum(payouts) == escrowed amount on every path.
    Per-token treasury accounting and an independently authorized withdrawal path.
    Explicitly documented and tested fee behavior for completion, cancellation, and disputes.

    I’ll add comprehensive unit/integration and invariant tests, including 1-unit amounts, near-i128::MAX values, zero/max fees, unauthorized actions, referrer/no-referrer cases, and randomized conservation tests.

    I’ll also document the storage/authorization decisions and any dependencies, add Cargo caching to CI, and verify the implementation with cargo fmt, Clippy with warnings denied, tests, and the optimized Soroban WASM build.

    The main goal is to keep the implementation minimal and auditable while guaranteeing no overpayment, no stranded dust, and exact payout reconciliation across every settlement path.

  5. balisdev commented on Aug 25, 2026

    @balisdev
    Contributor

    Hi maintainer,

    I’d love to take on this issue. Implementing deterministic, zero-dust fee settlement for Soroban smart contracts requires strict invariant management, carefully bounded arithmetic, and comprehensive property testing.

    Below is my proposed architecture, rounding model, design decisions, and testing plan to meet all acceptance criteria.

    1. Architectural & Data Layout Design

    Data Structures & Storage Layout

    • FeeConfig (Stored in Admin/Governance Instance Storage):

    • protocol_bps: u32 (Basis points for protocol treasury, e.g., 250 = 2.5%).

    • referrer_bps: u32 (Basis points for the optional referrer).

    • MAX_TOTAL_BPS: Constant hard-coded in the contract (e.g., 1000 = 10.00%). Admin/governance setter explicitly asserts protocol_bps + referrer_bps <= MAX_TOTAL_BPS.

    • TreasuryBalance (Stored in Persistent Data Storage keyed by (Symbol/Address) token):

    • Tracks cumulative accrued fees per token mint: DataKey::TreasuryBalance(Address) -> i128.

    • Settlement Invariant:

    $$\text{Amount}_{\text{total}} = \text{Amount}_{\text{worker}} + \text{Amount}_{\text{treasury}} + \text{Amount}_{\text{referrer}}$$

    2. Deterministic Arithmetic & Rounding Policy

    To guarantee zero stranded dust and no over-payouts:

    1. Basis Point Precision: Fee calculations use standard basis points ($1% = 100\text{ BPS}$, $100% = 10,000\text{ BPS}$).
    2. Floor Division & Remainder Assignment:
    • Calculate treasury_cut = (amount * protocol_bps) / 10000 (floored).
    • Calculate referrer_cut = (amount * referrer_bps) / 10000 (floored, if referrer exists).
    • Calculate primary payout (worker/recipient) as the exact deterministic remainder:
      $$\text{worker_cut} = \text{amount} - \text{treasury_cut} - \text{referrer_cut}$$
    1. No-Dust Invariant: Because the primary recipient receives $\text{amount} - \sum \text{cuts}$, the sum of all payouts identically reconciles to $\text{amount}$ in every execution path, making dust stranded in the contract mathematically impossible.

    3. Settlement Behavior Across Contract Paths

    • confirm_completion: Standard split applied across worker, protocol treasury, and optional referrer.

    • cancel_appointment (Refund Path):

    • Policy: 0% fee charged on full client refunds. Since services were not rendered, no platform value was realized. The client receives $100%$ of amount.

    • Cancellation after work started (partial refund): Split applied strictly to the non-refunded portion paid to the worker.

    • resolve_dispute:

    • Protocol fee is computed on the total appointment amount.

    • The remaining balance ($\text{amount} - \text{treasury_cut}$) is distributed according to the resolver’s awarded split ratio.

    4. Safety & Security Guardrails

    • Checked Arithmetic: All operations use Rust's checked_add, checked_mul, and checked_sub to protect against integer overflow/underflow.
    • Treasury Authorization: Dedicated withdraw_treasury(token: Address, to: Address, amount: i128) function requiring admin.require_auth(). Updates internal per-token accounting before executing the token::Client transfer.
    • Zero & Edge Amount Guard: Amounts $&lt; 10,000\text{ BPS}$ units round down safely to zero fee without failing, ensuring 1-unit micro-settlements execute cleanly without arithmetic panics.

    5. Execution & Testing Plan

    • Unit & Adversarial Edge Tests:

    • Micro-amounts (amount = 1), zero-fee configurations (0 BPS), and max-fee bounds (MAX_BPS).

    • Admin governance bounds (attempting to set fee $&gt; \text{MAX_TOTAL_BPS}$ panics cleanly).

    • Property/Invariant Testing (proptest / quickcheck):

    • Randomized inputs over full range ($1 \le \text{amount} \le i128::\text{MAX}$, arbitrary BPS setups, optional referrer present/absent).

    • Assert $\sum(\text{Payouts}) == \text{Amount}$ and $\text{ContractBalance}{\text{post}} == \text{ContractBalance}{\text{pre}} - \text{Amount}$.

    • CI & Build Pipeline:

    • Update GitHub Actions workflow to cache cargo and Soroban target builds.

    • Ensure clean execution of cargo fmt --check, cargo clippy -- -D warnings, cargo test, and soroban contract build.

    Please assign this issue to me. I am ready to begin work immediately!

  6. grantfox-oss commented on Aug 26, 2026

    @grantfox-oss

    🦊 GrantFox — @balisdev has been assigned to this issue as part of the Third Campaign campaign!

    Next steps:

    1. Open a Pull Request referencing this issue (e.g., Closes #39)
    2. Your PR will be reviewed by the workman-labs maintainers

    Good luck! Track your progress on GrantFox.

  7. grantfox-oss commented on Aug 29, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox as part of the Third Campaign campaign!

    @balisdev's PR #53 was approved and merged by @meshackyaro.

    🏆 @balisdev: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (923 total points). Track your full progress on GrantFox.

    👏 Great work, @balisdev! Keep contributing to workman-labs.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions