You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In multiple instances, the same array length is read multiple time from memory/calldata. It would be better to save the value on the stack once and for all.
Example:
functionbatchFillOrder(Order[]memoryorders,bytes[]calldatasignatures,uint256[][]memoryfloorAssetTokenIds)publicreturns(uint256[]memorypositionIds){require(orders.length==signatures.length,"Length mismatch in input");require(signatures.length==floorAssetTokenIds.length,"Length mismatch in input");positionIds=newuint256[](orders.length);for(uint256i=0;i<orders.length;i++){positionIds[i]=fillOrder(orders[i],signatures[i],floorAssetTokenIds[i]);}}
It can be rewritten like:
functionbatchFillOrder(Order[]memoryorders,bytes[]calldatasignatures,uint256[][]memoryfloorAssetTokenIds)publicreturns(uint256[]memorypositionIds){uint256_length=orders.length;require(_length==signatures.length,"Length mismatch in input");require(_length==floorAssetTokenIds.length,"Length mismatch in input");positionIds=newuint256[](_length);for(uint256i=0;i<_length;i++){positionIds[i]=fillOrder(orders[i],signatures[i],floorAssetTokenIds[i]);}}
Lines
grep -r '\.length'
(G2) Error codes instead of strings
Recent versions of solidity support custom errors. They are more gas efficient than error strings when deploying the contract and when the error is raised.
For example:
require(msg.sender==order.maker,"Not your order");
It can be rewritten like:
errorNotYourOrder();// this in the global scope
...
if(msg.sender!=order.maker)revertNotYourOrder();
functionhashOppositeOrder(Ordermemoryorder)publicviewreturns(bytes32orderHash){// use decode/encode to get a copy instead of referenceOrdermemoryoppositeOrder=abi.decode(abi.encode(order),(Order));// get the opposite side of the order (short/long)oppositeOrder.isLong=!order.isLong;orderHash=hashOrder(oppositeOrder);}
Here oppositeOrder is created by copying order to new memory. It would be better working with the same memory reference. We can make it safe by recasting order.isLong at the end.
functionhashOppositeOrder(Ordermemoryorder)publicviewreturns(bytes32orderHash){bool_isLong=order.isLong;// save on stackorder.isLong=!_isLong;orderHash=hashOrder(order);order.isLong=_isLong;}
(G1) Array length is read multiple times
In multiple instances, the same array length is read multiple time from memory/calldata. It would be better to save the value on the stack once and for all.
Example:
It can be rewritten like:
Lines
grep -r '\.length'
(G2) Error codes instead of strings
Recent versions of solidity support custom errors. They are more gas efficient than error strings when deploying the contract and when the error is raised.
For example:
It can be rewritten like:
Reference
Lines
grep -r 'require'
(G3) Transferring ERC721 IN doesn't need to be "safe"
Here
safeTransferFrom
performs aonERC721Received
call toaddress(this)
, which isn't needed (we know it does nothing).Suggested using the simpler
transferFrom
.https://github.com/code-423n4/2022-06-putty/blob/main/contracts/src/PuttyV2.sol#L610-L614
(G4) Opposite order creates unnecessary memory
Here
oppositeOrder
is created by copyingorder
to new memory. It would be better working with the same memory reference. We can make it safe by recastingorder.isLong
at the end.https://github.com/code-423n4/2022-06-putty/blob/main/contracts/src/PuttyV2.sol#L683-L690
(G5) for-loop
i++
In general, a for-loop like this can be made more gas efficient.
Consider rewriting it like this:
Lines
grep -r 'i++'
The text was updated successfully, but these errors were encountered: