F-2025-0002·logic-error

NXL distribution failure during ticket purchase leads to permanent fund lockup and broken lottery rounds

Fixedrafflelotteryvrf
TL;DR

When NXL rewards are exhausted, the product deactivates mid-transaction after payment is collected and tickets are assigned, leaving the round incomplete with funds permanently trapped.

Severity
CRITICAL
Impact
HIGH
Likelihood
HIGH
Method
MManual review
CAT.
Complexity
LOW
Exploitability
HIGH
02Section · Description

Description

The buyTickets() and buySpecificTickets() functions accept payment and assign tickets before attempting to distribute NXL rewards. When NXL rewards are exhausted, the _distributeNXL() function catches the failure and calls _handleNXLExhaustion(), which immediately deactivates the product. This creates a critical state where:

  1. User payment has already been collected
  2. Tickets have already been assigned
  3. Product becomes deactivated mid-transaction
  4. Round remains incomplete with insufficient tickets to trigger winner selection
solidity
// Current flow in buyTickets()
function buyTickets(...) external validProduct(productId) {
// Step 1: Product is active, validation passes
// Step 2: Payment collected
stablecoin.transferFrom(msg.sender, address(this), totalPrice);
// Step 3: Tickets assigned
ticketOwner[productId][roundId][ticketNumber] = msg.sender;
round.ticketsSold++;
// Step 4: NXL distribution fails
_distributeNXL(msg.sender, nxlAmount, productId);
// -> catch block triggers _handleNXLExhaustion(productId)
// -> products[productId].active = false
// Product now deactivated but transaction continues
}

Vulnerable Scenario:

  1. NXL rewards pool becomes exhausted or nearly exhausted
  2. First buyer after exhaustion calls buyTickets() for FLASH product (needs 1000 tickets)
  3. User pays 1 USDT, receives ticket #0
  4. NXL distribution fails, product deactivated
  5. Round now shows: 1 ticket sold / 1000 needed
  6. All subsequent buyers revert due to validProduct modifier: require(products[productId].active, "Product inactive")
  7. Round can never reach round.ticketsSold >= product.maxTickets
  8. VRF randomness is never requested
  9. Winner is never selected
  10. All funds collected in this round are permanently locked in the contract
03Section · Impact

Impact

This vulnerability results in permanent fund lockup and complete system failure once NXL rewards are depleted. The contract accepts payment and assigns tickets, then fails during NXL distribution and immediately deactivates the product mid-transaction. The round is left in an irrecoverable state with tickets sold but insufficient capacity to ever trigger winner selection through VRF.

All stablecoin payments collected in the affected round become permanently trapped in the NexumManager contract. The contract provides no refund mechanism for incomplete rounds and no administrative function exists to manually resolve or complete stuck rounds, making fund recovery impossible.

The first victim of NXL exhaustion pays full price for their tickets but receives no NXL rewards, with no clear error message indicating the failure. All subsequent purchase attempts revert immediately at the validProduct modifier, completely blocking further participation in that lottery product.

04Section · Recommendation

Recommendation

Replace the current try/catch logic in _distributeNXL() with explicit state validation:

solidity
// Fixed implementation
function _distributeNXL(address recipient, uint256 amount, uint256 productId) private {
if (amount == 0) return;
// Explicitly check NXL availability before distribution
uint256 available = nxlToken.getAvailableRewards();
if (available < amount) {
// Actually exhausted, handle it appropriately
_handleNXLExhaustion(productId);
return;
}
// Safe to distribute, any failure here is a real error that should revert
nxlToken.distributeReward(recipient, amount);
}
05Section · Resolution

Resolution

Nexalo: Fixed.

Zealynx: Verified. Fixed.

Status
Fixed
F-2025-0002

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx