Open code423n4 opened 2 years ago
The idea that all projects should exercise censorship is bonkers
The report is interesting and unique though
NC
L
Disagree with the specific example, the interface contracts are inheriting other interfaces, not same contracts
Will mark as R
Most linked are emitting, disputed
Disagree, good luck banning every account for every jurisdiction: https://www.youtube.com/watch?v=Q6euy5W1js4&ab_channel=aantonop
Disputed
Disputed, see OZ. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol
NC
R
Disputed for the examples shown, because there's a space between the two chars, you will not get a collision in that case as the two strings will have different meaning as the concat will be for x
'
y
meaning no clash can be achieved.
The only think you could do is provide the same values for both property name and item name and I believe in that case you'd be having the same issue for both encode and encodePacked
Disputed
I'm going to dispute not because wrong, but because you didn't say what the mistake is
Disagre as the sponsor wants to pass it as param which is immutable gas cost differences are negligible
L
Disagree the comment is about the mapping
NC
NC
Mostly disagree but w/e NC
Disagree as they are related while in different functions
Sounds good on paper, but code doesn't compile if you don't import ERC721
Disputed per the docs: https://docs.soliditylang.org/en/v0.8.17/control-structures.html?highlight=new#salted-contract-creations-create2
Cannot find when this was added, must be new
I appreciate the consideration but think this is out of scope, documentation should detail higher risk, but comment on already deploy proxy prob won't help, feel free to follow up with sponsor after the contest
R
Disagree, the role of the ERC721Votes is to track votes at a time
The role of governor is to allow voting, the function being in Governor is more appropriate
NC
NC
Overall a pretty good report, definitely can benefit by more of a human touch, but offers a good amount of insights
2L 3R 6NC
Low Risk Issues List
_owner
declaration shadows an existing declarationSafeTransferOwnership
instead oftransferOwnership
functionTotal 12 issues
Non-Critical Issues List
receive()
/fallback()
function0
address checkcastVote
andcastVotebySig
in ERC721VotesTotal 18 issues
[L-01] Floating Pragma
Description: 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. https://swcregistry.io/docs/SWC-103
Floating Pragma List: pragma ^0.8.4. (src/lib/ all files) pragma ^0.8.0. (src/lib/utils/TokenReceiver.sol)
Recommendation: Lock the pragma version and also consider known bugs (https://github.com/ethereum/solidity/releases) for the compiler version that is chosen.
[L-02]
_owner
declaration shadows an existing declarationContext: Treasury.sol#L141-L172
Description: Solidity docs: The function
initialize
in the file manager.sol#L82 has a local variable named_owner
. However, there is also a state variable in the Ownable.sol file with the same name, from which it inherited. Therefore, there is shadowing here. This shadowing does not pose a security threat because the owner in Ownable.sol is also updated with this function. However, shadowing is undesirable, state variable and local variable names should not be the same, this negatively audit control and code readability.Recommendation: State variable and local variable should be named differently.
following codes
[L-03] Non-essential inheritance list
Context: Auction.sol#L22
Description: If a contract inherited different contracts, the last inherited contract can be used directly. But there are files in the codes that are not implemented this way.
Recommendation:
IAuction;
A, B, C contracts are inherited.Auction
can inherit entire hierarchy by simply inheritingIAuction
following codes
[L-04] Need Fuzzing test
Context: 35 results - 9 files Project uncheckeds list:
Description: In total 9 contracts, 35 unchecked are used, the functions used are critical. For this reason, there must be fuzzing tests in the tests of the project. Not seen in tests.
Recommendation: Use should fuzzing test like Echidna.
As Alberto Cuesta Canada said: Fuzzing is not easy, the tools are rough, and the math is hard, but it is worth it. Fuzzing gives me a level of confidence in my smart contracts that I didn’t have before. Relying just on unit testing anymore and poking around in a testnet seems reckless now.
https://medium.com/coinmonks/smart-contract-fuzzing-d9b88e0b0a05
[L-05] Missing Event for Critical Parameters Change
Context: Auction.sol#L263 Auction.sol#L268 Governor.sol#L208 Treasury.sol#L210 Treasury.sol#L269
Description: Events help non-contract tools to track changes, and events prevent users from being surprised by changes.
Recommendation: Add
event-emit
[L-06] Add to Blacklist function
Description: Cryptocurrency mixing service, Tornado Cash, has been blacklisted in the OFAC. A lot of blockchain companies, token projects, NFT Projects have
blacklisted
all Ethereum addresses owned by Tornado Cash listed in the US Treasury Department's sanction against the protocol. https://home.treasury.gov/policy-issues/financial-sanctions/recent-actions/20220808 In addition, these platforms even ban accounts that have received ETH on their account with Tornadocash.Some of these Projects;
Details on the subject; https://twitter.com/bantg/status/1556712790894706688?s=20&t=HUTDTeLikUr6Dv9JdMF7AA
https://cryptopotato.com/defi-protocol-aave-bans-justin-sun-after-he-randomly-received-0-1-eth-from-tornado-cash/
For this reason, every project in the Ethereum network must have a blacklist function, this is a good method to avoid legal problems in the future, apart from the current need.
Transactions from the project by an account funded by Tonadocash or banned by OFAC can lead to legal problems.Especially American citizens may want to get addresses to the blacklist legally, this is not an obligation
If you think that such legal prohibitions should be made directly by validators, this may not be possible: https://www.paradigm.xyz/2022/09/base-layer-neutrality
The ban on Tornado Cash makes little sense, because in the end, no one can prevent people from using other mixer smart contracts, or forking the existing ones. It neither hinders cybercrime, nor privacy.
Here is the most beautiful and close to the project example; Manifold
Manifold Contract https://etherscan.io/address/0xe4e4003afe3765aca8149a82fc064c0b125b9e5a#code
Recommended Mitigation Steps add to Blacklist function and modifier
[L-07] No check if OnERC721Received is implemented
Context: Auction.sol#L206
Description: When minting a NFT, the function does not check if a receiving contract implements onERC721Received(). Check if OnERC721Received is implemented. If this is intended,
safemint
should be used instead ofmint
Recommendation: Consider using
_safeMint
instead of_mint
[L-08] Missing supportsInterface
Context: ERC721.sol#L61-L66
Description: ERC721TokenReceiver interface ID is missing in supportInterface
Recommendation:
[L-09] Use
SafeTransferOwnership
instead oftransferOwnership
functionContext: Ownable.sol#L63-L67
Description:
transferOwnership
function is used to change Ownership fromOwnable.sol
.transferOwnership
is used in Ownable.sol and MetadataRenderer.sol files to transfer ownership of the contract to the DAO.There is another function,
SafeTransferOwnership
, use it is more secure due to 2-stage ownership transfer.Recommendation:
[L-10] Insufficient Tests
Context: MetadataRenderer.sol
Description: It is crucial to write tests with possibly 100% coverage for smart contract systems. Contract of top in Context were found to be not included in the test cases.
Recommendation: It is recommended to write proper test for all possible code flows and specially edge cases.
[L-11] Use abi.encode() to avoid collision
Context: MetadataRenderer.sol#L243 MetadataRenderer.sol#L243 MetadataRenderer.sol#L259 MetadataRenderer.sol#L290 MetadataRenderer.sol#L208 MetadataRenderer.sol#L309
Description: If you use keccak256(abi.encodePacked(a, b)) and both a and b are dynamic types, it is easy to craft collisions in the hash value by moving parts of a into b and vice-versa. More specifically, abi.encodePacked("a", "bc") == abi.encodePacked("ab", "c"). If you use abi.encodePacked for signatures, authentication or data integrity, make sure to always use the same types and check that at most one of them is dynamic. Unless there is a compelling reason, abi.encode should be preferred.
When are these used?
abi.encode:
abi.encode encode its parameters using the ABI specs. The ABI was designed to make calls to contracts. Parameters are padded to 32 bytes. If you are making calls to a contract you likely have to use abi.encode. If you are dealing with more than one dynamic data type, you may prefer to use abi.encode as it avoids collision. keccak256(abi.encode(data, ...)) is the safe way to generate a unique ID for a given set of inputs.abi.encodePacked:
abi.encodePacked encode its parameters using the minimal space required by the type. Encoding an uint8 it will use 1 byte. It is used when you want to save some space, and not calling a contract.Takes all types of data and any amount of input.Proof of Concept
[L-12] Return value of transfer not checked
Context: Auction.sol#L363
Description: When there’s a failure in transfer()/transferFrom() the function signature has a boolean return value and they indicate errors that way instead. By not checking the return value, operations that should have marked as failed, may potentially go through without actually making a payment.
Recommendation: Add return value checks.
[N-01] Inconsistent solidity versions
Description: Different Solidity compiler versions are used throughout
src repositories
. The following contracts mix versions:pragma ^0.8.4 (src/lib/ all files) pragma ^0.8.15 pragma ^0.8.0 (src/lib/utils/TokenReceiver.sol) pragma 0.8.15
Recommendation: Versions must be consistent with each other
Full List:
[N-02] Use a more recent version of solidity
Context: TokenReceiver.sol
Description: Old version of Solidity is used (
^0.8.0
), newer version should be used[N-03] Unused/Empty
receive()
/fallback()
functionContext: Treasury.sol#L269
Description: 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)))
[N-04] Function writing that does not comply with the 'Solidity Style Guide’
Context: Treasury.sol
Description: Order of Functions; ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier. But there are contracts in the project that do not comply with this.
https://docs.soliditylang.org/en/v0.8.15/style-guide.html
Functions should be grouped according to their visibility and ordered:
[N-05] WETH address definition can be use directly
Context: Auction.sol#L41
Description: WETH is a wrap Ether contract with a specific address in the Etherum network, giving the option to define it may cause false recognition, it is healthier to define it directly.
Advantages of defining a specific contract directly:
WETH Address : 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Recommendation:
[N-06]
0
address checkContext: Token.sol#L30-L32 Auction.sol#L39-L42 Governor.sol#L41-L43 Treasury.sol#L33
Description: Also check of the address to protect the code from 0x0 address problem just in case. This is best practice or instead of suggesting that they verify address != 0x0, you could add some good natspec comments explaining what is valid and what is invalid and what are the implications of accidentally using an invalid address.
Recommendation: like this ;
if (_treasury == address(0)) revert ADDRESS_ZERO();
[N-07] Missing NatSpec mapping comment
Context: ManagerStorageV1.sol#L9
Description: Last value in Nested Mapping is missing from comments
Recommendation: ManagerStorageV1.sol#L9
Recomendation code:
[N-08] There is no need to cast a variable that is already an address, such as address(x)
Context: Governor.sol#L550 Governor.sol#L555
Description: There is no need to cast a variable that is already an address, such as address(auctioneer_), auctioneer also address.
Recommendation: Use directly variable.
[N-09] Add to indexed parameter for countable Events
Context: IAuction.sol#L22 IAuction.sol#L28 IGovernor.sol#L42 IGovernor.sol#L20 ITreasury.sol#L22
Recommendation: Add to indexed parameter for countable Events.
[N-10] Include return parameters in NatSpec comments
Context: All Contracts
Description: It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability.
https://docs.soliditylang.org/en/v0.8.15/natspec-format.html
Recommendation: Include return parameters in NatSpec comments
Recommendation Code Style: (from Uniswap3)
[N-11] Avoid to same local variable names declarated for code readability
Context: Token.sol#L179 Token.sol#L105
Description:
uint256 baseTokenId
local variable name is used in two different functions, this causes confusion and negatively affects code readability / controllability.Recommendation: Avoid to same local variable names declarated for code readability.
[N-12] Do not import more than one same contract
Context: Token.sol#L6-L7
Description: In
Token.sol
file,ERC721Votes
andERC721
contracts are imported, butERC721Votes
has already importedERC721
contract. Therefore, there is no need to import ERC721.Recommendation:
[N-13] Incorrect information in the document
Context: Manager.sol#L120-L129
Description: Protocol document states that contracts are created with
create2
, but contracts are created withnew instance
, these are two different architectures, must be updated.Recommendation: Update to document.
[N-14] Highest risk must be specified in NatSpec comments and documentation
Description: Although the UUPS model has many advantages and the proposed proxy model is currently the UUPS model, there are some caveats we should be aware of before applying it to a real-world project.
One of the main attention: Since upgrades are done through the implementation contract with the help of the
upgradeTo
method, there is a high risk of new implementations such as excluding theupgradeTo
method, which can permanently kill the smart contract's ability to upgrade. Also, this pattern is somewhat complicated to implement compared to other proxy patterns.Recommendation: Therefore, this highest risk must be found in NatSpec comments and documents.
[N-15] Implement some type of version counter that will be incremented automatically for contract upgrades
Description: As part of the upgradeability of
UUPS Proxies
, the contract can be upgraded multiple times, where it is a systematic approach to record the version of each upgrade.I suggest implementing some kind of version counter that will be incremented automatically when you upgrade the contract.
Recommendation:
[N-16] Add
castVote
andcastVotebySig
in ERC721VotesDescription: There are two methods by which a user can delegate their voting rights or cast votes on proposals: either calling the relevant functions (delegate, castVote) directly; or using by-signature functionality (delegateBySig, castVotebySig).
Recommendation: The ERC721Votes contract is just delegate and delegateBySig has the function. Consider adding
castVote
andcastVotebySig
.https://medium.com/compound-finance/delegation-and-voting-with-eip-712-signatures-a636c9dfec5e
[N-17] Empty blocks should be removed or Emit something
Context: Manager.sol#L209-L210
Description: Code contains empty block.
Recommendation: The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting.
Current code:
Suggested code:
[N-18] Long lines are not suitable for the ‘Solidity Style Guide’
Context: Token.sol#L59 Token.sol#L221 Token.sol#L310 Auction.sol#L376 Governor.sol#L27 Governor.sol#L363 Governor.sol#L620 Manager.sol#L167-L170 Token.sol#L310
Description: It is generally recommended that lines in the source code should not exceed 80-120 characters. Today's screens are much larger, so in some cases it makes sense to expand that. The lines above should be split when they reach that length, as the files will most likely be on GitHub and GitHub always uses a scrollbar when the length is more than 164 characters.
(why-is-80-characters-the-standard-limit-for-code-width)[https://softwareengineering.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width]
Recommendation: Multiline output parameters and return statements should follow the same style recommended for wrapping long lines found in the Maximum Line Length section.
https://docs.soliditylang.org/en/v0.8.17/style-guide.html#introduction