Omniscia Maverick Protocol Audit
MaverickV2VotingEscrowWSync Code Style Findings
MaverickV2VotingEscrowWSync Code Style Findings
MVS-01C: Ineffectual Usage of Safe Arithmetics
Type | Severity | Location |
---|---|---|
Language Specific | ![]() | MaverickV2VotingEscrowWSync.sol:L40, L42 |
Description:
The linked mathematical operation is guaranteed to be performed safely by logical inference, such as surrounding conditionals evaluated in require
checks or if-else
constructs.
Example:
39if (newBalance > oldBalance) {40 _mint(staker, newBalance - oldBalance);41} else if (newBalance < oldBalance) {42 _burn(staker, oldBalance - newBalance);43}
Recommendation:
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 (07ad29f773f16bdfbae3d97d3a7c2f9d64866093):
The referenced operations have been properly wrapped in an unchecked
code block, optimizing their gas cost whilst retaining their security guarantees via each operation's preceding statements.
MVS-02C: Inefficient mapping
Lookups
Type | Severity | Location |
---|---|---|
Gas Optimization | ![]() | MaverickV2VotingEscrowWSync.sol:L32, L44 |
Description:
The linked statements perform key-based lookup operations on mapping
declarations from storage multiple times for the same key redundantly.
Example:
32uint256 oldBalance = syncBalances[staker][legacyLockupIndex];33Lockup memory lockup = ILegacyVeMav(address(legacyVeMav)).lockups(staker, legacyLockupIndex);34if (lockup.end != 0 && lockup.end < block.timestamp + MIN_SYNC_DURATION)35 revert VotingEscrowLockupEndTooShortToSync(lockup.end, block.timestamp + MIN_SYNC_DURATION);36
37newBalance = lockup.votes;38if (newBalance != oldBalance) {39 if (newBalance > oldBalance) {40 _mint(staker, newBalance - oldBalance);41 } else if (newBalance < oldBalance) {42 _burn(staker, oldBalance - newBalance);43 }44 syncBalances[staker][legacyLockupIndex] = newBalance;45 emit Sync(staker, legacyLockupIndex, newBalance);46}
Recommendation:
As the lookups internally perform an expensive keccak256
operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping
in case of primitive types or holds a storage
pointer to the struct
contained.
As the compiler's optimizations may take care of these caching operations automatically at-times, we advise the optimization to be selectively applied, tested, and then fully adopted to ensure that the proposed caching model indeed leads to a reduction in gas costs.
Alleviation (07ad29f773):
The Maverick Protocol team requested clarification in relation to this exhibit; mapping
lookups can also be optimized via local mapping
declarations.
In the instance highlighted, a local mapping(uint256 => uint256) storage stakerBalancePerIndex
variable can be declared to optimize the lookups performed by the highlighted statements.
Alleviation (7ad1f96f09):
A local mapping
declaration has been introduced as advised, optimizing the gas cost of the MaverickV2VotingEscrowWSync::sync
function.