Platform: Code4rena
Start Date: 15/02/2022
Pot Size: $30,000 USDC
Total HM: 18
Participants: 35
Period: 3 days
Judge: GalloDaSballo
Total Solo HM: 8
Id: 87
League: ETH
Rank: 27/35
Findings: 2
Award: $117.86
🌟 Selected for report: 0
🚀 Solo Findings: 0
79.9481 USDC - $79.95
It is good to add a require() statement that checks the return value of token transfers or to use something like OpenZeppelin’s safeTransfer/safeTransferFrom unless one is sure the given token reverts in case of a failure. Failure to do so will cause silent failures of transfers and affect token accounting in contract.
Reference: This similar medium-severity finding from Consensys Diligence Audit of Fei Protocol: https://consensys.net/diligence/audits/2021/01/fei-protocol/#unchecked-return-value-for-iweth-transfer-call
Navigate to the following contract.
transfer/transferFrom functions are used instead of safe transfer/transferFrom on the following contracts.
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/ThecosomataETH.sol#L146 https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/ThecosomataETH.sol#L164
Code Review
Consider using safeTransfer/safeTransferFrom or require() consistently.
There are many external risks so my suggestion is that you should consider making the contracts pausable, so in case of an unexpected event, the admin can pause transfers.
Code Review
Consider making contracts Pausable https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/Pausable.sol.
The protocol do not appear to support rebasing/deflationary/inflationary tokens whose balance changes during transfers or over time. The necessary checks include at least verifying the amount of tokens transferred to contracts before and after the actual transfer to infer any fees/interest.
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/ThecosomataETH.sol#L146
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/ThecosomataETH.sol#L164
Code Review
The contract is inheriting from OpenZeppelin's Ownable contract which enables the onlyOwner role to transfer ownership to another address. It's possible that the onlyOwner role mistakenly transfers ownership to the wrong address, resulting in a loss of the onlyOwner role. The current ownership transfer process involves the current owner calling Unlock.transferOwnership(). This function checks the new owner is not the zero address and proceeds to write the new owner's address into the owner's state variable. If the nominated EOA account is not a valid account, it is entirely possible the owner may accidentally transfer ownership to an uncontrolled account, breaking all functions with the onlyOwner() modifier. Lack of two-step procedure for critical operations leaves them error-prone if the address is incorrect, the new address will take on the functionality of the new role immediately
for Ex : -Alice deploys a new version of the whitehack group address. When she invokes the whitehack group address setter to replace the address, she accidentally enters the wrong address. The new address now has access to the role immediately and is too late to revert
None
Implement zero address check and Consider implementing a two step process where the owner nominates an account and the nominated account needs to call an acceptOwnership() function for the transfer of ownership to fully succeed. This ensures the nominated EOA account is a valid and active account.
#0 - drahrealm
2022-02-19T04:04:22Z
Idem with previous issues regarding the usage of safeTransfer
, this will be fixed.
For the 0002 and 0004, the issues are not really a concern since the contracts are going to be used for a short period of time for filling up the LP pool(and can easily be redeployed as needed due to it nature of usage). For 0003, we are not dealing with the rebase nature of BTRFLY (only burning and sending it out to the LP pool), so we should be good.
#1 - GalloDaSballo
2022-02-26T23:43:46Z
I agree with finding 1
Rest of findings feel non-critical to me
#2 - GalloDaSballo
2022-02-27T00:25:34Z
4/10
The advantages of versions 0.8.* over <0.8.0 are:
All Contracts
None
Consider to upgrade pragma to at least 0.8.4.
++i is more gas efficient than i++ in loops forwarding.
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/BribeVault.sol#L269 https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/RewardDistributor.sol#L82
Code Review
It is recommend to use unchecked{++i} and change i declaration to uint256.
That would Increase gas costs on all privileged operations.
The following role variables are marked as constant.
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/TokemakBribe.sol#L40 https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/BribeVault.sol#L27
This results in the keccak operation being performed whenever the variable is used, increasing gas costs relative to just storing the output hash. Changing to immutable will only perform hashing on contract deployment which will save gas.
See: ethereum/solidity#9232 (https://github.com/ethereum/solidity/issues/9232#issuecomment-646131646)
Code Review
Consider to change the variable to be immutable rather than constant.
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/BribeVault.sol#L269
https://github.com/code-423n4/2022-02-redacted-cartel/blob/main/contracts/BribeVault.sol#L269
Code Review
Consider caching array call data elements in the for loop.
#0 - drahrealm
2022-02-19T07:30:21Z
Duplicate with previous similar gas optimization tips
#1 - GalloDaSballo
2022-02-26T01:15:23Z
003 is not correct, this "myth" emerged from old contests and we busted it
#2 - GalloDaSballo
2022-02-26T01:15:54Z
Very basic submission, I fell like these findings are a little too generic and compared to other warden's work there was more to be found
#3 - GalloDaSballo
2022-02-26T01:31:33Z
2/10