💎 LE_DIAMOND Deploy Tool — REAL PRODUCTION FACETS ⚠️ MAINNET

⚠️ REAL DEPLOY — real LearnAndEarn production logic, real gas, real consequence. This is NOT the toy tool. Every facet deployed here is real Learn & Earn logic (views, admin/epoch/pause config, member withdrawals, and the core payment- intake/injection/queue logic). Go through the steps below IN ORDER, at your own pace — every step is independent: you can stop after any step and resume later, nothing is lost (progress auto-saves to this browser). If a contract is already deployed and you know its address, paste it into that step's override field instead of redeploying.

⚠️ Step 12 (bootstrapFirstEpoch) is a NEW one-time call not present in the real v8.5.3 source — required because this Diamond has no initializer. See the file header comment for why. Do it right after Step 11, before anything else touches epochs.
Progress backup
Every resolved address auto-saves to this browser (localStorage key 'leDiamondDeployV1'). Export/Import move progress across devices/browsers; Reset clears everything (asks to confirm).

Step 1 — Connect wallet, verify OWNER + network

Strict OWNER gate, same as every other tool in this project — if the connected wallet isn't exactly OWNER, every deploy/write button stays disabled.

Step 2 — Deploy DiamondCutFacet

Standard EIP-2535 diamondCut facet. No constructor args.

Step 3 — Deploy DiamondLoupeFacet

Standard EIP-2535 loupe facet (facets()/facetAddress()/etc). No constructor args.

Step 4 — Deploy OwnershipFacet

Standard EIP-2535 ownership facet (owner()/transferOwnership()). No constructor args.

Step 5 — Deploy Diamond (needs Step 2's DiamondCutFacet address)

Constructor: (OWNER, DiamondCutFacet address) — DiamondCutFacet's own selector is wired in automatically inside the constructor, per Diamond.sol. This is the address you'll call everything through from here on.

Step 6 — diamondCut: register DiamondLoupeFacet + OwnershipFacet

Calls diamondCut on the Diamond from Step 5 to register Loupe's 4 selectors + Ownership's 2 selectors. Needs Steps 3, 4, 5 done first.

Step 7 — Deploy LearnAndEarnViewFacet

Pure reads — every getter + read function ported from LearnAndEarn_v8_5_3.sol. Zero state-mutation risk. No constructor args.

Step 8 — Deploy LearnAndEarnAdminFacet

Owner config, epoch management, pause system, manual payment entry, trading results, card pause/approval gate, reclaim, plus the NEW setAffiliateContract cross-Diamond wiring setter (not in the real source — added per task instructions for a future connector tool) and the NEW bootstrapFirstEpoch one-time epoch bootstrap. No constructor args.

Step 9 — Deploy LearnAndEarnPayoutFacet

Member withdraw/withdrawAndReinvest, per-card withdraw, card splitting. No constructor args.

Step 10 — Deploy LearnAndEarnCoreFacet

⚠️ THE MONEY-MOVING FACET — onPaymentReceived (called from PAY_DIAMOND once cross-wired via setMainContract), plus inject/injectCustom/setQueuePosition. Deploy LAST, only once every simpler facet on this Diamond is proven working, per the migration plan's explicit ordering. No constructor args.

Step 11 — diamondCut: register all 4 Learn & Earn facets (79 selectors)

Calls diamondCut once with all 4 Learn & Earn facets' real function selectors, derived LIVE from each facet's real compiled ABI via ethers.Interface.getFunction(name).selector — never hardcoded/guessed. Verified in advance (this session's compile/verification pass) that all 79 selectors across the 4 facets are distinct — no collisions. Needs Step 5 (Diamond) and all 4 facet addresses (Steps 7–10) done first.

Step 12 — Bootstrap Owner Wallet (REQUIRED — do this before any other admin-gated step, including Step 13)

⚠️ Critical one-time step. LearnAndEarnAdminFacet's business-logic ownerWallet field (distinct from the Diamond's own EIP-173 technical owner set in Step 5's constructor) starts at address(0) — every onlyOwner-gated function reverts until this is set. This bootstrapOwnerWallet(address) call is gated by the Diamond's REAL technical owner (LibDiamond.contractOwner()), not by the broken business-field check, and reverts if ownerWallet is already non-zero — so it can only ever run once. Needs Step 5 (Diamond) + Step 8 (LearnAndEarnAdminFacet) + Step 11 (diamondCut wiring) done first.

Step 13 — Bootstrap: open epoch #0 (one-time, required)

⚠️ NEW — not in the real v8.5.3 source. Calls bootstrapFirstEpoch(0) (0 = use current block timestamp) through the Diamond, routed to LearnAndEarnAdminFacet. Required once, right after Step 11 — every epoch-dependent function reverts until this has run. Guarded on-chain so it can only ever succeed once (reverts if epochs already exist). Deliberately left unguarded by onlyOwner (unlike every other Admin function) since, historically, ownerWallet had no bootstrap path either — Step 12 now provides one, but this function's own gate was intentionally left open in the original design so epoch #0 never depended on the owner-wallet bootstrap order.

Step 14 — Verify: read facets() through the Diamond

Calls facets() via DiamondLoupeFacet, routed through the Diamond's fallback — displays every registered facet address and how many selectors it owns, so the wiring can be visually confirmed.