# Corruptible Upgradability Pattern

Upgradeable Notional Balancer vaults inherit mixin contracts lacking storage gaps, so adding variables in an upgrade can corrupt child storage and freeze assets.

- Payout: Contest reward
- Severity: medium
- Program: Notional
- Credited: xiaoming90
- Disclosed: 2022-09-15
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-09-notional-judging/issues/64
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-09-notional%3AM-16
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:misconfiguration

**Target:** Solidity upgradeable vault contracts (Boosted3TokenAuraVault, MetaStable2TokenAuraVault)
**Root cause:** Intermediate inherited mixin contracts (PoolMixin, AuraStakingMixin, TwoTokenPoolMixin, etc.) define storage but no __gap, so future variable additions shift the storage layout of child contracts.
**Steps:**
1. Map inheritance chain of MetaStable2TokenAuraVault and Boosted3TokenAuraVault
2. Observe __gap only in BaseStrategyVault and BalancerStrategyBase
3. Note mixins like PoolMixin/AuraStakingMixin/TwoTokenPoolMixin/BalancerOracleMixin have no gap
4. Conclude adding a variable to any such mixin overwrites the start of child storage on upgrade
**How found:** Manual review of inheritance graphs and storage layout of upgradeable vaults, comparing which parents define __gap slots versus which do not.
**Insight:** When auditing UUPS/upgradeable contracts, walk the full inheritance chain and flag any parent with storage but no trailing __gap; gaps in only the base contracts don't protect against insertions in intermediate mixins.
