You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Functions run in Diamond's delegatecall context, so initialization happens in the right storage.
190
+
The init contract runs in the Diamond's delegatecall context, so initialization happens in the right storage. For factory/CREATE2/clone deployments where a constructor cannot run per-instance, expose an initializer-guarded `initialize` function in your concrete diamond instead (see `test/mocks/MockDiamond.sol` for a reference).
DiamondLib->>DiamondLib: validate & apply all cuts
318
289
DiamondLib->>Diamond: emit DiamondCut event
319
290
320
291
Diamond->>InitContract: delegatecall(initData)
321
292
InitContract->>Diamond: write state (owner, etc)
322
293
InitContract-->>Diamond: return
323
-
324
-
Diamond->>InitLib: postInitializer()
325
-
InitLib->>InitLib: set initializing=false, version++
326
-
InitLib->>Diamond: emit Initialized event
327
-
```
328
-
329
-
### Reinitialization Prevention
330
-
331
-
**Problem**: Without guards, anyone could reset state by calling init again.
332
-
333
-
**Solution: Version tracking**
334
-
335
-
```
336
-
First init: version 0 → 1 (success)
337
-
Retry same: version 1 → 1 (fails: InvalidInitialization)
338
-
Upgrade init: version 1 → 2 (success: reinitializer)
339
294
```
340
295
341
-
**Guarantees:**
342
-
- Cannot reinitialize to same or lower version
343
-
- Can upgrade to higher version (supports versioned upgrades)
344
-
- Initialization flag prevents reentrancy during init
296
+
Running the cut in the constructor is atomic: the diamond is never observable in a facetless, ownerless state, and there is no separate `initialize` transaction to front-run.
0 commit comments