fix: serialize concurrent buys per market + always verify on-chain payout before redeem
executeBuy (race condition): - Multiple WebSocket events for the same market can arrive concurrently. All calls saw no existing position and all proceeded to buy → 3x fills. - Added _buyQueue (Map<conditionId, Promise>) that chains each buy for the same market after the previous one. Second call now sees the filled position and respects maxPositionSize. redeemer (gas estimation error): - Gamma API can return resolved=true before payoutDenominator is written on-chain. Calling redeemPositions when payoutDenominator==0 causes the contract to revert → UNPREDICTABLE_GAS_LIMIT from ethers.js. - Now always verify on-chain payout after the API check. If on-chain payout not set yet, skip and retry next interval. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
526fc7a057
commit
365dc4e164
@@ -140,17 +140,22 @@ export async function checkAndRedeemPositions() {
|
||||
|
||||
for (const position of positions) {
|
||||
try {
|
||||
// 1. Check via Gamma API
|
||||
// 1. Quick check via Gamma API (low cost)
|
||||
const resolution = await checkMarketResolution(position.conditionId);
|
||||
const isResolved = resolution?.resolved;
|
||||
const apiResolved = resolution?.resolved;
|
||||
|
||||
if (!isResolved) {
|
||||
// 2. Fallback: on-chain check
|
||||
const onChain = await checkOnChainPayout(position.conditionId);
|
||||
if (!onChain.resolved) continue;
|
||||
logger.info(`Market resolved on-chain: ${position.market}`);
|
||||
} else {
|
||||
logger.info(`Market resolved: ${position.market}`);
|
||||
if (!apiResolved) continue; // Not resolved yet — check again next interval
|
||||
|
||||
logger.info(`Market resolved via API: ${position.market}`);
|
||||
|
||||
// 2. ALWAYS verify on-chain payout before calling redeemPositions.
|
||||
// Gamma API can report "resolved" before payoutDenominator is written
|
||||
// on-chain. Calling redeemPositions with payoutDenominator == 0 causes
|
||||
// the contract to revert → gas estimation failure.
|
||||
const onChain = await checkOnChainPayout(position.conditionId);
|
||||
if (!onChain.resolved) {
|
||||
logger.info(`On-chain payout not set yet for ${position.market} — will retry next interval`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 3. Simulate or execute real redeem
|
||||
|
||||
Reference in New Issue
Block a user