Skip to content

Price forwarder swaps against a partner reference with fee bands and a subsidy vault - #1375

Open
ebma wants to merge 17 commits into
stagingfrom
feat/monerium-forwarder-fee-subsidy
Open

ebma wants to merge 17 commits into
stagingfrom
feat/monerium-forwarder-fee-subsidy

Conversation

@ebma

@ebma ebma commented Sep 15, 2026

Copy link
Copy Markdown
Member

Why

The partner agreement fixes the client's rate against a reference: the Coinbase EURC-USD reference minus 12.5 bps, and never worse than 15 bps below it. The forwarder's flat feeBps skim on whatever the DEX returns cannot express that. The contracts from #1272 are not deployed yet, so this changes the design before launch with no clone migration.

Decisions are recorded in the dated amendment to docs/adr-0005-monerium-b2b-onramp.md; behaviour in docs/architecture-monerium-b2b-onramp.md ("Fees, reference rate and subsidy").

What changes

Contracts (contracts/monerium-forwarder)

  • Fee policy in ppm per clone (targetPpm 1250, floorPpm 1500 at launch) behind the existing 24 h increase timelock; MAX_FEE_PPM caps both.
  • swapAndForward(referenceRate, routeIndex): the caller supplies the reference, the contract bounds it to MAX_REFERENCE_DEVIATION_BPS around Chainlink; permissionless callers get Chainlink and no subsidy.
  • Three bands: surplus above the target is the fee (capped), between floor and target passes through, below the floor is topped up from the vault.
  • New shared VortexSubsidyVault: treasury-funded, pays only factory clones to their fixed destination, per-swap cap and UTC-daily budget, pausable, withdraws only to the treasury. A vault that cannot cover reverts the whole swap.
  • SLIPPAGE_BPS (now 40 bps) is enforced on the client's net after fee and subsidy; the router minimum is zero and the post-condition is the guard.
  • Factory route whitelist validated on chain (EURe/EURC/USDC only, four Uniswap tiers, at most two hops, immutable router); routes are disabled, never removed.
  • Sweep delay fixtures to 7 days (P3); manifest scripts learn the fee policy, vault and routes (manifest v3).

Backend (apps/api)

  • Migration 078: monerium_accounts.fee_bps becomes target_ppm / floor_ppm; provisioning, admin and read APIs, drift monitor follow.
  • Migration 079: executions carry reference (rate, source, trade id, time), route and subsidy; net is usdcOut - fee + subsidy.
  • reference-rate.ts computes a five-minute volume-weighted average of Coinbase Exchange EURC-USD one-minute candles before each swap (widened to an hour when the five minutes carry no volume), so a single thin weekend print cannot set the reference; the window is recorded on the execution row. The executor quotes every whitelisted route on the mainnet quoter, mirrors the contract settlement (projectSwap) and defers rather than sending when the vault could not cover, the net would breach the floor, the reference is unavailable or out of band, or no route quotes.
  • Crash recovery rebuilds the exact calldata from the persisted reference and route.
  • Monitoring: depth check over every route, subsidy-vault runway monitor, sweep-imminent note on stranding alerts.
  • Webhooks and the deposits endpoint expose an execution pricing block (reference, fee, subsidy) on each conversion.

Docs

  • ADR-0005 amendment and registry rows (B1, P1, P2, P3, P10, P11, new P12/P13), architecture, runbook (vault operations, triage rows, fork exercise), rollout terms inputs, security spec, API pages, OpenAPI.
  • Reaffirmed decisions: no payment bouncing, no guardian-triggered sweep to the fallback, permissionless path after 24 h accepted as unsubsidized.

Verification

  • forge test: 65 tests (unit, vault, invariants incl. pricing bounds and vault conservation). The mainnet fork suite compiles but was not run (no ETH_RPC_URL locally).
  • bun test on the B2B surface: 251 tests across 20 files against the Docker test database; API type-check, Biome, bun docs:api:check clean.

Reviewer notes

  • The old Sepolia manifest in contracts/monerium-forwarder/manifests/ is v2 and will fail verify-manifest until the contracts are redeployed; expected.
  • Still open before a deployment (rollout ledger): the 100 bps reference band value, whether the agreement's "Coinbase EURC oracle" means the Exchange ticker the keeper reads, and vault funding.
  • Overlaps with Run the Monerium OAuth and white-label apps in parallel on the EUR onramp #1372 only on the generated OpenAPI JSON and .d.ts; whichever merges second re-runs bun docs:api:types.

@netlify

netlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit fce73c2
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6aa98025cc52b90008cddfc4

@netlify

netlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit fce73c2
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6aa98025078edd00081e34d2
😎 Deploy Preview https://deploy-preview-1375--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit fce73c2
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6aa98025a7d487000889f226
😎 Deploy Preview https://deploy-preview-1375--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

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.

1 participant