Some contracts do not implement good upgradeable logic.
Proof of Concept
Upgrading a contract will need a __gap storage in order to avoid storage collisions.
Proxied contracts MUST include an empty reserved space in storage, usually named __gap, in all the inherited contracts.
For example, the contract Governed or GraphUpgradeable are inherited by upgradeable contracts, but these contracts don't have a __gap storage, so if a new variable is created it could lead to storage collisions that will produce a contract disaster, including loss of funds.
Lines of code
https://github.com/code-423n4/2022-10-thegraph/blob/309a188f7215fa42c745b136357702400f91b4ff/contracts/l2/token/GraphTokenUpgradeable.sol#L28
Vulnerability details
Impact
Some contracts do not implement good upgradeable logic.
Proof of Concept
Upgrading a contract will need a
__gap
storage in order to avoid storage collisions.Proxied contracts MUST include an empty reserved space in storage, usually named
__gap
, in all the inherited contracts.For example, the contract
Governed
orGraphUpgradeable
are inherited by upgradeable contracts, but these contracts don't have a__gap
storage, so if a new variable is created it could lead to storage collisions that will produce a contract disaster, including loss of funds.Reference:
Affected source code:
Recommended Mitigation Steps
uint256[50] private __gap;
to all contracts.