Withdrawals are matched by amount+address instead of nonce, and the Ethereum write pins no chain ID
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 38/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- blockchain, frontend
Direzione di ricerca
Start with src/components/modals/WithdrawalModal.tsx, src/hooks/wallet/useWithdraw.ts, and the SDK signingClient.ts initiation path. Compare the sibling hooks that use ETH_CHAIN_ID, then trace how initiation results and withdrawal events are represented. Done means the exact request identity is preserved, the Ethereum write is chain-pinned, stale requests cannot win, and the documented migration state is consistent.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
From the external repository review (10 Sep 2026). Verified, and there is a second defect in the same path the review flags only in passing.
a) Withdrawals are matched by amount + address, not identity
src/components/modals/WithdrawalModal.tsx:117-127:
const matching = withdrawals
.filter((w: any) => w.base_address?.toLowerCase() === targetBaseAddress.toLowerCase() && w.amount === targetAmount)
.sort((a: any, b: any) => {
if (a.status === "signed" && b.status !== "signed") return -1;
...
});
const found = matching[0];
signed sorts ahead of everything regardless of age, and there is no created_at > initiatedAt floor. A stale signed request for the same (address, amount) wins over the one just initiated, and its nonce is what gets handed to the Ethereum write (line 136 → 228).
The root cause is upstream: no nonce is available from initiation. initiateWithdrawal (SDK signingClient.ts:1076-1121) discards everything except result.transactionHash, throwing away the tx events that carry the nonce. The amount+address heuristic is a workaround for that, not a lapse in the modal alone — so fixing this properly requires an SDK change too (see poker-vm#2609, which is about the same discarded result object).
Minor: initiatedAmountRef (declared :64, written :180, reset :89) is never read — dead state.
b) The Ethereum write pins no chain
src/hooks/wallet/useWithdraw.ts:41-51 calls mutate({ address, abi, functionName, args }) with no chainId — wagmi uses whatever chain the wallet happens to be on.
This is inconsistent within the same codebase: useAllowance.ts:17, useWalletBalance.ts:17 and useDecimals.ts:15 all pass chainId: ETH_CHAIN_ID, and Dashboard.tsx:340-342 explicitly switchChain. useWithdraw and WithdrawalModal do neither, and there is no chain assertion anywhere in the withdrawal path.
Compounding it, the app configures networks = [mainnet, base] and the SDK memo for this flow still reads "Initiate USDC withdrawal to Base chain" — leftover from the migration. A user on Base would send a withdrawal at an address that means something different there.
This matters more given poker-vm#2611: the bridge digest has no domain separation, so a signature is not bound to a chain either. Neither layer pins it.
Suggested plan
- Return the nonce from initiation. Have the SDK surface the
MsgInitiateWithdrawalresponse / tx events rather than only the hash, then persist that nonce and resume that exact request. This is the fix; everything else is mitigation. - Until then, make the heuristic safe: require
created_at >= initiatedAt, and prefer the newest match rather than anysignedone. A stale signed request should never outrank a fresh initiation. - Pin the chain explicitly in
useWithdraw(chainId: ETH_CHAIN_ID) and assert the connected chain before enabling the button, matching the sibling hooks. - Reconcile against Ethereum: check
withdrawNonces[nonce]on the contract before presenting a request as claimable, so a consumed nonce cannot be retried. - Persist modal flow state so closing and reopening resumes rather than restarting.
- Fix the stale "Base chain" memo, and delete
initiatedAmountRef.
Original review finding 10.
- Lingua principale
- TypeScript
- Stelle
- 2
- Fork
- 5
- Merge medio
- 23h 23m
- PR unite (30g)
- 97
Preparare l'ambiente
Non abbiamo ancora controllato i file di configurazione di questo progetto. Parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di block52/ui
-
enhancement tech debt
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
feat(ui): player notes and tags — click a seat to note a player; tag icons (fish, shark, tight, loose…) show by their pillForse già presa @Dzeezbtc l’ha presa 2 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
-
chore(ui): move existing inline null/empty and typeof checks to the guardsForse già presa @bitcoinbrisbane l’ha presa 3 giorni fa. Apertarefactor tech debt UI
block52/ui#937 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
architecture refactor tech debt
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
I maintainer di solito rispondono entro 1 giorno
Issue simili
-
normalizePath removes the Windows device namespace prefixForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
caprover/caprover-frontend#273 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
ai-driven-dev/framework#1147 ·
I maintainer di solito rispondono entro 1 giorno
-
agent-ui bug p2
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
cybersemics/em#6232 ·
I maintainer di solito rispondono entro 1 giorno