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: 22/80
Findings: 3
Award: $197.95
🌟 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/d1c22a94ed08b08fe3f7d5c96e973d80d3dc0e54/contracts/matchingPolicies/StandardPolicyERC1155.sol#L33 https://github.com/code-423n4/2022-10-blur/blob/d1c22a94ed08b08fe3f7d5c96e973d80d3dc0e54/contracts/BlurExchange.sol#L145
While BlurExchange
retrieves the amount
parameter from _canMatchOrders
(which retrieves it from the policies), the amount
is always 1, even for ERC1155 trades. Therefore, the parameter in the order struct is currently completely unnecessary and an order with an amount of 1, 12, 44 (or even 0) is treated identical.
Moreover, the price within an order struct is for the whole order (otherwise, the logic in execute
would be wrong, as _executeFundsTransfer
would need to be called with price * amount
). Therefore, a user thinks he gets X tokens for the provided price, but only gets 1.
Bob wants to sell 42 ERC1155 tokens and creates a corresponding sell order for it (with the amount set to 42). Alice wants to buy 42 of these tokens and thinks the price (for all 42 tokens) is fair, so she submits a buy order. However, she receives only 1 token, but has paid for 42 tokens.
Incorporate the amount correctly (and optionally allow for partial fulfillment).
#0 - blur-io-toad
2022-10-16T23:38:01Z
This was an oversight on my part for not putting this contract as out-of-scope. Our marketplace does not handle ERC1155 yet and so we haven't concluded what the matching critieria for those orders will be. This contract was mainly created to test ERC1155 transfers through the rest of the exchange, but shouldn't be deployed initially. When we are prepared to handle ERC1155 orders we will have to develop a new matching policy that determines the amount from the order parameters. Acknowledging that it's incorrect, but won't be making any changes as the contract won't be deployed.
#1 - GalloDaSballo
2022-10-28T00:06:35Z
🌟 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
50.4817 USDC - $50.48
Blur does not support EIP 1271 and therefore no signatures that are validated by smart contracts. This limits the applicability for protocols that want to build on top of it and persons that use smart contract wallets. Consider implementing support for it
The recipient of a fee (https://github.com/code-423n4/2022-10-blur/blob/d1c22a94ed08b08fe3f7d5c96e973d80d3dc0e54/contracts/BlurExchange.sol#L478) may be address(0)
, leading to lost ETH.
The provided policies enforce that the prices match exactly (https://github.com/code-423n4/2022-10-blur/blob/d1c22a94ed08b08fe3f7d5c96e973d80d3dc0e54/contracts/matchingPolicies/StandardPolicyERC721.sol#L56), which is very restrictive in practice. If the seller has a lower sale price than the price that is provided by the buyer, this should ideally also match (either at the lower price or in between), because both parties would be happy with that.
In BlurExchange.execute
, it is not validated that buy.order.side == Side.Buy
(only the sell side is validated). With the current system, all policies ensure that, but it would also make sense to validate it in execute
IMO. Future policies may not validate that and such a basic check should also not be the responsibility of a policy in my opinion.
#0 - GalloDaSballo
2022-10-23T20:48:17Z
R
L
R
L
#1 - GalloDaSballo
2022-10-23T20:49:03Z
I think if you're going for a short report, this is a good example as all findings make you think and have utility (some other Wardens sent those as Meds, I think QA is very reasonable for these and saves everybody time while going for a good score)
#2 - GalloDaSballo
2022-11-07T19:08:24Z
2L 2R, will give a bonus for brevity and impact
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xNazgul, 0xSmartContract, Aymen0909, Heuss, Lambda, Pheonix, RaymondFam, ReyAdmirado, Ruhum, Shinchan, Shishigami, __141345__, adriro, ajtra, c3phas, ch0bu, cryptostellar5, d3e4, enckrish, gogo, halden, lucacez, mcwildy, medikko, neko_nyaa, pedr02b2, pfapostol, ret2basic, rvierdiiev, saian, sakman, sakshamguruji
32.6464 USDC - $32.65
// Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect.
unchecked
because an overflow is not possible (as the iterator is bounded):contracts/PolicyManager.sol:77: for (uint256 i = 0; i < length; i++) { contracts/lib/MerkleVerifier.sol:38: for (uint256 i = 0; i < proof.length; i++) { contracts/lib/EIP712.sol:77: for (uint256 i = 0; i < fees.length; i++) { contracts/BlurExchange.sol:199: for (uint8 i = 0; i < orders.length; i++) { contracts/BlurExchange.sol:476: for (uint8 i = 0; i < fees.length; i++) {
#0 - GalloDaSballo
2022-10-21T00:31:10Z
Honestly if you're going to send a short report, this is pretty good
#1 - GalloDaSballo
2022-10-23T00:43:50Z
5k + 150
5150