The mismatch between numberOfWinners set via setNumberOfWinners and the actual winners array passed during assertResults causes claimRewards() → getReward() in ProportionalToXPReward to always revert. This results in a lock of reward funds, as rewards can never be claimed once the game concludes, making it a critical vulnerability
Root cause:
setNumberOfWinners(sessionId, n) sets the expected number of winners.assertResults(sessionId, winners), the protocol does not enforce that the passed winners array length equals the stored numberOfWinners[sessionId].require(
numberOfWinners[sessionId] == winners.length,
NumberOfWinnersMismatch(sessionId, winners.length)
);
Additionally, since setNumberOfWinners is restricted to the Created state, the mismatch cannot be corrected once the game has started.
Code References: https://github.com/hackenproof-public/engage-protocol/blob/8476672096d591459dff56517956668f1f94b133/src/reward/ProportionalToXPReward.sol#L88 https://github.com/hackenproof-public/engage-protocol/blob/8476672096d591459dff56517956668f1f94b133/src/session/DefaultSession.sol#L136 https://github.com/hackenproof-public/engage-protocol/blob/8476672096d591459dff56517956668f1f94b133/src/SessionManager.sol#L540 https://github.com/hackenproof-public/engage-protocol/blob/8476672096d591459dff56517956668f1f94b133/src/reward/ProportionalToXPReward.sol#L68
Impact:
Lock of Funds as claimRewards() will always reverts
Mitigation: Consider these options accordingly
// Option 1: Enforce consistency during results assertion
require(
numberOfWinners[sessionId] == winners.length,
NumberOfWinnersMismatch(sessionId, winners.length)
);
Or
// Option 2: Allow updating until results are finalized
require(
state == SessionState.Created || state == SessionState.Started,
"Invalid state"
);
setNumberOfWinners(sessionId, 2).assertResults(sessionId, [addr1]) is executed with a single winnernumberOfWinners[sessionId] = 2, but winners.length = 1 (or vice versa)claimRewards(), execution reverts due to NumberOfWinnersMismatch.Coded POC attached. Refer @audit comments Update MajorityBaseTest.t.sol Create new file FullGameTestICX.t.sol
cmd: forge test --mt "test_FullGameFlow1" -vvvv