Skip to main content
PulseScanner.io

Address

0xfffffd64effb1f789bfdbb94db682bc764e4ffff
Current Holdings
$0.00
TXs sent
not counted
First Active
2025-10-29
block 24,880,975
Last Active
322 days ago
block 24,881,485
Funded By
not identified

Net worth historyi

No net-worth snapshots recorded yet
exact matchMoonsolc 0.8.24+commit.e11b9ed9runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/* 
 ┌────────────────────────────────────────────────────────────────────────┐
 │                                                                        │
 │                 ███    ███  ██████   ██████  ███    ██                 │
 │                 ████  ████ ██    ██ ██    ██ ████   ██                 │
 │                 ██ ████ ██ ██    ██ ██    ██ ██ ██  ██                 │
 │                 ██  ██  ██ ██    ██ ██    ██ ██  ██ ██                 │
 │                 ██      ██  ██████   ██████  ██   ████                 │
 │                                                                        │
 │                                                                        │
 │  MOON is the heart of a fully decentralized discovery system. It       │
 │  converts swap activity into reflections for SUN holders while         │
 │  benefiting every project that pairs with it.                          │       
 │                                                                        │
 │  How it works                                                          │
 │   • All swaps through official PulseX V2 pairs are taxed 3%.           │                             
 │   • MOON uses the tax to buy back the paired token and distributes it  │
 │     to SUN holders automatically.                                      │
 │   • Wallet transfers, liquidity mints/burns as well as swaps on other  │
 │     DEXs are untaxed.                                                  │
 │                                                                        │
 │  Add your token                                                        │                                                     
 │   • Create a V2 liquidity pair with your token and MOON on PulseX:     │                                                                                  
 │        → Add your token first.                                         │
 │        → Add MOON second. (PulseX UI: MOON on the bottom)              │
 │   • This lets you add/remove liquidity tax free and plugs your         │
 │     token into the reflection system automatically.                    │
 │                                                                        │
 │  Why pair with MOON?                                                   │
 │   • Organic exposure: Natural arbitrage connects your token directly   │
 │     with SUN holders, building awareness without paid promotion.       │
 │   • Constant buy pressure: whether users buy or sell through the pair, │
 │     the tax is always used to buy your token.                          │
 │   • Enhanced LP rewards: a built-in “pair bonus” leaves part of        │
 │     swap-back yield in the pool, boosting LP take on top of V2 fees.   │
 │                                                                        │
 └────────────────────────────────────────────────────────────────────────┘
*/

/*────────────────────────────  INTERFACES  ─────────────────────────────*/

/// @dev Minimal ERC-20 subset used by this contract.
interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/// @dev Uniswap V2 Pair subset used by the contract’s swap-backs.
interface IUniswapV2Pair {
    function swap(
        uint amount0Out,  
        uint amount1Out,
        address to,
        bytes calldata data
    ) external;
}

/// @notice Vault payout used in _emitRay.
interface IVault {
    function releaseToMember(address ray, uint256 amount, address member) external;
}

/// @notice All other external calls use precomputed selectors

/*──────────────────────── FLOAT‑96 CODEC (88+8) ────────────────────────*/

/// @title Uint256 <-> Float96 (88-bit mantissa + 8-bit exponent)
/// @notice Compact, lossy encoding for non-negative uint256 values.
/// @dev Layout: packed[95:88]=exponent, packed[87:0]=mantissa.
///      Decodes as (mantissa << exponent). Rounding = nearest, ties-to-even.
library Uint256Float96 {
    uint256 private constant MANTISSA_BITS = 88;
    uint256 private constant EXPONENT_BITS = 8; // reserved for clarity
    uint256 private constant MANTISSA_MASK = (uint256(1) << MANTISSA_BITS) - 1;
    uint8   private constant MAX_EXPONENT  = 168; // 256 - 88

    error BadPackedExponent(uint8 e);

    /// @notice Encode a uint256 into a uint96 float-like value.
    /// @dev Exact for values < 2^88 (exponent=0). Larger values are rounded
    ///      to nearest, ties-to-even; may saturate if exponent would overflow.
    function encode(uint256 x) internal pure returns (uint96 packed) {
        if (x == 0) return 0;

        // Find msb(x). After this block: bitLen = floor(log2(x)) + 1.
        uint256 msb;
        unchecked {
            uint256 y = x;
            if (y >= 1 << 128) { y >>= 128; msb += 128; }
            if (y >= 1 <<  64) { y >>=  64; msb +=  64; }
            if (y >= 1 <<  32) { y >>=  32; msb +=  32; }
            if (y >= 1 <<  16) { y >>=  16; msb +=  16; }
            if (y >= 1 <<   8) { y >>=   8; msb +=   8; }
            if (y >= 1 <<   4) { y >>=   4; msb +=   4; }
            if (y >= 1 <<   2) { y >>=   2; msb +=   2; }
            if (y >= 1 <<   1) {           msb +=   1; }
        }
        uint256 bitLen = msb + 1;

        // Fits entirely in mantissa -> exponent=0, exact store.
        if (bitLen <= MANTISSA_BITS) {
            return uint96(x);
        }

        // Normalize into 88-bit mantissa and an exponent in [1..168].
        uint256 shift = bitLen - MANTISSA_BITS;
        uint256 mant  = x >> shift;

        // Round to nearest, ties-to-even.
        {
            uint256 remMask = (uint256(1) << shift) - 1;
            uint256 rem     = x & remMask;
            uint256 half    = uint256(1) << (shift - 1);
            bool roundUp    = (rem > half) || (rem == half && (mant & 1) == 1);

            if (roundUp) {
                unchecked { mant += 1; }
                // If rounding overflowed mantissa to 2^88, renormalize.
                if (mant == (uint256(1) << MANTISSA_BITS)) {
                    mant >>= 1;
                    shift += 1;
                }
            }
        }

        // Saturate if exponent would exceed representable range.
        if (shift > MAX_EXPONENT) {
            shift = MAX_EXPONENT;
            mant  = MANTISSA_MASK;
        }

        // Pack: [ exponent | mantissa ].
        return (uint96(uint8(shift)) << uint96(MANTISSA_BITS)) | uint96(mant & MANTISSA_MASK);
    }

    /// @notice Decode a packed uint96 back into a uint256.
    /// @dev Reverts if exponent field is malformed (> MAX_EXPONENT).
    function decode(uint96 packed) internal pure returns (uint256 x) {
        uint8 exponent = uint8(packed >> MANTISSA_BITS);
        if (exponent > MAX_EXPONENT) revert BadPackedExponent(exponent);

        uint256 mantissa = uint256(packed) & MANTISSA_MASK;
        return mantissa << exponent;
    }
}

/*────────────────────────────────  MOON  ───────────────────────────────*/

