Create Trading Pair broken in dapp: #276 fee not attached + CREATE_PAIR_GAS_LIMIT below actual gas #345

Closed
opened 2026-06-09 02:58:21 +00:00 by Brouie · 12 comments
Brouie commented 2026-06-09 02:58:21 +00:00 (Migrated from gitlab.com)

Severity: High — the Create Trading Pair page fails on every attempt; permissionless pair creation is unusable from the UI. Fails safely (no fund risk), contract is fine.
Reachability: any user, 100% of create-pair attempts.
Found: #337 CP-00-02.

Repro

Create page → two whitelisted, unpaired CW20s (both show "Code ID whitelisted") → Create Pair:

failed to execute message; message index: 0: Pair creation requires 100000000 uluna attached: execute wasm contract failed

Root cause — two separate bugs

1. #276 creation fee not attached. frontend-dapp/src/services/terraclassic/factory.ts createPair() calls executeTerraContract(walletAddress, factory, { create_pair: {...} }) with no coins argument, so zero uluna is sent. The factory requires pair_creation_fee_uluna (live value 100000000) attached as funds, so it reverts. (origin/main still has this — not fixed upstream.)

2. CREATE_PAIR_GAS_LIMIT too low. terraGas.ts pins it at 800000, but a real create_pair (instantiate pair + LP token) costs 871,552 gas. So even once the fee is attached, it OOGs ("needed more gas than estimated"). Same class as the add-liquidity gas gap.

Contract is fine (isolation)

create_pair via terrad with the fee attached succeeds:

  • terrad tx wasm execute <factory> '{"create_pair":{"asset_infos":[IRON, AMBER]}}' --amount 100000000uluna --gas auto
  • tx 855DEFDE…, code 0, gas_used=871552, events create_pair → instantiate → reply_instantiate_pair. New IRON/AMBER pair instantiated.

Suggested fix

  • createPair() attach coins: [{ denom: 'uluna', amount: <fee> }]. Read the fee from the factory config (pair_creation_fee_uluna) rather than hardcode, so it tracks governance changes (and skip/attach 0 when the fee is 0).
  • Bump CREATE_PAIR_GAS_LIMIT 800000 → ~1000000 (over the measured 871,552 with headroom).

