Distribution of NXL failing during round settlement will not deactivate the product, resulting in a new raffle with new rewards available
_distributeRound calls nxlToken.distributeReward directly via try/catch, swallowing exhaustion failures and leaving the product active for a new round with no NXL available.
Description
The _distributeRound function distributes the NXL winner bonus by calling nxlToken.distributeReward(winner, product.nxlWinnerBonus) directly instead of using the _distributeNXL helper, which encapsulates the exhaustion handling logic for the NXL token supply.
When distributeReward fails because the NXL reward supply is exhausted, the try/catch in _distributeRound simply ignores the failure and does not trigger _handleNXLExhaustion, so products[productId].active remains true and the product is not deactivated.
Vulnerable Scenario:
The following steps help understand the issue:
- The last ticket of a raffle is bought and rewards distribution occurs normally
- The winner is selected, but there isn't enough NXL rewards for them
nxlToken.distributeRewardfails silently, and the product remains active- A new rounds is started, without NXL available anymore
Recommendation
Replace the direct try nxlToken.distributeReward(winner, product.nxlWinnerBonus) {} catch {} call in _distributeRound with a call to _distributeNXL(winner, product.nxlWinnerBonus, productId) so that exhaustion of NXL rewards always triggers _handleNXLExhaustion and deactivates the product as intended.
At the end of NexumManager::_distributeRound:
- try nxlToken.distributeReward(winner, product.nxlWinnerBonus) {} catch {}+ _distributeNXL(winner, product.nxlWinnerBonus, productId);
Resolution
Nexalo: Fixed.
Zealynx: Verified. Fixed.

