31264 - [SC - Insight] Multiple Reports QALowOOS Medium
Multiple Reports: QA/Low/OOS Medium
Submitted on May 15th 2024 at 22:57:26 UTC by @The_Seraphs for Boost | Alchemix
Report ID: #31264
Report type: Smart Contract
Report severity: Insight
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/AlchemixGovernor.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
AS PER RECOMMENDATION FROM PROJECT IN DISCORD:
Ref: https://discord.com/channels/787092485969150012/1232293258760028180/1238623014044827728
QA
(1) Use of a modifier to remove repetition and clean-up functions
In multiple contracts the repitition of the following require statement is present
e.g. AlchemixGovernor.sol
, VotingEscrow.sol
, Voting.sol
.
The protocol could benefit from implementing a modifier
in place of the require()
statements that exists across multiple functions and contracts.
(2) Zero address checks
There are several contracts that utilise a zero address check in constructors or functions. However, the use of require
conditions throughout the contracts may become gas heavy with repeated calls.
Examples from RevenueHandler
, Minter
, VotingEscrow
, RewardPoolManager
, Fluxtoken
Suggestions:
The protocols contract's could be improved in several ways, to name a couple:
Gas Efficiency: They reduce the cost of deploying and interacting with your contract by avoiding the storage of error strings in the bytecode. This efficiency is important for frequently called functions and during high gas price periods on the Ethereum network.
Code Clarity and Maintenance: Custom errors help in organising and streamlining error handling code. By defining errors in a single location and using them throughout the contract, you make your codebase easier to understand and modify. This structured approach is beneficial in large projects, with complex functions that repeat a lot of the checks - removing the need for duplication of code.
Suggested custom error:
1. Basic Zero Address Error A basic custom error for zero address checks.
2. Error with Context You can enhance the custom error by including a parameter that specifies the context or the function where the error occurred.
Usage example:
3. Mixed Errors In scenarios where different checks might lead to a zero address error under different conditions, defining multiple custom errors might be appropriate.
Usage example:
(3) Inefficiency of loops in functions
The current implementation to add revenue tokens can be improved, saving gas, by introducing mapping into the contract, additionally, adjusting the remove revenue token to match the changes
NB: Changes to this function would then require adjustments to other existing functions such as, checkpoint()
, which uses iteration of the revenueTokens
array. Using an array to store the keys of the mapping and then iterate, would need to be implemented in the function.
Suggested changes
Results: Gas saving
NB: I made a new function and left the old one in, so the deployment cost won't have reduced due to this.
Low
(1) RenounceOwnership still active from inherited Ownable contract
Title
Potential risk in RevenueHandler
Due to renounceOwnership()
inherited from Ownable contract
Overview
The renounceOwnership
function inherited from OpenZeppelin's Ownable
contract allows the contract owner to permanently transfer ownership to the zero address, effectively rendering the contract without an owner. This function could lock out administrative functions and prevent further updates or critical management actions in the RevenueHandler
contract.
Effected Component
Contract: RevenueHandler
POC
Add the following function to
RevenueHandler.t.sol
Run in cli
forge test --mt testRenounceOwnership -vvvv
for full visibility of the trace
Results
Impact
Permanent loss of contract control:
Loss of ability to call the following functions:
addRevenueToken
setTreasury
setTreasuryPct
enableRevenueToken
disableRevenueToken
setPoolAdapter
setDebtToken
removeAlchemicToken
addAlchemicToken
removeRevenueToken
addRevenueToken
Recommendation
Override the renounceOwnership
function in RevenueHandler
to make it redundant, ensuring that ownership cannot be unintentionally or maliciously renounced. This can be achieved by either removing the function body or reverting any calls to it:
OOS: Medium severity
Brief/Intro
The AlchemicTokenV2Base contract is integral to managing upgradeable alchemic tokens, yet it currently lacks a designated storage gap. Such a gap is pivotal for safely introducing new state variables in future contract versions without disturbing the existing storage layout. The omission of this storage gap could result in inadvertent overwriting of state variables in derived contracts, which could lead to significant disruptions or even financial losses.
Vulnerability Details
Components Affected
Contract Name:
AlchemicTokenV2Base
Functionality: Upgradeability and State Variable Management
Impact Details
The AlchemicTokenV2Base contract is designed to facilitate the upgradeable framework of the token system. Without a storage gap, there's a substantial risk that any future additions of state variables could overwrite existing variables in contracts that inherit from this base.
Proposed fix:
References
Refer to the OpenZeppelin documentation on this topic: OpenZeppelin Upgradeable Contracts, Storage Gaps
Proof of Concept
All required POCs are with the respective reports above
Last updated