function attendPerformance(uint256 performanceId) external {
require(hasPass(msg.sender), "Must own a pass");
hasAttended[performanceId][msg.sender] = true;
@> uint256 multiplier = getMultiplier(msg.sender);
BeatToken(beatToken).mint(msg.sender, performances[performanceId].baseReward * multiplier);
}
function test_ZeroMultiplierSilent() public {
vm.prank(alice);
festivalPass.buyPass{value: 0.1 ether}(VIP_PASS);
vm.prank(organizer);
uint256 perfId = festivalPass.createPerformance(block.timestamp + 1 hours, 2 hours, 100e18);
vm.warp(block.timestamp + 90 minutes);
MaliciousTransferrer malicious = new MaliciousTransferrer(address(festivalPass), alice, bob);
vm.prank(alice);
festivalPass.safeTransferFrom(alice, address(malicious), VIP_PASS, 1, "");
vm.prank(address(malicious));
malicious.attackAttendance(perfId);
assertTrue(festivalPass.hasAttended(perfId, address(malicious)), "Attendance marked");
assertEq(beatToken.balanceOf(address(malicious)), 0, "Zero BEAT minted");
}
contract MaliciousTransferrer {
FestivalPass festival;
address recipient;
uint256 constant VIP_PASS = 2;
bool transferred;
constructor(address _festival, address _alice, address _recipient) {
festival = FestivalPass(_festival);
recipient = _recipient;
}
function attackAttendance(uint256 perfId) external {
festival.attendPerformance(perfId);
}
function onERC1155Received(address, address, uint256, uint256, bytes calldata) external returns (bytes4) {
if (!transferred) {
transferred = true;
festival.safeTransferFrom(address(this), recipient, VIP_PASS, 1, "");
}
return this.onERC1155Received.selector;
}
}
function attendPerformance(uint256 performanceId) external {
require(hasPass(msg.sender), "Must own a pass");
+ uint256 multiplier = getMultiplier(msg.sender); // Calculate multiplier early
+ require(multiplier > 0, "No valid pass owned"); // Explicit check
require(!hasAttended[performanceId][msg.sender], "Already attended");
require(block.timestamp >= lastCheckIn[msg.sender] + COOLDOWN, "Cooldown not met");
hasAttended[performanceId][msg.sender] = true;
lastCheckIn[msg.sender] = block.timestamp;
- uint256 multiplier = getMultiplier(msg.sender);
BeatToken(beatToken).mint(msg.sender, performances[performanceId].baseReward * multiplier);
}