briVault::_getWinnerShares loops through the briVault::userAddress[] array to store the amount the user bet on the winning country. Store operations are expensive and if the briVault::userAddress[] become large, looping through it can exceed the gas limit.
Likelihood: Medium
Reason 1: This can happen when a lot of players participates to the game.
Reason 2: This can happen when an attacker join the game multiple times using the same stakedAsset (this is also a vulnerability) and gets pushed multiple times (also a vulnerability) into the briVault::userAddress. However, the attacker will lose some fees and gas fee during the attack with no explicit reward.
Impact: High
Impact 1: Denial of service will make the owner unable to call briVault::selectWinner() to select winner and make the game unable to continue.
This proof of concept is to be run inside the provided briVault.t.sol using forge test --mt testDOS -vvvv --gas-limit 45000000.The user1 deposited 5 tokens and joined the game 40000 times.Then when the owner tries to call briVault::setWinner(), the evm reverts with error: EvmError: ReentrancySentryOOG because it has exceeded the block gas limit of 45000000 on Ethereum.
Consider actively tracking the number of shares in each country during joinEvent and cancelParticipation using a mapping and check if the user is already in the briVault:userAddress with a mapping when joining to not push the same user several times.
The _getWinnerShares() function is intended to iterate through all users and sum their shares for the winning country, returning the total.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.