Platform: Code4rena
Start Date: 05/10/2022
Pot Size: $50,000 USDC
Total HM: 2
Participants: 80
Period: 5 days
Judge: GalloDaSballo
Id: 168
League: ETH
Rank: 40/80
Findings: 1
Award: $114.82
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: dipp
Also found by: 0x4non, 0x52, 0xRobocop, 0xc0ffEE, 8olidity, Ch_301, Jeiwan, Junnon, KIntern_NA, Lambda, M4TZ1P, MiloTruck, Nyx, PaludoX0, Ruhum, RustyRabbit, Soosh, TomJ, Trust, arcoun, aviggiano, bardamu, cryptonue, csanuragjain, d3e4, enckrish, exd0tpy, hansfriese, jayphbee, joestakey, ladboy233, minhquanym, minhtrng, nicobevi, obront, polymorphism, rokinot, romand, rotcivegaf, rvierdiiev, saian, serial-coder, trustindistrust, zzykxx
114.8239 USDC - $114.82
https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/BlurExchange.sol#L145 https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/matchingPolicies/StandardPolicyERC1155.sol#L59
In case a user would like to sell or buy an amount >1 of ERC1155 token, only 1 unit would be transferred even if orders match.
Let's say Alice intend to sell 5 ERC1155 tokens at 10ETH: this is possible because OrderStruct admits to set an amount >1 https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/lib/OrderStructs.sol#L19 Bobs agrees and set a buy order with the same quantity and price. He will receive just one token paying the price required by Alice because of the following code: Bobs calls "execute" function, which in turns calls "_canMatchOrders" function which returns "amount". "amount" is used as parameter in "_executeTokenTransfer" to set he amount of tokens to be transferred; "_canMatchOrders" calls IMatchingPolicy( ).canMatchMakerAsk (or canMatchMakerBid) which returns always amount == 1 Therefore the amount of token transferred to Bob will be always == 1 even if he paid for 5 tokens.
Review with Visual studio
Mitigation depends on devs willing: if they do not want to allow trading of amounts > 1 then it should be checked that amount ==1 whenever an order is submitted by maker if they want to allow trading of amounts of ERC1155 tokens > 1 then function canMatchMakerAsk shall be as following (canMatchMakerBid is similar)
function canMatchMakerAsk(Order calldata makerAsk, Order calldata takerBid) external pure override returns ( bool, uint256, uint256, uint256, AssetType) { return ( (makerAsk.side != takerBid.side) && (makerAsk.paymentToken == takerBid.paymentToken) && (makerAsk.collection == takerBid.collection) && (makerAsk.tokenId == takerBid.tokenId) && (makerAsk.matchingPolicy == takerBid.matchingPolicy) && (makerAsk.price == takerBid.price) && (makerAsk.amount == takerBid.amount), makerAsk.price, makerAsk.tokenId, makerAsk.amount, AssetType.ERC1155 ); }
#0 - GalloDaSballo
2022-10-13T22:30:21Z