A player who never referred anyone can receive a referral reward by calling ReferralSystem.claimReferralReward()
Proof of Concept
It appears that ReferralSystem.claimPerDraw() returns referral rewards for a player's own tickets even when that player hasn't referred anyone; this doesn't seem to be the purpose of referral rewards from reading their documentation.
POC: first remove "abstract" keyword from test/ReferralSystemBase.sol so these tests run (I noticed they were not running by default). Then add the following POC test:
function testClaimNoReferrer() public {
uint128 currentDraw = lottery.currentDraw();
vm.startPrank(user); // no referrer
buySameTickets(currentDraw, uint120(0x0F), address(0), 1);
vm.stopPrank();
executeDraw();
uint128[] memory drawIds = new uint128[](1);
drawIds[0] = 0;
uint prevUserBalance = lotteryToken.balanceOf(user);
vm.prank(user);
// this should be zero as the user didn't refer anyone
uint claimedReward = referralSystem.claimReferralReward(drawIds);
// this should fail but passes as a referral reward is received anyway,
// though this is less than if the user self-referred (see my other report)
assert(claimedReward > 0);
console.log(claimedReward); // outputs 961538500000000000000000
uint afterUserBalance = lotteryToken.balanceOf(user);
// user balance has increased
assert(afterUserBalance > prevUserBalance);
uint diffUserBalance = afterUserBalance - prevUserBalance;
// proves that the users balance has increased by the claimed referral reward
assertEq(diffUserBalance, claimedReward);
}
Tools Used
manual inspection
Recommended Mitigation Steps
Change ReferralSystem.claimPerDraw() to not return referral rewards simply for buying tickets, when the player has not actually referred anyone.
Lines of code
https://github.com/code-423n4/2023-03-wenwin/blob/main/src/ReferralSystem.sol#L145-L149
Vulnerability details
Impact
A player who never referred anyone can receive a referral reward by calling ReferralSystem.claimReferralReward()
Proof of Concept
It appears that ReferralSystem.claimPerDraw() returns referral rewards for a player's own tickets even when that player hasn't referred anyone; this doesn't seem to be the purpose of referral rewards from reading their documentation.
POC: first remove "abstract" keyword from test/ReferralSystemBase.sol so these tests run (I noticed they were not running by default). Then add the following POC test:
Tools Used
manual inspection
Recommended Mitigation Steps
Change ReferralSystem.claimPerDraw() to not return referral rewards simply for buying tickets, when the player has not actually referred anyone.