Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: high
Valid

Incorrect initialOwner in MembershipERC1155 TransparentUpgradeableProxy Initialization

Summary

The MembershipERC1155 TransparentUpgradeableProxy is initialized with the wrong initialOwner address in the createNewDAOMembership function. This error occurs due to the assignment of proxyAdmin (an address of a contract) as the initialOwner, instead of an EOA (Externally Owned Account) that could perform future upgrades. Consequently, if upgrades are needed for the MembershipERC1155, they would be inaccessible since the proxyAdmin contract cannot invoke upgradeAndCall.

Vulnerability Details

The TransparentUpgradeableProxy contract requires three parameters: _logic, initialOwner, and _data. In createNewDAOMembership, the initialOwner is set as the proxyAdmin, this is the address of the proxyAdmin contract created in the MembershipFactory constructor. The TransparentUpgradeableProxy contract creates a new proxyAdmin instance and sets the originally created proxyAdmin (from MembershipFactory) as its owner.

The onlyOwner modifier on upgradeAndCall restricts future upgrades, as the proxyAdmin contract (incorrectly set as the initialOwner) cannot be used to invoke upgradeAndCall.

// MembershipFactory
constructor(
address _currencyManager,
address _owpWallet,
string memory _baseURI,
address _membershipImplementation
) {
currencyManager = ICurrencyManager(_currencyManager);
baseURI = _baseURI;
owpWallet = _owpWallet;
membershipImplementation = _membershipImplementation;
@> proxyAdmin = new ProxyAdmin(msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(EXTERNAL_CALLER, msg.sender);
}
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.");
}
// enforce maxMembers
uint256 totalMembers = 0;
for (uint256 i = 0; i < tierConfigs.length; i++) {
totalMembers += tierConfigs[i].amount;
}
require(totalMembers <= daoConfig.maxMembers, "Sum of tier amounts exceeds maxMembers.");
console.log("admin1", address(proxyAdmin));
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
membershipImplementation,
@> address(proxyAdmin),
abi.encodeWithSignature(
"initialize(string,string,string,address,address)",
daoConfig.ensname,
"OWP",
baseURI,
_msgSender(),
daoConfig.currency
)
);
DAOConfig storage dao = daos[address(proxy)];
dao.ensname = daoConfig.ensname;
dao.daoType = daoConfig.daoType;
dao.currency = daoConfig.currency;
dao.maxMembers = daoConfig.maxMembers;
dao.noOfTiers = daoConfig.noOfTiers;
for (uint256 i = 0; i < tierConfigs.length; i++) {
require(tierConfigs[i].minted == 0, "Invalid tier config");
dao.tiers.push(tierConfigs[i]);
}
getENSAddress[daoConfig.ensname] = address(proxy);
userCreatedDAOs[_msgSender()][daoConfig.ensname] = address(proxy);
emit MembershipDAONFTCreated(daoConfig.ensname, address(proxy), dao);
return address(proxy);
}
// TransparentUpgradeableProxy
constructor(address _logic, address initialOwner, bytes memory _data) payable ERC1967Proxy(_logic, _data) {
@> _admin = address(new ProxyAdmin(initialOwner));
// Set the storage value and emit an event for ERC-1967 compatibility
ERC1967Utils.changeAdmin(_proxyAdmin());
}

Impact

There is no way to upgrade the MembershipERC1155 proxy contract if necessary. This could result in functional and security issues remaining unresolved.

Tools Used

Manual Review

Recommendations

Update the createNewDAOMembership function to set initialOwner to an address capable of performing upgrades, such as an EOA that is the actual owner or DAO multisig address for more secure access management.

Updates

Lead Judging Commences

0xbrivan2 Lead Judge
7 months ago
0xbrivan2 Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

MembershipERC1155 implementations can not be upgraded for already deployed proxies

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.