Missing Price Update Leads to User Being Unable to Receive Tickets
_getTicketsToMint reads getPriceNoOlderThan() from Pyth without first calling updatePriceFeeds(), so the price feed is stale and the post-swap ticket flow always reverts.
Description
The _getTicketsToMint function in the contract does not call updatePriceFeeds() before retrieving the price data from the Pyth oracle using getPriceNoOlderThan(). This function fetches the latest available price within a specified time window, but without updating the price feed beforehand, the contract may be using stale data. As a result, the process of receiving tickets after a swap fails.
According to the Pyth official documentation, it is recommended to call updatePriceFeeds() before using price data to ensure it is fresh and up-to-date.
PythStructs.Price memory price = IPyth(i_pyth).getPriceNoOlderThan(config.priceFeedId,config.noOlderThan);
Impact
Not calling updatePriceFeeds() causes the function to always revert, making users unable to receive tickets.
Recommendation
To mitigate this issue, ensure that the price feed is updated before retrieving the price from the oracle. This can be achieved by calling updatePriceFeeds() with the appropriate price update data before retrieving the price. Keep in mind that this updateData should be obtained off-chain using the Hermes API as recommended by the Pyth official documentation and passed as an argument to the function.
Implementation pattern:
- Update the swap functions in the
IMonadexV1Routerinterface to have an extraupdateDataparameter:
function swapExactTokensForTokens(uint256 _amountIn,uint256 _amountOutMin,address[] calldata _path,address _receiver,uint256 _deadline,MonadexV1Types.PurchaseTickets memory _purchaseTickets,bytes[] memory updateData) external returns (uint256[] memory, uint256);
-
Add the extra
updateDataparameter to the swap functions in theMonadexV1Routercontract and call_purchaseRaffleTicketswith theupdateDataparameter. -
Add the extra
updateDataparameter to the_purchaseRaffleTicketsfunction and callpurchaseTicketsfrom theMonadexV1Rafflecontract withupdateData. -
Create an
_updatePriceFeedsfunction in theMonadexV1Rafflecontract:
function _updatePriceFeeds(bytes[] memory updateData) internal {uint256 updateFee = IPyth(i_pyth).getUpdateFee(updateData);IPyth(i_pyth).updatePriceFeeds{ value: updateFee }(updateData);}
- Add the extra
updateDataparameter to thepurchaseTicketsfunction and call_updatePriceFeedsbefore callingpreviewPurchase, which calls_getTicketsToMint, where thegetPriceNoOlderThanfunction is called.

