Platform: Code4rena
Start Date: 31/03/2022
Pot Size: $75,000 USDC
Total HM: 7
Participants: 42
Period: 7 days
Judge: Jack the Pug
Total Solo HM: 5
Id: 102
League: ETH
Rank: 16/42
Findings: 2
Award: $268.40
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rayn
Also found by: 0xDjango, 0xkatana, 0xkowloon, BouSalman, CertoraInc, Dravee, Funen, Hawkeye, IllIllI, Jujic, Kenshin, Kthere, Meta0xNull, Sleepy, TerrierLover, async, aysha, berndartmueller, catchup, cccz, cmichel, csanuragjain, danb, defsec, georgypetrov, hake, hubble, kenta, kyliek, pauliax, rfa, robee, sahar, shenwilly, teryanarmen
177.1539 USDC - $177.15
2022-03-volt
1 delete unused import statement.
Delete the line.
2 update event error message which is related to FEI. The following event error messages include the name FEI. These messages must be updated.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/volt/Volt.sol#L92 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/volt/Volt.sol#L72
require(deadline >= block.timestamp, "Volt: EXPIRED"); require(recoveredAddress != address(0) && recoveredAddress == owner, "Volt: INVALID_SIGNATURE");
3 change the following comment. The following comment has the wrong description. It must be changed.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/core/Core.sol#L14
/// @notice the address of the VOLT contract
4 Use mixedCase for the immutable state variable. All capital letters will be used for constants. The following state variable is immutable, so mixedCase.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/RateLimited.sol#L11 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/RateLimited.sol#L52
uint256 public immutable maxRateLimitPerSecond;
5 check whether the value is under 112 bits or not. The following line try to convert uint from 256 to 112. Like safeCast.sol of openzeppelin the validation must be checked with require statement.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/MultiRateLimited.sol#L172-L173 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/MultiRateLimited.sol#L216-L222 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/MultiRateLimited.sol#L340-L342
require(individualMaxRateLimitPerSecond <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); require(individualMaxBufferCap <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
require(newBuffer - amount <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
6 Lock pragmas to specific compiler version. Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
pragma solidity 0.8.4;
7 check input validation in withdrawERC20. Param amount must be checked if it is 0 or not.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L201-L206
require(amount != 0, “Invalid amount”);
8 the wrong local variable name. The following local variable name makes the user confused.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L286 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L290
uint256 amountVoltToTransfer = Math.min() uint256 amountVoltToMint = amountVoltOut - amountFeiToTransfer;
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0xNazgul, 0xkatana, 0xkowloon, CertoraInc, Dravee, Funen, Hawkeye, Jujic, Kenshin, Meta0xNull, Sleepy, TerrierLover, catchup, csanuragjain, defsec, georgypetrov, kenta, okkothejawa, rayn, rfa, robee, saian, samruna
91.2509 USDC - $91.25
2022-03-volt gas optimization
1 use unchecked. Underflow is already checked in the previous require statement, so it will never happen. That’s why you can use unchecked to save gas costs in the following line.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/RateLimited.sol#L106
Unchecked { bufferStored = newBuffer - usedAmount; }
2 use unchecked. Like the comment describes, block timestamp always >= startTime and it will be also checked with if (!isTimeStarted()) that startTime is already initialized. You can use unchecked in the following line to save gas costs.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/Timed.sol#L57
uint256 timePassed unchecked { timePassed = block.timestamp - startTime; }
3 use cache and unchecked in the following places. In require statement underflow for amount <= newBuffer is checked, so you can use unchecked for the following calculations. In addition, the calculation must be executed in the other place too. You can use cache for it.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/MultiRateLimited.sol#L341 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/utils/MultiRateLimited.sol#L351
uint bufferStore;
unchecked { bufferStore = newBuffer - amount; } rateLimitPerAddress[rateLimitedAddress].bufferStored = uint112(bufferStore);
emit IndividualBufferUsed(rateLimitedAddress, amount, bufferStore);
3 use unchecked in mint. amountFeiToTransfer must be less than or equal to amountVoltOut. You can save gas costs by wrapping the following calculation with unchecked.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L290
uint256 amountFeiToMint; unchecked { amountFeiToMint = amountVoltOut - amountFeiToTransfer; }