# OG INDEX — Technical Paper

**Version:** 1.0
**Date:** 2026-04-23
**Standard:** ERC-20 (Ethereum Mainnet)
**Category:** Reflection Token / Index Vault / Auto-Buyback Distribution

---

## 1. Abstract

**OG INDEX** is an ERC-20 token engineered to act as a decentralized "legends index" of the Ethereum ecosystem. Transaction fees (2% on buys, 4% on sells) accumulate in a protocol-controlled vault and are periodically (every 4 hours) converted, through on-chain swaps, into a curated basket of *OG Ethereum tokens* — the original, historically proven assets of the chain, excluding forks, copies and derivatives. The acquired tokens are then redistributed pro-rata to OG INDEX holders who meet a **minimum eligibility threshold of $200 USD worth of OG INDEX** at the snapshot block.

The result is a passive, reflection-style yield product where holding OG INDEX is equivalent to holding a dynamically rebalanced, community-curated index of Ethereum legends — funded entirely by organic trading volume.

---

## 2. Design Goals

1. **Index exposure without custody risk** — holders never deposit assets; rewards arrive directly in their wallet.
2. **Curatorial purity** — only true "OG" Ethereum tokens (originals, not copies) are added to the buyback set.
3. **Deterministic distribution** — buybacks and airdrops are executed on a fixed 4-hour cadence by a keeper.
4. **Gas-aware scalability** — distributions are batched (10 / 20 / N holders per tx) to keep the cycle economically viable as the holder base grows.
5. **Transparent eligibility** — eligibility is derived from an on-chain price feed × on-chain balance, both independently verifiable via RPC.

---

## 3. Token Parameters

| Parameter          | Value                         |
|--------------------|-------------------------------|
| Name               | OG INDEX                      |
| Symbol             | OG                            |
| Standard           | ERC-20                        |
| Decimals           | 18                            |
| Total Supply       | TBD (fixed, non-mintable)     |
| Buy Fee            | 2.00%                         |
| Sell Fee           | 4.00%                         |
| Wallet-to-Wallet   | 0.00% (no fee on transfers)   |
| Max Fee Ceiling    | Hard-capped at 4% in code     |
| Ownership          | Renounceable after setup      |

> The fee ceiling is enforced by an immutable `MAX_FEE = 400` (basis points) constant in the contract, so no future owner can raise fees beyond the whitepaper commitment.

---

## 4. Fee Flow

```
┌──────────────┐   buy/sell    ┌─────────────────┐
│  DEX Router  │──────────────▶│  OG INDEX ERC20 │
└──────────────┘               │    (fee logic)  │
                               └───────┬─────────┘
                                       │ 2% / 4%
                                       ▼
                               ┌─────────────────┐
                               │  FeeVault (EOA  │
                               │  or Gnosis Safe)│
                               └───────┬─────────┘
                                       │ every 4h (keeper)
                                       ▼
                               ┌─────────────────┐
                               │   Distributor   │
                               │    Contract     │
                               └───────┬─────────┘
                             split N ways (N = active OG pairs)
                                       ▼
            ┌────────────┬────────────┬────────────┬──────┐
            │ buy OG#1   │ buy OG#2   │ buy OG#3   │ ...  │
            └─────┬──────┴─────┬──────┴─────┬──────┴──┬───┘
                  ▼            ▼            ▼         ▼
              airdrop     airdrop      airdrop    airdrop
              pro-rata    pro-rata     pro-rata   pro-rata
              to eligible holders of OG INDEX
```

The fees are accumulated **in ETH / WETH** (collected during the `_transfer` hook via an internal swap `OG → WETH`) rather than in OG tokens. Collecting in WETH:

- avoids self-referential price pressure during distributions,
- produces a single, fungible "fuel" balance that is trivially split across N target pairs,
- prevents MEV sandwich attacks against protocol-controlled swaps of OG itself.

---

## 5. Architecture

The system is composed of **four on-chain components** and **one off-chain keeper**.

