Skip to content

Make EVM destination funding fee-aware - #1312

Draft
ebma wants to merge 7 commits into
stagingfrom
codex/dynamic-evm-destination-funding
Draft

Make EVM destination funding fee-aware#1312
ebma wants to merge 7 commits into
stagingfrom
codex/dynamic-evm-destination-funding

Conversation

@ebma

@ebma ebma commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

  • replace static destination prefunding on every supported EVM chain with the validated presigned payout gas liability (gas × maxFeePerGas)
  • fund only cross-chain destination shortfalls, while keeping same-chain payout liability additive to the fixed source reserve
  • include the expected destination funding and payout costs in networkFeeUsd on fee-collecting flows, converted from each chain's native token and protected by a configurable USD ceiling
  • persist a quote-time fee envelope and reject registration if the prepared payout's fee moves beyond the configured margin
  • apply the presigned EVM fee multiplier exactly once during signing
  • retain the known fee-cap dust limitation without adding a sweep or smart-contract solution

Scope

This policy covers all configured EVM destinations: Ethereum, Arbitrum, Base, BSC, Avalanche, Moonbeam, Polygon, Base Sepolia, and Polygon Amoy. ETH-, POL/MATIC-, BNB-, AVAX-, and GLMR-denominated gas is converted to USD through the existing price feed.

Source-chain reserve constants remain static and continue to cover the upstream phase plan. For cross-chain payouts, the signed destination liability is funded separately. When source and destination are the same EVM network, the signed payout liability is added to the fixed source reserve so upstream phases cannot consume it. The former Moonbeam destination value is preserved explicitly as its source-chain reserve.

Exact provider-token direct payouts (currently BRLA and EURC on Base) remain source-reserved because those topologies have no fee-distribution phase. They neither advertise nor dynamically fund a destination fee that cannot be collected. Legacy non-direct quotes without a persisted fee envelope still derive the execution requirement from their validated signed payout.

Policy

Fee-collecting EVM BUY quotes price a 21,000-gas native funding transfer plus the destination payout: 21,000 gas for a native-token payout or 100,000 gas for an ERC-20 payout. The estimate uses EVM_DESTINATION_NETWORK_FEE_MARGIN_BPS (20% by default) and rejects quotes over EVM_DESTINATION_MAX_EXECUTION_FEE_USD ($5 by default).

The quote records the destination network, payout gas limit, and estimated maxFeePerGas. At registration, the prepared payout must match the quoted network and gas limit, and its maxFeePerGas must remain inside the configured margin. Short-lived quotes created before the envelope was introduced remain registerable during their existing TTL.

At execution, the actual destination prefund is derived from the validated signed payout transaction. There is deliberately no native-unit liability cap shared across chains because a single ETH/POL/BNB/AVAX/GLMR threshold would be misleading.

Review note

#1311 is merged. This PR now targets staging directly and includes the compatibility updates needed for staging's sequential EVM fee-distribution flow.

Verification

  • affected shared/API/frontend TypeScript checks
  • repository formatting/lint verification (bun run verify)
  • full shared suite: 100 passing, 1 intentionally skipped
  • full API unit/integration suite: 1,123 tests, 1,083 passing and 40 intentionally skipped
  • focused gas-policy, reserve-composition, direct-flow, funding, configuration, settlement, quote-golden, and BRL/EUR/AlfredPay flow tests
  • SDK/API AlfredPay lifecycle coverage verifies the positive dynamic network fee and fee-distribution presign without transferring real tokens
  • full Base Sepolia primary-plus-backup signing coverage (all five signed transactions)
  • existing Base RPC signing integration suites
  • hermetic, database-backed BRL cross-chain corridor scenario that independently decodes the signed Arbitrum payout, starts with a partial native balance, verifies the exact dynamic shortfall is funded, and rejects payout submission unless the full signed fee-cap liability is covered; all RPC/provider effects remain in memory and no tokens are transferred

@netlify

netlify Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit fedea2f
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6a762a551beb340008b82392
😎 Deploy Preview https://deploy-preview-1312--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.

@ebma
ebma requested a balanced review from Copilot August 5, 2026 09:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Same-chain reserve overlap, uncapped direct-flow funding, and incomplete Base Sepolia signing remain unresolved.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Makes EVM destination funding fee-aware across quoting, registration, signing, and execution.

