In this protocol, it's a standard auction but the lowest price wins. If a user gets outbid, they get a refund but must call a function in order to perform the refund.
The sale is considered ended when the last NFT is sold. This triggers the payout to the seller and fee collector. The verification for paying out is done by checking if the current ID matches the final sale id.
There is an additional check that checks that that the current id does not equal the final id. Otherwise, we've tried to get an NFT that already been sold.
In the code, the function buy(uint256 _amount) amount variable is for the AMOUNT of NFTs you want to buy. If a user buys 0 NFTs, then the currentId is not set properly. The check from before about the auction being over doesn't work since the currentId is not set from the iteration within a loop. It's obviously lower than the final ID, since it's set to 0.
This results in the sale being made with a larger value than the current bid. Since the auction has ended, we're able to get a refund from this still. More importantly, the check on whether to transfer the funds to the feeReceiver and saleReceiver can be hit over and over again because of the if statement failing.
Zero iteration in the array causes this problem. Overall, a pretty neat bug that is common in the web3 space.