https://github.com/hackenproof-public/rain-contracts
The enterOption function of the RainPool contract incorrectly charges the platformShare fee twice when executing buy orders that match existing sell orders in the order book.
At the start of enterOption, the protocol deducts the platform fee (platformShare) from the user’s total amount, regardless of whether the funds will be used to buy directly from the protocol or through existing sell orders.
If the order is instead matched with sell orders via _executeSellOrder, the function charges the platformShare again — resulting in double counting of fees on the same amount of funds.
While these double-charged fees aren’t immediately lost by the individual user (since the platformShare is deducted from the winning pool upon market close), they directly impact all users by inflating the platform’s share and reducing the pool’s distributable amount.
To fix the issue, move the platformShare fee calculation in enterOption to the end of the function.
Compute it based on totalAmountUsed, which represents the funds used to buy directly from the protocol (getReturnedShares) and excludes amounts already used for sell order executions (_executeSellOrder).
This ensures consistent fee behavior and prevents double-charging when orders are matched through the order book.
user1 enter option 1 and place a sell order for it.user2 buy shares through enterOption. Since there’s a sell order available, the purchase will execute _executeSellOrder, triggering the platform fee twice.user3 place a buy order with the same amount of funds through placeBuyOrder.platformShare increases roughly 2x more when using enterOption than when using placeBuyOrder for the same purchase volume./test folder and running forge test --mt test_Charging_Fees_Twice --fork-url https://arb1.arbitrum.io/rpc -vvventerOption with option 1 and creates a sellOrder through placeSellOrderenterOption with option 1 and amount half of the cost of user1's sell order.placeBuyOrder with option 1 and amount half of the cost of user1's sell order.platformShare by ~5000 baseToken, while user3 increased platformShare by ~2450 baseToken.baseToken, and by filling a sell order, user3 paid double the platformShare leading to losses for all the users.The platformShare should increase proportionally for both users.
enterOption charges roughly double the fee compared to placeBuyOrder for the same volume.