Open code423n4 opened 2 years ago
Duplicate of #131 and #314.
Confirmed the scenario as described.
Buyers specifying just a collection and no specific tokens is a basically a floor sweep which has become common for NFTs. In this scenario, the warden shows how a buyer can end up spending money and get nothing in return. This is a High risk issue.
Lines of code
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityOrderBookComplication.sol#L68-L116
Vulnerability details
The call stack: matchOneToManyOrders() -> _matchOneMakerSellToManyMakerBuys() -> _execMatchOneMakerSellToManyMakerBuys() -> _execMatchOneToManyOrders() -> _transferMultipleNFTs()
Based on the context, a maker buy order can set
OrderItem.tokens
as an empty array to indicate that they can accept any tokenId in this collection, in that case,InfinityOrderBookComplication.doTokenIdsIntersect()
will always returntrue
.However, when the system matching a sell order with many buy orders, the
InfinityOrderBookComplication
contract only ensures that the specified tokenIds intersect with the sell order, and the total count of specified tokenIds equals the sell order's quantity (makerOrder.constraints[0]
).This allows any maker buy order with same collection and
empty tokenIds
to be added tomanyMakerOrders
as long as there is another maker buy order with specified tokenIds that matched the sell order's tokenIds.https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityOrderBookComplication.sol#L68-L116
However, because
buy.nfts
is used asOrderItem
to transfer the nfts from seller to buyer, and there are no tokenIds specified in the matched maker buy order, the buyer wont receive any nft (_transferERC721s
does nothing, 0 transfers) despite the buyer paid full in price.https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L763-L786
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L1080-L1092
PoC
2
Punk with2 WETH
and specified tokenIds =1
,2
1
Punk with1 WETH
and with no specified tokenIds.3 WETH
for2
Punk and specified tokenIds =1
,2
matchOneToManyOrders()
match Charlie's sell order #3 with buy order #1 and #2, Alice received2
Punk, Charlie received3 WETH
, Bob paid1 WETH
and get nothing in return.Recommendation
Change to: