Omniscia Avant Protocol Audit
StakedAvUSDV2 Code Style Findings
StakedAvUSDV2 Code Style Findings
SAS-01C: Inefficient Event Emittance
Type | Severity | Location |
---|---|---|
Gas Optimization | StakedAvUSDV2.sol:L128-L130 |
Description:
The StakedAvUSDV2::setCooldownDuration
function will inefficiently emit the CooldownDurationUpdated
event as it will store a local variable redundantly and emit a value from storage.
Example:
121/// @notice Set cooldown duration. If cooldown duration is set to zero, the StakedAvUSDV2 behavior changes to follow ERC4626 standard and disables cooldownShares and cooldownAssets methods. If cooldown duration is greater than zero, the ERC4626 withdrawal and redeem functions are disabled, breaking the ERC4626 standard, and enabling the cooldownShares and the cooldownAssets functions.122/// @param duration Duration of the cooldown123function setCooldownDuration(uint24 duration) external onlyRole(DEFAULT_ADMIN_ROLE) {124 if (duration > MAX_COOLDOWN_DURATION) {125 revert InvalidCooldown();126 }127
128 uint24 previousDuration = cooldownDuration;129 cooldownDuration = duration;130 emit CooldownDurationUpdated(previousDuration, cooldownDuration);131}
Recommendation:
We advise the event to be emitted prior to the cooldownDuration
assignment, permitting the first argument to be the cooldownDuration
data entry directly and the second argument to be the input duration
, optimizing the function's gas cost.
Alleviation:
The event's emission was updated to utilize the in-memory duration
variable, optimizing its gas cost.
SAS-02C: Inefficient mapping
Lookups
Type | Severity | Location |
---|---|---|
Gas Optimization | StakedAvUSDV2.sol:L102-L103, L115-L116 |
Description:
The linked statements perform key-based lookup operations on mapping
declarations from storage multiple times for the same key redundantly.
Example:
95/// @notice redeem assets and starts a cooldown to claim the converted underlying asset96/// @param assets assets to redeem97function cooldownAssets(uint256 assets) external ensureCooldownOn returns (uint256 shares) {98 if (assets > maxWithdraw(msg.sender)) revert ExcessiveWithdrawAmount();99
100 shares = previewWithdraw(assets);101
102 cooldowns[msg.sender].cooldownEnd = uint104(block.timestamp) + cooldownDuration;103 cooldowns[msg.sender].underlyingAmount += uint152(assets);104
105 _withdraw(msg.sender, address(silo), msg.sender, assets, shares);106}107
108/// @notice redeem shares into assets and starts a cooldown to claim the converted underlying asset109/// @param shares shares to redeem110function cooldownShares(uint256 shares) external ensureCooldownOn returns (uint256 assets) {111 if (shares > maxRedeem(msg.sender)) revert ExcessiveRedeemAmount();112
113 assets = previewRedeem(shares);114
115 cooldowns[msg.sender].cooldownEnd = uint104(block.timestamp) + cooldownDuration;116 cooldowns[msg.sender].underlyingAmount += uint152(assets);117
118 _withdraw(msg.sender, address(silo), msg.sender, assets, shares);119}
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:
All referenced inefficient mapping
lookups have been optimized to the greatest extent possible, significantly reducing the gas cost of the functions the statements were located in.