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: 43/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/main/contracts/matchingPolicies/StandardPolicyERC1155.sol#L33 https://github.com/code-423n4/2022-10-blur/blob/main/contracts/matchingPolicies/StandardPolicyERC1155.sol#L59 https://github.com/code-423n4/2022-10-blur/blob/main/contracts/BlurExchange.sol#L145
Buyer can receive less ERC1155 tokens than expected but pay too much.
Alice sells ERC1155 token with tokenId 1
and amount 10 for total price 10 ether.
Bob matches Alice's order paying 10 ether and expects to receive 10 tokenId 1
.
Bob actually only get 1 tokenId 1
but paid 10 ether to Alice.
This is because _canMatchOrders
always returns amount
= 1 for ERC1155 tokens
(uint256 price, uint256 tokenId, uint256 amount, AssetType assetType) = _canMatchOrders(sell.order, buy.order);
due to
https://github.com/code-423n4/2022-10-blur/blob/main/contracts/matchingPolicies/StandardPolicyERC1155.sol#L33 https://github.com/code-423n4/2022-10-blur/blob/main/contracts/matchingPolicies/StandardPolicyERC1155.sol#L59
That is to say Bob pays the total price
(10 ether) when calling _executeFundsTransfer
and receive for 1 amount when calling _executeTokenTransfer
which leads to Bob lose 9 ether.
Manual review
canMatchMakerAsk
and canMatchMakerBid
should return the order said amount of tokens.
contract StandardPolicyERC1155 is IMatchingPolicy { 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 ); } function canMatchMakerBid(Order calldata makerBid, Order calldata takerAsk) external pure override returns ( bool, uint256, uint256, uint256, AssetType ) { return ( (makerBid.side != takerAsk.side) && (makerBid.paymentToken == takerAsk.paymentToken) && (makerBid.collection == takerAsk.collection) && (makerBid.tokenId == takerAsk.tokenId) && (makerBid.matchingPolicy == takerAsk.matchingPolicy) && (makerBid.price == takerAsk.price) && (makerBid.amount == takerAsk.amount), makerBid.price, makerBid.tokenId, makerBid.amount, AssetType.ERC1155 ); } }
#0 - GalloDaSballo
2022-10-13T22:27:32Z