Conversation
✅ Deploy Preview for vrtx-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortexfi ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Additive only: ConversionExecutionPricing and the required execution block on DepositConvertedWebhookPayload.conversions[], mirrored in WebhookPayload and WebhookDeliveryAttempt.
_settle returned the vault's claimed subsidy without observing it, and setSubsidyVault is guardian-only, untimelocked and unvalidated: a no-op vault let a below-floor fill pass the net floor on paper while the client received the raw fill. Count the subsidy only after exactly the shortfall landed at destination, the same exact-delta pattern _swap uses.
The only net-floor tests landed in the subsidy branch; a reference 100 bps under Chainlink with a fill above its target exercises the fee branch and must still revert / defer on the oracle floor.
The floor on the net binds at SLIPPAGE_BPS - floorPpm (~25 bps) below Chainlink, well inside the 100 bps band; the weekend-gap open item framed it purely as a band question.
The monitor compares the raw quote to SLIPPAGE_BPS, but settlement now enforces the floor on the client's net: a raw impact above it is subsidized up to the vault cap and the keeper still executes. Keep the raw depth-vs-oracle signal, name what it means (every swap draws a subsidy, the permissionless path reverts) instead of calling for a pause, and fix the stale _minOut reference.
flatten treated arrays as leaves, so String([...]) collapsed every route to "[object Object]" and a same-length path or enabled change produced no diff.
The partner docs said five-minute VWAP unconditionally; the keeper widens to sixty minutes when the five carry no volume.
…arder-fee-subsidy # Conflicts: # docs/api/pages/14-managed-profiles.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
feeBpsskim 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 indocs/architecture-monerium-b2b-onramp.md("Fees, reference rate and subsidy").What changes
Contracts (
contracts/monerium-forwarder)targetPpm1250,floorPpm1500 at launch) behind the existing 24 h increase timelock;MAX_FEE_PPMcaps both.swapAndForward(referenceRate, routeIndex): the caller supplies the reference, the contract bounds it toMAX_REFERENCE_DEVIATION_BPSaround Chainlink; permissionless callers get Chainlink and no subsidy.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.Backend (
apps/api)monerium_accounts.fee_bpsbecomestarget_ppm/floor_ppm; provisioning, admin and read APIs, drift monitor follow.usdcOut - fee + subsidy.reference-rate.tscomputes 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.executionpricing block (reference, fee, subsidy) on each conversion.Docs
Verification
forge test: 65 tests (unit, vault, invariants incl. pricing bounds and vault conservation). The mainnet fork suite compiles but was not run (noETH_RPC_URLlocally).bun teston the B2B surface: 251 tests across 20 files against the Docker test database; API type-check, Biome,bun docs:api:checkclean.Reviewer notes
contracts/monerium-forwarder/manifests/is v2 and will failverify-manifestuntil the contracts are redeployed; expected..d.ts; whichever merges second re-runsbun docs:api:types.