There may be errors when ProtocolDAO upgrades a contract with the same name #782
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-742
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/ProtocolDAO.sol#L190-L216
Vulnerability details
Impact
upgradeExistingContract()
without renaming and accidentally passes in the existingAddr as the newAddr, the protocol will be in error and never be upgraded again.upgradeExistingContract()
without changing their name will cause error.Proof of Concept
Since there are many direct name references between contracts, a contract can't change its name if it is to be upgraded separately.
However, the current implementatin of ProtocolDAO may cause errors if a contract upgrade without renaming.
Suppose ProtocolDAO is to be upgraded separately, from addr1 to addr2.
upgradeExistingContract(addr2, "ProtocolDAO", addr1)
: the storage will be in wrong state, because the address stored inkeccak256(abi.encodePacked("contract.address", "ProtocolDAO"))
will be deleted byunregisterContract(addr1)
.registerContract(addr2)
and thenunregisterContract(addr1)
: same error as case-1 above.unregisterContract(addr1)
and thenregisterContract(addr2)
: the second call will fail because the ProtocolDAO is no longer available (unregistered) after the first call, and the error will be unfixable because no contract can be upgraded anymore.upgradeExistingContract(addr1, "ProtocolDAO", addr1)
(accidentally provide addr1 as addr2): ProtocolDAO will be unavailable (unregistered), and the error will be unfixable because no contract can be upgraded anymore.Any contract that upgrade alone (without renaming) through upgradeExistingContract will cause error.
Similar to case 1/2 above,
upgradeExistingContract(addr2, name, addr1)
will case the address stored inkeccak256(abi.encodePacked("contract.address", name))
being deleted.Tools Used
VS Code
Recommended Mitigation Steps
The ProtocolDAO contract itself should be prohibited from being unregistered directly through
unregisterContract()
(Prevent ProtocolDAO from being unregistered due to misoperations).upgradeExistingContract()
should determine the case of an upgrade without a name change (as this will be common) and handle the case correctly.Sample code:
The text was updated successfully, but these errors were encountered: