Omniscia Euler Finance Audit

MetaProxyDeployer Code Style Findings

MetaProxyDeployer Code Style Findings

MPD-01C: Inefficient Memory Assignment

Description:

The referenced for loop will iterate from 0 in multiples of 32, however, the first iteration will inefficiently perform two add operations that are unnecessary as the i iterator will be 0.

Example:

src/GenericFactory/MetaProxyDeployer.sol
10function deployMetaProxy(address targetContract, bytes memory metadata) internal returns (address addr) {
11 // the following assembly code (init code + contract code) constructs a metaproxy.
12 assembly {
13 let offset := add(metadata, 32)
14 let length := mload(metadata)
15 // load free memory pointer as per solidity convention
16 let start := mload(64)
17 // keep a copy
18 let ptr := start
19 // deploy code (11 bytes) + first part of the proxy (21 bytes)
20 mstore(ptr, 0x600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73)
21 ptr := add(ptr, 32)
22
23 // store the address of the contract to be called
24 mstore(ptr, shl(96, targetContract))
25 // 20 bytes
26 ptr := add(ptr, 20)
27
28 // the remaining proxy code...
29 mstore(ptr, 0x5af43d3d93803e603457fd5bf300000000000000000000000000000000000000)
30 // ...13 bytes
31 ptr := add(ptr, 13)
32
33 // copy the metadata
34 {
35 for { let i := 0 } lt(i, length) { i := add(i, 32) } { mstore(add(ptr, i), mload(add(offset, i))) }
36 }
37 ptr := add(ptr, length)
38
39 // The size is deploy code + contract code + calldatasize - 4.
40 addr := create(0, start, sub(ptr, start))
41 }
42}

Recommendation:

We advise the loop and ensuing ptr assignment to be wrapped in an if lt(0, length) construct, ensuring that the loop and ptr offset is executed solely when a non-zero metadata payload has been specified.

Afterwards, the first metadata memory store can occur before the for loop and the for loop's i iterator can begin at 32, optimizing the code as advised whilst also optimizing the zero-metadata case of the MetaProxyDeployer::deployMetaProxy function.

Alleviation (fb2dd77a6f):

The Euler Finance team opted to acknowledge this exhibit based on the fact that they have copied their code from the reference code of the EIP-3448 page.

While we understand the exhibit's acknowledgement, we would like to clarify that an EIP's example implementation is not meant to be secure but rather illustrate how the code should function.

Alleviation (0f2192ac81):

The Euler Finance team opted to create their own MetaProxyDeployer implementation based on the definition of the EIP-3448 standard, significantly increasing the legibility of the implementation.

The latest version of the code does not perform a low-level for loop within an assembly block rendering the described optimization inapplicable.