Summary
In ChristmasDinner.sol, the function setDeadline() checks whether the state variable deadlineSet is set true. If it isn't the host can change the deadline state variable repeatedly.
Vulnerability Details
Once the deadline is set by the host, it should not be able to be changed.
Here is the POC:
pragma solidity 0.8.27;
import {Test, console} from "forge-std/Test.sol";
import {ChristmasDinner} from "../src/ChristmasDinner.sol";
import {ERC20Mock} from "../lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol";
contract ChristmasDinnerTest is Test {
ChristmasDinner cd;
ERC20Mock wbtc;
ERC20Mock weth;
ERC20Mock usdc;
uint256 constant DEADLINE = 7;
address deployer = makeAddr("deployer");
function setUp() public {
wbtc = new ERC20Mock();
weth = new ERC20Mock();
usdc = new ERC20Mock();
vm.startPrank(deployer);
cd = new ChristmasDinner(address(wbtc), address(weth), address(usdc));
vm.warp(1);
cd.setDeadline(DEADLINE);
vm.stopPrank();
}
function test_tryResettingDeadlineAsHost() public {
vm.startPrank(deployer);
uint256 timestamp = block.timestamp;
cd.setDeadline(8);
cd.setDeadline(9);
cd.setDeadline(10);
assertEq(cd.deadline(), timestamp + 10 days);
vm.stopPrank();
}
}
Impact
A malicious host can repeatedly change the deadline, while the participants believe that it's a set once only value.
Tools Used
Text editor.
Recommendations
Set deadlineSet to true like this:
function setDeadline(uint256 _days) external onlyHost {
if(deadlineSet) {
revert DeadlineAlreadySet();
} else {
deadline = block.timestamp + _days * 1 days;
deadlineSet = true;
emit DeadlineSet(deadline);
}
}