The platform is expected to collect a fee from each claimThrone()
action, which can later be withdrawn by the game operator to generate revenue.
However, the withdrawPlatformFees()
function has no access control, allowing any external user to withdraw all accumulated platform fees, regardless of their role or ownership status.
Likelihood:
This occurs every time any user calls withdrawPlatformFees()
after platform fees have been accumulated through throne claims.
There is no ownership check, so it will happen even if the caller is not the game deployer or owner.
Impact:
All platform revenue can be stolen by a malicious actor at any time.
The operator loses economic incentives, which could halt or discourage continued development and operation of the protocol.
This test demonstrates how any external user can withdraw all platform fees without being the contract owner.
First, player1
calls claimThrone
and pays the required claimFee
, which is partially stored as platformFees
.
Then, player2
—a malicious player who is not the owner or deployer—calls withdrawPlatformFees()
.
The balance of player2
is checked before and after the call, showing that they successfully received the platform’s funds.
This proves that ownership checks are missing, and anyone can steal fees from the game.
To fix this issue, the withdrawPlatformFees()
function should only be callable by the contract owner.
The suggested patch adds a check:
require(msg.sender == owner, "Only owner can withdraw platform fees");
This ensures only the trusted deployer or operator can access the accumulated fees.
Using OpenZeppelin’s Ownable
contract, you can simplify this logic with the onlyOwner
modifier for improved readability and standardization.
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.