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: 45/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
The functions StandardPolicyERC1155:canMatchMakerAsk
and StandardPolicyERC1155:canMatchMakerBid
incorrectly return 1
as the order amount
, which makes executeOrder
transfer only one ERC1155 token from the seller to the buyer, while the buyer pays the full price of the order.
The test scenario below does not pass. The seller creates an order of 3 NFTs ERC1155 and the buyer executes that order with a matching order. Instead of receiving 3 NFTs, the buyer receives only 1 NFT.
diff --git a/tests/execution.test.ts b/tests/execution.test.ts index 7b115b7..3b06a1b 100644 --- a/tests/execution.test.ts +++ b/tests/execution.test.ts @@ -127,6 +127,37 @@ export function runExecuteTests(setupTest: any) { feeRecipientBalanceWeth.add(fee), ); }); + it('should transfer order amount for ERC1155 tokens', async () => { + await mockERC1155.mint(alice.address, tokenId, 3); + sell = generateOrder(alice, { + side: Side.Sell, + tokenId, + amount: 3, + collection: mockERC1155.address, + matchingPolicy: matchingPolicies.standardPolicyERC1155.address, + }); + buy = generateOrder(bob, { + side: Side.Buy, + tokenId, + amount: 3, + collection: mockERC1155.address, + matchingPolicy: matchingPolicies.standardPolicyERC1155.address, + }); + sellInput = await sell.pack(); + buyInput = await buy.pack(); + + await waitForTx(exchange.execute(sellInput, buyInput)); + + expect(await mockERC1155.balanceOf(bob.address, tokenId)).to.be.equal(3); + await checkBalances( + aliceBalance, + aliceBalanceWeth.add(priceMinusFee), + bobBalance, + bobBalanceWeth.sub(price), + feeRecipientBalance, + feeRecipientBalanceWeth.add(fee) + ); + }); it('should revert with ERC20 not WETH', async () => { sell.parameters.paymentToken = mockERC721.address; buy.parameters.paymentToken = mockERC721.address;
Hardhat
Validate that both maker and taker order amount
s are equal and return its value instead of 1
diff --git a/contracts/matchingPolicies/StandardPolicyERC1155.sol b/contracts/matchingPolicies/StandardPolicyERC1155.sol index e17cc5e..ec4b982 100644 --- a/contracts/matchingPolicies/StandardPolicyERC1155.sol +++ b/contracts/matchingPolicies/StandardPolicyERC1155.sol @@ -27,10 +27,11 @@ contract StandardPolicyERC1155 is IMatchingPolicy { (makerAsk.collection == takerBid.collection) && (makerAsk.tokenId == takerBid.tokenId) && (makerAsk.matchingPolicy == takerBid.matchingPolicy) && - (makerAsk.price == takerBid.price), + (makerAsk.price == takerBid.price) && + (makerAsk.amount == takerBid.amount), makerAsk.price, makerAsk.tokenId, - 1, + makerAsk.amount, AssetType.ERC1155 ); } @@ -53,10 +54,11 @@ contract StandardPolicyERC1155 is IMatchingPolicy { (makerBid.collection == takerAsk.collection) && (makerBid.tokenId == takerAsk.tokenId) && (makerBid.matchingPolicy == takerAsk.matchingPolicy) && - (makerBid.price == takerAsk.price), + (makerBid.price == takerAsk.price) && + (makerBid.amount == takerAsk.amount), makerBid.price, makerBid.tokenId, - 1, + makerBid.amount, AssetType.ERC1155 ); }
After applying these changes, the test scenario described in the POC will pass.
#0 - GalloDaSballo
2022-10-13T22:27:06Z