Vulnerability Details
The closePot
function, can only be called by the owner. The function transfers the mangerCutPercent to the msg.sender
when called. The problem here is that themsg.sender
is the ContestManager.sol
contract and there is no way to recover any token sent to it.
function closePot() external onlyOwner {
if (block.timestamp - i_deployedAt < 90 days) {
revert Pot__StillOpenForClaim();
}
if (remainingRewards > 0) {
uint256 managerCut = remainingRewards / managerCutPercent;
i_token.transfer(msg.sender, managerCut);
uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
for (uint256 i = 0; i < claimants.length; i++) {
_transferReward(claimants[i], claimantCut);
}
}
}
Impact
Loss of Manager Funds.
Tools Used
Manual Analysis
Recommendations
Allow the caller to pass a recipient address when closing the pot.
Apply the changes to the ContestManager contract.
function _closeContest(address contest) internal {
Pot pot = Pot(contest);
- pot.closePot();
+ pot.closePot(msg.sender);
}
Apply the changes to the Pot contract.
- function closePot() external onlyOwner {
+ function closePot(address to) external onlyOwner {
if (block.timestamp - i_deployedAt < 90 days) {
revert Pot__StillOpenForClaim();
}
if (remainingRewards > 0) {
uint256 managerCut = remainingRewards / managerCutPercent;
- i_token.transfer(msg.sender, managerCut);
+ i_token.transfer(to, managerCut);
for (uint256 i = 0; i < claimants.length; i++) {
_transferReward(claimants[i], claimantCut);
}
}
}