Platform: Code4rena
Start Date: 17/02/2022
Pot Size: $75,000 USDC
Total HM: 20
Participants: 39
Period: 7 days
Judges: moose-code, JasoonS
Total Solo HM: 13
Id: 89
League: ETH
Rank: 19/39
Findings: 3
Award: $472.53
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: danb
Also found by: Meta0xNull, Ruhum, cmichel, csanuragjain, hyh, kirk-baird, leastwood, minhquanym, robee, throttle
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L48-L50 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L53-L67
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L48-L50 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L53-L67
Manual Review
In function withdraw(), require minimum withdrawal amount to avoid near zero cost DDOS. require(amount >= 10000000, 'Min Amount >= 10 VUSD');
#0 - atvanguard
2022-02-24T05:12:19Z
Duplicate of #119
🌟 Selected for report: defsec
Also found by: 0v3rf10w, 0x0x0x, 0x1f8b, 0xwags, CertoraInc, Dravee, IllIllI, Meta0xNull, Nikolay, Omik, WatchPug, bobi, cccz, csanuragjain, danb, gzeon, hubble, hyh, itsmeSTYJ, jayjonah8, kenta, kirk-baird, leastwood, pauliax, peritoflores, rfa, robee, sorrynotsorry, ye0lde
142.3223 USDC - $142.32
Use uint256 because it is consistent with other uint data types, which also specify their size, and also because making the size of the data explicit reminds the developer and the reader how much data they've got to play with, which may help prevent or detect bugs.
It's also better to be explicit when constructing method signature ID's. For example if doing bytes4(keccak('transfer(address, uint)')), you'll get a different method sig ID than bytes4(keccak('transfer(address, uint256)')) and smart contracts will only understand the latter when comparing method sig IDs.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L25 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L28 More...
Open TODOs can hint at programming or architectural errors that still need to be fixed.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/AMM.sol#L142 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/AMM.sol#L555 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/ClearingHouse.sol#L172 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/MarginAccount.sol#L277
Fix TODOs List and Remove it.
#0 - moose-code
2022-03-05T16:06:12Z
Would be nice to understand the motivation to use uint as opposed to uint256. Am sure its been thought through.
87.3994 USDC - $87.40
uint256[50] private __gap;
Variable __gap was not used in VUSD.sol and some other contracts. They will increase the size of deployment with no real benefit
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L30
Remove Line 30 in VUSD.sol.
string public name;
If data can fit into 32 bytes, then you should use bytes32 datatype rather than bytes or strings as it is much cheaper in solidity. Basically, Any fixed size variable in solidity is cheaper than variable size. That will save gas on the contract.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/AMM.sol#L28
bytes32 public name;
Shortening revert strings to fit in 32 bytes will decrease deployment time gas and will decrease runtime gas when the revert condition has been met.
Revert strings that are longer than 32 bytes require at least one additional mstore, along with additional overhead for computing memory offset, etc.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/AMM.sol#L487 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/AMM.sol#L511 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/ClearingHouse.sol#L84 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/ClearingHouse.sol#L101 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/MarginAccount.sol#L174 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/MarginAccount.sol#L354 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/MarginAccount.sol#L453 https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L55
Shorten the revert strings to fit in 32 bytes.
Or consider using Custom Errors (solc >=0.8.4).
uint constant VUSD_IDX = 0;
The local variable need not be initialized to 0 because the default value is 0. Avoiding this anti-pattern can save a few opcodes and therefore a tiny bit of gas.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/MarginAccount.sol#L31
Remove explicit 0 initialization.
uint constant VUSD_IDX;
A wrong user input or wallets defaulting to the zero addresses for a missing input can lead to the contract needing to redeploy or wasted gas.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/Registry.sol#L12-L23
Requires Addresses is not zero.
require(_oracle != address(0), "Address Can't Be Zero") require(_clearingHouse != address(0), "Address Can't Be Zero") require(_insuranceFund != address(0), "Address Can't Be Zero") require(_marginAccount != address(0), "Address Can't Be Zero") require(_vusd != address(0), "Address Can't Be Zero")
#0 - moose-code
2022-03-05T15:20:41Z
uint256[50] private __gap is common for smart contract upgrades to keep storage bits grouped logically together.