If a participant no longer wishes to participate in the event, they can claim the money by calling the refund() function, which returns all assets to the participant. But the function does not remove the participant from the participants list.
From the participant's point of view, a refund means not attending the dinner. However, the host will still count them because the address is still marked as a participant
pragma solidity 0.8.27;
import {Test, console2} from "forge-std/Test.sol";
import {ChristmasDinner} from "../src/ChristmasDinner.sol";
import {ERC20Mock} from "../lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol";
contract XmasDinnerTest is Test {
ChristmasDinner cd;
ERC20Mock wbtc;
ERC20Mock weth;
ERC20Mock usdc;
uint256 constant DEADLINE = 7;
address deployer = makeAddr("deployer");
address user1;
function setUp() public {
vm.stopPrank();
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();
user1 = makeAddr("user1");
usdc.mint(user1, 2e18);
vm.prank(user1);
usdc.approve(address(cd), 2e18);
}
function testRefundAndStayParticipant() public {
assert(!cd.getParticipationStatus(user1));
assert(usdc.balanceOf(user1) == 2e18);
assert(usdc.balanceOf(address(cd)) == 0);
vm.prank(user1);
cd.deposit(address(usdc), 1e18);
assert(cd.getParticipationStatus(user1));
assert(usdc.balanceOf(user1) == 1e18);
assert(usdc.balanceOf(address(cd)) == 1e18);
vm.prank(user1);
cd.refund();
assert(cd.getParticipationStatus(user1));
assert(usdc.balanceOf(user1) == 2e18);
assert(usdc.balanceOf(address(cd)) == 0);
}
}
function refund() external nonReentrant beforeDeadline {
address payable _to = payable(msg.sender);
_refundERC20(_to);
_refundETH(_to);
+ participant[msg.sender] = false;
emit Refunded(msg.sender);
}