Platform: Code4rena
Start Date: 20/01/2022
Pot Size: $80,000 USDC
Total HM: 5
Participants: 37
Period: 7 days
Judge: Jack the Pug
Total Solo HM: 1
Id: 76
League: ETH
Rank: 9/37
Findings: 2
Award: $2,494.83
🌟 Selected for report: 1
🚀 Solo Findings: 0
11.8662 USDC - $11.87
ye0lde
Redundant arithmetic underflow/overflow checks can be avoided when an underflow/overflow cannot happen.
The "unchecked" keyword can be applied here since there is an if
statement before to ensure the arithmetic operations would not cause an integer underflow or overflow.
https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockProtocolManager.sol#L327-L336
Change the code at 327 to:
unchecked { if (claimablePremiumError > lastClaimablePremiumsForStakers_) { insufficientTokens = claimablePremiumError - lastClaimablePremiumsForStakers_; lastClaimablePremiumsForStakers = 0; } else { // If the error is not bigger than the claimable premiums, then we just decrease claimable premiums // By the amount that was added in error (error) and insufficientTokens = 0 lastClaimablePremiumsForStakers = lastClaimablePremiumsForStakers_ - claimablePremiumError; } }
Visual Studio Code, Remix
Add the "unchecked" keyword as shown above.
#0 - jack-the-pug
2022-03-28T05:07:37Z
Dup #253
11.8662 USDC - $11.87
ye0lde
Gas savings and code clarity
Below are several occurrences of comparison with literal boolean values of true or false: https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/SherBuy.sol#L89 https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/SherBuy.sol#L126
https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockClaimManager.sol#L285 https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockClaimManager.sol#L417 https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockClaimManager.sol#L502
Visual Studio Code, Remix
Use the compared expression itself in place of comparison with a boolean literal. The expression can be replaced as is when the expression is expected to evaluate to true and negation can be used when the expression is expected to have a false value.
For example:
if (able == false) revert InvalidConditions();
can be replaced with
if (!able) revert InvalidConditions();
#0 - jack-the-pug
2022-03-26T07:34:27Z
Dup #132
🌟 Selected for report: Afanasyevich
Also found by: sirhashalot, wuwe1, ye0lde
36.1718 USDC - $36.17
ye0lde
Removing redundant code can reduce gas usage and improve code clarity.
The _isCleanupState function: https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockClaimManager.sol#L160-L164
I suggest this refactoring:
function _isCleanupState(State _oldState) internal pure returns (bool) { return _oldState == State.SpccDenied || _oldState == State.SpccPending ? true : false; }
Visual Studio Code, Remix
See POC for details.
#0 - jack-the-pug
2022-03-26T13:49:39Z
Should be:
function _isCleanupState(State _oldState) internal pure returns (bool) { return _oldState == State.SpccDenied || _oldState == State.SpccPending; }
Right?
But I also like the original one, it's quite clean and easy to read.
#1 - jack-the-pug
2022-03-28T05:08:39Z
Dup #130
🌟 Selected for report: ye0lde
ye0lde
A protocol
can be removed when the premium
is not zero or there is a misleading comment for function protocolRemove
.
A comment for function protocolRemove at: https://github.com/code-423n4/2022-01-sherlock/blob/c763f10c4b5fe2127677d6c25b83adcf3bcec212/contracts/managers/SherlockProtocolManager.sol#L598
states
/// @dev Before removing a protocol the premium must be 0
But the function does not check that the premium
is zero and calls _forceRemoveProtocol
which eventually "forces" the premium
to zero without any checking.
If the comment is correct then a check for premiums_[_protocol] == 0
is needed. While onlyOwner
can call this function, it still verifies that onlyOwner
does not pass in a non-existent protocol. It seems it should also check that premium
is zero.
On the other hand, if the comment is incorrect I suggest that it should be rewritten to something like this:
/// @dev Premium will be forced to 0 before the protocol is removed.
Visual Studio Code, Remix
See the POC