MegaETH → Terra tdec hits 'EXECUTION BLOCKED: exceeds maximum daily rate limit' on tiny 0.001 amount after multiple successful prior rows #130
Labels
No labels
agent:implement
agent:ready
backend
bug
cannot-reproduce
confirmed
desktop
docs
documentation
duplicate
enhancement
feature
frontend
good first issue
help wanted
high-risk
in-review
invalid
mobile
needs-triage
P0-critical
P1-high
P2-medium
P3-low
qa
QA
question
ready
report
responsive
security
security-escalate
smart-contract
solana
tablet
test-pass
ux
wallet-issue
wallet:keplr
wallet:metamask
wallet:station
wallet:walletconnect
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-bridge-monorepo#130
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Reproducible 2026-05-01: MegaETH → Terra tdec, 0.001 tokenc-cb input (0.000995 after fee), wallet 0xc46b15...80650.
Stepper goes through DEPOSIT + SUBMIT HASH + APPROVAL clean, then on COMPLETE step shows 'EXECUTION BLOCKED — The transfer amount exceeds the maximum daily rate limit. It cannot be executed even after the rate window resets. Contact support for assistance.'
xchain hash: 0xea7479193a3391ec98a61389576f9d465b40e8703816842bd7341960dd16535c
source tx: 0xcb13430aa30a65972960aa0b4df65da71137555c1abc0aa492ac98241e7a57bb
destination tx: 44C57ACE9139CEED38C2D6D257560A17022A98B600C0D4FEDF52873ACE49943A
Behavior is wrong because:
Likely a daily-cumulative cap collision: prior MegaETH outbound rows in this session (testa, testb, tdec to BSC/opBNB/Terra/Solana) may have filled the per-token-per-destination daily window and frontend is reporting 'exceeds maximum' on subsequent. Worth checking the daily cap accounting on tdec → Terra path specifically.
Same row family as #127 in the sense that the user-facing copy doesn't match what's actually wrong.
P2 medium. cc @PlasticDigits
mentioned in issue #123
Source-level analysis surfaces the root cause — decimal-scale comparison bug in the Terra rate-limit classifier.
The bug
src/services/terraBridgeQueries.ts:344has this comparison:The
|| amount > maxPerPeriodclause compares raw source-decimalamountto destination-decimalmaxPerPeriod. WhensrcDecimals > destDecimals(which is the case for every MegaETH → Terra outbound: 18 → 6), this falsely firespermanently-blockedeven on tiny payouts.Repro mapping (my #130 filing)
1_000_000_000_000_000n(1e15)maxPerPeriodstored in Terra contract in 6 decimals; even generously 1000 tokens cap =1_000_000_000n(1e9)amount > maxPerPeriod→1e15 > 1e9→permanently-blockedfalsely firespayoutAmount > maxPerPeriodwould correctly evaluate1e3 > 1e9→ false (the small-amount intent)The
||short-circuits to permanently-blocked before the correctpayoutAmountcomparison can pass.Why the new EVM classifier (#127,
eaa3d0a) does NOT have this bugsrc/services/evmExecutionRateLimit.ts(new code from your #127 fix):Single comparison on normalized
payoutAmountonly. Architecturally correct.The Terra classifier predates this work and never got the same fix.
Suggested fix
Drop the
|| amount > maxPerPeriodclause interraBridgeQueries.ts:344-345:The
payoutAmountvalue is already normalized to dest decimals vianormalizeBridgeAmountToDestDecimals(amount, srcDecimals, destDecimals)at line 329 — same helper that mirrorsBridge._normalizeDecimals1:1.Severity
P2-medium (unchanged from original filing). Affects every MegaETH/EVM → Terra outbound where
srcDecimals > destDecimals— i.e., essentially all of them, since MegaETH is 18-decimal and Terra native tokens are typically 6 decimals.The on-chain transfer itself is fine (deposit + submit hash + approval all clean per my repro hashes); only the frontend's pre-execution gate is falsely blocking the COMPLETE step.
Acceptance
terraBridgeQueries.ts:344permanently-blocked check uses onlypayoutAmount > maxPerPeriod(parity with EVM classifier).evmExecutionRateLimit.test.ts:77-82("normalizes decimals like the bridge contract") for the Terra path: 18-decimal source 0.001, 6-decimal dest, sensiblemaxPerPeriod→ expectkind === 'ok', not'permanently-blocked'.cc @PlasticDigits
mentioned in commit
5411c7d1c5mentioned in commit
95f8fd50bb/cc @brouie
Merged on main (merge
95f8fd5) — Terra rate-limit permanent-block now usespayoutAmount > maxPerPeriodonly, same pattern ascomputeEvmExecutionRateLimitStatus(EVM classifier from GL-127). Your root-cause write-up was validated before implementation:max_per_periodis expressed in destination base units, soamount > maxPerPeriodmixing raw source wei-scale amounts (e.g. 18→6 decimals) falsely returnedkind: permanently-blocked.What landed
packages/frontend/src/services/terraBridgeQueries.ts— dropped|| amount > maxPerPeriod; doc clarified INV-UX2-TERRA1 intent.terraBridgeQueries.test.ts— three Vitest cases: GL-130 regression (18d tiny amount, generous 6d cap ⇒ ok), permanent when normalized payout > cap, temporary when payout > remaining (normalized, aligned withevmExecutionRateLimit.test.tsnormalization idea).docs/FRONTEND_BRIDGE_INVARIANTS.md,docs/frontend.md,skills/agent-frontend-bridge-chains.md— INV-UX2-TERRA1, cross-links, GL-131 doc merge reconciled upstream.Leaving the issue open for your sign-off.
Checklist for you to verify
0.001source amount repro path — Transfer Status reaches COMPLETE without the red “maximum daily rate limit … cannot be executed even after … resets” when the payout is genuinely under the Terra period cap.remaining_amountbut <=max_per_period.max_per_period.cd packages/frontend && npm run test:run -- src/services/terraBridgeQueries.test.tspasses (plus fullnpm run test:unitif you want).Thanks for the pinpoint note on line 344 — that made this a surgical fix.
mentioned in issue #127
Production deploy gap — sign-off blocked
Verified prod bundle on bridge.cl8y.com today: footer reads
v0.1.345 · 27a5e42. RepomainHEAD is currently at95f8fd5, which is the merge commit containing all four fixes (#127eaa3d0a, #128b6c5b5a, #130 Terra||clause drop, #13167a48e4). Prod is therefore still on the pre-fix bundle and none of the four fixes are live yet.Confirming repro on prod (proves bundle is pre-fix):
ETHtext fallback while MetaMask is on MegaETH (chain 4326). This is the clean #131-D pre-fix behavior —getChainLogoPathhas no branch for 4326, falls through togetGasSymboldefaultETH.Cannot run mainnet sign-off on the verification checklist for #127 / #128 / #130 / #131 until prod cuts to current HEAD (or whichever release commit contains the four fixes).
Will re-run the combined live walk on bridge.cl8y.com once deploy is confirmed:
Plus the 4 #123 blocked rows pick-up that rides on #128 / #130 fixes.
cc @PlasticDigits
mentioned in issue #128
mentioned in issue #131
@Brouie bridge.cl8y.com frontend is now deployed at latest commit.
queued in the bundled bridge live-walk along with #128 — see https://gitlab.com/PlasticDigits/cl8y-bridge-monorepo/-/work_items/128#note_3322750554 for timing.
mentioned in issue #132