### 5.1 `OGIndexToken.sol` (ERC-20, fee-on-transfer)
- Standard OpenZeppelin ERC-20 + `Ownable`.
- `_update()` override applies buy/sell fees based on whether `from` or `to` is a whitelisted AMM pair.
- `swapAndLiquifyThreshold` — accumulated OG is swapped to WETH and forwarded to `FeeVault` once it exceeds a configurable threshold (prevents gas waste on every trade).
- Re-entrancy guard on the internal swap.

### 5.2 `FeeVault` (Gnosis Safe recommended, EOA acceptable at launch)
- Holds the collected WETH.
- Only the `Distributor` (authorized spender) can pull funds every 4h.
- Multisig in production; single signer acceptable only for the genesis period.

### 5.3 `PairRegistry.sol`
- On-chain list of the "OG basket" — each entry:
  ```solidity
  struct OGAsset {
      address token;         // ERC-20 of the OG asset (e.g., LINK, MKR, UNI, AAVE)
      address pool;           // Uniswap V3 / V2 pool address
      uint24  feeTier;        // 500 / 3000 / 10000 for V3
      bool    active;         // can be paused without removal
      uint64  addedAt;
  }
  ```
- Only `owner` (multisig) can add/remove — curation is deliberately centralized to preserve the "legend" criterion.
- Emits `AssetAdded`, `AssetRemoved`, `AssetPaused` events so the website can mirror state in real time.

### 5.4 `Distributor.sol`
- Triggered by the keeper every 4 hours.
- Workflow per cycle:
  1. Pull WETH balance from `FeeVault`.
  2. Read `N = activeAssets.length` from `PairRegistry`.
  3. Split WETH into N equal slices.
  4. For each slice: swap `WETH → OGAsset` through the registered pool.
  5. Snapshot eligible holders (see §6).
  6. Distribute each purchased OG asset pro-rata, **batched** by `batchSize` (10 or 20, admin-configurable).
- State variables:
  - `lastDistributionAt` — UNIX timestamp of last cycle.
  - `MIN_CYCLE_VALUE_USD` — if the vault balance is below this threshold at tick time, the cycle is **skipped** and a `DistributionDeferred(uint256 vaultWei, uint256 reason)` event is emitted. The frontend listens for this event and displays a notice on the homepage.
  - `batchSize` — admin-tunable holder batch length.
  - `batchCursor` — persists distribution progress across multiple txs within the same cycle, so very large holder sets are processed over several keeper calls.

### 5.5 Off-chain Keeper
- Two supported execution layers (redundant):
  - **Gelato / Chainlink Automation** (primary): cron `0 */4 * * *`.
  - **Self-hosted bot** (fallback): Node.js worker running on Ethereum full node RPC.
- Responsibilities:
  - Call `Distributor.tick()` every 4h.
  - If `batchCursor < eligibleHolders.length`, call `Distributor.continueBatch()` until cursor resets.
  - Compute holder snapshot off-chain (see §6.2) and submit the Merkle root to `Distributor.commitSnapshot(bytes32 root)` before the first batch.
  - Expose a public `/status` endpoint consumed by the website (next cycle ETA, deferred flag, last tx hashes).

---

## 6. Eligibility & Pro-Rata Computation

### 6.1 Eligibility Rule

A wallet `W` is eligible for a given distribution cycle if and only if:

```
balanceOf(W, OG_INDEX) × price(OG_INDEX, USD) ≥ 200 USD
```

evaluated at the snapshot block.

### 6.2 Price Source (RPC-based)

Price is derived **on-chain** from the canonical OG INDEX / WETH Uniswap V3 pool:

```
price_OG_in_WETH = sqrtPriceX96² / 2^192    (UniswapV3 slot0)
price_WETH_in_USD = Chainlink ETH/USD feed (Mainnet aggregator 0x5f4e…)
price_OG_in_USD   = price_OG_in_WETH × price_WETH_in_USD
```

