Skip to content

Resource Token Mint Event Deduplication Failure in Concurrent Settlement Finalization #36

Description

@elizabetheonoja-art

Resource Token Mint Event Deduplication Failure in Concurrent Settlement Finalization

Problem Statement

The src/settlement/finalizer.ts module finalizes resource token mint events after tariff evaluation completes. The finalizeMint() function at line 80 checks pending_mints for unprocessed events and submits them to the Soroban contract. When tariff evaluation completes for two resource types simultaneously (water and energy), both trigger finalizeMint() for the same batch. Both read pending_mints and see the same unprocessed events, and both submit identical mint transactions. The Soroban contract receives duplicate mint requests for the same resource token, minting twice the intended amount. The settlement balance sheet shows double the expected token supply.

State Invariants & Parameters

  • Resource types: water, energy, bandwidth (independent evaluation paths)
  • Mint submission: POST to Soroban RPC (idempotent if properly keyed)
  • Settlement batch: processed every 60s
  • Duplicate mint risk: 2× intended supply

Affected Code Paths

  • src/settlement/finalizer.ts:75-120 — Mint submission without dedup check
  • src/settlement/mintQueue.ts:40-65 — Pending mint queue management
  • src/billing/tariffFinalizer.ts:55-80 — Tariff completion triggers mint

Resolution Blueprint

  1. Add a processed_mints unique constraint on (batch_id, resource_type): INSERT INTO processed_mints (...) VALUES (...) ON CONFLICT DO NOTHING RETURNING id. If no row returned, mint was already processed — skip.
  2. Implement idempotency keys in Soroban mint: SHA256(batch_id || resource_type || 'mint') as the idempotency key. The contract checks the key before minting.
  3. Route all finalization through a single queue worker (BullMQ with resource-type concurrency limit of 1 per batch).
  4. Add a concurrent finalization test with both water and energy finalization triggering simultaneously and verify exactly one mint per resource type.

Labels

  • Complexity: Hardcore
  • Layer: Core-Engine
  • Type: Race-Condition

Metadata

Metadata

Assignees

Labels

Complexity: HardcoreIssues requiring deep systems-level engineering rigorGrantFox OSSIssue tracked in GrantFox OSSLayer: Core-EngineCore engine layerMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignType: Race-ConditionConcurrency and race condition related issues

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions