Repository navigation
fix(bridge): estimate the Axelar fee locally when the Axelar API is unavailable - #2958
Merged
Merged
Conversation
…navailable Mainnet requests to api.gmp.axelarscan.io intermittently receive a Cloudflare challenge (403) or a rate limit (429). In browsers the CORS preflight fails, getAxelarFee read `error.response.data` on an undefined response, and the bridge widget stalled on the fee skeleton. getAxelarFee now tries the Axelar API on every call with a 5s timeout and, on any failure, estimates the fee from the destination gas price and USD prices from the checkout API: (gas limit + 250k base gas) × max(gas price, 1 gwei) × 2, plus 5 cents The 250k base gas covers Axelar's base fee, which tracks destination gas (~185k gas observed for Ethereum on 2026-10-07). Axelar refunds unused gas to the sender, so the estimate errs high. Against mainnet quotes on 2026-10-07 the fallback is ~2.3x for withdrawals and ~3.6x for deposits. On testnet, withdrawals estimate ~50x Axelar's quote because Sepolia gas sits below the 1 gwei floor and Axelar's testnet quotes use synthetic token prices. Each fallback logs a console warning prefixed `[imtbl-bridge]` with the reason, and fee responses carry `bridgeFeeSource: 'axelar' | 'fallback'`. If the fallback also fails, getAxelarFee throws AXELAR_GAS_ESTIMATE_FAILED. Also drop the Content-Type header from the GMP status GET so browsers send it without a preflight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
View your CI Pipeline Execution ↗ for commit eadb9ca
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
ermyas
enabled auto-merge
October 6, 2026 23:18
lfportal
reviewed
Oct 6, 2026
Axelar error replies ({error: true, message}), 4xx responses other than
403/429, and unparseable 2xx bodies now throw AXELAR_GAS_ESTIMATE_FAILED,
as before the fallback was added. The fallback estimate runs only for no
response (including CORS rejections), timeouts, 403 (Cloudflare
challenge), 429 and 5xx.
The fallback multiplier is now max(gasMultiplier, 2) for a numeric
gasMultiplier, and 2 for 'auto', so a caller asking for a larger buffer
keeps it during an outage. The gasMultiplier docs on the fee request
types describe this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
Mainnet requests to
api.gmp.axelarscan.iointermittently get a Cloudflare challenge (403) or rate limit (429). In browsers the CORS preflight fails,getAxelarFeedereferenced an undefinederror.response, and the bridge widget stalled on the fee skeleton. Testnet is unaffected.getAxelarFeenow tries the Axelar API on every call (5s timeout). When the API is unavailable (no response incl. CORS rejections, timeout, 403, 429, 5xx) it estimates the fee locally; Axelar error replies and other 4xx still throwAXELAR_GAS_ESTIMATE_FAILED.msg.sender(RootERC20Bridge.sol:411,ChildERC20Bridge.sol:328), so the estimate errs high.[imtbl-bridge] Axelar fee API unavailable, using fallback estimate {reason, …};getFeeandgetUnsignedBridgeBundledTxfee data carrybridgeFeeSource: 'axelar' | 'fallback'.AXELAR_GAS_ESTIMATE_FAILED.GETno longer sendsContent-Type, so browsers skip the preflight.Fallback vs Axelar
Testnet withdrawals overshoot because Sepolia gas sits below the 1 gwei floor and Axelar's testnet quotes use synthetic token prices. A fallback withdrawal on testnet needs ~15 test IMX for the fee.
Testing
value= amount + fallback fee.HTTP 429falls back.Follow-ups
BridgeReviewSummarynever clearsloadingif the fee fetch throws (BridgeReviewSummary.tsx:287-296), so a double failure still shows a stuck skeleton.🤖 Generated with Claude Code