Submitted by gasperpre, also found by evan, hansfriese, SmartSek, and orion
https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L173 
https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L304 
https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L127
The raffle creator is not required to actually give the NFT away. The NFT that is used for the raffle is transferred to the contract when startDraw is executed. Before that, the NFT is in the hands of the creator. This means that he might create a raffle to make users buy NFTs required to participate and then refuse to draw a winner and keep the NFT to himself. Furthermore, he might not even be the owner of the NFT in the first place, which he can achieve by flash loaning the NFT in order to pass the ownerOf check in initialize function.
Example 1
Example 2
Example 3
Transfer the NFT to the contract at the time of creation of the raffle.  You can do that by approving the factory contract to transfer the token and do the transfer in makeNewDraw function between cloning and initialization.
Remember to remove token transfer from startDraw function.
Notice that the creator can still claim NFT after a week, without drawing, by executing lastResortTimelockOwnerClaimNFT. To prevent that, I would recommend adding a check in lastResortTimelockOwnerClaimNFT, if a winner was drawn.
So now a user can trust that the NFT is locked in the contract, and it will be claimable only by a winner (or creator if the winner does not claim it). However, there is still no guarantee that the winner will actually be drawn, because the creator has to manually execute startDraw function.
To fix this, I would recommend allowing anyone to execute startDraw function, so there is no need to rely on the creator. But we would need to limit the time window of when startDraw can be executed, so users have the time to get tokens before the drawing. That can be done by introducing a new state variable firstDrawTime, that acts as a timestamp after which drawing can happen.
Notice that now the NFT can only be claimed after the winner has been drawn. This means that we are depending on ChainLink VRF to be successful. For that reason I would recommend adding a role that has the power to change the VRF subscription or restore the NFT in cases where the winner is not picked in reasonable time. This role would be given to protocol owner (owner of the factory) / DAO / someone who would be considered as most reliable.
gzeon (judge) decreased severity to Medium and commented:
iainnash (Forgeries) confirmed
