Omniscia Euler Finance Audit
ESynth Code Style Findings
ESynth Code Style Findings
ESH-01C: Ineffectual Usage of Safe Arithmetics
| Type | Severity | Location |
|---|---|---|
| Language Specific | ![]() | ESynth.sol:L73 |
Description:
The linked mathematical operation is guaranteed to be performed safely by surrounding conditionals evaluated in either require checks or if-else constructs.
Example:
73minterCache.minted = minterCache.minted > amount ? minterCache.minted - uint128(amount) : 0; // down-casting is safe because amount < minted <= max uint128Recommendation:
Given that safe arithmetics are toggled on by default in pragma versions of 0.8.X, we advise the linked statement to be wrapped in an unchecked code block thereby optimizing its execution cost.
Alleviation (fb2dd77a6ff9b7f710edb48e7eb5437e0db4fc1a):
The referenced subtraction has been wrapped in an unchecked code block safely, optimizing its gas cost.
ESH-02C: Inefficient Loop Limit Evaluation
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | ESynth.sol:L138 |
Description:
The linked for loop evaluates its limit inefficiently on each iteration.
Example:
138for (uint256 i = 0; i < ignoredForTotalSupply.length(); i++) {Recommendation:
We advise the statements within the for loop limit to be relocated outside to a local variable declaration that is consequently utilized for the evaluation to significantly reduce the codebase's gas cost. We should note the same optimization is applicable for storage reads present in such limits as they are newly read on each iteration (i.e. length members of arrays in storage).
Alleviation (fb2dd77a6ff9b7f710edb48e7eb5437e0db4fc1a):
The referenced loop limit evaluation (ignoredForTotalSupply.length()) has been properly cached outside the for loop to a dedicated local variable ignoredLength that is consequently utilized, optimizing the loop's gas cost significantly.
ESH-03C: Inefficient Structure Mutability Specifiers
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | ESynth.sol:L45, L55, L65, L74 |
Description:
The MinterData structures that are loaded in the ESynth::mint and ESynth::burn functions are declared as storage yet they are re-written to their respective mapping slot after being mutated.
Example:
40/// @notice Mints a certain amount of tokens to the account.41/// @param account The account to mint the tokens to.42/// @param amount The amount of tokens to mint.43function mint(address account, uint256 amount) external nonReentrant {44 address sender = _msgSender();45 MinterData storage minterCache = minters[sender];46
47 if (48 amount > type(uint128).max - minterCache.minted49 || minterCache.capacity < uint256(minterCache.minted) + amount50 ) {51 revert E_CapacityReached();52 }53
54 minterCache.minted += uint128(amount); // safe to down-cast because amount <= capacity <= max uint12855 minters[sender] = minterCache;56
57 _mint(account, amount);58}59
60/// @notice Burns a certain amount of tokens from the accounts balance. Requires the account, except the owner to have an allowance for the sender.61/// @param account The account to burn the tokens from.62/// @param amount The amount of tokens to burn.63function burn(address account, uint256 amount) external nonReentrant {64 address sender = _msgSender();65 MinterData storage minterCache = minters[sender];66
67 // The allowance check should be performed if the spender is not the account with the exception of the owner burning from this contract.68 if (account != sender && !(account == address(this) && sender == owner())) {69 _spendAllowance(account, sender, amount);70 }71
72 // If burning more than minted, reset minted to 073 minterCache.minted = minterCache.minted > amount ? minterCache.minted - uint128(amount) : 0; // down-casting is safe because amount < minted <= max uint12874 minters[sender] = minterCache;75
76 _burn(account, amount);77}Recommendation:
We advise both variables to be set as memory, optimizing the gas cost of each function to one SLOAD and one SSTORE operation.
Alleviation (fb2dd77a6ff9b7f710edb48e7eb5437e0db4fc1a):
The data locations of the two referenced local MinterData declarations have been properly updated to memory, optimizing each function's gas cost.
ESH-04C: Loop Iterator Optimization
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | ESynth.sol:L138 |
Description:
The linked for loop increments / decrements the iterator "safely" due to Solidity's built-in safe arithmetics (post-0.8.X).
Example:
138for (uint256 i = 0; i < ignoredForTotalSupply.length(); i++) {Recommendation:
We advise the increment / decrement operation to be performed in an unchecked code block as the last statement within the for loop to optimize its execution cost.
Alleviation (fb2dd77a6f):
The recommendation has been indirectly addressed due to the alleviation of exhibit ESH-02C and thus the optimizer's application.
To note, the original loop iterator was not optimized as the ignoredForTotalSupply.length() statement was considered dynamic and thus the optimizer did not assume the increment would be securely performed.
Alleviation (0f2192ac81):
After further testing of the proposed optimization, we concluded that the built-in optimizations of the Solidity compiler the project uses (0.8.23) would have covered the iterator case described in the exhibit per the official requirements of the optimization.
As such, we consider the optimization nullified as it would not have resulted in a gas reduction in its original form.