/// @title Moon (MOON)
/// @notice ERC‑20 token with integrated pair‑aware taxation and SUN reflections.
contract Moon is IERC20 {

    /*//////////////////////////////////////////////////////////////////////
                                  METADATA                                
    //////////////////////////////////////////////////////////////////////*/

    /// @notice Token name.
    string  public constant name     = "Moon";
    /// @notice Token symbol.
    string  public constant symbol   = "MOON";
    /// @notice Token decimals (fixed at 18).
    uint8   public constant decimals = 18;

    /*//////////////////////////////////////////////////////////////////////
                                    EVENTS                                 
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Fired once when a new ray (paired token) is discovered & cached.
    event RayInitialized(address indexed ray);

    /*//////////////////////////////////////////////////////////////////////
                                  IMMUTABLES                               
    //////////////////////////////////////////////////////////////////////*/

    /// @notice Total SUN supply credited at deploy (1e18‑scaled).
    uint256 public immutable totalSunSupply;

    /// @notice Verified Uniswap‑style V2 factory used for pair recognition.
    address public immutable factory;

    /// @notice SUN ERC‑20 contract linked for distributions.
    address public immutable sun;

    /// @notice Vault that custodies Rays.
    address public immutable vault;

    /// @notice Uniswap‑style fee in basis points (e.g., 30 for 0.30%).
    uint24  public immutable feeBps;

    /// @notice Multiplier used in x*y=k fee math: (FEE_DENOMINATOR - feeBps).
    /// @dev Example: 9_970 for a 0.30% fee.
    uint24  public immutable feeMul;

    /*//////////////////////////////////////////////////////////////////////
                                   CONSTANTS                                
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Basis points denominator for AMM fee math (10_000 = 100%).
    uint24 public constant FEE_DENOMINATOR     = 10_000;

    /// @notice Swap tax rate (3%).
    uint256 public constant SWAP_TAX           = 3e16;

    /// @notice Percentage of swap-back left in the pair as an LP bonus (25%).
    uint256 public constant PAIR_BONUS         = 25e16;

    /// @notice Appreciation tax applied to positive value deltas (20%).
    uint256 public constant APPRECIATION_TAX   = 20e16;

    /// @notice Gas stipend for the radiation loop.
    uint256 public constant RADIATE_GAS_LIMIT  = 220_000;

    /// @notice Gas stipend for swapBack.
    uint256 public constant SWAPBACK_CALL_GAS  = 350_000;

    /// @notice Minimum pending MOON before a swap-back is attempted (1 MOON).
    uint256 public constant MIN_SWAP_BACK      = 1e18;

    /// @notice Minimum value emitted per payout (1e-9 MOON).
    uint256 public constant MIN_EMIT           = 1e9;

    /// @notice Minimum SUN tokens for automatic payout (1 SUN)
    /// Members below this threshold can still call collect()
    uint256 public constant MIN_SUN_RADIATE    = 1e18;

    /// @notice Maximum distinct tokens to attempt in a single payout iteration.
    uint256 public constant MAX_PAYOUT_TOKENS  = 6;

    /// @notice Index scaling factor (1e32) — “index decimals”.
    uint256 public constant INDEX_DECIMALS     = 1e32;

    /// @notice Conventional burn sink address (irretrievable).
    /// @dev Tokens sent here are considered permanently destroyed.
    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;

    /*//////////////////////////////////////////////////////////////////////
                                ERC-20 STORAGE                             
    //////////////////////////////////////////////////////////////////////*/

    /// @notice Current total supply of MOON tokens in existence.
    /// @dev This value is initialized at deployment and monotonically decreases 
    ///      as tokens are burned. There is no mechanism to increase supply.
    uint256 public override totalSupply;

    /// @dev MOON balances.
    mapping(address => uint256) internal balances;

    /// @dev ERC‑20 allowances: owner => (spender => amount).
    mapping(address => mapping(address => uint256)) internal allowances;

    /*//////////////////////////////////////////////////////////////////////
                           CLASSIFICATION BOOKKEEPING                         
    //////////////////////////////////////////////////////////////////////*/
    
    /*
     * moonClass:
     *   0 = unknown (not yet probed)
     *   1 = regular holder or non‑verified contract
     *   2 = verified V2 pair that contains MOON (taxed)
     */
    mapping(address => uint8) internal moonClass;

    /*//////////////////////////////////////////////////////////////////////
                               SUN MEMBER STATE                            
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Member accounting snapshot (first four fields are persisted).
    struct Member {
        // persisted fields
        uint128 pastIndex;   // index snapshot (1e32‑scaled)
        uint112 uncollected; // uncollected value (MOON‑value terms)
        uint8   class;       // 0 unknown | 1 eligible | 2 ineligible
        uint8   status;      // 0 not active | 1 queued for removal | 2 active

        // transient helpers (NEVER written to storage) 
        address self;        // member address in memory
        uint256 balance;     // SUN balance (queried lazily)
    }

    /// @dev Member records (only the first four fields are read/written).
    mapping(address => Member) internal members;

    /*//////////////////////////////////////////////////////////////////////
                               RAY TOKEN STATE                        
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Ray = per‑token accounting for a reflection asset paired with MOON.
    struct Ray {
        // slot 0
        address pair;             // verified V2 pair that contains MOON & this ray

        // slot 1 (tightly packed to 256 bits)
        uint112 reserve;          // current Vault balance credited as “value bearing”
        uint112 pending;          // pending MOON earmarked for swap‑back
        uint8   swapStatus;       // 0 not listed | 2 in swapQueue
        uint8   brightStatus;     // 0 not listed | 1 pending removal | 2 in brightRays
        bool    thisZero;         // true if MOON is token0 in the pair

        // slot 2 (tightly packed to 256 bits)
        uint96  quote96;          // MOON per token, 1e38‑scaled (compressed)
        uint96  candidateQuote96; // intra‑block max quote (compressed)
        uint64  updateBlock;      // last quote update block

        // transient helpers (NEVER written to storage)
        address self;             // this ray address (for convenience)
        uint256 ra;               // pair’s ray reserve (pre‑event)
        uint256 rm;               // pair’s MOON reserve (pre‑event)
        uint256 quote;            // decoded committed quote (1e38‑scaled)
        uint256 candidateQuote;   // decoded candidate quote (1e38‑scaled)
        uint256 cursor;           // place in brightRays list during emitRay
    }

    /// @dev Per‑token accounting. Public getter exposes persisted fields.
    mapping(address => Ray) internal rays;

    /*//////////////////////////////////////////////////////////////////////
                                  PAIR STATE                        
    //////////////////////////////////////////////////////////////////////*/

     /// @dev Per-pair bookkeeping.
    struct Pair {
        address ray;       // Ray associated with that pair
        bool    swapLock;  // prevents swaps during untaxed mints/burns
    }

    /// @notice Registered pairs containing MOON, keyed by pair address.
    mapping(address => Pair) public pairs;

    /*//////////////////////////////////////////////////////////////////////
                          GLOBAL AGGREGATES (PACKED)                         
    //////////////////////////////////////////////////////////////////////*/

    /// @dev [hi 128] = active SUN tokens | [lo 128] = index (1e32‑scaled).
    uint256 private packedIndexAndActive;

    /// @dev [hi 128] = oath (MOON‑value) | [lo 128] = pool (MOON‑value).
    uint256 private packedPoolAndOath;

    /// @dev Ephemeral “global” bundle to pass between helpers.
    struct GlobalMemory {
        uint128 pool;   // total value currently held by vault
        uint128 oath;   // total value owed to active SUN members
        uint128 index;  // cumulative owed value/share (1e32‑scaled)
        uint128 active; // total SUN tokens held by active SUN members
    }

    /*//////////////////////////////////////////////////////////////////////
                           DYNAMIC LISTS & CURSORS                          
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Tokens whose pairs should be swapped through (pending ≥ MIN_SWAP_BACK).
    address[] private swapQueue;

    /// @dev Rays ready to be distributed to SUN members.
    address[] private brightRays;

    /// @dev Active SUN members (round‑robin radiation processor).
    address[] private activeMembers;

    /// @dev Cursor for `activeMembers` round‑robin.
    uint256 public activeMembersCursor;

    /*//////////////////////////////////////////////////////////////////////////
                              PRECOMPUTED SELECTORS
    //////////////////////////////////////////////////////////////////////////*/

    /// @dev Precomputed selectors for gas savings.
    bytes4 constant SEL_BALANCEOF     = bytes4(keccak256("balanceOf(address)"));         // ERC-20 style balanceOf(owner)
    bytes4 constant SEL_V1_tokenAddr  = bytes4(keccak256("tokenAddress()"));             // Uniswap V1: tokenAddress()
    bytes4 constant SEL_TOKEN0        = bytes4(keccak256("token0()"));                   // token0()
    bytes4 constant SEL_TOKEN1        = bytes4(keccak256("token1()"));                   // token1()    
    bytes4 constant SEL_BALANCEOF6909 = bytes4(keccak256("balanceOf(address,uint256)")); // ERC‑6909 style balanceOf(owner,id)
    bytes4 constant SEL_GETRESERVES   = bytes4(keccak256("getReserves()"));              // Uniswap V2: getReserves()
    bytes4 constant SEL_GETPAIR       = bytes4(keccak256("getPair(address,address)"));   // Ask factory for pair   

    /*//////////////////////////////////////////////////////////////////////
                               REENTRANCY GUARDS                          
    //////////////////////////////////////////////////////////////////////*/

    /// @dev Reentrancy guard state: 1 = unlocked, 2 = locked. Never write zero (gas savings)
    uint256 private constant _UNLOCKED = 1;
    uint256 private constant _LOCKED   = 2;

    /// @dev Storage slot for the guard (initialized to unlocked).
    uint256 private _reentrancyStatus = _UNLOCKED;

    /// @notice Reentrancy guard using a dedicated storage slot (sload/sstore).
    /// @dev
    /// - Uses non-zero states (1↔2) to avoid clearing slot.
    /// - Contract-wide single-entry guard: an external `nonReentrant` function
    ///   cannot `external`-call another `nonReentrant` one in the same tx.
    /// - Pattern: check-effects-interactions still applies inside the body.
    modifier nonReentrant() {
        require (_reentrancyStatus == _UNLOCKED, "Reentrancy");
        _reentrancyStatus = _LOCKED;
        _;
        _reentrancyStatus = _UNLOCKED;
    }

    /*//////////////////////////////////////////////////////////////////////////
                                   CONSTRUCTOR
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Initializes Moon: mints full supply to deployer, wires SUN/Vault, and seeds SUN accounting.
    /// @dev Scales `supply` and `sunSupply` by 1e18; requires non-zero key addrs and `v2FactoryFee <= 10_000` BPS.
    ///      Caches factory/fee, marks Moon/SUN/Vault as ineligible for reflections, seeds SUN accounting,
    ///      enlists sunDeployer in the active rotation, and emits the initial {Transfer}.
    /// @param supply             Whole-token MOON amount to mint to deployer (unscaled; 18 decimals applied).
    /// @param verifiedV2Factory  Canonical V2 factory used to recognize taxable pairs.
    /// @param v2FactoryFee       Factory swap fee in basis points (e.g., 30 = 0.30%).
    /// @param sunAddress         SUN ERC-20 used for distributions.
    /// @param vaultAddress       Vault that holds rays.
    /// @param sunDeployer        Initial SUN holder to seed reflection index.
    /// @param sunSupply          Whole-token SUN credited to `sunDeployer` (unscaled; 18 decimals applied).
    constructor(
        uint256  supply,
        address  verifiedV2Factory,
        uint24   v2FactoryFee,
        address  sunAddress,
        address  vaultAddress,
        address  sunDeployer,
        uint256  sunSupply
    )
    {
        // ──────────────────────────── Sanity checks ────────────────────────────
        // Require all critical external addresses (factory, SUN, Vault) to be set.
        require(
            verifiedV2Factory != address(0) &&
            sunAddress        != address(0) &&
            sunDeployer       != address(0) &&
            vaultAddress      != address(0),
            "zero address"
        );

        // Ensure AMM fee (in BPS) is not larger than 100% (10_000 BPS).
        require(v2FactoryFee <= FEE_DENOMINATOR, "fee too large");

        // Bound the unscaled MOON and SUN supplies so that, once multiplied by 1e18,
        // they can still be safely packed into the internal uint112 fields used elsewhere.
        require(supply    <= type(uint112).max / 1e18 &&
                sunSupply <= type(uint112).max / 1e18, "Supply too large");
        
        // ──────────────────────── Immutable configuration ───────────────────────
        // Save addresses/fee knobs used for pair detection & AMM math.
        factory        = verifiedV2Factory;                // Canonical (taxable) V2 factory
        sun            = sunAddress;                       // SUN token used for payouts
        vault          = vaultAddress;                     // Custody for rays
        totalSupply    = supply * 1e18;                    // Scale to 18 decimals
        totalSunSupply = sunSupply * 1e18;                 // Scale to 18 decimals
        feeBps         = v2FactoryFee;                     // e.g., 30 for 0.30%
        feeMul         = uint24(FEE_DENOMINATOR - feeBps); // e.g., 9_970 for 0.30%

        // ─────────────────────────── Mint MOON to deployer ──────────────────────
        // Mint the entire MOON supply to the deployer (`msg.sender`).
        balances[msg.sender] = totalSupply;

        // Cache the deployer as a known class-1 MOON holder (regular holder, not a pair).
        // (micro-gas: avoids first-touch classification on their first transfer)
        moonClass[msg.sender] = 1;

        // Standard ERC-20 Transfer event for the initial mint.
        emit Transfer(address(0), msg.sender, totalSupply);

        // ────────────────────────── Seed SUN bookkeeping ────────────────────────
        // Add the initial SUN holder to the active rotation list.
        activeMembers.push(sunDeployer);

        // Mark MOON, SUN, and Vault as class-2 for SUN eligibility (ineligible).
        // - MOON contract itself (no dividends to the token contract)
        // - SUN token contract
        // - Vault (custody contract)
        members[address(this)].class = 2;
        members[sunAddress].class    = 2;
        members[vaultAddress].class  = 2;

        // Initialize the global dividend index & active SUN supply:
        //   index   = 0 (no value distributed yet)
        //   active  = totalSunSupply (all initial SUN held by `sunDeployer`)
        writeIndexActive(0, uint128(totalSunSupply));

        // Initialize the `sunDeployer` member record:
        //   class   = 1 (eligible holder)
        //   status  = 2 (in activeMembers rotation)
        writeMember(sunDeployer, 0, 0, 1, 2);

        // Initialize DEAD as ineligible for emissions.
        //   class   = 2 (ineligible)
        writeMember(DEAD, 0, 0, 2, 0);

    }

    /*//////////////////////////////////////////////////////////////////////////
                                ERC-20 — VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Return MOON balance of `owner`.
    /// @dev Can revert only when part of a deceptive swap.
    function balanceOf(address owner) public view override returns (uint256) {
        require(_unlocked(owner), "Moon: Pair locked. Call skim()");
        return balances[owner];
    }

    /// @notice Return allowance from `owner` to `spender`.
    function allowance(address owner, address spender) public view override returns (uint256) {
        return allowances[owner][spender];
    }

    /// @notice Returns the number of tokens currently in the swap queue.
    function swapQueueLength() external view returns (uint256) {
        return swapQueue.length;
    }

    /// @notice Returns the number of rays currently marked as bright rays.
    function brightRaysLength() external view returns (uint256) {
        return brightRays.length;
    }

    /// @notice Returns the number of active SUN members in the rotation.
    function activeMembersLength() external view returns (uint256) {
        return activeMembers.length;
    }

    /// @notice Returns the current global pool and oath values (MOON-value terms).
    function getPoolOath() external view returns (uint128 pool, uint128 oath) {
        (pool, oath) = readPoolOath();
    }

    /// @notice Returns the current global dividend index and active SUN supply.
    function getIndexActive() external view returns (uint128 index, uint128 active) {
        (index, active) = readIndexActive();
    }

    /// @notice Returns the stored member record for a given SUN holder.
    /// @dev Exposes the persisted fields of the Member struct from storage.
    /// @param a The SUN holder’s address.
    /// @return pastIndex   Last index checkpoint for this member (1e32-scaled).
    /// @return uncollected Accrued but unclaimed MOON-value credit.
    /// @return class       Eligibility class (1 = eligible, 2 = ineligible).
    /// @return status      List status code (0 = none, 1 = pending removal, 2 = active).
    function getMember(address a)
        external
        view
        returns (uint128 pastIndex, uint112 uncollected, uint8 class, uint8 status)
    {
        (pastIndex, uncollected, class, status) = readMember(a);
    }

    /// @notice Returns the stored ray accounting data for a given paired token.
    /// @dev Provides both persisted fields and live Vault balance/decoded quotes.
    /// @param  token The address of the paired token (ray) to inspect.
    /// @return pair            Verified V2 pair that contains MOON and this token.
    /// @return reserve         Credited Vault reserve for this token.
    /// @return liveVaultBal    Current on-chain Vault balance for this token.
    /// @return pending         Pending MOON earmarked for swap-back.
    /// @return swapStatus      Swap queue status.
    /// @return brightStatus    Bright-rays list status.
    /// @return thisZero        True if MOON is token0 in the pair.
    /// @return decodedQuote    Committed price quote (MOON per token, 1e38-scaled).
    /// @return candidateQuote  Candidate intra-block high quote (1e38-scaled).
    /// @return updateBlock     Block number of last quote update.
    function getRay(address token)
        external
        view
        returns (
            address pair,
            uint112 reserve,
            uint256 liveVaultBal,
            uint112 pending,
            uint8   swapStatus,
            uint8   brightStatus,
            bool    thisZero,
            uint256 decodedQuote,
            uint256 candidateQuote,
            uint64  updateBlock
        )
    {
        Ray memory r;
        r.self = token;
        (,liveVaultBal) = _safeBalanceOf(token, vault);
        (r.pair) = readRay0(r.self);
        (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);
        (r.quote, r.candidateQuote, r.updateBlock) = readRay2(r.self);
        return (
            r.pair,
            r.reserve,
            liveVaultBal,
            r.pending,
            r.swapStatus,
            r.brightStatus,
            r.thisZero,
            r.quote,
            r.candidateQuote,
            r.updateBlock
        );
    }

    /*//////////////////////////////////////////////////////////////////////////
                    ERC-20 — MUTATIVE (ALLOWANCE & TRANSFERS)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Approve `spender` to transfer up to `amount` MOON on caller’s behalf.
    /// @dev Emits an {Approval} event.
    function approve(address spender, uint256 amount)
        external 
        override
        returns (bool)
    {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /// @notice Transfer `amount` MOON from msg.sender to `to`.
    /// @dev Triggers tax logic when interacting with class-2 V2 pairs.
    function transfer(address to, uint256 amount)
        external
        override
        nonReentrant
        returns (bool)
    {
        _transfer(msg.sender, to, amount);
        return true;
    }

    /// @notice Move `amount` MOON from `from` to `to` using caller’s allowance.
    /// @dev Deducts allowance and emits {Transfer} & {Approval} events.
    function transferFrom(address from, address to, uint256 amount)
        external
        override
        nonReentrant
        returns (bool)
    {
        uint256 currentAllowance = allowances[from][msg.sender];
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                allowances[from][msg.sender] = currentAllowance - amount;
            }
            emit Approval(from, msg.sender, currentAllowance - amount);
        }
        _transfer(from, to, amount);
        return true;
    }

    /*//////////////////////////////////////////////////////////////////////////
                            ERC-20 — INTERNAL MUTATORS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Set `spender`'s allowance over `owner`'s tokens to `amount`.
    /// @dev Internal helper, emits an {Approval} event.
    function _approve(address owner, address spender, uint256 amount) internal {
        allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /// @notice Permanently destroys `amount` of MOON from `from`, reducing the total supply.
    /// @dev
    /// Behavior:
    ///  • Updates storage under `unchecked` (safe after guards).  
    ///  • Emits the ERC-20 canonical {Transfer} to the zero address.
    /// @param from   The address whose balance is reduced (often `address(this)`).
    /// @param amount The amount of MOON to destroy (18-decimals).
    function _burn(address from, uint256 amount) internal {
        require(balances[from] >= amount);
        unchecked {
            balances[from] -= amount;
            totalSupply    -= amount;
        }
        emit Transfer(from, address(0), amount); // ERC-20 canonical burn signal
    }

    /// @notice Internal untaxed transfer helper — moves MOON without any classification or hooks.
    /// @dev
    ///  • Performs only balance updates and emits the standard {Transfer} event.  
    ///  • Skips all taxation, swap-back, and radiation logic.  
    ///  • Reverts if `from` lacks sufficient balance.  
    /// @param from   Source address.
    /// @param to     Destination address (may be any non-zero address).
    /// @param amount Amount of MOON to move (18-decimals).
    function _transferExempt(address from, address to, uint256 amount) internal {
        require(to != address(0));
        require(balances[from] >= amount);

        unchecked {
            balances[from] -= amount;
            balances[to]   += amount;
        }

        emit Transfer(from, to, amount);
    }

    /*//////////////////////////////////////////////////////////////////////////
                        EXTERNAL ENTRYPOINTS (USER / SELF)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Claims caller’s SUN emissions and opportunistically advances maintenance.
    /// @dev If eligible, settles the caller via `_emitRay()`, then attempts one swap-back and
    ///      runs the radiation loop before committing updated aggregates. Calling is optional;
    ///      emissions accrue automatically.
    function collect() external nonReentrant {
        // Snapshot caller and their membership record.
        Member memory m;
        m.self = msg.sender;
        (m.pastIndex, m.uncollected, m.class, m.status) = readMember(m.self);

        // Snapshot global aggregates (pool/oath/index/active) for this maintenance pass.
        (uint128 pool, uint128 oath)  = readPoolOath();
        (uint128 index, uint128 active) = readIndexActive();
        GlobalMemory memory g = GlobalMemory(pool, oath, index, active);

        // If the caller is an eligible SUN holder, try to settle their pending value.
        if (m.class == 1) {
            Ray memory r;
            (g, r) = _emitRay(g, r, m);
            if (r.self != address(0)) {
                writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
            }
        }

        // Opportunistic maintenance: try one swap-back (skip none) and advance payouts.
        g = _swapBack(g, address(0));
        g = _radiate(g);
        _commitFromG(g);
    }

    /// @notice Thin wrapper that is nonReentrant and delegates to the internal implementation.
    function manuallyReclassify(address addr) external nonReentrant 
        returns (uint8 moonC, uint8 sunC)
    {
        return _manuallyReclassify(addr);
    }

    /// @notice Manually fund a ray with MOON (adds to that ray’s pending and updates value).
    /// @dev External wrapper; simply delegates to the internal implementation.
    ///      Callable by anyone. Transfer from the caller to this contract is untaxed.
    ///      Does not require a Ray with V2 MOON pair initialized. 
    function manuallyFundRay(address ray, uint256 amount) external nonReentrant {
        _manuallyFundRay(ray, amount);
    }

    /// @notice SUN transfer hook that keeps MOON’s accounting correct.
    /// @dev Only callable by `sun`. Respects MOON's reentrancy window. 
    ///      Delegates full bookkeeping to `_transferSun()` using
    ///      pre-transfer balances for fair accrual.
    /// @param from    SUN holder sending tokens.
    /// @param to      SUN holder receiving tokens.
    /// @param fromBal `from` holder’s SUN balance before the transfer (1e18-scaled).
    /// @param toBal   `to` holder’s SUN balance before the transfer (1e18-scaled).
    /// @param amount  SUN amount moved (1e18-scaled).
    function transferSun(
        address from,
        address to,
        uint256 fromBal,
        uint256 toBal,
        uint256 amount
    ) external {
        // Restrict caller to the configured SUN contract.
        require(msg.sender == sun, "Can only be called by SUN");

        // Respect Moon’s reentrancy window.
        require(_reentrancyStatus == _UNLOCKED ,"Reentrancy");

        _transferSun(from, to, fromBal, toBal, amount);
    }

    /*//////////////////////////////////////////////////////////////////////////
                         TRANSFER ENGINE (MOON TAX LOGIC)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Core MOON transfer routine with pair‑aware taxation.
    /// @dev
    /// - Applies 3% tax on verified V2 swaps; all other movements are untaxed.
    /// - Tax is routed to `this` and attributed to the ray; then one swap‑back
    ///   and a radiation step are opportunistically executed.
    /// - Sending to `DEAD` performs a hard burn and returns early.
    /// @param from   Sender address.
    /// @param to     Recipient address (non‑zero).
    /// @param amount MOON amount to move.
    function _transfer(address from, address to, uint256 amount) internal {
        // Basic guards
        require(to != address(0), "ERC20: transfer to zero address");
        require(balances[from] >= amount, "ERC20: Balance insufficient");

        // Burning path (official sink)
        if (to == DEAD) {
            _burn(from, amount);
            return;
        }

        // Classify: verified‑pair swap (taxed) vs everything else (untaxed)
        (bool taxed, Ray memory r) = _transferType(amount, from, to);

        if (taxed) {
            // Split to recipient and protocol tax
            uint256 tax     = (amount * SWAP_TAX) / 1e18;
            uint256 postTax = amount - tax;

            unchecked {
                balances[from]          -= amount;
                balances[to]            += postTax;
                balances[address(this)] += tax;
            }
            emit Transfer(from, to, postTax);
            emit Transfer(from, address(this), tax);

            // Attribute tax to the ray (may enqueue for swap‑back)
            _updatePending(r, tax);

            // Opportunistic maintenance: one swap‑back (skip current ray) + radiation
            (uint128 pool, uint128 oath)  = readPoolOath();
            (uint128 index, uint128 active) = readIndexActive();
            GlobalMemory memory g = GlobalMemory(pool, oath, index, active);

            // Performs system maintenance.
            g = _swapBack(g, r.self);
            g = _radiate(g);

            // Defensive re‑read of active supply, then commit
            _commitFromG(g);
        } else {
            unchecked {
                balances[from] -= amount;
                balances[to]   += amount;
            }
            emit Transfer(from, to, amount);
        }
    }

    /// @notice Classifies an address for MOON‑pair semantics (tax scope).
    /// @dev
    /// - Returns 2 iff `a` is the canonical V2 pair (from `factory`) that
    ///   contains MOON; otherwise 1.
    /// - On first positive identification, caches ray token + orientation,
    ///   wires `pairs[a].ray`, and emits {RayInitialized}.
    /// - All probes are gas‑capped; failures degrade to class 1.
    /// @param a Address to classify.
    /// @return c 2 = verified V2 MOON pair; 1 = regular holder/other.
    function _getMoonClass(address a) internal returns (uint8 c) {
        // Cached
        c = moonClass[a];
        if (c != 0) return c;

        // EOAs are regular
        if (a.code.length == 0) { c = 1; moonClass[a] = c; return c; }

        // token0()/token1() probe
        (bool ok0, address t0) = _probeToken(a, SEL_TOKEN0, 40000);
        if (!ok0) { c = 1; moonClass[a] = c; return c; }
        (bool ok1, address t1) = _probeToken(a, SEL_TOKEN1, 40000);
        if (!ok1) { c = 1; moonClass[a] = c; return c; }

        // Must include MOON
        if (t0 != address(this) && t1 != address(this)) {
            c = 1; moonClass[a] = c; return c;
        }

        // Factory confirmation
        (, address official) = _probeGetPair(t0, t1, 40000);
        if (official != a) { c = 1; moonClass[a] = c; return c; }

        // Initialize ray state (pair + orientation)
        Ray memory r;
        r.pair = a;

        if      (t1 == address(this)) { r.self = t0; r.thisZero = false; } // MOON is token1
        else if (t0 == address(this)) { r.self = t1; r.thisZero = true;  } // MOON is token0

        pairs[r.pair].ray = r.self;
        moonClass[a] = 2;

        (r.reserve, r.pending, r.swapStatus, r.brightStatus,) = readRay1(r.self);
        writeRay0(r.self, a);
        writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);

        emit RayInitialized(r.self);
        return 2;
    }

    /// @notice Distinguishes taxed swaps from untaxed LP mints/burns/off‑pair transfers.
    /// @dev
    /// - If neither side is a verified MOON pair → untaxed.
    /// - If any reserve is zero (bootstrap) → untaxed.
    /// - Opposite‑sign deltas in (A,M) or unchanged A → swap (taxed).
    /// - Otherwise apply a proportionality window (~±20%); outside → swap,
    ///   inside → LP mint/burn (untaxed) with a temporary `swapLock`.
    /// Note: for mint or burn to be properly identified, MOON must be sent second.
    ///       For burns this happens automatically as long as the other token has a 
    ///       smaller contract address than MOON. Hence MOON's large address.
    /// @param amount MOON amount moved.
    /// @param from   Sender.
    /// @param to     Recipient.
    /// @return taxed True if swap (taxed); false otherwise.
    /// @return r     Ray context (pair, token, reserves, orientation).
    function _transferType(
        uint256 amount,
        address from,
        address to
    )
        internal
        returns (
            bool taxed,
            Ray memory r
        )
    {
        if (amount == 0) return (false, r);

        uint8 classFrom = _getMoonClass(from);
        uint8 classTo   = _getMoonClass(to);

        // Neither touches a verified pair ⇒ untaxed
        if (!(classFrom == 2 || classTo == 2)) {
            return (false, r);
        }

        // Resolve ray + orientation + reserves
        r.pair = (classFrom == 2) ? from : to;
        r.self = pairs[r.pair].ray;
        (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);

        (bool okR, uint112 r0, uint112 r1, /*uint32 ts*/) = _probeReserves(r.pair, 40000);
        if (!okR) return (true, r); // Broken pair ⇒ taxed

        r.ra = r.thisZero ? _cap112(r1) : _cap112(r0); 
        r.rm = r.thisZero ? _cap112(r0) : _cap112(r1); 

        // Reconcile any prior swapLock
        uint256 bm = balances[r.pair]; // MOON live balance
        if (pairs[r.pair].swapLock) {
            // Tax the untaxed MOON in the pair
            // While swapLock is true, (bm - rm) amount was falsely untaxed.
            if (bm > r.rm){
                uint256 tax = (bm - r.rm) * SWAP_TAX / 1e18;
                _transferExempt(r.pair, address(this), tax);
                _updatePending(r, tax);
            }
            pairs[r.pair].swapLock = false;
        }

        // Live A balance
        (bool okB, uint256 ba) = _safeBalanceOf(r.self, r.pair); // other‑token live bal
        if (!okB) return (true, r); // Broken token ⇒ taxed

        // Adjust MOON balance directionally after this transfer
        if      (to   == r.pair) bm = _satAdd(bm, amount); // M→A swap or mint
        else if (from == r.pair) bm = _satSub(bm, amount); // A→M swap or burn

        // Bootstrap guard
        if (r.ra == 0 || r.rm == 0) return (false, r);

        // Sign test (opposite signs ⇒ swap); unchanged A ⇒ swap
        if (!_sameSign(ba, r.ra, bm, r.rm) || ba == r.ra) {
            return (true, r);
        }

        // Proportionality (~±20%) — outside window ⇒ swap
        uint256 da = ba > r.ra ? ba - r.ra : r.ra - ba; // Difference between ba and ra
        uint256 dm = bm > r.rm ? bm - r.rm : r.rm - bm; // Difference between bm and rm
        unchecked {
            // Cross terms for the ratio comparison: da/dm = r.ra/r.rm  ⇔  da*r.rm = dm*r.ra
            uint256 a = da * r.rm;
            uint256 b = dm * r.ra;

            // Scale once and compare to 6/5 (1.2) and 4/5 (0.8) bounds.
            uint256 a5 = a * 5;

            // Out of bounds if a/b > 1.2  or  a/b < 0.8
            if (a5 > b * 6 || a5 < b * 4) return (true, r);
        }

        // Inside window ⇒ LP mint/burn (untaxed); engage lock until completion
        pairs[r.pair].swapLock = true;
    }

    /// @notice Accrues MOON tax to a ray and enqueues it for swap‑back when thresholded.
    /// @dev
    /// - `pending` saturates to uint112.
    /// - Enqueues once when `pending ≥ MIN_SWAP_BACK`.
    /// - If the ray is SUN, burn the tax immediately (do not queue).
    /// @param tax Newly collected MOON.
    function _updatePending(Ray memory r, uint256 tax) internal {
        if (r.self == sun) {_burn(address(this), tax); return;}
        r.pending = _cap112(r.pending + tax);
        if (r.pending >= MIN_SWAP_BACK && r.swapStatus == 0) {
            swapQueue.push(r.self);
            r.swapStatus = 2; // in list
        }
        writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
    }

    /// @notice Read‑only guard used by `balanceOf` to enforce swap‑lock semantics.
    /// @dev
    /// - While `swapLock` is set, verifies that the (balance - reserve) are the same
    ///   sign for each token. If not, returns false (caller should `skim`).
    /// - Returns true when unlocked or probes fail (fail‑open).
    /// Note: SwapLock is only enabled when transferType identifies an LP action (Mint/Burn)
    ///       This function ensures that the action is really an LP action and not a swap.
    ///       This function should never return false outside of a malicious swap.
    /// @param pair The pair address to check.
    /// @return Whether the pair is safe/unlocked for balance queries.
    function _unlocked(address pair) internal view returns (bool){
        bool swapLock = pairs[pair].swapLock;
        if (!swapLock) return true;

        Ray memory r;
        r.pair = pair;
        r.self = pairs[r.pair].ray;
        (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);

        // Stored reserves
        (bool okR, uint112 r0, uint112 r1, /*uint32 ts*/) = _probeReserves(pair, 40000);
        if (!okR) return true;

        // Map to (A,M)
        r.ra = r.thisZero ? _cap112(r1) : _cap112(r0);
        r.rm = r.thisZero ? _cap112(r0) : _cap112(r1);

        // Live balances
        uint256 bm = balances[pair];
        (bool ok, uint256 ba) = _safeBalanceOf(r.self, pair);
        if (!ok) return true;

        // If signs still match, it's safe; otherwise block
        if (_sameSign(ba, r.ra, bm, r.rm)) return true;
        return false;
    }


    /*//////////////////////////////////////////////////////////////////////////
                              SWAPBACK (QUEUE & SWAP)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Attempts at most one swap-back from the queue, then revalues the ray.
    /// @dev
    /// - Picks a ray pseudo-randomly, pruning small/invalid entries on the way.
    /// - Reads reserves, computes a safe `amountIn` (appreciation-coverage guard
    ///   + small impact guard), and performs a bounded self-call swap.
    /// - On success: decrements `pending`, re-probes reserves, revalues the ray,
    ///   and updates global aggregates.
    /// - On failure: removes the ray from the queue and returns.
    /// @param skipRay Optional ray to avoid (the ray in the user’s current taxed swap).
    function _swapBack(GlobalMemory memory g, address skipRay)
        internal
        returns (GlobalMemory memory)
    {
        // Early exit if nothing to do
        uint256 len = swapQueue.length;
        if (len == 0) return g;

        // Pseudo-random starting point.
        uint256 cursor = block.prevrandao + activeMembersCursor;

        Ray memory r;
        bool found;

        // Candidate selection + lazy pruning (bounded attempts)
        for (uint256 attempts = 0; attempts < 6; ++attempts) {
            len = swapQueue.length;
            if (len == 0) return g;
            cursor = (cursor + 1) % len;

            r.self = swapQueue[cursor];

            // Skip the ray currently used by the calling swap
            if (r.self == skipRay) {
                if (len == 1) return g;
                continue;
            }

            // Load packed ray fields
            (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);

            // Cull entries below threshold
            if (r.pending < MIN_SWAP_BACK) {
                _removeFromList(swapQueue, cursor);
                writeRay1(r.self, r.reserve, r.pending, 0, r.brightStatus, r.thisZero);

                // If queue emptied, we’re done; otherwise continue with element swapped into `cursor`
                len = swapQueue.length;
                if (len == 0) return g;
                continue;
            }

            // Resolve pair and cached quotes for downstream logic
            (r.quote, r.candidateQuote, r.updateBlock) = readRay2(r.self);
            r.pair = readRay0(r.self);

            found = true;
            break;
        }
        if (!found) return g;

        // Probe reserves (drop from queue if probe fails or 0 reserves)
        (bool okR, uint112 r0, uint112 r1, /*uint32 ts*/) = _probeReserves(r.pair, 40000);
        if (!okR || r0 == 0 || r1 == 0) {
            _removeFromList(swapQueue, cursor);
            writeRay1(r.self, r.reserve, r.pending, 0, r.brightStatus, r.thisZero);
            return g;
        }
        r.ra = r.thisZero ? r1 : r0;  // other token reserve
        r.rm = r.thisZero ? r0 : r1;  // MOON reserve

        //  A) Leave enough pending to cover appreciation tax after the swap
        uint256 maxInAppreciation = _maxInForAppreciation(r);
        //  B) Keep price impact no greater than SWAP_TAX
        uint256 maxInFee = (r.rm * SWAP_TAX) / 1e18;

        // Combine guards and clamp to availability
        uint256 maxIn    = maxInAppreciation <= maxInFee ? maxInAppreciation : maxInFee;
        uint256 amountIn = r.pending <= maxIn ? r.pending : maxIn;

        // Too small → drop from queue and update new price
        if (amountIn < MIN_SWAP_BACK) {
            _removeFromList(swapQueue, cursor);
            r.swapStatus = 0;
            g = _updateValue(g, r);
            return g;
        }

        // Execute swap via bounded self-call
        bytes memory swapCalldata = abi.encodeWithSelector(
            this.__swapWithPair.selector,
            r.pair,
            r.thisZero,
            amountIn,
            r.rm,
            r.ra
        );

        (bool ok, ) = address(this).call{gas: SWAPBACK_CALL_GAS}(swapCalldata);

        if (ok) {
            // Swap succeeded — shrink pending and optionally dequeue
            r.pending = r.pending - uint112(amountIn);
            if (r.pending < MIN_SWAP_BACK && r.swapStatus == 2) {
                _removeFromList(swapQueue, cursor);
                r.swapStatus = 0;
            }

            // Re-probe reserves (best effort)
            (okR, r0, r1, /*uint32 ts*/) = _probeReserves(r.pair, 40000);
            if (okR) {
                r.ra = r.thisZero ? r1 : r0;
                r.rm = r.thisZero ? r0 : r1;
            } // If probe fails, use old reserves

            // Revalue and update global aggregates
            g = _updateValue(g, r);
            return g;

        } else {
            // Swap failed — remove from queue
            _removeFromList(swapQueue, cursor);
            writeRay1(r.self, r.reserve, r.pending, 0, r.brightStatus, r.thisZero);
            return g;
        }
    }

    
    /// @notice Computes the max MOON-in that keeps pending sufficient to pay appreciation tax post-swap.
    /// @dev
    /// Goal:
    /// - Choose `x ≤ r.pending` so that after swapping `x`, the remaining `pending` can still
    ///   cover the appreciation tax that would be owed if the ray’s MOON‑denominated value
    ///   increases using the *post‑swap* reserves and quote.
    /// Notes:
    /// - Considers pair fee, pair bonus (portion left in the pool), and any uncredited tokens
    ///   already in the Vault for this ray.
    /// - Uses saturating math and defensive guards; never reverts. Returns a ceil’d `x`.
    /// @param r Ray snapshot (expects `rm`, `ra`, `reserve`, `quote`, `pending`, `self`).
    /// @return x Max MOON-in to swap now while preserving coverage.
    function _maxInForAppreciation(Ray memory r) internal view returns (uint256 x) {
        // Unpack & early guards
        uint256 P = r.pending;
        if (P == 0) return 0;

        uint256 M = r.rm;
        uint256 A = r.ra;
        if (M == 0 || A == 0) return 0;

        // Live Vault balance of token (uncredited portion considered as part of new value)
        (, uint256 B) = _safeBalanceOf(r.self, vault);

        // Shorthands (locals are cheap; immutables/consts already are)
        uint256 WAD = 1e18;
        uint256 D   = FEE_DENOMINATOR;  // 10_000
        uint256 F   = feeMul;           // ≤ 10_000
        uint256 K   = APPRECIATION_TAX; // 0.20e18

        // Pair bonus and complement
        uint256 bBonusW = PAIR_BONUS;          // 0.25e18
        uint256 gammaW  = WAD - bBonusW;       // compile-time fold; safe

        // Pending scaling vs reserves, prior credited value in MOON terms
        // pW = ceil(P * WAD / M) — safe to compute directly (P*WAD < 2^256)
        uint256 pW;
        unchecked { pW = (P * WAD + (M - 1)) / M; }

        uint256 vq      = _mulDivDown(r.reserve, r.quote, 1e38);
        uint256 kBetaUp = _mulDivUp(K, vq, M);

        // Constant term with up-bias (unsigned sign+magnitude)
        uint256 lhs   = _mulDivDown(K, B, A);       // cache: used twice
        uint256 rhs   = _satAdd(kBetaUp, pW);
        bool    negC  = lhs < rhs;
        uint256 absC  = negC ? (rhs - lhs) : (lhs - rhs);

        // Helper pieces for coefficients
        uint256 FBoverA = _mulDivDown(F, B, A);
        // Fgamma = floor(F * gammaW / WAD) — safe (F*gammaW < 2^256)
        uint256 Fgamma;
        unchecked { Fgamma = (F * gammaW) / WAD; }

        uint256 FBplus = _satAdd(FBoverA, Fgamma);

        // Quadratic/linear coefficients (WAD units, up-biased)
        // aW = floor(bBonusW * F / D) — safe (product < 2^256)
        uint256 aW = (bBonusW * F) / D;
        // KFoverD cached once; may saturate inside _mulDivDown (that’s fine)
        uint256 KFoverD = _mulDivDown(K, FBplus, D);
        aW = _satAdd(aW, KFoverD);

        uint256 bWpos = _satAdd(WAD, lhs);        // lhs was floor(K*B/A)
        bWpos         = _satAdd(bWpos, KFoverD);  // reuse

        uint256 sTot  = _satAdd(pW, kBetaUp);

        // neg = ceil( ceil(sTot * bBonusW / WAD) * F / D )
        uint256 tmp   = _mulDivUp(sTot, bBonusW, WAD);
        uint256 neg   = _mulDivUp(tmp, F, D);

        uint256 bW = (neg >= bWpos) ? 0 : (bWpos - neg);

        // Solve for t (normalized by WAD), using ceil where needed to preserve up-bias
        uint256 tW = 0;

        if (aW == 0) {
            if (negC) {
                tW = _mulDivUp(absC, WAD, bW); // may saturate if bW==0 → OK (clamped later)
            }
        } else {
            bool safe_b2   = (bW == 0) || (bW <= type(uint256).max / bW);
            bool safe_a4   = (aW <= type(uint256).max / 4);
            bool safe_four = safe_a4 && (absC == 0 || ((aW << 2) <= type(uint256).max / absC));
            bool safe_den  = (aW <= type(uint256).max / 2);

            if (safe_b2 && safe_four && safe_den) {
                uint256 b2;           unchecked { b2 = bW * bW; }
                uint256 four_a_abs_c; unchecked { four_a_abs_c = (aW << 2) * absC; }

                uint256 disc;
                if (!negC) {
                    disc = (b2 >= four_a_abs_c) ? (b2 - four_a_abs_c) : 0;
                } else {
                    disc = (type(uint256).max - b2 < four_a_abs_c) ? type(uint256).max : (b2 + four_a_abs_c);
                }

                uint256 s = _isqrt(disc);

                if (s > bW) {
                    uint256 num; unchecked { num = s - bW; }
                    uint256 den; unchecked { den = aW << 1; }
                    tW = _mulDivUp(num, WAD, den);
                }
            } else {
                if (negC) {
                    tW = _mulDivUp(absC, WAD, bW);
                }
            }
        }

        // Convert normalized t to MOON-in, ceil, and clamp to pending
        x = _mulDivUp(tW, M, WAD);
        if (x > P) x = P;
    }



    /// @notice Internal router for MOON→token swaps on a verified V2 pair (self-call only).
    /// @dev
    /// - Transfers `amountIn` MOON into the pair, recomputes the *actual* input,
    ///   applies factory fee and the pair bonus, and routes output directly to the Vault.
    /// - Reverts on zero output to avoid no-op swaps.
    /// - Orientation-aware: if MOON is token0, outputs token1; otherwise token0.
    /// @param pair       V2 pair to swap against.
    /// @param thisZero   True if MOON is token0 in the pair.
    /// @param amountIn   Intended MOON input (ledger transfer).
    /// @param reserveIn  Pre-swap MOON reserve (orientation-correct).
    /// @param reserveOut Pre-swap other-token reserve (orientation-correct).
    function __swapWithPair(
        address pair,
        bool    thisZero,
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external {
        // Self-call only
        require(msg.sender == address(this), "Moon: self-call only");

        // Disable swapLock
        if (pairs[pair].swapLock) {
            pairs[pair].swapLock = false;
        }

        // Router-style ledger move: push MOON to the pair
        _transferExempt(address(this), pair, amountIn);

        // Compute the actual input observed by the pair
        uint256 realIn = _satSub(balances[pair], reserveIn);

        // V2 x*y=k with factory fee
        uint256 inWithFee   = realIn * uint256(feeMul);
        uint256 numerator   = inWithFee * reserveOut;
        uint256 denominator = reserveIn * FEE_DENOMINATOR + inWithFee;
        uint256 amountOut   = (denominator == 0) ? 0 : (numerator / denominator);

        // Apply pair bonus (leave a fraction in the pool)
        amountOut = amountOut * (1e18 - PAIR_BONUS) / 1e18;
        require(amountOut != 0);

        // Execute the swap; send proceeds to the Vault
        if (thisZero) {
            IUniswapV2Pair(pair).swap(0, amountOut, vault, new bytes(0));
        } else {
            IUniswapV2Pair(pair).swap(amountOut, 0, vault, new bytes(0));
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                            LIGHT ENGINE (RADIATE/EMIT)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Processes active SUN members within a fixed gas stipend and advances payouts.
    /// @dev
    /// - Round‑robin over `activeMembers` from `activeMembersCursor`.
    /// - Removes stale entries (no longer active)
    /// - Calls {_emitRay} for active entries, then persists the new cursor.
    function _radiate(GlobalMemory memory g)
        internal
        returns (GlobalMemory memory)
    {
        // Open gas window and snapshot cursor (monotonic measure: start - gasleft() increases)
        uint256 start = gasleft();
        uint256 i = activeMembersCursor;

        Ray memory r;
        Member memory m;

        // Iterate while we have gas budget
        while (start - gasleft() < RADIATE_GAS_LIMIT) {
            uint256 lenNow = activeMembers.length;
            if (lenNow == 0) break;             // nothing to do
            if (i >= lenNow) i = 0;             // wrap if list shrank

            // Load member snapshot
            m.self = activeMembers[i];
            (m.pastIndex, m.uncollected, m.class, m.status) = readMember(m.self);

            if (m.status != 2) {
                // Remove from rotation (swap‑and‑pop); do not advance i (new element sits at i)
                _removeFromList(activeMembers, i);
                writeMember(m.self, m.pastIndex, m.uncollected, m.class, 0);
            } else {
                // Active entry: attempt an emission, then advance
                (g, r) = _emitRay(g, r, m);
                unchecked { ++i; }
            }
        }

        // Persist new credited reserves
        if (r.self != address(0)) {
            writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
        }

        // Persist cursor for next pass
        activeMembersCursor = i;
        return g;
    }

    /// @notice Settles a SUN holder’s MOON‑valued claim by releasing tokens from the Vault.
    /// @dev
    /// - Accrues the caller’s pending MOON‑value using Δindex and their SUN balance at the start
    ///   of the interval, folding any previously stored `uncollected`.
    /// - Pays out against “bright” ray buckets. A member is typically paid from a single token
    ///   type per call; if that bucket cannot cover the scaled claim, a new bucket is selected.
    /// - Payouts respect current coverage (pool/oath). Accounting advances as if the full
    ///   unscaled value were settled, while the member actually receives `unscaled × pool/oath`.
    /// - Grief‑resistant by design: Whether the token transfer succeeds or not, the global pool 
    ///   is reduced by the realized value removed from the bucket. When the transfer succeeds, 
    ///   the member’s claim (`m.uncollected`) and the global (`g.oath`) are debited proportionally.
    /// - List maintenance is O(1). This function only writes ray state immediately when it has to
    ///   delist; otherwise the caller of {_emitRay} persists the last touched ray with a single
    ///   packed write after the loop.
    /// @param r acts as a reusable cursor: it may persist across calls, and is only 
    ///   written back to storage when the selected bucket is fully drained or delisted.
    function _emitRay(GlobalMemory memory g, Ray memory r, Member memory m)
        internal
        returns (GlobalMemory memory, Ray memory)
    {
        // Accrue the member’s claim for the current index window.
        // Index is monotonic; wrapping is allowed in unchecked math.
        uint128 deltaIndex;
        unchecked { deltaIndex = g.index - m.pastIndex; }

        if (m.class != 1) return (g, r);
        if (g.oath == 0)  return (g, r);

        // Resolve the member’s SUN balance at the beginning of this index interval
        if (deltaIndex != 0) {
            (/*ok*/, m.balance) = _safeBalanceOf(sun, m.self);
            uint256 earned = _divIndex(uint256(m.balance) * uint256(deltaIndex));
            m.uncollected  = _cap112(earned + uint256(m.uncollected));
        }
        if (m.uncollected < MIN_EMIT) return (g, r);

        // Seed for pseudo‑random bucket order.
        uint256 seed;
        if (r.self == address(0)) {
            seed = uint256(keccak256(abi.encodePacked(block.prevrandao, m.self)));
        }

        // Settle against at most MAX_PAYOUT_TOKENS buckets to bound work per call.
        uint256 iter;
        while (m.uncollected >= MIN_EMIT && iter < MAX_PAYOUT_TOKENS) {
            unchecked { ++iter; }
            if (g.pool < MIN_EMIT || g.oath < MIN_EMIT) break;

            // Cursor resets to a new ray only when the current one delists or is too small.
            if (r.self == address(0)) {
                uint256 len = brightRays.length;
                if (len == 0) break;

                // Xorshift to mix the seed between selections.
                unchecked {
                    seed ^= (seed << 13);
                    seed ^= (seed >> 7);
                    seed ^= (seed << 17);
                }

                // Choose a bucket and fetch its persisted accounting.
                r.cursor = seed % len;
                r.self   = brightRays[r.cursor];

                (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);
                (r.quote, r.candidateQuote, r.updateBlock) = readRay2(r.self);

                // Lazy prune: if it is no longer marked “in‑list”, drop it now.
                if (r.brightStatus != 2) {
                    _removeFromList(brightRays, r.cursor);
                    writeRay1(r.self, r.reserve, r.pending, r.swapStatus, 0, r.thisZero);
                    r.self = address(0);
                    continue;
                }
            }

            // Scale the member’s unscaled claim by the live coverage ratio.
            // The member receives: paid = unscaled × (pool / oath)
            // while accounting burns the full unscaled amount from `m.uncollected` and `g.oath`.
            uint256 scaled = _mulDivDown(uint256(m.uncollected), uint256(g.pool), g.oath);

            // Convert scaled MOON‑value into whole tokens available from this ray,
            // using the committed quote. 
            uint256 payAmt = (r.quote == 0) ? 0 : _mulDivDown(scaled, 1e38, r.quote);
            if (payAmt == 0) {
                r.self = address(0);
                continue;
            }

            // Clamp to the credited reserve (never over‑draw a bucket).
            if (payAmt > r.reserve) payAmt = r.reserve;

            // Compute the value to be removed from the pool at the committed quote.
            uint256 tokenValBefore = _mulDivDown(uint256(r.reserve), r.quote, 1e38);
            r.reserve              = _cap112(_satSub(uint256(r.reserve), payAmt));
            uint256 tokenValAfter  = _mulDivDown(uint256(r.reserve), r.quote, 1e38);
            uint256 rayDeltaVal    = tokenValBefore - tokenValAfter; // realized value

            // Attempt release from the Vault (bounded gas, tolerant of non‑standard ERC‑20s).
            // Zero‑length return is considered success; revert or false is failure.
            (bool ok, ) = vault.call{gas: 150_000}(
                abi.encodeWithSelector(
                    IVault.releaseToMember.selector,
                    r.self,
                    payAmt,
                    m.self
                )
            );

            // When the transfer succeeds, burn the member’s unscaled claim and reduce global oath
            if (ok) {
                uint256 payValUnscaled = (g.pool == 0)
                    ? 0
                    : _mulDivDown(rayDeltaVal, uint256(g.oath), uint256(g.pool));
                if (payValUnscaled > m.uncollected) payValUnscaled = m.uncollected;

                g.oath        = _satSub128(g.oath, _cap128(payValUnscaled));
                m.uncollected = _cap112(_satSub(uint256(m.uncollected), payValUnscaled));
            }

            // The global pool is debited by the realized value regardless of transfer outcome.
            g.pool = _satSub128(g.pool, _cap128(rayDeltaVal));

            // If the bucket’s residual value falls below the emission floor, delist it immediately.
            // Remove its residual contribution from the pool and clear its bright flag.
            if (tokenValAfter < MIN_EMIT) {
                _removeFromList(brightRays, r.cursor);
                r.brightStatus = 0;
                g.pool         = _satSub128(g.pool, _cap128(tokenValAfter));
                writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
                r.self = address(0);
            }
        }
        writeMember(m.self, g.index, m.uncollected, m.class, m.status);

        return (g, r);
    }


    /*//////////////////////////////////////////////////////////////////////////
                    SUN ACCOUNTING & ELIGIBILITY (TRACKING)                     
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Bookkeeps a SUN transfer so index accrual, rotation, and active supply stay correct.
    /// @dev
    /// - Uses **pre‑transfer** balances (supplied by SUN) to accrue each side fairly at the
    ///   current index, then snapshots both to close the window.
    /// - Maintains the active member list (eligible = balance ≥ MIN_SUN_RADIATE) 
    ///   and updates the global count of eligible SUN (`active`) only when class boundaries are crossed.
    /// @param from    SUN holder sending tokens.
    /// @param to      SUN holder receiving tokens.
    /// @param fromBal Pre‑transfer SUN balance of `from` (1e18‑scaled).
    /// @param toBal   Pre‑transfer SUN balance of `to` (1e18‑scaled).
    /// @param amount  SUN amount moved (1e18‑scaled).
    function _transferSun(address from, address to, uint256 fromBal, uint256 toBal, uint256 amount) internal { 
        // No-op guard: zero amount or self-transfer has no accounting effect.
        if (amount == 0 || from == to) return;

        Member memory f;
        Member memory t;

        f.self    = from;
        f.balance = fromBal;
        t.self    = to;
        t.balance = toBal;    

        (f.pastIndex, f.uncollected, f.class, f.status) = readMember(f.self);
        (t.pastIndex, t.uncollected, t.class, t.status) = readMember(t.self);

        // First-touch classification if unknown. Only class-1 holders accrue & rotate.
        if (f.class == 0) f = _getSunClass(f);
        if (t.class == 0) t = _getSunClass(t);

        (uint128 index, uint128 active) = readIndexActive();

        // Accrue “uncollected” using the **pre-transfer** balances at this index.
        if (f.class == 1) f = _recordUncollected(f, index); 
        if (t.class == 1) t = _recordUncollected(t, index);

        // Snapshot both members to the current index to close this accrual window.
        f.pastIndex = index;
        t.pastIndex = index;

        // Calculate post transfer balances.
        unchecked {
            f.balance -=amount;
            t.balance +=amount;
        }
        
        // Maintain active-member rotation: class-1 with balance ≥ MIN_SUN_RADIATE are listed.
        if (f.class == 1) f.status = _updateList(activeMembers, f.self, f.status, f.balance >= MIN_SUN_RADIATE);
        if (t.class == 1) t.status = _updateList(activeMembers, t.self, t.status, t.balance >= MIN_SUN_RADIATE);

        // Update global count of eligible (class-1) SUN tokens used by index math.
        _updateActiveToken(f.class, t.class, amount, index, active); 

        writeMember(f.self, f.pastIndex, f.uncollected, f.class, f.status);
        writeMember(t.self, t.pastIndex, t.uncollected, t.class, t.status);
    }

    /// @notice Classifies an address for SUN eligibility (1 = eligible EOA/holder, 2 = ineligible pool).
    /// @dev
    /// - EOAs → class 1.
    /// - Pool‑like contracts (V2/V3 token0(), Uniswap V1 tokenAddress(), ERC‑6909 balanceOf) → class 2.
    /// - All probes are gas‑capped STATICCALLs; failures degrade to class 1.
    /// - View‑only helper; does not write to storage.
    /// Note: all other contracts can hold SUN and receive reflections.
    ///       Pair‑like contracts are only excluded to avoid wasting rays that would get trapped in them.
    /// @param m Member snapshot with `self` set.
    /// @return m Same struct with `class` updated in memory.
    function _getSunClass(Member memory m)
        internal view
        returns (Member memory)
    {
        address member = m.self;

        // EOAs eligible by default
        if (member.code.length == 0) { m.class = 1; return m; }

        // V2/V3‑style pools expose token0()
        (bool ok0, address t0) = _probeToken(member, SEL_TOKEN0, 50000);
        if (ok0 && t0 != address(0)) { m.class = 2; return m; }

        // Uniswap V1 pairs expose tokenAddress()
        (bool ok2, address t1) = _probeToken(member, SEL_V1_tokenAddr, 50000);
        if (ok2 && t1 != address(0)) { m.class = 2; return m; }

        // ERC‑6909 multi‑token style exposes balanceOf(address,uint256)
        (bool ok3, /*uint256*/) = _probeBalanceOf6909(member, address(1), 0, 50000);
        if (ok3) { m.class = 2; return m; }

        m.class = 1;
        return m;
    }

    /// @notice Accrues a member’s uncollected MOON‑valued claim up to `index`.
    /// @dev
    /// - If balance > 0 and `index` moved, adds round‑to‑nearest( balance * Δindex / 1e32 ).
    /// - Does not change `pastIndex`; caller should snapshot after accrual.
    /// - Caps to uint112 to preserve storage packing.
    /// @param m     Member snapshot (expects `balance` and `pastIndex` set).
    /// @param index Current global index (1e32‑scaled).
    /// @return m    Member with `uncollected` updated (capped).
    function _recordUncollected(Member memory m, uint128 index) internal pure returns (Member memory){
        if (m.balance != 0 && index != m.pastIndex) {
            uint128 delta;
            // Index is monotonic; wrapping allowed in unchecked math
            unchecked { delta = index - m.pastIndex; }

            // Newly earned unscaled value (rounded to nearest via _divIndex)
            uint256 add = _divIndex(uint256(m.balance) * uint256(delta));
            m.uncollected = _cap112(m.uncollected + add);
        }
        return m;
    }

    /// @notice Adjusts global eligible SUN supply when tokens enter/exit class‑1.
    /// @dev
    /// - Increases `active` when tokens move into class‑1; decreases when they leave it.
    /// - No change for 1→1 or 2→2 moves.
    /// - Writes `(index, active)` only when `active` changes to save gas.
    /// @param classFrom Previous class (1 = eligible).
    /// @param classTo   New class (1 = eligible).
    /// @param amount    SUN amount moved (1e18‑scaled).
    /// @param index     Current global index (persisted alongside `active`).
    /// @param active    Snapshot of current eligible supply to adjust/persist.
    function _updateActiveToken(
        uint8 classFrom,
        uint8 classTo,
        uint256 amount,
        uint128 index,
        uint128 active
    ) internal {
        uint256 oldActive = active; // avoid unnecessary writes

        if (classTo == 1 && classFrom != 1) {
            // Entering class‑1
            active = _satAdd128(active, uint128(amount));        
        } else if (classFrom == 1 && classTo != 1) {
            // Leaving class‑1
            active = _satSub128(active, uint128(amount));    
        }

        // Persist only if changed
        if (active != oldActive) {
            writeIndexActive(index, active);
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                             VALUE & QUOTE TRACKING 
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Revalues a ray (paired token) against the Vault and updates pool/oath/index.
    /// @dev
    /// - Refresh credited reserve from the Vault and update the committed quote.
    /// - Compute prior value (oldReserve @ oldQuote), then apply appreciation coverage:
    ///   burn from `r.pending` first, then withhold reserve for any unpaid portion.
    /// - Maintain list membership (bright rays) and apply Δvalue to (pool/oath/index).
    /// - Persist updated packed fields (reserve/pending/status/orientation).
    /// @return g Updated global aggregates.
    function _updateValue(
        GlobalMemory memory g,
        Ray memory          r
    ) internal returns (GlobalMemory memory){

        // Previous credited reserve; refresh from Vault (safe read, capped)
        uint256 oldReserve = r.reserve;
        (bool ok, uint256 balance) = _safeBalanceOf(r.self, vault);
        if (ok) r.reserve = _cap112(balance);
        
        // Update quote; capture the previously committed quote for oldVal
        uint256 oldQuote;
        (r, oldQuote) = _updateQuote(r);

        // Prior value at (oldReserve, oldQuote); then apply appreciation coverage
        uint256 oldVal = _mulDivDown(oldReserve, oldQuote, 1e38);
        uint256 newVal;
        (r, newVal) = _applyAppreciationTax(r, oldVal);

        // Maintain bright‑ray membership by current value
        uint8 oldStatus = r.brightStatus;
        r.brightStatus = _updateList(brightRays, r.self, r.brightStatus, newVal > MIN_EMIT);

        // Apply Δvalue:
        // - If active: positive deltas lift pool, oath and index; negatives reduce pool only.
        // - If delisted now: remove its previous contribution immediately.
        int256 deltaVal = int256(newVal); 

        if (r.brightStatus == 2) {
            if (oldStatus == 2) deltaVal -= int256(oldVal);
            if (deltaVal >= 0) {
                uint128 inc = _cap128(uint256(deltaVal));
                g.pool = _satAdd128(g.pool, inc);
                if (g.active > 0) { // if active = 0 only pool increases
                    g.oath = _satAdd128(g.oath, inc);
                    uint256 indexInc = uint256(inc) * 1e32 / g.active;
                    unchecked { g.index += uint128(indexInc); } // index can wrap
                }
            } else {
                g.pool = _satSub128(g.pool, _cap128(uint256(-deltaVal))); // oath and index unaffected  
            }
        } else if (r.brightStatus == 1 && oldStatus == 2) { // Removed from brightRays
            g.pool = _satSub128(g.pool, _cap128(oldVal)); 
        } 
        
        writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
        return g;
    }

    /// @notice Updates a ray’s committed quote using spot and intra‑block highs.
    /// @dev
    /// Policy:
    /// - If spot > committed: lift immediately (quote=candidate=spot).
    /// - Same block: candidate tracks the running max.
    /// - New block: commit last block’s high to `quote`, seed `candidate` with current spot.
    /// Quotes are 1e38‑scaled MOON‑per‑token and encoded/decoded via Uint256Float96.
    /// Note: This system prevents artificial price dips that increase ray emission amount.
    /// @return r         Ray snapshot with refreshed quote fields.
    /// @return prevQuote The committed quote before this update.
    function _updateQuote(Ray memory r)
        internal
        returns (Ray memory, uint256 prevQuote)
    {
        prevQuote = r.quote;

        // 1e38‑scaled spot = rm/ra (if both non‑zero), then encode/decode to align rounding
        uint256 spot;
        if (r.ra != 0 && r.rm != 0) {
            spot = r.rm * 1e38 / r.ra; // No overflow risk
        } else return (r, prevQuote); 

        // Encode and Decode for standardization.
        uint96 spot96 = Uint256Float96.encode(spot);
        spot          = Uint256Float96.decode(spot96);

        // Immediate lift on higher spot (or when previous quote is zero)
        if (spot > prevQuote || prevQuote == 0) {
            r.quote          = spot;                  
            r.candidateQuote = spot;               
            r.updateBlock    = uint64(block.number);
            writeRay2(r.self, r.quote, r.candidateQuote, r.updateBlock);
            return (r, prevQuote);
        }

        // Same block: keep a running intra‑block max in candidate
        if (uint256(r.updateBlock) == block.number) {
            if (spot > r.candidateQuote) {
                r.candidateQuote = spot;
                writeRay2(r.self, r.quote, r.candidateQuote, r.updateBlock);
            }
            return (r, prevQuote);
        }

        // New block: commit last block’s high; seed candidate with current spot
        r.quote          = r.candidateQuote;
        r.candidateQuote = spot;
        r.updateBlock    = uint64(block.number);
        writeRay2(r.self, r.quote, r.candidateQuote, r.updateBlock);

        return (r, prevQuote);
    }

    /// @notice Applies appreciation coverage: pay for positive value increases or withhold reserve.
    /// @dev
    /// - If the ray’s MOON‑denominated value rose vs `oldVal`, charge
    ///   `due = ceil(APPRECIATION_TAX * (newVal - oldVal) / 1e18)`.
    /// - Pay from `r.pending` first (burning MOON). Any unpaid portion is “withheld” by
    ///   reducing the credited reserve so that unpaid gains are not counted.
    /// - Returns the final `newVal` after withholding (uses the committed quote).
    function _applyAppreciationTax(
        Ray memory r,
        uint256 oldVal
    )
        internal
        returns (Ray memory, uint256 newVal)
    {   
        if (r.quote == 0) return(r, 0);

        // Tax is only applied to positive delta
        newVal = _mulDivDown(uint256(r.reserve), r.quote, 1e38);
        if (newVal <= oldVal) return (r, newVal);

        uint256 dValue;
        unchecked { dValue = newVal - oldVal; }

        // Required coverage for this event
        uint256 unpaidValue = _mulDivUp(APPRECIATION_TAX, dValue, 1e18);

        if (r.pending != 0){
            // Burn from pending, clamped by pending and contract balance
            uint256 payNow = (unpaidValue <= r.pending) ? unpaidValue : r.pending;
            uint256 moonBal = balances[address(this)];
            payNow = payNow <= moonBal ? payNow : moonBal;

            r.pending = r.pending - uint112(payNow);
            _burn(address(this), payNow);

            unpaidValue = _satSub(unpaidValue, payNow);
        }

        // Withhold any unpaid portion by reducing credited reserve
        if (unpaidValue != 0) {
            uint256 unpaidValueTokens = _mulDivUp(unpaidValue, 1e18, APPRECIATION_TAX);
            uint256 unpaidTokens      = _mulDivUp(unpaidValueTokens, 1e38, r.quote);
            r.reserve = uint112(_satSub(r.reserve, unpaidTokens));
        }

        // Recompute value from the final credited reserve
        newVal = _mulDivDown(r.reserve, r.quote, 1e38);
        return (r, newVal);
    }

    /*//////////////////////////////////////////////////////////////////////////
                     LIST MANAGEMENT (LIST / DELIST / INIT)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Maintains membership flags for a rotation list (add / mark‑for‑removal).
    /// @dev
    /// Status codes (shared convention):
    ///   0 = not in list
    ///   1 = pending removal (will be physically removed later when index is known)
    ///   2 = in list
    ///
    /// Policy:
    /// - If `shouldBe` and not already 2: ensure presence (push if 0) and set to 2.
    /// - If not `shouldBe` and currently 2: mark as 1 (defer actual removal to keep this path O(1)).
    /// - Returns the new status to be persisted by the caller.
    /// @param list      Target storage array.
    /// @param self      Address whose membership is being updated.
    /// @param status    Current persisted status for `self`.
    /// @param shouldBe  Whether `self` should be in the list given current conditions.
    /// @return          New status code for `self`.
    function _updateList(
        address[] storage list,
        address self,
        uint8 status,
        bool shouldBe
    ) internal returns (uint8) {
        if (shouldBe && status != 2) {
            // Ensure presence when transitioning to "in list"
            if (status == 0) {
                list.push(self);
            }
            status = 2;
        } else if (!shouldBe && status == 2) {
            // Mark for later physical removal
            status = 1;
        }
        return status;
    }  

    /// @notice Removes element at index `i` from `list` in O(1) via swap‑and‑pop (order not preserved).
    /// @dev Caller must ensure `i < list.length`. Reverts if array is empty.
    /// @param list The storage array to modify.
    /// @param i    Index to remove.
    function _removeFromList(address[] storage list, uint256 i) internal {
        uint256 last = list.length - 1;

        if (i != last) {
            list[i] = list[last];
        }

        // Manually decrement list.length to avoid clearing slot (gas savings)
        assembly {
            let lenSlot := list.slot
            sstore(lenSlot, sub(sload(lenSlot), 1))
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                                 MANUAL MAINTENANCE 
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Re-probes MOON pair detection and SUN eligibility for `addr`, reconciling accounting if eligibility flips.
    /// @dev
    /// MOON side:
    /// - Verified pairs are sticky (remain class 2). Otherwise clear cached class and re‑probe via `_getMoonClass`.
    /// SUN side:
    /// - If currently not ineligible, recompute advisory class in memory.
    /// - If it becomes ineligible (class 2): recycle value back into index and remove from activeMembers list
    /// - Returns latest observed classes: `moonC` (1|2) and `sunC` (1|2).
    /// @param addr Address to reclassify.
    /// @return moonC Latest MOON class after (optional) re-probe (2 = verified pair; 1 = regular).
    /// @return sunC  Latest SUN eligibility (2 = ineligible; 1 = eligible).
    function _manuallyReclassify(address addr)
        internal
        returns (uint8 moonC, uint8 sunC)
    {
        /*───────────────────────  MOON CLASS (pair detection)  ───────────────────────*/
        // Keep verified pairs sticky; otherwise clear and re‑probe.
        uint8 cachedMoon = moonClass[addr];
        if (cachedMoon < 2) {
            moonClass[addr] = 0;           // clear only when not a verified pair
            moonC = _getMoonClass(addr);   // re‑classify (2 = verified V2 pair; else 1)
        } else {
            moonC = cachedMoon;            // leave sticky classification as‑is
        }

        /*────────────────────────  SUN CLASS (eligibility)  ──────────────────────────*/
        Member memory m;
        m.self = addr;
        (m.pastIndex, m.uncollected, m.class, m.status) = readMember(m.self);

        uint8 oldClass = m.class;

        // Recompute advisory SUN class in memory (no write unless it becomes 2).
        if (m.class != 2)  {
            m = _getSunClass(m);
            sunC = m.class; 
        } else {
            // Already ineligible; return current state.
            sunC = 2;
        }

        if (oldClass == 1 && m.class == 2) {
            // Update active SUN supply and remove from rotation.
            (uint128 index, uint128 active) = readIndexActive();
            (,m.balance) = _safeBalanceOf(sun, m.self);  // live SUN balance (safe read)
            _updateActiveToken(oldClass, 2, m.balance, index, active);
            (, active) = readIndexActive();

            // Recycle value back into index
            m = _recordUncollected(m, index);
            if (active != 0){
                uint256 indexInc = uint256(m.uncollected) * 1e32 / active;
                unchecked { index += uint128(indexInc); } // index can wrap
                writeIndexActive(index, active);
            } else { // If for some reason active is 0, oath is decremented instead.
                (uint128 pool, uint128 oath) = readPoolOath();
                writePoolOath(pool, _satSub128(oath, _cap128(uint256(m.uncollected))));
            }
            m.uncollected = 0;
            m.pastIndex = index;

            // Delist from activeMembers rotation
            m.status = _updateList(activeMembers, m.self, m.status, false);
        } 
        writeMember(m.self, m.pastIndex, m.uncollected, m.class, m.status);
    }

    /// @notice Adds MOON to a ray’s `pending` and optionally updates value/enqueue for swap-back.
    /// @dev
    /// - Pulls `amount` from caller to this contract (untaxed internal transfer).
    /// - Increases `pending` (saturating). If the ray’s pair is initialized and reserves exist:
    ///   • Enqueue for swap-back when `pending ≥ MIN_SWAP_BACK` and not already queued.
    ///   • Update value/quotes and global aggregates, then commit.
    /// - If pair is uninitialized or probes fail, only the packed ray fields are updated.
    /// @param ray    Ray token address.
    /// @param amount MOON amount to add to `pending`.
    function _manuallyFundRay(address ray, uint256 amount) internal {
        // Ray cannot be MOON, SUN, a class 2 pair, or an EOA.
        require(ray != address(this)
             && ray.code.length > 0
             && pairs[ray].ray == address(0)
             && ray != sun 
             && amount != 0, "Moon: invalid ray or 0 amount");

        // Pull MOON into the contract (untaxed internal transfer)
        _transferExempt(msg.sender, address(this), amount);

        // Initialize local ray context
        Ray memory r;
        r.self = ray;
        (r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero) = readRay1(r.self);

        // Add to pending (saturating); queuing decision happens below
        r.pending = _cap112(r.pending + amount);

        // If the pair is initialized, try to update value and queue if appropriate
        bool valueUpdated;
        r.pair = readRay0(r.self);
        if (r.pair != address(0)) {
            (bool okR, uint112 r0, uint112 r1, /*uint32 ts*/) = _probeReserves(r.pair, 40000);
            if (okR && r0 != 0 && r1 != 0) {
                r.ra = r.thisZero ? r1 : r0;  // other token reserve
                r.rm = r.thisZero ? r0 : r1;  // MOON reserve

                // Enqueue for swap-back once threshold is met and not already listed
                if (r.pending >= MIN_SWAP_BACK && r.swapStatus == 0) {
                    swapQueue.push(r.self);
                    r.swapStatus = 2; // in list
                }

                // Refresh value + globals, then commit
                (uint128 pool,  uint128 oath)   = readPoolOath();
                (uint128 index, uint128 active) = readIndexActive();
                GlobalMemory memory g = GlobalMemory(pool, oath, index, active);

                (r.quote, r.candidateQuote, r.updateBlock) = readRay2(r.self);

                g = _updateValue(g, r);
                valueUpdated = true;

                // Opportunistic maintenance: try one swap-back (skip none) and advance payouts.
                g = _swapBack(g, address(0));
                g = _radiate(g);
                _commitFromG(g);
            }
        }

        if (!valueUpdated) {
            writeRay1(r.self, r.reserve, r.pending, r.swapStatus, r.brightStatus, r.thisZero);
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                                  STORAGE HELPERS
    //////////////////////////////////////////////////////////////////////////*/

    // Bit masks
    uint256 private constant _MASK_64   = (uint256(1) << 64)  - 1;
    uint256 private constant _MASK_96   = (uint256(1) << 96)  - 1;
    uint256 private constant _MASK_112  = (uint256(1) << 112) - 1;
    uint256 private constant _MASK_128  = (uint256(1) << 128) - 1;

    /// Base slot of: mapping(address => Member) internal members;
    function _membersBase() private pure returns (bytes32 s) {
        assembly ("memory-safe") { s := members.slot }
    }

    /// Base slot of: mapping(address => Ray) internal rays;
    function _raysBase() private pure returns (bytes32 s) {
        assembly ("memory-safe") { s := rays.slot }
    }

    /// Slot of: uint256 private packedIndexAndActive;   // [hi 128]=active | [lo 128]=index
    function _idxActSlot() private pure returns (bytes32 s) {
        assembly ("memory-safe") { s := packedIndexAndActive.slot }
    }

    /// Slot of: uint256 private packedPoolAndOath;      // [hi 128]=oath   | [lo 128]=pool
    /// (Kept the function name your helpers already reference: _poolOathSlot)
    function _poolOathSlot() private pure returns (bytes32 s) {
        assembly ("memory-safe") { s := packedPoolAndOath.slot }
    }

    /// @dev keccak256(abi.encode(key, base))
    function _map(bytes32 base, address key) private pure returns (bytes32 slot) {
        assembly ("memory-safe") {
            mstore(0x00, key)
            mstore(0x20, base)
            slot := keccak256(0x00, 0x40)
        }
    }

    /// @dev Computes the base storage slot for `members[who]` (slot0 of the Member struct).
    function _memberSlot0(address who) private pure returns (bytes32 s0) {
        s0 = _map(_membersBase(), who);
    }

    /// @dev Computes the base storage slot for `rays[token]` (slot0 of the Ray struct).
    function _raySlot0(address token) private pure returns (bytes32 s0) {
        s0 = _map(_raysBase(), token);
    }

    /// @dev Computes slot1 of `rays[token]` (holds reserve/pending/status/orientation fields).
    function _raySlot1(address token) private pure returns (bytes32 s1) {
        bytes32 s0 = _raySlot0(token);
        unchecked { s1 = bytes32(uint256(s0) + 1); }
    }

    /// @dev Computes slot2 of `rays[token]` (holds packed quote96/candidateQuote96/updateBlock).
    function _raySlot2(address token) private pure returns (bytes32 s2) {
        bytes32 s0 = _raySlot0(token);
        unchecked { s2 = bytes32(uint256(s0) + 2); }
    }

    /// @notice Read (index, active) from `packedIndexAndActive`.
    function readIndexActive() internal view returns (uint128 index, uint128 active) {
        bytes32 s = _idxActSlot();
        uint256 w; assembly ("memory-safe") { w := sload(s) }
        index  = uint128(w);
        active = uint128(w >> 128);
    }

    /// @notice Write (index, active) to `packedIndexAndActive`.
    function writeIndexActive(uint128 index, uint128 active) internal {
        bytes32 s = _idxActSlot();
        uint256 nw = (uint256(active) << 128) | uint256(index);
        assembly ("memory-safe") { sstore(s, nw) }
    }

    /// @notice Read (pool, oath) from `packedPoolAndOath`.
    function readPoolOath() internal view returns (uint128 pool, uint128 oath) {
        bytes32 s = _poolOathSlot();
        uint256 w; assembly ("memory-safe") { w := sload(s) }
        pool   = uint128(w);
        oath = uint128(w >> 128);
    }

    /// @notice Write (pool, oath) to `packedPoolAndOath`.
    function writePoolOath(uint128 pool, uint128 oath) internal {
        bytes32 s = _poolOathSlot();
        uint256 nw = (uint256(oath) << 128) | uint256(pool);
        assembly ("memory-safe") { sstore(s, nw) }
    }

    /// @notice Read members[who].slot0 → (pastIndex:128, uncollected:112, class:8, status:8).
    /// @dev    Single-slot layout. All bits are densely packed as documented above.
    function readMember(address who)
        internal
        view
        returns (uint128 pastIndex, uint112 uncollected, uint8 class, uint8 status)
    {
        bytes32 s0 = _memberSlot0(who);
        uint256 w; assembly ("memory-safe") { w := sload(s0) }

        pastIndex   = uint128( w         & _MASK_128 );
        uncollected = uint112((w >> 128) & _MASK_112 );
        class       = uint8  ((w >> 240) & 0xFF);
        status      = uint8  ((w >> 248) & 0xFF);
    }

    /// @notice Write members[who].slot0 ← (pastIndex:128, uncollected:112, class:8, status:8).
    /// @dev    Densely packs fields and overwrites the entire word.
    function writeMember(address who, uint128 pastIndex, uint112 uncollected, uint8 class, uint8 status) internal {
        bytes32 s0 = _memberSlot0(who);

        uint256 nw =
            (uint256(pastIndex)    & _MASK_128)         |
            ((uint256(uncollected) & _MASK_112) << 128) |
            ((uint256(class)       & 0xFF)      << 240) |
            ((uint256(status)      & 0xFF)      << 248);

        assembly ("memory-safe") { sstore(s0, nw) }
    }

    /// @notice Read rays[token].slot0 → (pair).
    function readRay0(address token)
        internal
        view
        returns (address pair)
    {
        bytes32 s0 = _raySlot0(token);
        uint256 w; assembly ("memory-safe") { w := sload(s0) }
        pair = address(uint160(w));
    }

    /// @notice Write rays[token].slot0 ← (pair).
    function writeRay0(address token, address pair) internal {
        bytes32 s0 = _raySlot0(token);
        uint256 nw = uint256(uint160(pair));
        assembly ("memory-safe") { sstore(s0, nw) }
    }

    /// @notice Read rays[token].slot1 → (reserve:uint112, pending:uint112, swapStatus:uint8, brightStatus:uint8, thisZero:bool).
    /// @dev    The topmost 8 bits [248..255] are reserved and ignored.
    function readRay1(address token)
        internal
        view
        returns (uint112 reserve, uint112 pending, uint8 swapStatus, uint8 brightStatus, bool thisZero)
    {
        bytes32 s1 = _raySlot1(token);
        uint256 w; assembly ("memory-safe") { w := sload(s1) }

        reserve      = uint112( w         & _MASK_112 );
        pending      = uint112((w >> 112) & _MASK_112 );
        swapStatus   = uint8  ((w >> 224) & 0xFF);
        brightStatus = uint8  ((w >> 232) & 0xFF);
        thisZero     = ((w >> 240)        & 0xFF) != 0;
    }

    /// @notice Write rays[token].slot1 ← (reserve:uint112, pending:uint112, swapStatus:uint8, brightStatus:uint8, thisZero:bool).
    /// @dev    Preserves the topmost reserved 8-bit lane [248..255]; only updates bits [0..247].
    function writeRay1(
        address token,
        uint112 reserve,
        uint112 pending,
        uint8 swapStatus,
        uint8 brightStatus,
        bool thisZero
    ) internal {
        bytes32 s1 = _raySlot1(token);

        // Low 248 bits (everything we control)
        uint256 lw =
            (uint256(reserve)       & _MASK_112)         |
            ((uint256(pending)      & _MASK_112) << 112) |
            ((uint256(swapStatus)   & 0xFF)      << 224) |
            ((uint256(brightStatus) & 0xFF)      << 232) |
            ((thisZero ? uint256(1) : uint256(0)) << 240);

        // Preserve the reserved top 8 bits [248..255] from the existing word.
        uint256 oldW; assembly ("memory-safe") { oldW := sload(s1) }
        uint256 keepTop8 = oldW & ~((uint256(1) << 248) - 1);

        uint256 nw = keepTop8 | lw;
        assembly ("memory-safe") { sstore(s1, nw) }
    }

    /// @notice Read rays[token].slot2 → (quote:uint256, candidateQuote:uint256, updateBlock:uint64).
    /// @dev     Decodes Float96-packed quote fields into uint256 for call‑sites.
    function readRay2(address token)
        internal
        view
        returns (uint256 quote, uint256 candidateQuote, uint64 updateBlock)
    {
        bytes32 s2 = _raySlot2(token);
        uint256 w; assembly ("memory-safe") { w := sload(s2) }
        uint96 qPacked  = uint96(w & _MASK_96);
        uint96 cPacked  = uint96((w >> 96)  & _MASK_96);
        updateBlock     = uint64((w >> 192) & _MASK_64);

        quote          = Uint256Float96.decode(qPacked);
        candidateQuote = Uint256Float96.decode(cPacked);
    }

    /// @notice Write rays[token].slot2 ← (quote:uint256, candidateQuote:uint256, updateBlock:uint64).
    /// @dev     Encodes the uint256 quote fields into Float96 before packing.
    function writeRay2(address token, uint256 quote, uint256 candidateQuote, uint64 updateBlock) internal {
        bytes32 s2 = _raySlot2(token);
        uint96 qPacked = Uint256Float96.encode(quote);
        uint96 cPacked = Uint256Float96.encode(candidateQuote);

        uint256 nw = uint256(qPacked)
                   | (uint256(cPacked)     << 96)
                   | (uint256(updateBlock) << 192);
        assembly ("memory-safe") { sstore(s2, nw) }
    }

    /*//////////////////////////////////////////////////////////////////////////
                            SAFE STATIC PROBE SYSTEM
    ////////////////////////////////////////////////////////////////////////////*/

    /// @notice Probes a target contract for an `address` return value (e.g., token0/token1).
    /// @dev
    /// Behavior
    ///  • Performs a gas‑capped `STATICCALL` via {_staticProbeRaw} expecting a 32‑byte ABI word.  
    ///  • On success, decodes the low 20 bytes as an `address`.  
    ///  • On failure (revert, short/empty return, etc.), returns `(false, address(0))`.
    /// Notes
    ///  • This helper is used for various “what token is this?” checks, and never reverts.  
    ///  • It is safe against non‑standard contracts: all decoding is bounds‑checked.
    /// @param target   Contract to probe.
    /// @param selector 4‑byte function selector (e.g., `SEL_TOKEN0`, `SEL_TOKEN1`, `SEL_V1_tokenAddr`).
    /// @param gasCap   Gas limit to forward to the probe (keeps failures cheap/deterministic).
    /// @return ok      True if the call succeeded and returned at least 32 bytes.
    /// @return token   Decoded address (low 20 bytes of the first 32‑byte word) or zero on failure.
    function _probeToken(address target, bytes4 selector, uint256 gasCap)
        internal
        view
        returns (bool ok, address token)
    {
        bytes memory out;
        (ok, out) = _staticProbeRaw(target, selector, 0, 0, 0, gasCap, 32);
        if (!ok) return (false, address(0));

        // ABI returns address left‑padded in 32 bytes — take the low 20 bytes.
        assembly ("memory-safe") {
            token := and(mload(add(out, 32)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
    }

    /// @notice Reads Uniswap‑V2‑style reserves from a pair via `getReserves()`.
    /// @dev
    /// Behavior
    ///  • Calls `pair.getReserves()` via a gas‑capped `STATICCALL`.  
    ///  • Expects exactly 96 bytes: (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast).  
    ///  • Returns `(false, 0, 0, 0)` on failure.  
    ///  • On success, saturates each reserve to `uint112` to guard against maliciously wide values.
    /// Security & Robustness
    ///  • Never reverts; unsuitable/misbehaving pairs simply yield `ok=false`.  
    ///  • Saturating downcasts ensure internal math cannot overflow reserve‑sized lanes.
    /// @param pair   The V2‑style pair to probe.
    /// @param gasCap Gas limit to forward to the probe.
    /// @return ok    True when a 96‑byte response was obtained.
    /// @return r0    Reserve0 (saturated to uint112).
    /// @return r1    Reserve1 (saturated to uint112).
    /// @return ts    Pair’s `blockTimestampLast` (uint32).
    function _probeReserves(address pair, uint256 gasCap)
        internal
        view
        returns (bool ok, uint112 r0, uint112 r1, uint32 ts)
    {
        bytes memory out;
        (ok, out) = _staticProbeRaw(pair, SEL_GETRESERVES, 0, 0, 0, gasCap, 96);
        if (!ok) return (false, 0, 0, 0);

        // Decode three 32‑byte words; only low bits of the first two are used post‑saturation.
        uint256 a;
        uint256 b;
        uint256 c;
        assembly ("memory-safe") {
            let ptr := add(out, 32)
            a := mload(ptr)
            b := mload(add(ptr, 32))
            c := mload(add(ptr, 64))
        }

        // Saturating downcasts (guard against malicious wide values).
        r0 = a > type(uint112).max ? type(uint112).max : uint112(a);
        r1 = b > type(uint112).max ? type(uint112).max : uint112(b);
        ts = uint32(c);
    }

    /// @notice Asks a canonical factory for a pair address via `getPair(tokenA, tokenB)`.
    /// @dev
    /// Behavior
    ///  • Performs a gas‑capped `STATICCALL` to the factory’s `getPair(a,b)`, expecting 32 bytes.  
    ///  • On success, decodes and returns the low 20 bytes as an `address`.  
    ///  • On failure, returns `(false, address(0))`.
    /// Notes
    ///  • This is used to verify that an observed pair is the official one constructed by `factory`.
    /// @param tokenA  First token of the pair (order usually irrelevant in factories).
    /// @param tokenB  Second token of the pair.
    /// @param gasCap  Gas limit to forward to the probe.
    /// @return ok     True when a 32‑byte response was obtained.
    /// @return pair   The decoded pair address (low 20 bytes) or zero on failure.
    function _probeGetPair(address tokenA, address tokenB, uint256 gasCap)
        internal
        view
        returns (bool ok, address pair)
    {
        bytes memory out;
        (ok, out) = _staticProbeRaw(
            factory,
            SEL_GETPAIR,
            uint256(uint160(tokenA)),
            uint256(uint160(tokenB)),
            2,
            gasCap,
            32
        );
        if (!ok) return (false, address(0));

        // ABI returns address left‑padded in 32 bytes — take the low 20 bytes.
        assembly ("memory-safe") {
            pair := and(mload(add(out, 32)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
    }

    /// @notice Safe, gas‑capped `balanceOf(owner)` probe against an ERC‑20‑like `token`.
    /// @dev
    /// Behavior
    ///  • Calls `token.balanceOf(owner)` as a gas‑capped `STATICCALL`.  
    ///  • On success, decodes a 32‑byte word and returns it, clamped to `uint112` (reserve‑style bound).  
    ///  • On failure, returns `(false, 0)`.
    /// Notes
    ///  • Some non‑standard tokens return no/short data or revert; all cases are treated as failure.  
    ///  • Clamping to `uint112` preserves packing assumptions used elsewhere in this contract.
    /// @param token  ERC‑20‑style token to query.
    /// @param owner  Account whose balance is being probed.
    /// @return ok    True if the probe returned at least 32 bytes.
    /// @return bal   Decoded balance (clamped to `uint112`) or 0 on failure.
    function _safeBalanceOf(address token, address owner)
        internal
        view
        returns (bool ok, uint256 bal)
    {
        bytes memory out;
        (ok, out) = _staticProbeRaw(
            token,
            SEL_BALANCEOF,
            uint256(uint160(owner)),
            0,
            1,
            30000,
            32
        );
        if (!ok) return (false, 0);

        assembly ("memory-safe") { bal := mload(add(out, 32)) }
        if (bal > type(uint112).max) bal = type(uint112).max;
    }

    /// @notice ERC‑6909‑style `balanceOf(owner, id)` probe for multi‑token pools.
    /// @dev
    /// Behavior
    ///  • Calls `token.balanceOf(owner, id)` via gas‑capped `STATICCALL`.  
    ///  • On success, decodes a 32‑byte word and returns it.  
    ///  • On failure, returns `(false, 0)`.
    /// Notes
    ///  • Used purely as a detection probe for “multi‑asset” style pool contracts.  
    ///  • Never reverts; unsuitable targets just yield `ok=false`.
    /// @param token   Multi‑token contract to query.
    /// @param owner   Account whose balance is being probed.
    /// @param id      Token ID within the multi‑token contract.
    /// @param gasCap  Gas limit to forward to the probe.
    /// @return ok     True when a 32‑byte response was obtained.
    /// @return bal    Decoded balance or 0 on failure.
    function _probeBalanceOf6909(address token, address owner, uint256 id, uint256 gasCap)
        internal
        view
        returns (bool ok, uint256 bal)
    {
        bytes memory out;
        (ok, out) = _staticProbeRaw(
            token,
            SEL_BALANCEOF6909,
            uint256(uint160(owner)),
            id,
            2,
            gasCap,
            32
        );
        if (!ok) return (false, 0);

        assembly ("memory-safe") { bal := mload(add(out, 32)) }
    }

    /// @notice Uniswap V1‑style `tokenAddress()` probe (returns the ERC‑20 token held by the V1 pair).
    /// @dev Thin wrapper over {_probeToken} using `SEL_V1_tokenAddr`. See {_probeToken} for semantics.
    /// @param v1Pair The V1‑style pair to query.
    /// @param gasCap Gas limit to forward to the probe.
    /// @return ok    True if a 32‑byte response was obtained.
    /// @return token Decoded token address or zero on failure.
    function _probeV1TokenAddress(address v1Pair, uint256 gasCap)
        internal
        view
        returns (bool ok, address token)
    {
        return _probeToken(v1Pair, SEL_V1_tokenAddr, gasCap);
    }

    /// @notice Low‑level, gas‑capped `STATICCALL` helper with flexible ABI encoding and length checks.
    /// @dev
    /// Behavior
    ///  • Builds calldata for 0, 1, or 2 arguments with the provided `selector`.  
    ///  • For zero‑arg calls, first tries canonical 4‑byte selector encoding; if that fails or returns
    ///    fewer than `minLen` bytes, retries with a 32‑byte padded selector (certain odd interfaces expect this).  
    ///  • Executes a `STATICCALL` with `gasCap` forwarded.  
    ///  • If `success && ret.length >= minLen`, copies exactly `minLen` bytes into a freshly allocated buffer
    ///    and returns `(true, out)`. Otherwise returns `(false, "")`.
    /// Constraints & Conventions
    ///  • `minLen` in this codebase is always a multiple of 32 (32 or 96), enabling tight word‑wise copying.  
    ///  • This function never reverts; it is safe to use in heuristics and detection flows.
    /// @param target   Contract to call.
    /// @param selector 4‑byte function selector.
    /// @param arg0     First ABI argument (ignored when `argCount == 0`).
    /// @param arg1     Second ABI argument (used when `argCount == 2`).
    /// @param argCount Number of ABI arguments to encode: 0, 1, or 2.
    /// @param gasCap   Gas forwarded to the `STATICCALL`.
    /// @param minLen   Minimum return‑data length required for success (bytes).
    /// @return ok      True if the call succeeded and returned at least `minLen` bytes.
    /// @return out     A `bytes` buffer of length `minLen` containing the first `minLen` bytes of returndata.
    function _staticProbeRaw(
        address target,
        bytes4  selector,
        uint256 arg0,
        uint256 arg1,
        uint256 argCount,
        uint256 gasCap,
        uint256 minLen
    ) internal view returns (bool ok, bytes memory out) {
        bytes memory data;
        if (argCount == 0) {
            data = abi.encodeWithSelector(selector);              // 4-byte calldata
        } else if (argCount == 1) {
            data = abi.encodeWithSelector(selector, arg0);
        } else {
            data = abi.encodeWithSelector(selector, arg0, arg1);
        }

        bool success;
        uint256 size;

        // First attempt: copy 0 bytes on call, then copy only minLen if size is sufficient
        assembly ("memory-safe") {
            success := staticcall(gasCap, target, add(data, 0x20), mload(data), 0, 0)
            size := returndatasize()
        }

        if (argCount == 0 && (!success || size < minLen)) {
            // Retry with 32-byte padded selector
            bytes memory data32 = new bytes(32);
            assembly ("memory-safe") {
                mstore(add(data32, 32), shl(224, selector))
                success := staticcall(gasCap, target, add(data32, 0x20), 0x20, 0, 0)
                size := returndatasize()
            }
        }

        ok = success && size >= minLen;
        if (!ok) return (false, bytes(""));

        // Allocate exactly minLen and copy only that much from the return buffer
        out = new bytes(minLen);
        assembly ("memory-safe") {
            returndatacopy(add(out, 0x20), 0, minLen)
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                        INTERNAL UTILITIES (MATH & PROBES)
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Saturating subtraction – clamps at zero instead of under-flowing.
    function _satSub(uint256 a, uint256 b) internal pure returns (uint256 r) {
        unchecked { r = a > b ? a - b : 0; }
    }

    /// @notice Saturating addition – clamps at max uint256 instead of overflowing.
    function _satAdd(uint256 a, uint256 b) internal pure returns (uint256 r) {
        unchecked {
            r = a + b;
            if (r < a) {
                // Overflow happened, clamp to max
                r = type(uint256).max;
            }
        }
    }

    /// @notice Saturating subtraction – clamps at zero instead of under-flowing.
    function _satSub128(uint128 a, uint128 b) internal pure returns (uint128 r) {
        unchecked { r = a > b ? a - b : 0; }
    }

    /// @notice Saturating addition – clamps at max uint128 instead of overflowing.
    function _satAdd128(uint128 a, uint128 b) internal pure returns (uint128 r) {
        unchecked {
            r = a + b;
            if (r < a) {
                // Overflow happened, clamp to max
                r = type(uint128).max;
            }
        }
    }

    /// @notice Compare signs of (a1 - a2) and (b1 - b2) without subtracting.
    /// @dev Zero is inclusive; only false when one delta >0 and the other <0
    function _sameSign(uint256 a1, uint256 a2, uint256 b1, uint256 b2)
        internal
        pure
        returns (bool)
    {
        return (a1 >= a2 && b1 >= b2) || (a1 <= a2 && b1 <= b2);
    }

    // Floor: saturating semantics, with 512 fallback only on overflow.
    function _mulDivDown(uint256 a, uint256 b, uint256 d) internal pure returns (uint256 r) {
        unchecked {
            // Common trivials first (helps inlining + constant folding)
            if ((a | b) == 0) return 0;
            if (d == 0) return type(uint256).max;

            // Try 256-bit product; if it overflowed, bail to 512
            uint256 p = a * b;
            if (a == 0 || p / a == b) {
                return p / d; // floor
            }
        }
        // Rare: overflow -> 512-bit saturated path
        return __mulDiv512_sat(a, b, d, false);
    }

    // Ceil: saturating semantics, with 512 fallback only on overflow.
    function _mulDivUp(uint256 a, uint256 b, uint256 d) internal pure returns (uint256 r) {
        unchecked {
            if ((a | b) == 0) return 0;
            if (d == 0) return type(uint256).max;

            uint256 p = a * b;
            if (a == 0 || p / a == b) {
                uint256 q = p / d;
                // ceil (avoid wrap on MAX)
                return q + (((p % d) != 0 && q != type(uint256).max) ? 1 : 0);
            }
        }
        return __mulDiv512_sat(a, b, d, true);
    }

    /// @dev Shared 512-bit mulDiv (floor/ceil) with saturation. Never reverts.
    function __mulDiv512_sat(uint256 a, uint256 b, uint256 d, bool roundUp) private pure returns (uint256 result) {
        assembly ("memory-safe") {
            // Defensive: saturate if d == 0 (shouldn't happen due to early returns above)
            if iszero(d) {
                result := not(0)
            }
            if d {
                // 512-bit multiply: [prod1 prod0] = a * b
                let mm := mulmod(a, b, not(0))
                let prod0 := mul(a, b)
                let prod1 := sub(sub(mm, prod0), lt(mm, prod0))

                // If quotient wouldn't fit in 256 bits, saturate: (prod1 >= d)
                if iszero(gt(d, prod1)) {
                    result := not(0)
                }
                if gt(d, prod1) {
                    // Compute remainder and make division exact.
                    let rem := mulmod(a, b, d)
                    prod1 := sub(prod1, gt(rem, prod0))
                    prod0 := sub(prod0, rem)

                    // Factor powers of two out of d.
                    let twos := and(d, sub(0, d))
                    d := div(d, twos)

                    // Divide [prod1 prod0] by the factored power of two.
                    prod0 := div(prod0, twos)
                    twos := add(div(sub(0, twos), twos), 1)    // twos = 2^256 / twos
                    prod0 := or(prod0, mul(prod1, twos))

                    // Compute floor quotient q. If reduced d == 1, skip inverse.
                    let q
                    if eq(d, 1) {
                        q := prod0
                    }
                    if iszero(eq(d, 1)) {
                        // Newton-Raphson modular inverse of odd d modulo 2^256 (6 steps)
                        let inv := xor(mul(3, d), 2)
                        inv := mul(inv, sub(2, mul(d, inv)))
                        inv := mul(inv, sub(2, mul(d, inv)))
                        inv := mul(inv, sub(2, mul(d, inv)))
                        inv := mul(inv, sub(2, mul(d, inv)))
                        inv := mul(inv, sub(2, mul(d, inv)))
                        inv := mul(inv, sub(2, mul(d, inv)))
                        q := mul(prod0, inv)
                    }

                    result := q

                    // If round up: add 1 iff (remainder != 0) and result != MAX (saturate instead of wrap)
                    if roundUp {
                        result := add(result, and(gt(rem, 0), iszero(eq(result, not(0)))))
                    }
                }
            }
        }
    }

    /// @notice Caps a uint256 value down to uint128, clamping at the max if overflow.
    function _cap128(uint256 x) internal pure returns (uint128) {
        return x > type(uint128).max ? type(uint128).max : uint128(x);
    }

    /// @notice Caps a uint256 value down to uint112, clamping at the max if overflow.
    function _cap112(uint256 x) internal pure returns (uint112) {
        return x > type(uint112).max ? type(uint112).max : uint112(x);
    }

    /// @dev Integer floor sqrt with a good first guess; 7 Newton steps are enough for 256-bit.
    function _isqrt(uint256 x) internal pure returns (uint256 y) {
        if (x == 0) return 0;
        uint256 z = uint256(1) << (_log2(x) >> 1);
        unchecked {
            // 7 Newton iterations
            for (uint256 i; i < 7; ++i) { z = (z + x / z) >> 1; }
        }
        y = z;
        // Safe clamp: avoids overflow when y >= 2^128
        if (y > 0 && y > x / y) y--;
    }

    /// @dev Tiny log2 used to seed sqrt (gas-cheap).
    function _log2(uint256 x) internal pure returns (uint256 n) {
        if (x >= 2**128) { x >>= 128; n += 128; }
        if (x >= 2**64)  { x >>= 64;  n += 64;  }
        if (x >= 2**32)  { x >>= 32;  n += 32;  }
        if (x >= 2**16)  { x >>= 16;  n += 16;  }
        if (x >= 2**8)   { x >>= 8;   n += 8;   }
        if (x >= 2**4)   { x >>= 4;   n += 4;   }
        if (x >= 2**2)   { x >>= 2;   n += 2;   }
        if (x >= 2**1)   {            n += 1;   }
    }

    // Round to nearest integer: Tie is rounded down
    // Returns round( num / INDEX_DECIMALS ).
    function _divIndex(uint256 num) internal pure returns (uint256 q) {
        // q = floor(num / 1e32), r = num - q*1e32  (0 <= r < 1e32)
        q = num / INDEX_DECIMALS;
        uint256 r = num - q * INDEX_DECIMALS;

        // Compare 2*r to the denominator to avoid floating point
        uint256 twice = r * 2;

        if (twice > INDEX_DECIMALS) {
            unchecked { q += 1; } // strictly above half -> round up
        } 
        // else below half -> keep q
    }

    /// @dev commits global g values if the slots changed.
    /// Always refers to cached 'active'
    function _commitFromG(GlobalMemory memory g) internal {
        (uint128 _index, uint128 _active) = readIndexActive();
        (uint128  _pool, uint128   _oath) = readPoolOath();

        if (g.index != _index) {
            // keep the latest active; only advance index
            writeIndexActive(g.index, _active);
        }
        if (g.pool != _pool || g.oath != _oath) {
            writePoolOath(g.pool, g.oath);
        }
    }

}