Exchange counts a wallet's fresh fill twice for 1–3 seconds and rejects its next order

Status Closed — not planned
Maintainer reply None cached
Activity 1 comment · opened Oct 6, 2026 · closed Oct 9, 2026

問題

錢包餘額明明夠,交易所還是回 400 not enough balance,單被拒。

發現

被拒時交易所回的訊息(金額單位 1e-6 pUSD):

not enough balance / allowance: the balance is not enough -> balance: <X>, sum of matched orders: <M>, order amount (inc. fees): <Y>

balance 是交易所記的錢包餘額,sum of matched orders 是交易所認為已經撮合、還沒結算的金額,
order amount 是這張單含手續費的金額。交易所要 balance − sum of matched orders ≥ order amount
才收單。

拿這些數字對照 trader log:

  • balance 和 trader 本地記的餘額幾乎一樣。本地餘額沒有記錯。
  • sum of matched orders 等於這支錢包前一筆成交的金額。
  • 前一筆成交到這張被拒,間隔都在 1.2 到 3.0 秒之間,沒有超過 3 秒的。

10-05 的一支錢包,三個訊號接連進來:

  1. 餘額 $111.15。第一個訊號分給它一張 $48.22 的單,交易所接受。本地餘額扣成 $62.93。
  2. 1.2 秒後,第二個訊號分給它一張 $62.88 的單。$62.88 沒有超過 $62.93,照餘額是夠的。

交易所拒絕,回的 balance 是 $64.19,sum of matched orders 是 $47.07(第一張單不含手續費的金額)。
交易所算的可用餘額是 $64.19 − $47.07 = $17.12。

  1. 再過 1.1 秒,第三個訊號分給它一張 $64.18 的單,交易所接受。

前一筆再小也一樣。10-04 的一支錢包:餘額 $955.20,成交一張 $5.56 的單,本地餘額 $949.64。
1.5 秒後分到一張 $949.63 的單,被拒:交易所回的 balance 是 $949.64,sum of matched orders 是 $5.56。

原因(2026-10-01 用實驗確認)

一筆成交之後,交易所的兩個數字在不同時間更新:

  • balance 在這筆成交被打包上鏈的時候扣掉,大約是送單後 1.0 到 2.0 秒。
  • sum of matched orders 要等到這筆成交的狀態變成 MINED 才把它拿掉,大約是送單後 2.1 秒。

balance 已經扣掉、sum of matched orders 還沒拿掉的這段時間,同一筆成交被扣了兩次。
MINED 之後恢復正常。

從 MATCHED 到 MINED 要多久,量了 1,388 筆成交:中位數 2.05 秒,98.4% 在 2.5 秒以內,
大約 1.5% 落在 4 秒左右(晚了一個區塊)。

提議方向

兩個做法,都是每支錢包各自計時,從交易所接受那張單的時候開始算。

  1. 直接鎖住錢包 4 秒:這 4 秒內不再把任何單分給這支錢包。

影響:兩個訊號相隔不到 4 秒的時候,第二個訊號會跳過剛用過的錢包,改用下一支。
大約 8% 的訊號和前一個訊號相隔不到 3 秒。

  1. 多鎖一份餘額,錢包照常交易:這 4 秒內,這支錢包的可用餘額再扣一份前一筆成交的金額,

和交易所的算法一樣。餘額扣完還夠的單照樣可以分給它,只有填到剛好用光的單會改派別支。
4 秒後把這份扣款放回去。

兩個做法都不改本地餘額本身,也不改拒單時把本地餘額設成 balance 的做法。

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