Platform: Code4rena
Start Date: 20/05/2022
Pot Size: $1,000,000 USDC
Total HM: 4
Participants: 59
Period: 14 days
Judge: leastwood
Id: 128
League: ETH
Rank: 25/59
Findings: 2
Award: $2,339.78
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Spearbit
Also found by: 0xsanson, Chom, IllIllI, OriDabush, Saw-mon_and_Natalie, broccoli, cccz, cmichel, csanuragjain, foobar, hack3r-0m, hickuphh3, hubble, hyh, ilan, kebabsec, mayo, oyc_109, peritoflores, rfa, scaraven, sces60107, shung, sorrynotsorry, tintin, twojoy, zkhorse, zzzitron
1904.8298 USDC - $1,904.83
initialOwner
in createConduit
of ConduitController.sol
initialOwner
.function createConduit(bytes32 conduitKey, address initialOwner) external override returns (address conduit) { ...... //recommendation if(initialOwner == address(0){ revert ZeroAddressError(); ..... }
In contracts/lib/GettersAndDerivers.sol#L68
While writing assembly, use the specific memory offset variable for specific structs instead of using generic offsets such as OneWords
TwoWords
. This make the code easy to read/understand and reduces chances of error on change.
// Current // Get the pointer to the offers array. let offerArrPtr := mload(add(orderParameters, TwoWords)) // Recommended Change: // Get the pointer to the offers array. let offerArrPtr := mload(add(orderParameters, OrderParameters_offer_head_offset))
#0 - GalloDaSballo
2022-07-17T18:29:32Z
Valid Low per #56
Disagree
1L
🌟 Selected for report: Dravee
Also found by: 0x1f8b, 0x29A, 0xalpharush, Chom, Czar102, Hawkeye, IllIllI, MaratCerby, MiloTruck, NoamYakov, OriDabush, RoiEvenHaim, Spearbit, Tadashi, TerrierLover, TomJ, asutorufos, cccz, cmichel, csanuragjain, defsec, delfin454000, djxploit, ellahi, foobar, gzeon, hake, hickuphh3, ignacio, ilan, joestakey, kaden, mayo, ming, oyc_109, peritoflores, rfa, sach1r0, sashik_eth, shung, sirhashalot, twojoy, zer0dot, zkhorse
434.9484 USDC - $434.95
_deriveTypehashes()
of ConsiderationBase.sol
the keccak256 hash of the encoded values can be precomputed......... eip712DomainTypehash = keccak256( abi.encodePacked( "EIP712Domain(", "string name,", "string version,", "uint256 chainId,", "address verifyingContract", ")" ) .... // recommendation: precompute eip712DomainTypehash = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f
The loop bounds are calculated with array.length
which are calculated in every loop iterations which can result in high gas.
The array length can be cached instead of calculating in every loop iteration to save gas.
// Current for (uint i = 0; i < offer.length; ++i) { } // Recommendation uint len = offer.length; for (uint i = 0; i < len; ++i) { }
The instances where this pattern can be applied is found as follows
❯ grep -rn './contracts/' -e 'for.*[.]length' ./contracts/lib/OrderFulfiller.sol:217: for (uint256 i = 0; i < orderParameters.offer.length; ) { ./contracts/lib/OrderFulfiller.sol:306: for (uint256 i = 0; i < orderParameters.consideration.length; ) { ./contracts/lib/OrderCombiner.sol:247: for (uint256 j = 0; j < offer.length; ++j) { ./contracts/lib/OrderCombiner.sol:291: for (uint256 j = 0; j < consideration.length; ++j) { ./contracts/lib/OrderCombiner.sol:598: for (uint256 j = 0; j < consideration.length; ++j) { ./contracts/lib/OrderCombiner.sol:621: for (uint256 i = 0; i < executions.length; ) {
#0 - HardlyDifficult
2022-06-24T19:08:13Z
keccak256 hash computation can be precomputed to save deployment gas
Given that this only impacts the constructor and therefore will not impact users, it seems reasonable to leave the code as-is for improved readability. If the precomputed form was used one would need to run the hash manually in order to validate it is as expected.
The other two findings should provide small savings.