Omniscia Native Audit
Order Code Style Findings
Order Code Style Findings
ORE-01C: Improper Specialized Encoding Mechanism
Type | Severity | Location |
---|---|---|
Gas Optimization | Order.sol:L12-L23, L25, L26, L27, L40-L46 |
Description:
The encoding mechanism employed by Order
is inefficient. As it correctly states in the commented out code, the size of an address
type is 20
whilst it is used as 32
in the encoding mechanism. This is due to the code not performing an actual tight encoding mechanism.
Example:
12struct Order {13 uint256 id;14 address signer;15 address buyer;16 address seller;17 address buyerToken;18 address sellerToken;19 uint256 buyerTokenAmount;20 uint256 sellerTokenAmount;21 uint256 deadlineTimestamp;22 address txOrigin;23}24
25uint256 private constant ADDR_SIZE = 32; //20;26uint256 private constant UINT256_SIZE = 32; //32;
Recommendation:
Given that each byte is stored in sequence, a special decoding mechanism can be employed similarly to Uniswap V3 whereby the arguments are decoded one-by-one. This will significantly optimize the Native exchange when dealing with multiple orders as the memory needs of the contract will be greatly minimized.
Alleviation:
The code now properly decodes the Order
struct manually byte-by-byte, significantly optimizing the data needs of an Order
struct.
ORE-02C: Inexistent Error Messages
Type | Severity | Location |
---|---|---|
Code Style | Order.sol:L43, L53 |
Description:
The linked require
checks have no error messages explicitly defined.
Example:
43require(orders.length != 0 && orders.length % HOP_SIZE == 0);
Recommendation:
We advise each to be set so to increase the legibility of the codebase and aid in validating the require
checks' conditions.
Alleviation:
An error message has been properly introduced for all referenced require
statements.
ORE-03C: Potential Enhancement of Functionality
Type | Severity | Location |
---|---|---|
Gas Optimization | Order.sol:L40-L46, L52-L55 |
Description:
The decodeFirstOrder
, getFirstOrder
, and skipOrder
functions are separate but are used together in the Router
implementation.
Example:
40function decodeFirstOrder(41 bytes memory orders42) internal pure returns (Order memory order, bytes memory signature) {43 require(orders.length != 0 && orders.length % HOP_SIZE == 0);44 order = abi.decode(orders.slice(0, ORDER_SIZE), (Order));45 signature = orders.slice(ORDER_SIZE, SIG_SIZE);46}47
48function getFirstOrder(bytes memory orders) internal pure returns (bytes memory) {49 return orders.slice(0, HOP_SIZE);50}51
52function skipOrder(bytes memory orders) internal pure returns (bytes memory) {53 require(orders.length != 0 && orders.length % HOP_SIZE == 0);54 return orders.slice(HOP_SIZE, orders.length - HOP_SIZE);55}
Recommendation:
We advise their functionality to be merged into a single function that decodes the first order, returns it, and additionally returns the remaining orders
sliced via skipOrder
(i.e. decodeAndSkipFirstOrder
).
Alleviation:
The Native team evaluated this exhibit but opted not to apply a remediation for it as they consider it inconsequential.