If a user performs at least two deposits and a transfer in the same block it can encourage the receiver to front-run or reorg if one of the deposits has a much higher value.
Because the deposits are identified by NFT tokenIDs. In a scenario where:
User makes two deposits. First gets ID: 1 and has a a large amount of tokens deposited. Second gets ID: 2 and has low amount of tokens deposited.
Same depositer makes a transfer to a receiver. And the transfer contains the NFT with ID: 2 which had a low amount of tokens deposited.
In this scenario the receiver can be incetivized enough to try front-run or do a reorg attack where if the first two deposits are front-runned or another deposit is put in front (reorg), their corresponding IDs will shift by one (ID: 1 -> ID: 2, ID: 2 -> ID: 3), but the amounts will not. Because of this now the transfer with ID: 2 will contain large amount of tokens and the receiver will benefit.
Receiver can manipulate transaction order to steal a higher value deposit. But this requires specific conditions (multiple transactions in a single block) and original depositer has to send a deposit to the attacker or someone willing to attack.
This can also in theory happen by accident if a user sends all the transaction one after another, but they are not executed in the expected order.
Similar attack can be done using block re-ordering, but would require considerably more resources.
The attack can result in considerable funds lost, but due to special conditions required (multiple transactions and malicious receiver) - Medium.
Manual review + foundry tests.
Few possible approaches.
1) Intead of TokenID, specfiy the amount user wants to transfer. And perform similar functionality to fees, where the code goes through all sender owned deposits and takes necessary amounts. Using those amounts creates a new deposit for the receiver.
2) Add a maxSent parameter to transfer which would verify that no more than maxSent tokens are transfered with the NFT.
3) Add a timelock on deposits to prevent immediate transfers.
4) Use a deterministic hash like NFT ID = hash(++numMinted, bptAmount)
even if the transfer is front-runned the ID will no longer correspond to the original one. And even if they still match the deposit amount will be the same and therefore same Bpt amount will be transferred.
Likelyhood: Informational/Very Low, 2 deposits and transfer of the second one, and the value of the first one should be higher. All of that in the same block. Winning the lotto seems almost more probable. Impact: Medium/High, transfer the first NFT instead the second one.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.