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: 18/80
Findings: 2
Award: $531.64
🌟 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#L540 https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/matchingPolicies/StandardPolicyERC1155.sol#L12 https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/matchingPolicies/StandardPolicyERC1155.sol#L38 https://github.com/code-423n4/2022-10-blur/blob/2fdaa6e13b544c8c11d1c022a575f16c3a72e3bf/contracts/BlurExchange.sol#L145
Detailed description of the impact of this finding.
the ERC1155 policy failed to validate if the two order's amount when handling the ERC1155 order matching.
note the linke
(uint256 price, uint256 tokenId, uint256 amount, AssetType assetType) = _canMatchOrders(sell.order, buy.order);
the _canMatchOrders eventually call the function below.
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.price, makerBid.tokenId, 1, AssetType.ERC1155 );
the returned amount would always return 1 no matter what the original amount in the order specified.
then later when ERC1155 is transferred, the transferred amount would always be 1 if order matched.
executionDelegate.transferERC1155(collection, from, to, tokenId, amount);
This critical bug can leads to invalid ERC1155 order settlement at the cost of user's fund and NFT.
Alice create a order, she wants to buy 5 ERC1155 NFT for NFT id 1 at the price of 1 ETH.
Bob create a order, he wants to sell 10 ERC1155 NFT for NFT id 1 at the price of 1 ETH.
Two order is matched.
Bob discovered that only 1 of the ERC1155 NFT is transferred out to Alice and he receives 1 ETH, he is happy and write a bot to exploit his bug.
Alice discovered that she paid 1 ETH for 1 ERC1155 NFT but she wants to buy 5, she is very sad and upset.
We recommend the project validate the order amount for both order in ERC1155 matching policy
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 && // amount check is added here ), makerBid.price, makerBid.tokenId, markerBid.amount, // amount of nft is returned here. AssetType.ERC1155 );
#0 - GalloDaSballo
2022-10-13T22:27:53Z
🌟 Selected for report: 0x4non
Also found by: 0x1f8b, 0xNazgul, 0xSmartContract, Deivitto, IllIllI, Lambda, RaymondFam, Rolezn, RustyRabbit, Trust, arcoun, bin2chen, brgltd, csanuragjain, d3e4, enckrish, exd0tpy, ladboy233, nicobevi, rbserver, rotcivegaf, simon135, zzykxx
416.821 USDC - $416.82
bytes32 hash = _hashOrder(order, nonces[order.trader]);
User will not know which steps goes wrong when transaction reverted.
require(sell.order.side == Side.Sell);
require(msg.sender == order.trader);
require(msg.value == price);
the Policy Manager ownership can be transferred to 0, then no one can set matching policy.
address(0) can be added as policy
According to the implementation of
the function
function add(AddressSet storage set, address value) internal returns (bool) {
and
function remove(AddressSet storage set, address value) internal returns (bool) {
returns value, but when adding and removing policy, the return value are not properly handled.
the package used is
"@openzeppelin/contracts": "4.4.1", "@openzeppelin/contracts-upgradeable": "^4.6.0",
we recommend the project upgrade to the newest implementation of the openzepplin to avoid any known vulnerability in the openzepplin package
https://security.snyk.io/package/npm/@openzeppelin%2Fcontracts
#0 - GalloDaSballo
2022-10-23T20:47:21Z
Doesn't seem like it https://dev.to/koha/the-31-reserved-keywords-in-solidity-bda
I did see the flag in the Consensy Visual Developer tool but cannot verify, skipping
NC
Disagree as renouncing is a feature
L
Disagree as we know contains above performs check for idempotency and implementation is trivial
R
L
I think it's an ok report, would benefit by having more details and perhaps a few more nuanced findings / unique perspective
#1 - GalloDaSballo
2022-10-23T20:47:33Z
2L 1R 1NC