Summary
noOfTiers
of DAOConfig
in MembershipDAOStructs
should use uint8
instead of uint256
Vulnerability Details
noOfTiers
of DAOConfig
is using uint256
. But it is only storing values from 1 to 7.
We can ensure that by seeing the TIER_MAX
of MembershipDAOStructs
and createNewDAOMembership
, updateDAOMembership
function of MembershipFactory
.
https://github.com/Cyfrin/2024-11-one-world/blob/main/contracts/dao/libraries/MembershipDAOStructs.sol
pragma solidity 0.8.22;
β
uint64 constant TIER_MAX = 7; π
β
enum DAOType {
PUBLIC,
PRIVATE,
SPONSORED
}
β
β
struct DAOConfig {
string ensname;
DAOType daoType;
TierConfig[] tiers;
address currency;
uint256 maxMembers;
uint256 noOfTiers; π
}
β
struct DAOInputConfig {
string ensname;
DAOType daoType;
address currency;
uint256 maxMembers;
uint256 noOfTiers;
}
β
struct TierConfig {
uint256 amount;
uint256 price;
uint256 power;
uint256 minted;
}
β
Here we can see it is checking that daoConfig.noOfTiers
should less than or equal to TIER_MAX
and greater than 0
.
2024-11-one-world/contracts/dao/MembershipFactory.sol at main Β· Cyfrin/2024-11-one-world
function createNewDAOMembership(DAOInputConfig calldata daoConfig, TierConfig[] calldata tierConfigs)
external returns (address) {
require(currencyManager.isCurrencyWhitelisted(daoConfig.currency), "Currency not accepted.");
require(daoConfig.noOfTiers == tierConfigs.length, "Invalid tier input.");
π require(daoConfig.noOfTiers > 0 && daoConfig.noOfTiers <= TIER_MAX, "Invalid tier count.");
require(getENSAddress[daoConfig.ensname] == address(0), "DAO already exist.");
if (daoConfig.daoType == DAOType.SPONSORED) {
require(daoConfig.noOfTiers == TIER_MAX, "Invalid tier count for sponsored.");
}
β
...OTHER_CODE...
}
Also here we can see, that it is also checking the same things.
https://github.com/Cyfrin/2024-11-one-world/blob/main/contracts/dao/MembershipFactory.sol#L96C5-L134C6
function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyRole(EXTERNAL_CALLER) returns (address) {
address daoAddress = getENSAddress[ensName];
π require(tierConfigs.length <= TIER_MAX, "Invalid tier count.");
require(tierConfigs.length > 0, "Invalid tier count.");
require(daoAddress != address(0), "DAO does not exist.");
DAOConfig storage dao = daos[daoAddress];
if(dao.daoType == DAOType.SPONSORED){
require(tierConfigs.length == TIER_MAX, "Invalid tier count.");
}
β
...OTHER_CODE...
π dao.noOfTiers = tierConfigs.length;
return daoAddress;
}
Impact
using a larger data type like uint256
for a limited range of values wouldn't necessarily and is taking a lot of storage.
It is not storage efficient and also not gas optimized.
Tools Used
Manually Reviewed.
Recommendations
Use uint8
instead of uint256
.
uint8
can store values from 0 to 255