Omniscia Euler Audit

EulDistributor Code Style Findings

EulDistributor Code Style Findings

EDR-01C: Inefficient Execution of Safe Arithmetics

Description:

The linked arithmetic statement can be "unsafely" executed in an unchecked code block as its safety is guaranteed by the require check that precedes it.

Example:

contracts/mining/EulDistributor.sol
57require(claimable > alreadyClaimed, "already claimed");
58uint amount = claimable - alreadyClaimed;

Recommendation:

We advise the calculation to be performed in an unchecked block reducing the gas cost of the function.

Alleviation:

The unchecked code block was introduced to the codebase as advised optimizing it.

EDR-02C: Inefficient Packing Operation

Description:

The linked function executes an encodePacked operation from the abi package on input arguments that each occupy a full storage slot and thus cannot be tight-packed (address-160 bits, address-160 bits, uint256-256 bits).

Example:

contracts/mining/EulDistributor.sol
52function claim(address account, address token, uint claimable, bytes32[] calldata proof, address stake) external {
53 bytes32 candidateRoot = MerkleProof.processProof(proof, keccak256(abi.encodePacked(account, token, claimable))); // 72 byte leaf

Recommendation:

We advise the abi.encode function to be utilized instead optimizing the function's gas cost.

Alleviation:

The Euler team stated that protocol changes will be required to perform the optimization identified. We should note that the outputs of abi.encode and abi.encodePacked will remain the same as none of the input arguments can be tight-packed to a single slot thus incurring extraneous gas cost at no data benefit.

EDR-03C: Inexistent Visibility Specifiers

Description:

The linked variables have no visibility specifiers explicitly set.

Example:

contracts/mining/EulDistributor.sol
18bytes32 currRoot;
19bytes32 prevRoot;

Recommendation:

We advise them to be set to avoid potential compilation discrepancies in the future as the current behaviour is for the compiler to assign one automatically which may deviate between pragma versions.

Alleviation:

Both variables have been set as public thereby alleviating this exhibit.

EDR-04C: Potential Lookup Optimizations

Description:

The linked mapping lookup operations incur an extraneous keccak256 instruction gas cost as they are performed each time.

Example:

contracts/mining/EulDistributor.sol
56uint alreadyClaimed = claimed[account][token];
57require(claimable > alreadyClaimed, "already claimed");
58uint amount = claimable - alreadyClaimed;
59
60claimed[account][token] = claimable;

Recommendation:

We advise the claimed[account] lookup to be stored to a local mapping(address => uint) storage claimedPerToken variable that is consequently utilized for both reading the value and writing to it in the linked statements, significantly optimizing the gas cost of the code block.

Alleviation:

The Euler team has noted the gas optimization achievable but they wish to avoid complicating the code at this stage.