All contracts in scope implements an upgradeable contract from OZ. However, those contracts misses _gap variable, which can cause corruptible storage when being upgraded.
Root Cause
Stablecoin contract implements ERC20PermitUpgradeable and Blacklist:
contract Stablecoin is ERC20PermitUpgradeable, Blacklist
and Blacklist also implements AccessControlUpgradeable:
abstract contract Blacklist is AccessControlUpgradeable
The similar applies to StablecoinHandler and AmirX:
abstract contract StablecoinHandler is
AccessControlUpgradeable,
PausableUpgradeable
contract AmirX is StablecoinHandler
But _gap is missing, when either one of those contracts gets upgraded, it can cause corrupted storage, breaking contract states.
y4y
Medium
Corruptible storage pattern in multiple contracts
Summary
All contracts in scope implements an upgradeable contract from OZ. However, those contracts misses
_gap
variable, which can cause corruptible storage when being upgraded.Root Cause
Stablecoin
contract implementsERC20PermitUpgradeable
andBlacklist
:and
Blacklist
also implementsAccessControlUpgradeable
:The similar applies to
StablecoinHandler
andAmirX
:But
_gap
is missing, when either one of those contracts gets upgraded, it can cause corrupted storage, breaking contract states.Internal pre-conditions
No response
External pre-conditions
No response
Attack Path
No response
Impact
Storage can be broken when being upgraded.
PoC
No response
Mitigation
Add
_gap
to all upgradeable contracts.