Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benchmarks/bridge-execution-latency.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ methodology:
- "Outcome classification: settled (funds received), reverted or refunded (capital returned to source), or errored (never broadcast). Only settled transactions contribute to the latency distribution; reverts and refunds count against the success rate."
- "Region: EU-West only at present. The execution node runs a single wallet, so a second origin would race the same inventory; additional origins are not planned for the execution loop."
- "Cohort: Mobula, Relay and LI.FI. deBridge is quote-only in this loop. Providers without a symmetric route on all three legs are excluded so the triangle conserves."
- "Cost metrics captured per real execution (beyond latency and success): realized output on-chain, execution slippage vs the quote (realized fee minus quote-projected fee), our own on-chain gas paid (approve + deposit, measured as source-chain native balance delta), and the refund rate split from hard-fail rate. These surface the true all-in cost and the gap between a quote and what actually settles."

findings:
- "{{name:mobula}} settles at {{p50:mobula}} (p50, broadcast to funds received) with a {{success:mobula}} success rate over the last 24 hours."
Expand Down
36 changes: 35 additions & 1 deletion harnesses/bridge-monitor/cmd/monitor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type ExecutionResult struct {
E2ELatencyMs int64 // Time from quote start to funds received
Success bool
Reverted bool
Refunded bool // subset of Reverted: provider returned capital (status "refunded")
Error error
QuoteFeeUSD float64 // Fee from quote
ActualFeeUSD float64 // Actual fee paid (input - output)
Expand All @@ -55,6 +56,7 @@ type ExecutionResult struct {
FeesPercent float64
CostUSD float64
OutputUSD float64 // What landed on destination (the fill)
ExecGasUSD float64 // Our on-chain gas paid (approve + deposit), source native delta
}

// Executor handles the execution loop
Expand Down Expand Up @@ -374,6 +376,15 @@ func (e *Executor) executeOnBridge(bridge string, route TestRoute, amount, amoun
log.Printf(" ⚠️ pre-execution balance read failed (%v) — falling back to quote-projected fill", preBalErr)
}

// Source-chain native balance before execution, to measure the real gas we
// pay (approve + deposit) as the pre-minus-post delta. Single-flight (execMu)
// guarantees no other tx moves it during this one leg.
srcOwner := e.walletManager.EVMAddress
if route.FromChain == "Solana" {
srcOwner = e.walletManager.SolanaAddress
}
preNativeUSD, preNativeErr := e.txExecutor.nativeBalanceUSD(route.FromChain, srcOwner)

// PHASE 1: Get quote with TX data
quoteStart := time.Now()
var txHash string
Expand Down Expand Up @@ -434,6 +445,15 @@ func (e *Executor) executeOnBridge(bridge string, route TestRoute, amount, amoun
}
}

// Real gas we paid this leg = source native balance delta (approve + deposit).
if preNativeErr == nil {
if postNativeUSD, nerr := e.txExecutor.nativeBalanceUSD(route.FromChain, srcOwner); nerr == nil {
if g := preNativeUSD - postNativeUSD; g > 0 {
result.ExecGasUSD = g
}
}
}

result.FeesUSD = result.ActualFeeUSD
if amountUSD > 0 {
result.FeesPercent = (result.ActualFeeUSD / amountUSD) * 100
Expand Down Expand Up @@ -618,6 +638,7 @@ func (e *Executor) executeMobula(route TestRoute, amount float64, quoteStart tim
result.ActualFeeUSD = result.QuoteFeeUSD
} else if status.Status == "refunded" {
result.Reverted = true
result.Refunded = true
log.Printf(" [mobula] ⚠️ Transaction was refunded!")
}

Expand Down Expand Up @@ -755,6 +776,7 @@ func (e *Executor) executeRelay(route TestRoute, rawUnits string, quoteStart tim
result.ActualFeeUSD = result.QuoteFeeUSD
} else if status.Status == "refunded" {
result.Reverted = true
result.Refunded = true
log.Printf(" [relay] ⚠️ Transaction was refunded!")
}

Expand Down Expand Up @@ -886,6 +908,7 @@ func (e *Executor) executeLiFi(route TestRoute, rawUnits string, quoteStart time
result.ActualFeeUSD = result.QuoteFeeUSD
} else if status.Status == "refunded" || status.Status == "failed" {
result.Reverted = true
result.Refunded = status.Status == "refunded"
log.Printf(" [lifi] ⚠️ Transaction was refunded/failed!")
}

Expand Down Expand Up @@ -925,18 +948,29 @@ func (e *Executor) recordExecutionMetrics(result *ExecutionResult) {
bridgeReverts.WithLabelValues(labels...).Inc()
bridgeConsecutiveFailures.WithLabelValues(result.Bridge, e.region).Inc()
}
if result.Refunded {
bridgeRefunds.WithLabelValues(labels...).Inc()
}
if result.Error != nil {
bridgeErrors.WithLabelValues(append(labels, "execution_failed")...).Inc()
if !result.Reverted {
bridgeConsecutiveFailures.WithLabelValues(result.Bridge, e.region).Inc()
}
}

// Record fees
// Record fees + the new execution-cost metrics
bridgeFeesUSD.WithLabelValues(labels...).Set(result.ActualFeeUSD)
if result.AmountUSD > 0 {
bridgeFeesPercent.WithLabelValues(labels...).Set((result.ActualFeeUSD / result.AmountUSD) * 100)
}
if result.OutputUSD > 0 {
bridgeRealizedOutputUSD.WithLabelValues(labels...).Set(result.OutputUSD)
}
// Execution slippage vs quote = realized fee - quote-projected fee.
bridgeQuoteSlippageUSD.WithLabelValues(labels...).Set(result.ActualFeeUSD - result.QuoteFeeUSD)
if result.ExecGasUSD > 0 {
bridgeExecGasUSD.WithLabelValues(labels...).Set(result.ExecGasUSD)
}
}

