# Wrong implementation of EIP712MetaTransaction

EIP712MetaTransaction initializer used `initializer` instead of `onlyInitializing`, breaking inheritance-based initialization and preventing re-init on upgrade.

- Payout: Audit contest
- Severity: high
- Program: Rolla
- Found by: WatchPug
- Disclosed: 2022-06-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-03-rolla-findings/issues/43
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-rolla%3AH-03
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:misconfiguration

**Target:** Solidity upgradeable utility contract (EIP712MetaTransaction)
**Root cause:** The base utility contract's initializer used the `initializer` modifier instead of `onlyInitializing`, so when a concrete contract's own `initializer` calls it, the nested call is treated as reentrancy and reverts; also `initializer` can only run once, contradicting the 'every upgrade' intent.
**Steps:**
1. Inherit EIP712MetaTransaction into a concrete upgradeable contract with its own `initializer` function.
2. Have the concrete initializer call `initializeEIP712(name, version)`.
3. Observe revert 'Initializable: contract is already initialized' because `_initializing` is true and not in constructor context.
4. Fix: make contract abstract, rename to `__EIP712MetaTransaction_init`, use `internal onlyInitializing`.
**How found:** Code review comparing the contract's initializer pattern against OpenZeppelin's EIP712Upgradeable reference implementation, noticing the wrong modifier for an inherited utility contract.
**Insight:** When auditing upgradeable Solidity, check that base/utility initializers use `onlyInitializing` (not `initializer`) and are `internal`; a nested `initializer` call reverts outside constructor context, breaking deployment or upgrade flows.
