Platform: Code4rena
Start Date: 02/08/2022
Pot Size: $50,000 USDC
Total HM: 12
Participants: 69
Period: 5 days
Judge: gzeon
Total Solo HM: 5
Id: 150
League: ETH
Rank: 27/69
Findings: 2
Award: $131.26
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xDjango, 0xNazgul, 0xc0ffEE, 8olidity, Bnke0x0, Chom, CodingNameKiki, Deivitto, Dravee, Funen, JC, JohnSmith, NoamYakov, ReyAdmirado, Rohan16, Rolezn, Sm4rty, SooYa, TomFrenchBlockchain, TomJ, Waze, __141345__, ajtra, ak1, aysha, bin2chen, bobirichman, brgltd, bulej93, c3phas, delfin454000, durianSausage, erictee, fatherOfBlocks, gogo, horsefacts, hyh, ladboy233, mics, natzuu, nxrblsrpr, oyc_109, rbserver, samruna, sikorico, simon135, tofunmi, wagmi
88.166 USDC - $88.17
Severity: Low
function transferOwnership(address newOwner) external override {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L117
function deployFor(address owner) public override returns (IMIMOProxy proxy) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L45
function deployFor(address owner) public override returns (IMIMOProxy proxy) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L45
Consider adding zero-address checks in the mentioned codebase.
Severity: Low
The owner is the authorized user in the solidity contracts. Usually, an owner can be updated with transferOwnership function. However, the process is only completed with single transaction. If the address is updated incorrectly, an owner functionality will be lost forever.
function transferOwnership(address newOwner) external override {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L117
proxy.transferOwnership(owner);
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L50
Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.
Severity: Low
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert
receive() external payable {}
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L38
The function should call another function, otherwise it should revert
Severity: Non-Critical
uint256 targetRatio = autoVault.targetRatio + 1e15; // add 0.1% to account for rounding
if (_operationTracker[vaultId] > block.timestamp - 1 days) {
if (_operationTracker[rbData.vaultId] > block.timestamp - 1 days) {
minGasReserve = 5_000;
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L30
Severity: Non-Critical
Each event should use three indexed fields if there are three or more fields. In addition, each event should have at least one indexed fields to allow easier filtering of logs.
event AutomationSet(uint256 vaultId, AutomatedVault autoVault);
event ManagerSet(address manager, bool isManager);
event ManagementSet(uint256 vaultId, ManagedVault managedVault);
event Execute(address indexed target, bytes data, bytes response);
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/interfaces/IMIMOProxy.sol#L9
event DeployProxy(address indexed deployer, address indexed owner, address proxy);
Severity: Non-Critical
function setPermission(
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L104
OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5
Severity: Non-Critical
contract MIMOEmptyVault is MIMOSwap, MIMOFlashloan, IMIMOEmtpyVault
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOEmptyVault.sol#L14
contract MIMOFlashloan is IMIMOFlashloan
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOFlashloan.sol#L15
contract MIMOLeverage is MIMOFlashloan, MIMOSwap, IMIMOLeverage
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOLeverage.sol#L14
contract MIMORebalance is MIMOFlashloan, MIMOSwap, IMIMORebalance
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMORebalance.sol#L14
contract MIMOSwap is IMIMOSwap
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOSwap.sol#L16
contract MIMOVaultActions is IMIMOVaultActions
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOVaultActions.sol#L16
contract MIMOAutoAction is IMIMOAutoAction
contract MIMOAutoRebalance is MIMOAutoAction, MIMOFlashloan, IMIMOAutoRebalance
contract MIMOManagedAction is IMIMOManagedAction
contract MIMOManagedRebalance is MIMOManagedAction, MIMOFlashloan, IMIMOManagedRebalance
contract MIMOProxy is IMIMOProxy, Initializable, BoringBatchable
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L12
contract MIMOProxyFactory is IMIMOProxyFactory
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L12
contract MIMOProxyRegistry is IMIMOProxyRegistry
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L12
Severity: Non-Critical
Use a solidity version of at least 0.8.12 to get string.concat() instead of abi.encodePacked(<str>,<str>) Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOEmptyVault.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOFlashloan.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOLeverage.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMORebalance.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOSwap.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOVaultActions.sol#L3
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/automated/MIMOAutoAction.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/automated/MIMOAutoRebalance.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/automated/interfaces/IMIMOAutoAction.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/automated/interfaces/IMIMOAutoRebalance.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOEmptyVault.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOFlashloan.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOLeverage.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOProxyAction.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMORebalance.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOSwap.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/interfaces/IMIMOVaultActions.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/managed/MIMOManagedAction.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/managed/MIMOManagedRebalance.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/managed/interfaces/IMIMOManagedAction.sol#L2
Found old version 0.8.10 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/managed/interfaces/IMIMOManagedRebalance.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/interfaces/IMIMOProxy.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/interfaces/IMIMOProxyFactory.sol#L2
Found old version 0.8.4 of Solidity https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/interfaces/IMIMOProxyRegistry.sol#L2
Consider updating to a more recent solidity version.
Severity: Non-Critical
The type of the variable is the same as the type to which the variable is being cast
uint256 toVaultMcr = _a.config().collateralMinCollateralRatio(address(toCollateral));
🌟 Selected for report: Dravee
Also found by: 0x040, 0x1f8b, 0xDjango, 0xNazgul, 0xSmartContract, 0xc0ffEE, Aymen0909, Bnke0x0, Chom, CodingNameKiki, Deivitto, Fitraldys, Funen, IllIllI, JC, JohnSmith, NoamYakov, ReyAdmirado, Rolezn, TomJ, Waze, ajtra, bearonbike, bobirichman, brgltd, c3phas, durianSausage, fatherOfBlocks, gogo, ignacio, jag, joestakey, ladboy233, mics, oyc_109, rbserver, samruna, sikorico, simon135
43.0933 USDC - $43.09
Severity: Gas Optimizations
bytes memory params = abi.encode(msg.sender, swapAmount, swapData);
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOLeverage.sol#L54
bytes memory params = abi.encode(msg.sender, rbData, swapData);
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMORebalance.sol#L49
_takeFlashLoan(flData, abi.encode(vaultOwner, autoFee, rbData, swapData));
_takeFlashLoan(flData, abi.encode(vaultsData.vaultOwner(rbData.vaultId), managerFee, rbData, swapData));
Severity: Gas Optimizations
The overheads outlined below are PER LOOP, excluding the first loop
storage arrays incur a Gwarmaccess (100 gas) memory arrays use MLOAD (3 gas) calldata arrays use CALLDATALOAD (3 gas)
Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset
for (uint256 i = 0; i < targets.length; i++) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L132
Severity: Gas Optimizations
The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the contract is meant to be extended, the contract should be abstract and the function signatures be added without any default implementation. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if(x){}else if(y){...}else{...} => if(!x){if(y){...}else{...}})
) external virtual override returns (bool) {}
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/MIMOFlashloan.sol#L44
receive() external payable {}
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L38
Severity: Gas Optimizations
Saves 6 gas per loop
for (uint256 i = 0; i < targets.length; i++) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L132
For example, use ++i instead of i++
Severity: Gas Optimizations
for (uint256 i = 0; i < targets.length; i++) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L132
Severity: Gas Optimizations
If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table
uint256 public constant override VERSION = 1; https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L19
Set variable to private.
Severity: Gas Optimizations
To help the optimizer, declare a storage type variable and use it instead of repeatedly fetching the reference in a map or an array. The effect can be quite significant. As an example, instead of repeatedly calling someMap[someIndex], save its reference like this: SomeStruct storage someStruct = someMap[someIndex] and use it.
return _automatedVaults[vaultId];
return _operationTracker[vaultId];
AutomatedVault memory autoVault = _automatedVaults[vaultId];
AutomatedVault memory autoVault = _automatedVaults[vaultId];
return _getAmounts(_automatedVaults[vaultId], vaultState, toCollateral);
if (_operationTracker[vaultId] > block.timestamp - 1 days) {
return _managedVaults[vaultId];
return _operationTracker[vaultId];
return _managers[manager];
return _permissions[envoy][target][selector];
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L48
_permissions[envoy][target][selector] = permission;
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L113
result = _proxies[proxy];
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L34
proxy = _currentProxies[owner];
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L34
IMIMOProxy currentProxy = _currentProxies[owner];
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L46
IMIMOProxy currentProxy = _currentProxies[owner];
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyRegistry.sol#L46
Severity: Gas Optimizations
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP
for (uint256 i = 0; i < targets.length; i++) {
https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L132
Severity: Gas Optimizations
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.
mapping(address => bool) internal _managers; https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/actions/managed/MIMOManagedAction.sol#L17
mapping(address => mapping(address => mapping(bytes4 => bool))) internal _permissions; https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxy.sol#L24
mapping(address => bool) internal _proxies; https://github.com/code-423n4/2022-08-mimo/tree/main/contracts/proxy/MIMOProxyFactory.sol#L24