# Holographable tokens can be reinitialized

Reentrancy in Holographer.initialize lets a malicious source contract overwrite _holographSlot, making getBridge/getOperator return attacker addresses that bypass ERC20 allowance.

- Payout: Contest reward
- Severity: medium
- Program: Holograph
- Credited: securerodd
- Disclosed: 2022-12-15
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-10-holograph-findings/issues/215
- Library page: https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:reentrancy

**Target:** HolographFactory / Holographer initializer (Solidity contracts)
**Root cause:** Holographer.initialize delegatecalls the enforcer, which optionally calls the source contract's init before initialization state is set, allowing reentrancy into initialize and overwriting _holographSlot/_adminSlot/_sourceContractSlot.
**Steps:**
1. Deploy malicious SourceContract whose init(bytes) reenters Holographer.init with a crafted payload.
2. Craft DeploymentConfig with byteCode = SourceContract creationCode and initCode encoding token metadata.
3. Sign the deployment hash with any key and call HolographFactory.deployHolographableContract(config, sig, user).
4. During enforcer init, SourceContract.init reenters Holographer.init, setting _holographSlot to the attacker contract.
5. Attacker contract's getBridge()/getOperator() return arbitrary addresses, which HolographERC20.transferFrom treats as allowance-free.
6. Verify via Holographer(newAsset).getHolog() == attacker contract.
**How found:** Code reading of the initialization flow: noticed the enforcer's optional call to the source contract occurs before initialization completes, making the initializer reentrant.
**Exploitation:** Attacker deploys a token through the legitimate HolographFactory that looks safe but whose _holographSlot points to attacker code; getBridge/getOperator return attacker-controlled addresses that can transferFrom any holder without allowance, enabling a rugpull.
**Insight:** When a proxy initializer delegatecalls into an enforcer that then calls back into attacker-supplied code, check whether initialization flags are set before the external call; also audit allowance-bypass special addresses (bridge/operator) since they amplify slot-overwrite bugs into fund theft.