// getSourceTokenName returns the source token name for balance checking (legacy - fallback)
Expand Down
29 changes: 29 additions & 0 deletions harnesses/bridge-monitor/cmd/monitor/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,35 @@ var (
Help: "Total number of reverted/refunded bridge transactions",
}, []string{"bridge", "from_chain", "to_chain", "from_token", "to_token", "amount_usd", "region", "chain"})

// Refund counter: subset of reverts where the bridge returned capital to
// source (status "refunded") rather than an on-chain revert. Lets us split
// refund-rate from hard-fail-rate (reverts minus refunds).
bridgeRefunds = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "bridge_refunds_total",
Help: "Bridge transactions the provider refunded (capital returned to source)",
}, []string{"bridge", "from_chain", "to_chain", "from_token", "to_token", "amount_usd", "region", "chain"})

// Realized output that actually landed on the destination (on-chain fill).
bridgeRealizedOutputUSD = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_realized_output_usd",
Help: "USD value that actually landed on the destination chain (realized fill)",
}, []string{"bridge", "from_chain", "to_chain", "from_token", "to_token", "amount_usd", "region", "chain"})

// Execution slippage vs the quote: realized fee minus quote-projected fee.
// Positive means the execution cost more than the quote promised.
bridgeQuoteSlippageUSD = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_quote_slippage_usd",
Help: "Realized fee minus quote-projected fee (execution cost above what the quote promised)",
}, []string{"bridge", "from_chain", "to_chain", "from_token", "to_token", "amount_usd", "region", "chain"})

// Our own on-chain gas cost for this execution (approve + deposit), measured
// as the source-chain native balance delta. This is the cost WE bear, on top
// of the bridge's own fee, for the true all-in cost.
bridgeExecGasUSD = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_exec_gas_usd",
Help: "On-chain gas we paid (approve + deposit), source-chain native balance delta in USD",
}, []string{"bridge", "from_chain", "to_chain", "from_token", "to_token", "amount_usd", "region", "chain"})

// Error counter
bridgeErrors = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "bridge_errors_total",
Expand Down
1 change: 1 addition & 0 deletions harnesses/bridge-monitor/cmd/monitor/nearintents_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ func (e *Executor) executeNearIntents(route TestRoute, amountUSD float64, rawUni
result.Success = true
case "REFUNDED", "FAILED":
result.Reverted = true
result.Refunded = status == "REFUNDED"
default:
// Timed out in PROCESSING/PENDING: terminal-ambiguous. Leave Success
// false with the TxHash set so the caller treats it as in-flight.
Expand Down
23 changes: 23 additions & 0 deletions harnesses/bridge-monitor/cmd/monitor/tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,29 @@ func (tx *TxExecutor) getRelayStatus(requestID string) (*BridgeStatus, error) {
}

// Close closes all connections

// nativeBalanceUSD returns the native-token (ETH/SOL) balance of ownerAddr on
// chain, valued in USD. Used to measure the real gas we pay for an execution
// as the source-chain native balance delta (pre - post).
func (tx *TxExecutor) nativeBalanceUSD(chain, ownerAddr string) (float64, error) {
if strings.EqualFold(chain, "Solana") {
k, err := solana.PublicKeyFromBase58(ownerAddr)
if err != nil {
return 0, err
}
lamports, err := tx.solanaNativeBalance(k)
if err != nil {
return 0, err
}
return rawToFloat(lamports, 9) * TokenPriceUSD("SOL", 150), nil
}
wei, err := tx.evmNativeBalance(chain, common.HexToAddress(ownerAddr))
if err != nil {
return 0, err
}
return rawToFloat(wei, 18) * TokenPriceUSD("ETH", 3600), nil
}

func (tx *TxExecutor) Close() {
if tx.baseClient != nil {
tx.baseClient.Close()
Expand Down
Loading