Both reads are performed over RPC by the keeper at the exact snapshot block, and the resulting `priceOGinUSD_x1e8` is committed on-chain inside `commitSnapshot` so that any observer can reproduce the computation.

TWAP (30-minute observation window from UniswapV3's oracle) is used — not spot — to resist flash-price manipulation at the snapshot block.

### 6.3 Holder Snapshot

- The keeper iterates `Transfer` events from the token contract since genesis to maintain an off-chain holder set.
- At the snapshot block it queries `balanceOf` for each candidate via **multicall3** (batch RPC), producing `(address, balance)` tuples.
- Tuples are filtered by the `USD ≥ 200` rule.
- A **Merkle tree** of `(address, share_wei_perAsset)` is built; the root is committed on-chain.
- Claims/airdrops then execute via Merkle proofs, which:
  - avoids O(N) on-chain storage per cycle,
  - enables the 10/20-per-batch execution without any per-holder state bloat,
  - makes every distribution independently auditable.

### 6.4 Pro-Rata Formula

For a cycle where the distributor purchased `Aᵢ` units of OG asset `i` (out of N assets), the share of wallet `W` in asset `i` is:

```
shareᵢ(W) = Aᵢ × balanceOf(W) / Σ balanceOf(H)    for all eligible H
```

A rounding dust sweep — any residual `< 1 wei` per token — is swept back to `FeeVault` at cycle close.

---

## 7. Batching & Scale

The number of eligible holders is expected to grow without a predefined cap. To keep each keeper transaction within Ethereum's block gas limit:

| Variable             | Meaning                                           | Default  |
|----------------------|---------------------------------------------------|----------|
| `batchSize`          | Holders paid per `continueBatch` call             | 20       |
| `maxAssetsPerBatch`  | Distinct OG assets iterated per batch call        | 3        |
| `continueBatch()`    | Idempotent, resumable, guarded by `batchCursor`   | —        |

Admins can tune `batchSize` from the web panel (writes to `Distributor.setBatchSize(uint256)`). Recommended ranges:
- `10` when gas is > 80 gwei (safe, slower),
- `20` under normal conditions,
- `30+` only if the protocol migrates to an L2.

If the full holder set is not fully served within the 4-hour window, the cycle is *extended* — no new cycle starts until the current one fully completes. The frontend displays `Cycle N in progress (holders 3400 / 5200)`.

---

## 8. Deferred Distribution (Low-Value Cycles)

If at tick time the FeeVault balance satisfies:

```
vaultBalance_USD < MIN_CYCLE_VALUE_USD    (default: 500 USD)
```

then:

1. The cycle is **not executed**.
2. `DistributionDeferred(vaultWei, nextAttemptAt)` is emitted.
3. The next keeper tick (in 4 hours) re-evaluates; the fees continue to accumulate.
4. The website subscribes to this event via WebSocket RPC and shows a banner:
   > *"Next distribution deferred — vault balance below minimum. Next attempt: {T+4h}."*

This protects holders from uneconomic cycles where gas cost would exceed the per-holder reward.

---

## 9. Admin Control Surface

All admin keys point to a Gnosis Safe multisig (threshold 3/5 recommended).

| Function                            | Effect                                                |
|-------------------------------------|-------------------------------------------------------|
| `PairRegistry.add(asset, pool, fee)`| Add a new OG asset to the buyback basket              |
| `PairRegistry.pause(asset)`         | Temporarily exclude an asset (delisting, depeg, etc.) |
| `PairRegistry.remove(asset)`        | Permanent removal                                     |
| `Distributor.setBatchSize(n)`       | Tune holder-per-tx count                              |
| `Distributor.setMinCycleUSD(v)`     | Adjust deferred-cycle threshold                       |
| `Distributor.setEligibilityUSD(v)`  | Adjust holder minimum (default: 200)                  |
| `OGIndexToken.renounceOwnership()`  | Lock fee logic forever (planned post-launch)          |

Fee percentages themselves are **not** admin-mutable — they are fixed in bytecode.

---

## 10. Security Considerations

| Vector                           | Mitigation                                                              |
|----------------------------------|-------------------------------------------------------------------------|
| Re-entrancy on fee swap          | `nonReentrant` modifier + `lockTheSwap` internal flag                   |
| Price manipulation at snapshot   | 30-minute UniswapV3 TWAP (not spot) + Chainlink ETH/USD                 |
| Sandwich on protocol swaps       | Swap with explicit `amountOutMin` from TWAP ± 2% + `deadline`           |
| Keeper censorship / downtime     | Dual keeper (Gelato + self-hosted) + public `kick()` callable by anyone after `lastTick + 5h` |
| Snapshot forgery                 | Merkle root committed on-chain; keeper publishes full snapshot to IPFS   |
| Dust accumulation                | Residual wei swept back to FeeVault at cycle close                      |
| Blacklisted assets               | `PairRegistry.pause()` emergency lever + per-cycle `skipList`           |
| Reflective-token interaction     | OG basket restricted to non-reflective, non-rebasing ERC-20s            |

External audit (two independent firms) is a prerequisite for Mainnet launch.

---

## 11. RPC Requirements (Keeper & Frontend)

The keeper and website both rely on an Ethereum archive-capable RPC (Alchemy / QuickNode / self-hosted Erigon). Minimum required endpoints:

| Endpoint                    | Purpose                                                    |
|-----------------------------|------------------------------------------------------------|
| `eth_call`                  | `balanceOf`, `slot0`, Chainlink `latestRoundData`          |
| `eth_getLogs`               | Transfer event indexing for holder set                     |
| `eth_blockNumber`           | Snapshot block pinning                                     |
| WebSocket `eth_subscribe`   | Frontend real-time banners (DistributionDeferred, etc.)    |
| Multicall3 (0xcA11…)        | Batched balance reads at snapshot block                    |
| Uniswap V3 Quoter           | Pre-trade slippage estimation                              |

The keeper is rate-limit-aware and uses exponential backoff; snapshots are cached on IPFS for reproducibility.

---

## 12. Frontend Integration (Public Website)

The main site surfaces, in real time:

- Current OG INDEX price (TWAP-derived, updated each block).
- Current FeeVault balance (WETH & USD).
- Countdown to next distribution tick.
- Holder eligibility checker (`connectWallet → isEligible(addr)`).
- Live list of OG basket assets (from `PairRegistry` events).
- Recent distributions (tx hashes, per-asset amounts, IPFS snapshot CIDs).
- **Banner**: shown whenever the last emitted event was `DistributionDeferred`.

Frontend stack: React + ethers.js + wagmi + a lightweight indexer (Ponder or Envio) subscribed to the contracts.

---

## 13. Roadmap

| Phase | Milestone                                                   |
|-------|-------------------------------------------------------------|
| 0     | Spec freeze (this document), contract development           |
| 1     | Testnet (Sepolia) deployment + keeper dry runs              |
| 2     | Independent audits × 2                                       |
| 3     | Mainnet deployment, initial liquidity locked                |
| 4     | Seed OG basket (LINK, MKR, UNI, AAVE, ENS, MANA, …)         |
| 5     | First live distribution cycle                               |
| 6     | Governance hand-off: `renounceOwnership()` on token contract|

---

## 14. Glossary

- **OG Asset** — An ERC-20 token whose genesis is on Ethereum, with no meaningful fork/copy preceding it, curated into the basket by the multisig.
- **Cycle** — A 4-hour window at the end of which the distributor executes buybacks and airdrops.
- **Snapshot** — The block at which holder balances are frozen for pro-rata calculation.
- **Deferred Cycle** — A cycle skipped because the vault balance fell below the minimum USD threshold.
- **Eligible Holder** — A wallet whose OG INDEX balance is worth ≥ $200 USD at snapshot time.
- **Batch** — A group of `batchSize` holders paid in a single transaction to keep gas bounded.

---

*End of document.*
