Omniscia Olympus DAO Audit
OlympusTokenMigrator Code Style Findings
OlympusTokenMigrator Code Style Findings
OTM-01C: Inexistent Error Messages
Type | Severity | Location |
---|---|---|
Code Style | Informational | OlympusTokenMigrator.sol:L99, L101, L103, L105, L107, L109, L111, L210, L238, L239, L328, L330, L332 |
Description:
The linked require
checks have no explicit error messages defined.
Example:
208// withdraw backing of migrated OHM209function defund(address reserve) external onlyGovernor {210 require(ohmMigrated && timelockEnd < block.number && timelockEnd != 0);211 oldwsOHM.unwrap(oldwsOHM.balanceOf(address(this)));212
213 uint256 amountToUnstake = oldsOHM.balanceOf(address(this));214 oldsOHM.approve(address(oldStaking), amountToUnstake);215 oldStaking.unstake(amountToUnstake, false);216
217 uint256 balance = oldOHM.balanceOf(address(this));218
219 oldSupply = oldSupply.sub(balance);220
221 uint256 amountToWithdraw = balance.mul(1e9);222 oldOHM.approve(address(oldTreasury), amountToWithdraw);223 oldTreasury.withdraw(amountToWithdraw, reserve);224 IERC20(reserve).safeTransfer(address(newTreasury), IERC20(reserve).balanceOf(address(this)));225
226 emit Defunded(balance);227}
Recommendation:
We advise them to be set so to aid in the validation of the conditionals as well as in debugging the application.
Alleviation:
Error messages were included to all require
checks across the contract.
OTM-02C: Multiple Top-Level Declarations
Type | Severity | Location |
---|---|---|
Code Style | Informational | OlympusTokenMigrator.sol:L17-L44, L46-L50 |
Description:
The linked interface
implementations should be relocated to dedicated files to not pollute the top-level of the contract file.
Example:
17interface IUniswapV2Router {18 function addLiquidity(19 address tokenA,20 address tokenB,21 uint256 amountADesired,22 uint256 amountBDesired,23 uint256 amountAMin,24 uint256 amountBMin,25 address to,26 uint256 deadline27 )28 external29 returns (30 uint256 amountA,31 uint256 amountB,32 uint256 liquidity33 );34
35 function removeLiquidity(36 address tokenA,37 address tokenB,38 uint256 liquidity,39 uint256 amountAMin,40 uint256 amountBMin,41 address to,42 uint256 deadline43 ) external returns (uint256 amountA, uint256 amountB);44}45
46interface IStakingV1 {47 function unstake(uint256 _amount, bool _trigger) external;48
49 function index() external view returns (uint256);50}51
52contract OlympusTokenMigrator is OlympusAccessControlled {
Recommendation:
We advise them to be relocated to the interfaces
sub-folder, potentially under an external
second-level subfolder, to ensure that the code structure of the system is maintainable.
Alleviation:
All required interfaces were split to their dedicated files and are now properly imported to the codebase.
OTM-03C: Redundant & Confusing Comparisons
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | OlympusTokenMigrator.sol:L137, L182 |
Description:
The if-else
structure within migrate
and _send
evaluate all states of the enum
redundantly which can also cause ambiguous behaviour if the compiler does not enforce the value range of the TYPE
enum due to a compiler issue given that it is internally represented by a uint8
.
Example:
118enum TYPE {119 UNSTAKED,120 STAKED,121 WRAPPED122}123
124// migrate OHMv1, sOHMv1, or wsOHM for OHMv2, sOHMv2, or gOHM125function migrate(126 uint256 _amount,127 TYPE _from,128 TYPE _to129) external {130 uint256 sAmount = _amount;131 uint256 wAmount = oldwsOHM.sOHMTowOHM(_amount);132
133 if (_from == TYPE.UNSTAKED) {134 oldOHM.safeTransferFrom(msg.sender, address(this), _amount);135 } else if (_from == TYPE.STAKED) {136 oldsOHM.safeTransferFrom(msg.sender, address(this), _amount);137 } else if (_from == TYPE.WRAPPED) {138 oldwsOHM.safeTransferFrom(msg.sender, address(this), _amount);139 wAmount = _amount;140 sAmount = oldwsOHM.wOHMTosOHM(_amount);141 }142
143 if (ohmMigrated) {144 require(oldSupply >= oldOHM.totalSupply(), "OHMv1 minted");145 _send(wAmount, _to);146 } else {147 gOHM.mint(msg.sender, wAmount);148 }149}
Recommendation:
We advise the last else if
branch to be converted to an else
branch to ensure transfer of funds is performed at all times from the user to the contract and vice versa for the migration to occur.
Alleviation:
The if-else
optimization was only applied to the first linked segment thereby partially alleviating this exhibit.