It is recommended to add zero address checks for listed parameters.
2. Missing events
Risk
Low
Impact
Multiple contracts are not implementing events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
It is recommended to add missing events to listed functions.
3. Use SafeERC20 safeTransfer
Risk
Low
Impact
The IERC20.transfer() function returns a boolean value indicating success. This parameter needs to be checked for success. Some tokens do not revert if the transfer failed but return false instead.
Tokens that don't actually perform the transfer and return false are still counted as a correct transfer. Furthermore, tokens that do not correctly implement the EIP20 standard, like USDT which does not return a success boolean, will revert.
It is recommended to use OpenZeppelin's SafeERC20 with the safeTransfer function that handles the return value check as well as non-standard-compliant tokens.
4. Not following checks-effects-interactions pattern
Risk
Low
Impact
Function PermissionlessBasicPoolFactory.fundPool does not follow checks-effects-interactions pattern that might lead to reentrancy attacks.
success = success && IERC20(pool.rewardTokens[i]).transferFrom(msg.sender, address(this), amount);
// bookkeeping to make sure pools don't share tokens
pool.rewardFunding[i] += amount;
It is recommended to first set the effects and then perform interactions such as external calls.
5. Owner - critical address change
Impact
Changing critical addresses such as ownership should be a two-step process where the first transaction (from the old/current address) registers the new address (i.e. grants ownership) and the second transaction (from the new address) replaces the old address with the new one. This gives an opportunity to recover from incorrect addresses mistakenly used in the first step. If not, contract functionality might become inaccessible.
1. Missing zero address checks
Risk
Low
Impact
FactoryDAO's contracts do not check for zero addresses which might lead to loss of funds, failed transactions and can break the protocol functionality
Proof of Concept
MerkleDropFactory.sol
:tokenAddress
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleDropFactory.sol#L49destination
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleDropFactory.sol#L88MerkleResistor.sol
:tokenAddress
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleResistor.sol#L80MerkleVesting.sol
:tokenAddress
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleVesting.sol#L62MerkleIdentity.sol
:_mgmt
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleIdentity.sol#L52newMgmt
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleIdentity.sol#L60newAdder
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleIdentity.sol#L67nftAddress
,priceGateAddress
,eligibilityAddress
addresses - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleIdentity.sol#L92-L94MerkleEligibility.sol
:_gateMaster
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleEligibility.sol#L35FixedPricePassThruGate.sol
:_beneficiary
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/FixedPricePassThruGate.sol#L28SpeedBumpPriceGate.sol
:beneficiary
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/SpeedBumpPriceGate.sol#L37VoterID.sol
:ooner
andminter
addresses - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/VoterID.sol#L108thisOwner
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/VoterID.sol#L122newOwner
address - https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/VoterID.sol#L151PermissionlessBasicPoolFactory.sol
:_globalBeneficiary
address - https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/PermissionlessBasicPoolFactory.sol#L75depositTokenAddress
address - https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/PermissionlessBasicPoolFactory.sol#L97excessBeneficiary
address - https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/PermissionlessBasicPoolFactory.sol#L98rewardTokenAddresses
addresses - https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/PermissionlessBasicPoolFactory.sol#L116Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add zero address checks for listed parameters.
2. Missing events
Risk
Low
Impact
Multiple contracts are not implementing events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
Proof of Concept
MerkleIdentity.sol
:MerkleEligibility.sol
:FixedPricePassThruGate.sol
:SpeedBumpPriceGate.sol
:PermissionlessBasicPoolFactory.sol
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add missing events to listed functions.
3. Use SafeERC20 safeTransfer
Risk
Low
Impact
The
IERC20.transfer()
function returns a boolean value indicating success. This parameter needs to be checked for success. Some tokens do not revert if the transfer failed but return false instead.Tokens that don't actually perform the transfer and return false are still counted as a correct transfer. Furthermore, tokens that do not correctly implement the EIP20 standard, like USDT which does not return a success boolean, will revert.
Proof of Concept
MerkleVesting.sol
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to use OpenZeppelin's SafeERC20 with the
safeTransfer
function that handles the return value check as well as non-standard-compliant tokens.4. Not following checks-effects-interactions pattern
Risk
Low
Impact
Function
PermissionlessBasicPoolFactory.fundPool
does not follow checks-effects-interactions pattern that might lead to reentrancy attacks.Proof of Concept
PermissionlessBasicPoolFactory.sol
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to first set the effects and then perform interactions such as external calls.
5. Owner - critical address change
Impact
Changing critical addresses such as ownership should be a two-step process where the first transaction (from the old/current address) registers the new address (i.e. grants ownership) and the second transaction (from the new address) replaces the old address with the new one. This gives an opportunity to recover from incorrect addresses mistakenly used in the first step. If not, contract functionality might become inaccessible.
Proof of Concept
MerkleIdentity.sol
:VoterID.sol
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to implement two-step process for passing ownership for HolyPaladinToken.sol and PaladinRewardReserve.sol contracts.
6. Missing validation
Risk
Low
Impact
Missing check for
_globalTaxPerCapita
that should not exceeds1000
.Proof of Concept
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add check for
_globalTaxPerCapita
to make sure that the value cannot be bigger than1000
.7. VoterID tokenURI does not revert for non existent tokens
Risk
Non-Critical
Impact
Function
VoterID.tokenURI
that implements ERC721 standard should revert in case of non existent tokens.Proof of Concept
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to revert for non existent tokens.
8. Contracts use different compiler versions
Risk
Non-Critical
Impact
Using different compiler versions across contracts of the same project might lead to confusion and accidental errors.
Proof of Concept
Examples:
0.8.12
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/FixedPricePassThruGate.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/SpeedBumpPriceGate.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleIdentity.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleEligibility.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/VoterID.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleDropFactory.sol#L30.8.9
- https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleResistor.sol#L3Tools Used
Manual Review / VS Code
Recommended Mitigation Steps
Consider using a single compiler version for compiling both contracts, for example 0.8.12.