fix(swap): sign gas from one LCD simulate at 1.2× #1361

Merged
PlasticDigits merged 1 commit from fix/1360-swap-auto-gas into main 2026-09-27 12:58:58 +00:00

Summary

Closes #1360.

Retail two-hop swaps were signing a static gas_wanted of 1,910,000 and getting included with code 11 around 1,937,97x gas used. Swap-shaped executes now LCD-simulate once and sign ceil(gas_used × 1.2) in uluna when that gas_used is between 100,000 and 15,000,000. Anything else (timeout, bad HTTP, zero, negative, or the 147,000,000 Station figure) signs the existing global per-hop envelope. The CL8Y → UST1 3,000,000 pair floor is no longer a fee input.

Acceptance

  • 1. gas_used 1,937,976 signs gas_wanted 2,325,572 in uluna. The same multiplier applies for every CW20 address.
  • 2. Timeout, HTTP 500, empty body, gas_used 0, -1, and 147,000,000 fall back to 1,910,000 for two hops. 147,000,000 is not multiplied by 1.2. Values under 100,000 also fall back.
  • 3. A successful CL8Y → UST1 simulate uses ceil(sim × 1.2), not 3,000,000. A failed simulate of that route uses 1,910,000. A failed wrap + one hop uses 1,800,000. No pair-address function picks the number.
  • 4. Swap and Trade market Network fee use the same resolver: 1.2× after a successful simulate, otherwise the per-hop uluna amount.
  • 5. Submit calls simulate once and broadcastTx once. An included code 11 does not broadcast again.
  • 6. Route slippage above 5% does not sit next to a different 2.63% worst-hop line. Use {amount} instead is hidden while phase is recovering or confirming, and that control only edits the pay field.
  • 7. Out of gas for gasWanted: 1910000, gasUsed: 1937976 does not say “try again” or “vary slightly”. The sentence is a constant.
  • 8. New fixtures and docs use token contracts and synthetic gas_used values. They do not embed a trader address.

Not done here

  • Read-only Columbus-5 simulate. make verify-issue-1360 skips it until VERIFY1360_SIMULATE_ADDRESS is set. The script does not broadcast.
  • Signed Keplr swap (gas_used < gas_wanted, on-screen Network fee matches the wallet). The issue leaves that as a later wallet check.

Test plan

  • make verify-issue-1360
  • make verify-issue-1328
  • Related broadcast, network-fee, and Swap page fee tests
  • make measure-issue-1360 with a funded simulate account
  • One signed CL8Y → KENA swap on columbus-5

Docs

Known residual, accepted in the issue: if simulate fails, two-hop CL8Y routes still sign 1,910,000. Station WalletConnect atomic post remains G-AUTO-8.

## Summary Closes #1360. Retail two-hop swaps were signing a static `gas_wanted` of 1,910,000 and getting included with `code` 11 around 1,937,97x gas used. Swap-shaped executes now LCD-simulate once and sign `ceil(gas_used × 1.2)` in `uluna` when that `gas_used` is between 100,000 and 15,000,000. Anything else (timeout, bad HTTP, zero, negative, or the 147,000,000 Station figure) signs the existing global per-hop envelope. The CL8Y → UST1 3,000,000 pair floor is no longer a fee input. ## Acceptance - [x] 1. `gas_used` 1,937,976 signs `gas_wanted` 2,325,572 in `uluna`. The same multiplier applies for every CW20 address. - [x] 2. Timeout, HTTP 500, empty body, `gas_used` 0, `-1`, and 147,000,000 fall back to 1,910,000 for two hops. 147,000,000 is not multiplied by 1.2. Values under 100,000 also fall back. - [x] 3. A successful CL8Y → UST1 simulate uses `ceil(sim × 1.2)`, not 3,000,000. A failed simulate of that route uses 1,910,000. A failed wrap + one hop uses 1,800,000. No pair-address function picks the number. - [x] 4. Swap and Trade market Network fee use the same resolver: 1.2× after a successful simulate, otherwise the per-hop uluna amount. - [x] 5. Submit calls simulate once and `broadcastTx` once. An included `code` 11 does not broadcast again. - [x] 6. Route slippage above 5% does not sit next to a different 2.63% worst-hop line. **Use {amount} instead** is hidden while phase is `recovering` or `confirming`, and that control only edits the pay field. - [x] 7. Out of gas for `gasWanted: 1910000, gasUsed: 1937976` does not say “try again” or “vary slightly”. The sentence is a constant. - [x] 8. New fixtures and docs use token contracts and synthetic `gas_used` values. They do not embed a trader address. ## Not done here - [ ] Read-only Columbus-5 simulate. `make verify-issue-1360` skips it until `VERIFY1360_SIMULATE_ADDRESS` is set. The script does not broadcast. - [ ] Signed Keplr swap (`gas_used < gas_wanted`, on-screen Network fee matches the wallet). The issue leaves that as a later wallet check. ## Test plan - [x] `make verify-issue-1360` - [x] `make verify-issue-1328` - [x] Related broadcast, network-fee, and Swap page fee tests - [ ] `make measure-issue-1360` with a funded simulate account - [ ] One signed CL8Y → KENA swap on columbus-5 ## Docs - [ADR 0014](docs/adr/0014-swap-auto-gas.md) invariants **G1360-1–G1360-8** - [ADR 0013](docs/adr/0013-cl8y-ust1-gas-floor.md) records the 3M figure as history, not a fee input - [`skills/AGENTS_SWAP_AUTO_GAS.md`](skills/AGENTS_SWAP_AUTO_GAS.md) and [`skills/AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md) Known residual, accepted in the issue: if simulate fails, two-hop CL8Y routes still sign 1,910,000. Station WalletConnect atomic post remains **G-AUTO-8**.
fix(swap): sign gas from one LCD simulate at 1.2×
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
e4edb8c9ea
Static two-hop gas of 1,910,000 was below measured CL8Y router use. Successful simulates now sign ceil(gas_used × 1.2); failures keep the global per-hop fallback, and the CL8Y to UST1 pair floor is no longer a fee input.
PlasticDigits deleted branch fix/1360-swap-auto-gas 2026-09-27 12:58:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!1361
No description provided.