The UpgradeBranch
implementation contract does not call _disableInitializers
to lock the contract. This leaves it vulnerable to being initialized by an attacker, who can then call arbitrary initializables and potentially kill the contract using selfdestruct
. This critical vulnerability can render the RootProxy unable to exercise its upgrading operations, effectively making the Tree Proxy system inoperable.
The root cause of the vulnerability is that _disableInitializers
is not called to lock the implementation contract. Let us walk through the issue with the following scenario:
Alice discovers that the _disableInitializers
function was not called in the UpgradeBranch
implementation contract.
Alice initializes the UpgradeBranch
implementation contract, gaining ownership.
Alice uses the ownership to call an arbitrary initializable via upgrade
function, potentially invoking the selfdestruct
call, killing the UpgradeBranch
implementation contract.
As a result, the RootProxy
or PerpsEngine
cannot exercise its upgrading operations, rendering the Tree Proxy pattern inoperable.
Run following command to execute the POC:
git apply upgradeBranchDestruction.patch && forge test -vv --mt test_killImplementationContract
Notes: part of destroying code is in the setUp, due to the limitation of foundry reported at https://github.com/foundry-rs/foundry/issues/1543. The code size will be checked in the test_killImplementationContract.
upgradeBranchDestruction.patch:
The severity of this vulnerability is critical as it breaks the entire Tree Proxy upgrading pattern and potentially leading to significant disruptions or losses.
Foundry test
Call _disableInitializers
in the constructor of the UpgradeBranch
implementation contract. This locks the contract and prevents any unauthorized initialization attempts.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.