Root + Impact
Description
function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
uint256 sentAmount = msg.value;
@> uint256 previousKingPayout = 0;
uint256 currentPlatformFee = 0;
uint256 amountToPot = 0;
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
platformFeesBalance = platformFeesBalance + currentPlatformFee;
amountToPot = sentAmount - currentPlatformFee;
pot = pot + amountToPot;
currentKing = msg.sender;
lastClaimTime = block.timestamp;
playerClaimCount[msg.sender] = playerClaimCount[msg.sender] + 1;
totalClaims = totalClaims + 1;
claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;
@> Missing calculate payout for previous King
emit ThroneClaimed(
msg.sender,
sentAmount,
claimFee,
pot,
block.timestamp
);
}
Risk
Likelihood:
Impact:
-
Impact 1: Its missing that logic, not as described in the document.
-
Impact 2: Previous King will receive less than expected.
Proof of Concept
-
pendingWinnings
state is updated only one time when declareWinner
-
and it add pot
for currentKing
, not previous King
function declareWinner() external gameNotEnded {
...
pendingWinnings[currentKing] = pendingWinnings[currentKing] + pot;
...
}
Recommended Mitigation
contract Game is Ownable {
+ uint256 previousKingPayoutPercentage;
+ function updatePreviousKingPayoutPercentage(uint256 percentage) external onlyOwner isValidPercentage(percentage) {
+ previousKingPayoutPercentage = percentage;
+
+ emit UpdatePreviousKingPayoutPercentage(percentage);
+ }
function claimThrone() external payable gameNotEnded nonReentrant {
...
+ currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
- uint256 previousKingPayout = 0;
+ uint256 previousKingPayout = currentPlatformFee * previousKingPayoutPercentage / 100;
uint256 currentPlatformFee = 0;
uint256 amountToPot = 0;
- // Calculate platform fee
- currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
...
- platformFeesBalance = platformFeesBalance + currentPlatformFee;
+ platformFeesBalance = platformFeesBalance + currentPlatformFee - previousKingPayout;
amountToPot = sentAmount - (currentPlatformFee);
pot = pot + amountToPot;
+ address previousKing = currentKing;
currentKing = msg.sender;
+ pendingWinnings[previousKing] = pendingWinnings[previousKing] + previousKingPayout;
...
}
}