If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth)))
There are 1 finding of this issue:
//Links to github files
//actual codes used
token/IToken.sol:51: function initialize(
token/metadata/interfaces/IBaseMetadata.sol:27: function initialize(
auction/IAuction.sol:93: function initialize(
governance/treasury/ITreasury.sol:64: function initialize(address governor, uint256 delay) external;
src/governance/governor/IGovernor.sol:119: function initialize(
3. Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom
Description
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.
Consider using safeTransfer/safeTransferFrom or require() consistently.
4.Avoid using Floating Pragma
In the contracts, floating pragmas should not be used. 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.
7. Add constructor initializer in implementation contracts
Description
As per OpenZeppelin’s (OZ) recommendation, “The guidelines are now to make it impossible for anyone to run initialize on an implementation contract, by adding an empty constructor with the initializer modifier. So the implementation contract gets initialized automatically upon deployment.”
Note that this behaviour is also incorporated the OZ Wizard since the UUPS vulnerability discovery: “Additionally, we modified the code generated by the Wizard 19 to include a constructor that automatically initializes the implementation when deployed.”
Furthermore, this thwarts any attempts to frontrun the initialization tx of the implementation contract.
Incorporating this change would require inheriting the Initializable contract instead of having an explicit initialized variable.
1. UNUSED/EMPTY RECEIVE()/FALLBACK() FUNCTION
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth)))
There are 1 finding of this issue: //Links to github files
Treasury.sol:L269
2. Multiple initialization due to initialize function not having initializer modifier.
Description
The attacker can initialize the contract, take malicious actions, and allow it to be re-initialized by the project without any error being noticed.
Findings
IToken.sol:L51 IBaseMetadata.sol:L27 IAuction.sol:L93 ITreasury.sol:L64 IGovernor.sol:L119
3. Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom
Description
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.
Findings
Auction.sol:L192 Auction.sol:L363
Recommended Mitigation Steps
Consider using safeTransfer/safeTransferFrom or require() consistently.
4.Avoid using Floating Pragma
In the contracts, floating pragmas should not be used. 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.
Findings
ERC1967Upgrade.sol:L2
ERC1967Proxy.sol:L2
UUPS.sol:L2
ERC721Votes.sol:L2
ERC721.sol:L2
5. Immutable addresses lack zero-address check
Constructors should check the address written in an immutable address variable is not the zero address.
Findings
6. USE _SAFEMINT() INSTEAD OF _MINT()
_mint()
is discouraged in favor of_safeMint()
which ensures that the recipient is either an EOA or implementsIERC721Receiver
.Findings
Token.sol:L161 Token.sol:L188
7. Add constructor initializer in implementation contracts
Description
As per OpenZeppelin’s (OZ) recommendation, “The guidelines are now to make it impossible for anyone to run initialize on an implementation contract, by adding an empty constructor with the initializer modifier. So the implementation contract gets initialized automatically upon deployment.”
Note that this behaviour is also incorporated the OZ Wizard since the UUPS vulnerability discovery: “Additionally, we modified the code generated by the Wizard 19 to include a constructor that automatically initializes the implementation when deployed.”
Furthermore, this thwarts any attempts to frontrun the initialization tx of the implementation contract.
Incorporating this change would require inheriting the Initializable contract instead of having an explicit initialized variable.
Findings