Changes:

  • Prices destination gas and persists a registration-time fee envelope.
  • Funds only the signed payout liability shortfall.
  • Adds configuration, documentation, translations, and test coverage.
File summaries
File Description
packages/shared/src/helpers/signUnsigned.ts Centralizes the signing fee multiplier.
packages/shared/src/endpoints/quote.endpoints.ts Adds the high-network-fee error.
docs/security-spec/03-ramp-engine/ephemeral-accounts.md Documents dynamic destination funding.
apps/frontend/src/translations/pt.json Adds Portuguese error text.
apps/frontend/src/translations/en.json Adds English error text.
apps/frontend/src/stores/quote/useQuoteStore.ts Maps the new friendly error.
apps/api/src/tests/quote-pricing.golden.test.ts Updates fee-pricing goldens.
apps/api/src/tests/corridors/brl-onramp-crosschain.scenario.test.ts Expands destination pricing scenarios.
apps/api/src/test-utils/fake-world/fake-prices.ts Adds native-token test prices.
apps/api/src/constants/constants.ts Separates Moonbeam source reserves.
apps/api/src/config/vars.ts Adds destination gas configuration.
apps/api/src/config/vars.test.ts Tests configuration validation.
apps/api/src/api/services/phases/blocks/phases/subsidize-pre/simulation.ts Deducts destination network fees.
apps/api/src/api/services/phases/blocks/phases/fund-ephemeral/execution.ts Implements dynamic shortfall funding.
apps/api/src/api/services/phases/blocks/phases/final-settlement-subsidy/execution.ts Uses signed gas liability for native settlement.
apps/api/src/api/services/phases/blocks/phases/destination-transfer/transactions.ts Validates prepared fees against quotes.
apps/api/src/api/services/phases/blocks/core/types.ts Extends phase gas context.
apps/api/src/api/services/phases/blocks/core/metadata.ts Defines persisted fee envelopes.
apps/api/src/api/services/phases/blocks/core/flow.ts Controls and persists gas pricing.
apps/api/src/api/services/phases/blocks/core/fees.ts Includes destination execution costs.
apps/api/src/api/services/phases/blocks/core/evm-transactions.ts Defers fee multiplication to signing.
apps/api/src/api/services/phases/blocks/core/evm-destination-gas.ts Implements destination gas policy.
apps/api/src/api/services/phases/blocks/core/evm-destination-gas.test.ts Tests gas pricing and envelopes.
apps/api/src/api/services/phases/blocks/core/destination-funding.ts Replaces static funding amounts.
apps/api/src/api/services/phases/blocks/core/destination-funding.test.ts Tests liability and shortfalls.
apps/api/src/api/services/phases/blocks/__tests__/fund-ephemeral-user-hashes.test.ts Tests non-Ethereum funding liability.
apps/api/src/api/services/phases/blocks/__tests__/brl-onramp-base-same-chain.flow.test.ts Updates same-chain fixtures.
apps/api/src/api/services/phases/blocks/__tests__/brl-onramp-base-cross-chain.transactions.test.ts Verifies single fee multiplication.
apps/api/src/api/services/phases/blocks/__tests__/brl-onramp-base-cross-chain.flow.test.ts Updates cross-chain fixtures.
apps/api/src/api/services/phases/blocks/__tests__/alfredpay-onramp-direct.flow.test.ts Updates direct-flow fixtures.
apps/api/src/api/services/phases/blocks/__tests__/alfredpay-onramp-cross-chain.flow.test.ts Updates cross-chain fixtures.
apps/api/.env.example Documents gas-policy settings.
Review details
  • Files reviewed: 32/32 changed files
  • Comments generated: 3
  • Review effort level: Balanced

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread apps/api/src/api/services/phases/blocks/phases/fund-ephemeral/execution.ts Outdated
Comment thread apps/api/src/api/services/phases/blocks/core/evm-destination-gas.ts
Base automatically changed from codex/enable-ethereum-onramps to staging August 7, 2026 16:50
@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit fedea2f
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6a762a53f3ed42000805e568
😎 Deploy Preview https://deploy-preview-1312--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.

@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

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

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.

2 participants