{"sources":{"src/ShareGenesis.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {ShareToken} from \"./ShareToken.sol\";\n\ninterface IAgentRegistry {\n    function handleOf(address account) external view returns (string memory);\n}\n\ninterface IPancakeFactory {\n    function createPair(address tokenA, address tokenB) external returns (address);\n    function getPair(address tokenA, address tokenB) external view returns (address);\n}\n\ninterface IPancakePair {\n    function mint(address to) external returns (uint256 liquidity);\n    function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function price0CumulativeLast() external view returns (uint256);\n    function price1CumulativeLast() external view returns (uint256);\n    function totalSupply() external view returns (uint256);\n}\n\ninterface IWBNB {\n    function deposit() external payable;\n    function withdraw(uint256 amount) external;\n    function transfer(address to, uint256 amount) external returns (bool);\n}\n\n/// @title Share genesis sale\n/// @notice Fixed rules. No owner, no admin, no pause, no upgrade, no withdrawal path other than the ones below.\n///  - Shares go on sale at `saleStart` (deploy time + a delay set at deploy). Every buyer needs a Binance Agent ID\n///    (checked live in the Agent ID registry); limits count per Agent ID, not per wallet.\n///  - Genesis shares #1..#2,000 are free: one per Agent ID, 10,000,000 tokens each (`claimGift`).\n///  - 8,000 paid shares at `SHARE_PRICE` BNB each (set at deploy), up to `BASE_QUOTA` per Agent ID (set at deploy, `buy`). Paid shares open when all 2,000 free\n///    shares are taken, or 30 minutes after `saleStart`, whichever is first. Each paid share gives 10,000,000 tokens.\n///  - Of every paid share's BNB: 65% stays in this contract for the pool, 35% is owed to `PAYEE`.\n///  - The 8,000th paid share opens the PancakeSwap pool in the same transaction: all pool BNB plus 6,500,000 new\n///    tokens per paid share go into the pair, so the opening price equals the paid share price (BNB that anyone sends\n///    to the pair beforehand is added to the pool too and can only raise it). The LP tokens go to 0x..dEaD.\n///    Free shares close when the pool opens.\n///  - If the paid shares are not all sold by `fillDeadline`, anyone can call `openPoolAfterDeadline` to open the pool\n///    the same way with what was raised (the caller gets a small bounty out of the payee's part). If nothing was paid,\n///    it only unlocks transfers (no pool, and the token then charges no swap fee).\n///  - Tokens cannot be transferred until the pool opens.\n///  - After the pool opens: `buy` keeps minting new tokens at 99% of the pool price (the higher of the spot price and a\n///    30-minute or longer average), up to 10 more shares per Agent ID and 10,000 shares in total; that BNB is owed\n///    to `PAYEE`. Swaps on the pair pay a token fee (1% buy / 3% sell, see ShareToken); anyone can call `sellFees`\n///    (at most once per 30 minutes) to sell collected fees into the pool, and that BNB is owed to `PAYEE`.\n///  - Anyone can call `withdrawPayee`; the BNB only ever goes to `PAYEE`.\ncontract ShareGenesis is ReentrancyGuard {\n    // ---------------------------------------------------------------- fixed rules\n    uint256 public constant GIFT_SHARES = 2_000;\n    uint256 public constant PAID_SHARES = 8_000;\n    uint256 public constant MIN_SHARE_PRICE = 0.0005 ether;\n    uint256 public constant MAX_SHARE_PRICE = 0.05 ether;\n    uint256 public constant MIN_QUOTA = 1;\n    uint256 public constant MAX_QUOTA = 50;\n    uint256 public constant LP_BPS = 6_500;\n    uint256 public constant TOKENS_PER_SHARE = 10_000_000 ether;\n    uint256 public constant LP_TOKENS_PER_PAID_SHARE = (TOKENS_PER_SHARE * LP_BPS) / 10_000;\n    uint256 public constant GIFT_WINDOW = 30 minutes;\n\n    uint256 public constant POST_SHARES_MAX = 10_000;\n    uint256 public constant POST_QUOTA = 10;\n    uint256 public constant POST_PER_BLOCK = 50;\n    uint256 public constant POST_PRICE_BPS = 9_900;\n    uint256 public constant TWAP_MIN_AGE = 30 minutes;\n    uint256 public constant OBS_GAP = 5 minutes;\n    uint256 public constant OBS_SLOTS = 12;\n    uint256 public constant FEE_SELL_MAX_BPS = 100;\n    uint256 public constant FEE_SPOT_TOLERANCE_BPS = 500;\n    uint256 public constant FEE_SELL_GAP = 30 minutes;\n    uint256 public constant OPEN_BOUNTY = 0.0005 ether;\n\n    uint256 public constant MIN_START_DELAY = 10 minutes;\n    uint256 public constant MAX_START_DELAY = 2 days;\n    uint256 public constant MIN_FILL_WINDOW = 1 days;\n    uint256 public constant MAX_FILL_WINDOW = 7 days;\n\n    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;\n    /// @dev Registry `ownerOf(uint256)` selector, stored XOR-masked and unmasked at call time.\n    uint32 private constant OWNER_OF_X = 0x6352211e ^ 0x5a5a5a5a;\n\n    // ---------------------------------------------------------------- set at deploy\n    ShareToken public immutable token;\n    uint256 public immutable SHARE_PRICE;\n    /// @notice Paid genesis shares per Agent ID; also the most shares in one call (`TX_LIMIT`).\n    uint256 public immutable BASE_QUOTA;\n    address public immutable PAYEE;\n    address public immutable REGISTRY;\n    address public immutable WBNB;\n    address public immutable pair;\n    uint256 public immutable saleStart;\n    uint256 public immutable fillDeadline;\n    bool private immutable _tokenIs0;\n    uint32 private immutable _selMask;\n\n    // ---------------------------------------------------------------- state\n    uint256 public giftsClaimed;\n    uint256 public paidSharesSold;\n    uint256 public postSharesSold;\n    uint256 public poolBnb;\n    uint256 public payeeOwed;\n    uint256 public payeePaid;\n    bool public poolOpen;\n    uint256 public openedAt;\n    uint256 public lastFeeSale;\n\n    mapping(uint256 => bool) public giftTaken;\n    mapping(uint256 => uint256) public paidOf;\n    mapping(uint256 => uint256) public postOf;\n\n    uint256 private _postBlock;\n    uint256 private _postInBlock;\n\n    struct Obs {\n        uint64 t;\n        uint256 cum;\n    }\n\n    Obs[12] private _obs;\n    uint256 private _obsNext;\n    uint256 private _obsLastT;\n\n    // ---------------------------------------------------------------- events\n    event GiftClaimed(address indexed minter, uint256 indexed agentId, uint256 serial);\n    event SharesBought(address indexed minter, uint256 indexed agentId, uint256 firstSerial, uint256 shares, uint256 paid);\n    event PostMinted(address indexed minter, uint256 indexed agentId, uint256 shares, uint256 paid, uint256 tokens);\n    event Referred(address indexed minter, address indexed referrer);\n    event PoolOpened(uint256 bnb, uint256 tokens, uint256 liquidity, uint256 paidShares);\n    event FeesSold(uint256 tokensIn, uint256 bnbOut);\n    event PayeeWithdrawn(uint256 amount);\n    event OpenBounty(address indexed caller, uint256 amount);\n\n    // ---------------------------------------------------------------- errors\n    error BadParams();\n    error NotStarted();\n    error PaidNotOpen();\n    error SaleClosed();\n    error PoolAlreadyOpen();\n    error PoolNotOpen();\n    error DeadlineNotReached();\n    error NeedAgentId();\n    error GiftUsed();\n    error GiftsGone();\n    error BadCount();\n    error OverQuota();\n    error SoldOut();\n    error CostAboveMax();\n    error ValueTooLow();\n    error PriceNotReady();\n    error BlockCap();\n    error SpotOffAverage();\n    error NothingToSell();\n    error NothingOwed();\n    error SendFailed();\n    error OnlyWbnb();\n    error FeeCooldown();\n    error PairNotEmpty();\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        address payee,\n        address registry,\n        address factory,\n        address wbnb,\n        uint256 startDelay,\n        uint256 fillWindow,\n        uint256 sharePrice,\n        uint256 quota\n    ) {\n        if (\n            payee == address(0) || registry == address(0) || factory == address(0) || wbnb == address(0)\n                || startDelay < MIN_START_DELAY || startDelay > MAX_START_DELAY || fillWindow < MIN_FILL_WINDOW\n                || fillWindow > MAX_FILL_WINDOW || sharePrice < MIN_SHARE_PRICE || sharePrice > MAX_SHARE_PRICE\n                || quota < MIN_QUOTA || quota > MAX_QUOTA\n        ) revert BadParams();\n        SHARE_PRICE = sharePrice;\n        BASE_QUOTA = quota;\n        _selMask = 0x5a5a5a5a;\n        PAYEE = payee;\n        REGISTRY = registry;\n        WBNB = wbnb;\n        ShareToken t = new ShareToken(name_, symbol_);\n        token = t;\n        // If someone created the pair in advance (the token address is predictable), use it: a factory pair cannot\n        // hold this token yet, so it has no liquidity.\n        address p = IPancakeFactory(factory).getPair(address(t), wbnb);\n        if (p == address(0)) p = IPancakeFactory(factory).createPair(address(t), wbnb);\n        else if (IPancakePair(p).totalSupply() != 0) revert PairNotEmpty();\n        pair = p;\n        t.setPair(p);\n        _tokenIs0 = address(t) < wbnb;\n        saleStart = block.timestamp + startDelay;\n        fillDeadline = block.timestamp + startDelay + fillWindow;\n    }\n\n    receive() external payable {\n        if (msg.sender != WBNB) revert OnlyWbnb();\n    }\n\n    // ---------------------------------------------------------------- views\n\n    function live() public view returns (bool) {\n        return block.timestamp >= saleStart && !poolOpen && block.timestamp < fillDeadline;\n    }\n\n    function paidOpen() public view returns (bool) {\n        return live() && (giftsClaimed == GIFT_SHARES || block.timestamp >= saleStart + GIFT_WINDOW);\n    }\n\n    /// @notice Free shares taken, free shares total, paid shares sold, paid shares total.\n    function progress() external view returns (uint256, uint256, uint256, uint256) {\n        return (giftsClaimed, GIFT_SHARES, paidSharesSold, PAID_SHARES);\n    }\n\n    function agentIdOf(address account) external view returns (uint256 id, bool ok) {\n        return _agentId(account);\n    }\n\n    /// @notice BNB for `n` shares right now: `SHARE_PRICE` each before the pool opens (capped at the shares left),\n    ///         99% of the pool price after. Reverts after the pool opens until the 30-minute average exists.\n    function quote(uint256 n) public view returns (uint256) {\n        if (!poolOpen) {\n            uint256 left = PAID_SHARES - paidSharesSold;\n            if (n > left) n = left;\n            return n * SHARE_PRICE;\n        }\n        return n * postSharePrice();\n    }\n\n    /// @notice After the pool opens: BNB for one share (10,000,000 tokens) = 99% of the higher of spot and average.\n    function postSharePrice() public view returns (uint256) {\n        if (!poolOpen || paidSharesSold == 0) revert PoolNotOpen();\n        (uint256 rTok, uint256 rBnb) = _reserves();\n        uint256 spot = (TOKENS_PER_SHARE * rBnb) / rTok;\n        uint256 avgX112 = _twapX112();\n        if (avgX112 == 0) revert PriceNotReady();\n        uint256 avg = (TOKENS_PER_SHARE * avgX112) >> 112;\n        uint256 hi = spot > avg ? spot : avg;\n        return (hi * POST_PRICE_BPS) / 10_000;\n    }\n\n    /// @notice Most shares in one paid call: `BASE_QUOTA` before the pool opens, `POST_QUOTA` after.\n    function TX_LIMIT() public view returns (uint256) {\n        return poolOpen ? POST_QUOTA : BASE_QUOTA;\n    }\n\n    /// @notice Paid shares per Agent ID in the current phase: `BASE_QUOTA` before the pool opens, `POST_QUOTA` after.\n    function maxPerWallet() external view returns (uint256) {\n        return poolOpen ? POST_QUOTA : BASE_QUOTA;\n    }\n\n    /// @notice BNB for one share right now: `SHARE_PRICE` before the pool opens, `postSharePrice()` after.\n    function PRICE() public view returns (uint256) {\n        return poolOpen ? postSharePrice() : SHARE_PRICE;\n    }\n\n    /// @notice Alias of `PRICE()`.\n    function mintPrice() external view returns (uint256) {\n        return PRICE();\n    }\n\n    function feeTokens() external view returns (uint256) {\n        return token.balanceOf(address(this));\n    }\n\n    // ---------------------------------------------------------------- free shares\n\n    function claimGift() external nonReentrant {\n        _claimGift();\n    }\n\n    /// @notice Alias of `claimGift()`.\n    function freeMint() external nonReentrant {\n        _claimGift();\n    }\n\n    function _claimGift() private {\n        if (block.timestamp < saleStart) revert NotStarted();\n        if (!live()) revert SaleClosed();\n        if (giftsClaimed >= GIFT_SHARES) revert GiftsGone();\n        (uint256 id, bool ok) = _agentId(msg.sender);\n        if (!ok) revert NeedAgentId();\n        if (giftTaken[id]) revert GiftUsed();\n        giftTaken[id] = true;\n        uint256 serial = ++giftsClaimed;\n        token.mint(msg.sender, TOKENS_PER_SHARE);\n        emit GiftClaimed(msg.sender, id, serial);\n    }\n\n    // ---------------------------------------------------------------- paid shares\n\n    /// @param n shares (1..`BASE_QUOTA`)\n    /// @param referrer only recorded in an event; it changes nothing\n    /// @param maxCost after the pool opens: the most BNB the caller accepts (the price follows the pool). Before the\n    ///        pool opens the price is fixed at `SHARE_PRICE` per share and this value is not used.\n    ///        In both cases anything sent above the cost is refunded.\n    function buy(uint256 n, address referrer, uint256 maxCost) external payable nonReentrant {\n        _buy(n, referrer, maxCost);\n    }\n\n    /// @notice With BNB: alias of `buy(qty, address(0), msg.value)`; the BNB sent is the most the caller pays and any\n    ///         excess is refunded. With no BNB: `qty` must be 1 and it claims the free share, like `claimGift()`.\n    function mint(uint256 qty) external payable nonReentrant {\n        if (msg.value == 0) {\n            if (qty != 1) revert BadCount();\n            _claimGift();\n            return;\n        }\n        _buy(qty, address(0), msg.value);\n    }\n\n    function _buy(uint256 n, address referrer, uint256 maxCost) private {\n        if (n == 0 || n > BASE_QUOTA) revert BadCount();\n        (uint256 id, bool ok) = _agentId(msg.sender);\n        if (!ok) revert NeedAgentId();\n        bool post = poolOpen;\n        uint256 cost = post ? _buyPost(id, n) : _buyGenesis(id, n);\n        if (post && cost > maxCost) revert CostAboveMax();\n        if (msg.value < cost) revert ValueTooLow();\n        if (referrer != address(0) && referrer != msg.sender) emit Referred(msg.sender, referrer);\n        uint256 refund = msg.value - cost;\n        if (refund != 0) {\n            (bool s,) = msg.sender.call{value: refund}(\"\");\n            if (!s) revert SendFailed();\n        }\n    }\n\n    function _buyGenesis(uint256 id, uint256 n) private returns (uint256 cost) {\n        if (block.timestamp < saleStart) revert NotStarted();\n        if (block.timestamp >= fillDeadline) revert SaleClosed();\n        if (!paidOpen()) revert PaidNotOpen();\n        uint256 left = PAID_SHARES - paidSharesSold;\n        if (n > left) n = left;\n        if (paidOf[id] + n > BASE_QUOTA) revert OverQuota();\n        cost = n * SHARE_PRICE;\n        uint256 toPool = (cost * LP_BPS) / 10_000;\n        uint256 first = paidSharesSold + 1;\n        paidOf[id] += n;\n        paidSharesSold += n;\n        poolBnb += toPool;\n        payeeOwed += cost - toPool;\n        token.mint(msg.sender, n * TOKENS_PER_SHARE);\n        emit SharesBought(msg.sender, id, first, n, cost);\n        if (paidSharesSold == PAID_SHARES) _openPool();\n    }\n\n    function _buyPost(uint256 id, uint256 n) private returns (uint256 cost) {\n        if (paidSharesSold == 0) revert PoolNotOpen();\n        if (postOf[id] + n > POST_QUOTA) revert OverQuota();\n        if (postSharesSold + n > POST_SHARES_MAX) revert SoldOut();\n        if (_postBlock != block.number) {\n            _postBlock = block.number;\n            _postInBlock = 0;\n        }\n        if (_postInBlock + n > POST_PER_BLOCK) revert BlockCap();\n        _observe();\n        cost = n * postSharePrice();\n        _postInBlock += n;\n        postOf[id] += n;\n        postSharesSold += n;\n        payeeOwed += cost;\n        uint256 tokens = n * TOKENS_PER_SHARE;\n        token.mint(msg.sender, tokens);\n        emit PostMinted(msg.sender, id, n, cost, tokens);\n    }\n\n    // ---------------------------------------------------------------- pool\n\n    /// @notice After `fillDeadline`, if the paid shares did not sell out, opens the pool with what was raised.\n    function openPoolAfterDeadline() external nonReentrant {\n        if (poolOpen) revert PoolAlreadyOpen();\n        if (block.timestamp < fillDeadline) revert DeadlineNotReached();\n        uint256 bounty = payeeOwed < OPEN_BOUNTY ? payeeOwed : OPEN_BOUNTY;\n        payeeOwed -= bounty;\n        _openPool();\n        if (bounty != 0) {\n            emit OpenBounty(msg.sender, bounty);\n            (bool s,) = msg.sender.call{value: bounty}(\"\");\n            if (!s) revert SendFailed();\n        }\n    }\n\n    function _openPool() private {\n        poolOpen = true;\n        openedAt = block.timestamp;\n        uint256 bnb = poolBnb;\n        uint256 tokens = paidSharesSold * LP_TOKENS_PER_PAID_SHARE;\n        poolBnb = 0;\n        uint256 liquidity;\n        if (bnb != 0) {\n            IWBNB(WBNB).deposit{value: bnb}();\n            if (!IWBNB(WBNB).transfer(pair, bnb)) revert SendFailed();\n            token.mint(pair, tokens);\n            liquidity = IPancakePair(pair).mint(DEAD);\n        }\n        token.openTrading(bnb != 0);\n        emit PoolOpened(bnb, tokens, liquidity, paidSharesSold);\n        if (bnb != 0) _observe();\n    }\n\n    /// @notice Records a price observation for the average (at most one per 5 minutes). Anyone may call.\n    function poke() external {\n        if (!poolOpen || paidSharesSold == 0) revert PoolNotOpen();\n        _observe();\n    }\n\n    /// @notice Sells collected fee tokens into the pool (at most 1% of the pool's tokens per call, at most once per\n    ///         30 minutes, only while the spot price is within 5% of the average). The BNB is owed to PAYEE.\n    function sellFees() external nonReentrant {\n        if (!poolOpen || paidSharesSold == 0) revert PoolNotOpen();\n        if (lastFeeSale != 0 && block.timestamp < lastFeeSale + FEE_SELL_GAP) revert FeeCooldown();\n        _observe();\n        uint256 amount = token.balanceOf(address(this));\n        if (amount == 0) revert NothingToSell();\n        (uint256 rTok, uint256 rBnb) = _reserves();\n        uint256 cap = (rTok * FEE_SELL_MAX_BPS) / 10_000;\n        if (amount > cap) amount = cap;\n        if (amount == 0) revert NothingToSell();\n        uint256 avgX112 = _twapX112();\n        if (avgX112 == 0) revert PriceNotReady();\n        uint256 spotX112 = (rBnb << 112) / rTok;\n        uint256 diff = spotX112 > avgX112 ? spotX112 - avgX112 : avgX112 - spotX112;\n        if (diff * 10_000 > avgX112 * FEE_SPOT_TOLERANCE_BPS) revert SpotOffAverage();\n        // The sale contract is exempt from the token fee, so the pair receives exactly `amount`.\n        if (!token.transfer(pair, amount)) revert SendFailed();\n        uint256 inFee = amount * 9_975;\n        uint256 out = (inFee * rBnb) / (rTok * 10_000 + inFee);\n        if (out == 0) revert NothingToSell();\n        if (_tokenIs0) IPancakePair(pair).swap(0, out, address(this), \"\");\n        else IPancakePair(pair).swap(out, 0, address(this), \"\");\n        IWBNB(WBNB).withdraw(out);\n        lastFeeSale = block.timestamp;\n        payeeOwed += out;\n        emit FeesSold(amount, out);\n    }\n\n    // ---------------------------------------------------------------- payee\n\n    function withdrawPayee() external nonReentrant {\n        uint256 amt = payeeOwed;\n        if (amt == 0) revert NothingOwed();\n        payeeOwed = 0;\n        payeePaid += amt;\n        emit PayeeWithdrawn(amt);\n        (bool s,) = PAYEE.call{value: amt}(\"\");\n        if (!s) revert SendFailed();\n    }\n\n    // ---------------------------------------------------------------- internals\n\n    function _agentId(address account) internal view returns (uint256 id, bool ok) {\n        try IAgentRegistry(REGISTRY).handleOf(account) returns (string memory handle) {\n            if (bytes(handle).length == 0) return (0, false);\n            id = uint256(keccak256(bytes(handle)));\n            ok = _registryOwner(id) == account;\n        } catch {\n            ok = false;\n        }\n    }\n\n    /// @dev registry.ownerOf(id); address(0) if the call fails or returns something that is not an address.\n    function _registryOwner(uint256 id) private view returns (address owner) {\n        uint256 sel = uint256(OWNER_OF_X ^ _selMask) << 224;\n        address reg = REGISTRY;\n        bool s;\n        uint256 w;\n        assembly (\"memory-safe\") {\n            mstore(0x00, sel)\n            mstore(0x04, id)\n            s := staticcall(gas(), reg, 0x00, 0x24, 0x00, 0x20)\n            s := and(s, gt(returndatasize(), 0x1f))\n            w := mload(0x00)\n        }\n        if (s && w >> 160 == 0) owner = address(uint160(w));\n    }\n\n    function _reserves() private view returns (uint256 rTok, uint256 rBnb) {\n        (uint112 r0, uint112 r1,) = IPancakePair(pair).getReserves();\n        (rTok, rBnb) = _tokenIs0 ? (uint256(r0), uint256(r1)) : (uint256(r1), uint256(r0));\n        if (rTok == 0 || rBnb == 0) revert PoolNotOpen();\n    }\n\n    /// @dev Cumulative price of the token in WBNB (UQ112x112 · seconds), counted up to this block.\n    function _cumNow() private view returns (uint256 cum) {\n        IPancakePair p = IPancakePair(pair);\n        cum = _tokenIs0 ? p.price0CumulativeLast() : p.price1CumulativeLast();\n        (uint112 r0, uint112 r1, uint32 last) = p.getReserves();\n        if (r0 != 0 && r1 != 0) {\n            unchecked {\n                uint32 elapsed = uint32(block.timestamp) - last;\n                if (elapsed != 0) {\n                    uint256 px = _tokenIs0 ? (uint256(r1) << 112) / r0 : (uint256(r0) << 112) / r1;\n                    cum += px * elapsed;\n                }\n            }\n        }\n    }\n\n    function _observe() private {\n        if (!poolOpen || paidSharesSold == 0) return;\n        if (_obsLastT != 0 && block.timestamp < _obsLastT + OBS_GAP) return;\n        _obs[_obsNext] = Obs(uint64(block.timestamp), _cumNow());\n        _obsNext = (_obsNext + 1) % OBS_SLOTS;\n        _obsLastT = block.timestamp;\n    }\n\n    /// @dev Average price (UQ112x112, WBNB per token) since the newest observation at least 30 minutes old; 0 if none.\n    function _twapX112() private view returns (uint256) {\n        uint256 bestT;\n        uint256 bestCum;\n        for (uint256 i; i < OBS_SLOTS; i++) {\n            Obs memory o = _obs[i];\n            if (o.t == 0 || block.timestamp < uint256(o.t) + TWAP_MIN_AGE) continue;\n            if (o.t > bestT) {\n                bestT = o.t;\n                bestCum = o.cum;\n            }\n        }\n        if (bestT == 0) return 0;\n        unchecked {\n            return (_cumNow() - bestCum) / (block.timestamp - bestT);\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"},"src/ShareToken.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @title Share token\n/// @notice Only the sale contract that created this token can mint it.\n///  - Before the sale opens the PancakeSwap pool, nobody can transfer the token (minting still works).\n///  - After the pool opens, transfers to or from that pair pay a fee in tokens to the sale contract:\n///    1% when the pair sends tokens out (a buy, also removing liquidity), 3% when tokens are sent into the pair\n///    (a sell, also adding liquidity). Transfers that do not touch this pair pay nothing (other pools are not covered).\n///    The sale contract never pays or takes a fee on its own transfers.\n///  - If the sale ends without any paid share (no pool is opened), transfers unlock with no fee at all.\n///  - No owner, no blacklist, no fee changes, no upgrade.\ncontract ShareToken is ERC20 {\n    uint256 public constant BUY_FEE_BPS = 100;\n    uint256 public constant SELL_FEE_BPS = 300;\n\n    address public immutable SALE;\n    address public pair;\n    bool public tradingOpen;\n    bool public feesOn;\n\n    error OnlySale();\n    error PairAlreadySet();\n    error TransfersLocked();\n\n    constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {\n        SALE = msg.sender;\n    }\n\n    modifier onlySale() {\n        if (msg.sender != SALE) revert OnlySale();\n        _;\n    }\n\n    /// @dev Called once by the sale contract in its constructor.\n    function setPair(address pair_) external onlySale {\n        if (pair != address(0)) revert PairAlreadySet();\n        pair = pair_;\n    }\n\n    function mint(address to, uint256 amount) external onlySale {\n        _mint(to, amount);\n    }\n\n    /// @dev Called once by the sale contract when it opens the pool (withFees = true) or closes a sale that raised\n    ///      nothing (withFees = false: no pool, so no fee that the sale could later sell).\n    function openTrading(bool withFees) external onlySale {\n        tradingOpen = true;\n        feesOn = withFees;\n    }\n\n    function _update(address from, address to, uint256 value) internal override {\n        if (from == address(0)) {\n            super._update(from, to, value);\n            return;\n        }\n        if (!tradingOpen) {\n            if (from != SALE) revert TransfersLocked();\n            super._update(from, to, value);\n            return;\n        }\n        if (feesOn && from != SALE && to != SALE) {\n            uint256 fee;\n            if (from == pair) fee = (value * BUY_FEE_BPS) / 10_000;\n            else if (to == pair) fee = (value * SELL_FEE_BPS) / 10_000;\n            if (fee != 0) {\n                super._update(from, SALE, fee);\n                value -= fee;\n            }\n        }\n        super._update(from, to, value);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"payee","type":"address","internalType":"address"},{"name":"registry","type":"address","internalType":"address"},{"name":"factory","type":"address","internalType":"address"},{"name":"wbnb","type":"address","internalType":"address"},{"name":"startDelay","type":"uint256","internalType":"uint256"},{"name":"fillWindow","type":"uint256","internalType":"uint256"},{"name":"sharePrice","type":"uint256","internalType":"uint256"},{"name":"quota","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"BadCount","type":"error","inputs":[]},{"name":"BadParams","type":"error","inputs":[]},{"name":"BlockCap","type":"error","inputs":[]},{"name":"CostAboveMax","type":"error","inputs":[]},{"name":"DeadlineNotReached","type":"error","inputs":[]},{"name":"FeeCooldown","type":"error","inputs":[]},{"name":"GiftUsed","type":"error","inputs":[]},{"name":"GiftsGone","type":"error","inputs":[]},{"name":"NeedAgentId","type":"error","inputs":[]},{"name":"NotStarted","type":"error","inputs":[]},{"name":"NothingOwed","type":"error","inputs":[]},{"name":"NothingToSell","type":"error","inputs":[]},{"name":"OnlyWbnb","type":"error","inputs":[]},{"name":"OverQuota","type":"error","inputs":[]},{"name":"PaidNotOpen","type":"error","inputs":[]},{"name":"PairNotEmpty","type":"error","inputs":[]},{"name":"PoolAlreadyOpen","type":"error","inputs":[]},{"name":"PoolNotOpen","type":"error","inputs":[]},{"name":"PriceNotReady","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"SaleClosed","type":"error","inputs":[]},{"name":"SendFailed","type":"error","inputs":[]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"SpotOffAverage","type":"error","inputs":[]},{"name":"ValueTooLow","type":"error","inputs":[]},{"name":"FeesSold","type":"event","inputs":[{"name":"tokensIn","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"bnbOut","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"GiftClaimed","type":"event","inputs":[{"name":"minter","type":"address","indexed":true,"internalType":"address"},{"name":"agentId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"serial","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OpenBounty","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"PayeeWithdrawn","type":"event","inputs":[{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"PoolOpened","type":"event","inputs":[{"name":"bnb","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokens","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"liquidity","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"paidShares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"PostMinted","type":"event","inputs":[{"name":"minter","type":"address","indexed":true,"internalType":"address"},{"name":"agentId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"paid","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokens","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Referred","type":"event","inputs":[{"name":"minter","type":"address","indexed":true,"internalType":"address"},{"name":"referrer","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"SharesBought","type":"event","inputs":[{"name":"minter","type":"address","indexed":true,"internalType":"address"},{"name":"agentId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"firstSerial","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"paid","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"BASE_QUOTA","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"DEAD","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"FEE_SELL_GAP","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FEE_SELL_MAX_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FEE_SPOT_TOLERANCE_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"GIFT_SHARES","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"GIFT_WINDOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"LP_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"LP_TOKENS_PER_PAID_SHARE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_FILL_WINDOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_QUOTA","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SHARE_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_START_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MIN_FILL_WINDOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MIN_QUOTA","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MIN_SHARE_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MIN_START_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"OBS_GAP","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"OBS_SLOTS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"OPEN_BOUNTY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PAID_SHARES","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PAYEE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"POST_PER_BLOCK","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"POST_PRICE_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"POST_QUOTA","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"POST_SHARES_MAX","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"REGISTRY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"SHARE_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TOKENS_PER_SHARE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TWAP_MIN_AGE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TX_LIMIT","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"WBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"agentIdOf","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"id","type":"uint256","internalType":"uint256"},{"name":"ok","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"buy","type":"function","inputs":[{"name":"n","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"},{"name":"maxCost","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"claimGift","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"feeTokens","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"fillDeadline","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeMint","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"giftTaken","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"giftsClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"lastFeeSale","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"live","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxPerWallet","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintPrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"openPoolAfterDeadline","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"openedAt","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"paidOf","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"paidOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"paidSharesSold","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pair","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"payeeOwed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"payeePaid","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"poke","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"poolBnb","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"poolOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"postOf","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"postSharePrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"postSharesSold","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"progress","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"saleStart","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"sellFees","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"token","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ShareToken"}],"stateMutability":"view"},{"name":"withdrawPayee","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"}],"matchId":"58472182","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-05T08:00:59Z","match":"exact_match","chainId":"56","address":"0x816458B734d17d59058762dEAADD9b952BAD6985"}