PancakeSwap is a platform for swapping tokens and many other functionality. In this blog post, the author goes into the lottery functionality. The vulnerable code persisted in several other projects, since they had forked PancakeSwap.
When claiming a ticket, an array of tickets can be used. The flow of code verifies that the ticket has not been claimed yet and adds the reward for each ticket in a variable. Once the verification has been done, the reward is sent to the user.
This becomes a problem when the tickets are NOT all unique. In particular, the verification step does NOT mark the ticket as used. So, the same ticket can be provided multiple times. None of the checks validated that this happened.
To pull this off, you would need to win a lottery ticket, which isn't very hard. Once you win the lottery, call multiClaim() with the same winning ticket up to 255 times. I think there is a hard limit on the amount of elements for dynamic arrays in Solidity.
Overall, a really simple bug that could have lost all user funds. The fix was to set the lottery ticket specified to have claimed the reward during the verification step.