Open code423n4 opened 2 years ago
There were several reports of this issue. Accepting this one as the primary since it's the best description that also included a test demonstrating the problem. This helps a lot to understand and confirm the issue.
This is a High risk issue. The PoC demonstrates how a maker specifying a bundle of NFTs could incorrectly have one ERC1155 item in that bundle processed several times by the taker - the bundle is not fully accepted as expected, the item processed multiple times is essentially overfilled, and this may be abused to the taker's advantage when the NFTs are not valued the same.
Lines of code
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityOrderBookComplication.sol#L154-L164 https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityOrderBookComplication.sol#L68-L116 https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L336-L364 https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L178-L243
Vulnerability details
Impact
When any user provides a
sellOrder
and they are trying to sell multiple tokens from n (n > 1) differentERC1155
collections in a single order, hakcers can get the tokens of most expensive collections (with n times of the original amount) by paying the same price.In short, hackers can violate the user-defined orders.
Root Cause
The logic of
canExecTakeOrder
andcanExecMatchOneToMany
is not correct.Let's
canExecTakeOrder(OrderTypes.MakerOrder calldata makerOrder, OrderTypes.OrderItem[] calldata takerItems)
as an example, whilecanExecMatchOneToMany
shares the same error.Specifically, it first checks whether the number of selling item in
makerOrder
matches with the ones intakerItems
. Note that the number is an aggregated one. Then, it check whether all the items intakerItems
are within the scope defined bymakerOrder
.The problem comes when there are duplicated items in
takerItems
. The aggregated number would be correct and all taker's Items are indeed in the order. However, it does not meanstakerItems
exactly matches all items inmakerOrder
, which means violation of the order.For example, if the order requires
and the taker provides
The taker can grabs two
mock1155Contract1
tokens by paying the order which tries to sell amock1155Contract1
token and amock1155Contract2
token. Whenmock1155Contract1
is much more expensive, the victim user will suffer from a huge loss.As for the approving issue, the users may grant the contract unlimited access, or they may have another order which sells
mock1155Contract1
tokens. The attack is easy to perform.Proof of Concept
First put the
MockERC1155.sol
under thecontracts/
directory:And then put
poc.js
under thetest/
directory.And run
Note that the passed test denotes a successful hack.
Tools Used
Manual inspection.
Recommended Mitigation Steps
I would suggest a more gas-consuming approach by hashing all the items and putting them into a list. Then checking whether the lists match.