New pairs are discovered lazily by the indexer — sync_all_pairs runs once at startup (poller.rs:22); after that a pair is only added when the parser first sees a swap/fill/placement on it (parser.rs:367/777/1068). So a freshly-created empty pair won't appear in the pool/markets list until it's traded or the indexer restarts (#311 design). Worth a look as part of the create→discover flow.

**Severity:** High — the Create Trading Pair page fails on every attempt; permissionless pair creation is unusable from the UI. Fails safely (no fund risk), contract is fine. **Reachability:** any user, 100% of create-pair attempts. **Found:** #337 CP-00-02. ## Repro Create page → two whitelisted, unpaired CW20s (both show "Code ID whitelisted") → Create Pair: ``` failed to execute message; message index: 0: Pair creation requires 100000000 uluna attached: execute wasm contract failed ``` ## Root cause — two separate bugs **1. #276 creation fee not attached.** `frontend-dapp/src/services/terraclassic/factory.ts` `createPair()` calls `executeTerraContract(walletAddress, factory, { create_pair: {...} })` with **no `coins`** argument, so zero `uluna` is sent. The factory requires `pair_creation_fee_uluna` (live value `100000000`) attached as funds, so it reverts. (origin/main still has this — not fixed upstream.) **2. `CREATE_PAIR_GAS_LIMIT` too low.** `terraGas.ts` pins it at `800000`, but a real `create_pair` (instantiate pair + LP token) costs **871,552** gas. So even once the fee is attached, it OOGs ("needed more gas than estimated"). Same class as the add-liquidity gas gap. ## Contract is fine (isolation) `create_pair` via terrad **with** the fee attached succeeds: - `terrad tx wasm execute <factory> '{"create_pair":{"asset_infos":[IRON, AMBER]}}' --amount 100000000uluna --gas auto` - tx `855DEFDE…`, code 0, `gas_used=871552`, events `create_pair → instantiate → reply_instantiate_pair`. New IRON/AMBER pair instantiated. ## Suggested fix - `createPair()` attach `coins: [{ denom: 'uluna', amount: <fee> }]`. Read the fee from the factory config (`pair_creation_fee_uluna`) rather than hardcode, so it tracks governance changes (and skip/attach 0 when the fee is 0). - Bump `CREATE_PAIR_GAS_LIMIT` 800000 → ~1000000 (over the measured 871,552 with headroom). ## Related (separate, lower priority) New pairs are discovered lazily by the indexer — `sync_all_pairs` runs once at startup (`poller.rs:22`); after that a pair is only added when the parser first sees a swap/fill/placement on it (`parser.rs:367/777/1068`). So a freshly-created **empty** pair won't appear in the pool/markets list until it's traded or the indexer restarts (#311 design). Worth a look as part of the create→discover flow.
Brouie commented 2026-06-09 02:59:12 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
Brouie commented 2026-06-09 03:12:43 +00:00 (Migrated from gitlab.com)

The same gas-underestimate class shows up on the fee-tier register, flagging here since it's the same root. The dapp register (feeDiscount.ts register -> {register:{tier_id}}) isn't handled in getGasLimitForTx, so it falls through to BASE_GAS_LIMIT (200000). Measured register gas_used=208940 -> OOGs the same way ("needed more gas than estimated"). Contract is fine (terrad register tier 9 = code 0, get_discount 9500 bps).

So the fixed gas limits in terraGas.ts look broadly uncalibrated vs current contract costs:

  • add-liquidity 500000 < 507509 (MR !843)
  • create-pair 800000 < 871552 (this issue)
  • register -> BASE_GAS_LIMIT 200000 < 208940

Might be worth a holistic pass — measure each execute path's real gas and set limits with headroom (or simulate per-tx) rather than chasing them one bug at a time.

The same gas-underestimate class shows up on the fee-tier register, flagging here since it's the same root. The dapp register (feeDiscount.ts `register` -> `{register:{tier_id}}`) isn't handled in `getGasLimitForTx`, so it falls through to `BASE_GAS_LIMIT` (200000). Measured `register` gas_used=208940 -> OOGs the same way ("needed more gas than estimated"). Contract is fine (terrad register tier 9 = code 0, get_discount 9500 bps). So the fixed gas limits in terraGas.ts look broadly uncalibrated vs current contract costs: - add-liquidity 500000 < 507509 (MR !843) - create-pair 800000 < 871552 (this issue) - register -> BASE_GAS_LIMIT 200000 < 208940 Might be worth a holistic pass — measure each execute path's real gas and set limits with headroom (or simulate per-tx) rather than chasing them one bug at a time.
PlasticDigits commented 2026-06-09 06:48:27 +00:00 (Migrated from gitlab.com)

mentioned in commit 1f1933956f

mentioned in commit 1f1933956f3e440b8e89b0a0dd729e94a93bcb2e
PlasticDigits commented 2026-06-09 06:53:24 +00:00 (Migrated from gitlab.com)

mentioned in merge request !845

mentioned in merge request !845
PlasticDigits commented 2026-06-09 06:53:39 +00:00 (Migrated from gitlab.com)

MR !844 opened

Changes: createPair() reads pair_creation_fee_uluna and attaches uluna coins; CREATE_PAIR_GAS_LIMIT → 1M; Create Pair page shows fee.

Verify

  • npm test -- factory.test.ts
  • Create Pair with two whitelisted unpaired CW20s — tx code 0
  • gas_used ≥ 871552

Follow-up: indexer lazy empty-pair discovery (#311) unchanged.

## MR !844 opened **Changes:** `createPair()` reads `pair_creation_fee_uluna` and attaches uluna coins; `CREATE_PAIR_GAS_LIMIT` → 1M; Create Pair page shows fee. ### Verify - [ ] `npm test -- factory.test.ts` - [ ] Create Pair with two whitelisted unpaired CW20s — tx code 0 - [ ] `gas_used` ≥ 871552 **Follow-up:** indexer lazy empty-pair discovery (#311) unchanged.
ghost1 commented 2026-06-09 06:53:47 +00:00 (Migrated from gitlab.com)

mentioned in merge request !847

mentioned in merge request !847
ghost1 commented 2026-06-09 06:53:50 +00:00 (Migrated from gitlab.com)

mentioned in merge request !849

mentioned in merge request !849
PlasticDigits commented 2026-06-09 06:53:52 +00:00 (Migrated from gitlab.com)

mentioned in merge request !844

mentioned in merge request !844
ghost1 commented 2026-06-09 06:53:52 +00:00 (Migrated from gitlab.com)

mentioned in merge request !846

mentioned in merge request !846
ghost1 commented 2026-06-09 06:53:52 +00:00 (Migrated from gitlab.com)

mentioned in merge request !848

mentioned in merge request !848
PlasticDigits commented 2026-06-09 07:06:00 +00:00 (Migrated from gitlab.com)

mentioned in commit e7fba864e5

mentioned in commit e7fba864e5d689bf06431bc33f051cc741b4bf6a
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-09 07:06:00 +00:00
Brouie commented 2026-06-10 01:51:42 +00:00 (Migrated from gitlab.com)

mentioned in issue #353

mentioned in issue #353
Sign in to join this conversation.
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#345
No description provided.