Skip to content

Soroban: On-chain contribution router with slippage enforcement #60

@dotunv

Description

@dotunv

Problem

Path payment slippage is currently enforced client-side in the backend (SLIPPAGE_BPS = 500 hardcoded in contributions.js:14). The backend fetches a quote, calculates sendMax, and submits — but there is no on-chain guarantee the slippage rule is respected. A malicious or buggy backend could submit a transaction with no slippage protection.

A Soroban contract can enforce contribution routing rules on-chain, making the contribution flow trustless.

What needs to happen

Soroban Contract (contracts/soroban/router/)

Write a Rust Soroban contract that:

  • Accepts: send_asset, send_max, dest_asset, dest_amount, path, campaign_wallet, platform_wallet, fee_bps
  • Validates: send_max does not exceed dest_amount * (1 + max_slippage_bps / 10000)
  • Executes a path_payment_strict_receive on-chain
  • Splits the received amount: (1 - fee_bps / 10000) to campaign wallet, fee_bps / 10000 to platform wallet — atomically in one call
  • Emits a ContributionRouted event with: sender, campaign, dest_amount, source_amount, fee_amount, path

Backend changes

  • Replace prepareSignedContributionPathPayment() in stellarService.js with a contract invocation
  • Fee split (Issue Feature: Platform fee collection on contributions #20) moves into the contract — no separate operation needed
  • Backend indexes ContributionRouted events instead of raw path_payment_strict_receive operations

Why atomic fee split matters

Currently the fee would need to be a separate transaction or operation. The router contract does it in one atomic call — the campaign either receives the full net amount or nothing. No partial states.

Acceptance criteria

  • Slippage ceiling enforced at contract level, not backend
  • Fee split to platform wallet atomic with the contribution
  • ContributionRouted event emitted and indexable
  • Existing contribution UI works unchanged
  • Path payment quote still fetched from Horizon (off-chain is fine for quotes)
  • Contract rejects transactions that exceed slippage threshold

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveIssues in the Stellar wave program

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions