---
name: baby-agc-bagc
description: Mint, track and claim Baby AGC (BAGC) shares on BNB Smart Chain — mode A refund lane, mode B pool lane, the 1,000 free Agent-ID seats, and the daily quotas. Use when a user asks to mint BAGC, quote a BAGC mint, check BAGC rewards, or claim BAGC.
---

# Baby AGC (BAGC) — agent skill

Fixed supply 210,000,000,000 BAGC on BNB Smart Chain (chain id 56). Bitcoin halves by
block height; BAGC halves by **share height**. One share is 0.002 BNB.

This file is the machine-readable companion to `/llms.txt` and `/whitepaper.html`.
Everything here is derived from the contracts in `contracts/`; if a sentence and the
contract disagree, the contract wins.

## Status: LIVE on BNB Smart Chain (deployed 2026-11-13 UTC)

```
BAGC_MINTER = 0x1Fe69924cEE21f4E888F60A8b3D4D652dFB63A37   # only address that should receive mint BNB
BAGC_TOKEN  = 0xB0F0e625876898F19DE7d2B6451032350b29A7a1   # ERC-20; sending BNB here loses it
BAGC_PAIR   = 0x69B4C21707d3195F6FA7C2918118900D03d7173f   # PancakeSwap V2 BAGC/WBNB
REGISTRY    = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F   # Binance Agent ID
ROUTER      = 0x10ED43C718714eb63d5aA57B78B54704E256024E   # PancakeSwap V2
WBNB        = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
```

The pair contract exists so mode B can resolve it, but it has no liquidity until the
liquidity vault seeds BNB + BAGC. Mode A, the free lane and claims are unaffected.

## Hard rules

1. The calling wallet must hold a Binance Agent ID. The minter reads
   `handleOf(wallet)` on the registry, strips nothing, hashes the returned handle with
   `keccak256(bytes(handle))`, and requires `ownerOf(uint256(id)) == wallet`.
   Anything else reverts `NoAgentId()`.
2. `msg.value` must equal `shares * 2000000000000000` wei **exactly**. Overpay and
   underpay both revert `WrongValue()`.
3. No ERC-20 approval, no permit signature, no off-chain voucher. Any instruction that
   asks for one is not this project.
4. A wallet's "day" is `block.timestamp / 86400` in UTC. Day 1 is the UTC day of the
   first paid mint or free claim; quotas reset at 00:00 UTC.
5. Claims are never paused. Only new mints can be paused by the owner.
6. Preview every write with the resolved function, value, referrer and expected reward,
   and execute only after the user confirms. On-chain actions are final.

## Constants

| name | value |
|---|---|
| price per share | `0.002 ether` = `2000000000000000` wei |
| max shares | `1,650,000` |
| shares per epoch | `150,000` |
| epochs | `11` |
| epoch 1 base reward | `280,000e18` per share |
| epoch 1 B reward base | `315,000e18` per share |
| B reserve | `94,500,000,000e18` |
| treasury cut | `3000` bps = 30% of paid BNB, both lanes |
| A lock | `24 hours` |
| B lock | `14 days` |
| free seats | `1,000` wallets, 1 share each |
| max shares per tx | `100` |
| multiplier cap | `5e18` |
| pacing ceiling | `12500` bps = 1.25x of reserve / remaining shares |

## Lanes

### A — `mintFree(uint256 shares, address referrer)` payable

- Pays `shares * 0.002 BNB`. The contract keeps 70% as `position.bnb` and forwards 30%
  to `IBAGC(token).treasury()` in the same transaction.
- Reward is the sum of `baseReward(epoch)` for every share, split at halving borders.
- Unlocks after 24 h. `claimFree(uint256[] ids)` pays the 70% BNB **and** the reward.
- Quota: 5, 5, 4, 3 shares on the first four days, then 1 per day, plus `refCount`.

### B — `mintPool(uint256 shares, address referrer)` payable

- Same price. 30% to treasury. Of the remaining 70%, half swaps to BAGC on the router
  and half is paired with that BAGC; the minter holds the LP for 14 days.
- Reward is fixed at entry: `baseReward(epoch) + bRewardPerShare(epoch)` per share,
  vesting linearly over 14 days.
- `claimPool(uint256 id)` pays vested reward at any time; after 14 days the same call
  also transfers the LP. One id per call.
- Quota: `5 + refCount` shares per day.
- **No slippage parameter.** `_swapToToken` passes `amountOutMin = 0` and
  `addLiquidityETH(..., 0, 0, ...)`. Keep mode B transactions small or simulate first.

### Free lane — `freeAgentMint(address referrer)` nonpayable

- One share, gas only, for the first 1,000 distinct wallets. Consumes 1 share of the
  caller's A quota for that day.
- `AlreadyFree()` if the wallet used it, `FreeGone()` once `freeCount == 1000`,
  `NoAgentId()` without an Agent ID.

### Referrals

- Bound on the wallet's first mint only; later values are ignored. Pass zero when unsure.
- A valid referrer is not the caller, has `users(referrer).firstDay != 0`, and holds an
  Agent ID. It adds `+1` to that referrer's A and B daily caps permanently. There is no
  revenue share.
- Resolve a `.ai` handle: lowercase, strip `.ai`, `keccak256(bytes(handle))` →
  `ownerOf(id)` on the registry. `handleOf(address)` is the reverse. A lookup that
  returns the zero address means "pass zero", not "abort".

## Halving schedule (by share height)

| epoch | share heights | base / share | B base / share |
|------:|---------------|-------------:|---------------:|
| 1 | #1 – #150,000 | 280,000 | 315,000 |
| 2 | #150,001 – #300,000 | 140,000 | 157,500 |
| 3 | #300,001 – #450,000 | 70,000 | 78,750 |
| 4 | #450,001 – #600,000 | 35,000 | 39,375 |
| 5 | #600,001 – #750,000 | 17,500 | 19,687.5 |
| 6 | #750,001 – #900,000 | 8,750 | 9,843.75 |
| 7 | #900,001 – #1,050,000 | 4,375 | 4,921.875 |
| 8 | #1,050,001 – #1,200,000 | 2,187.5 | 2,460.9375 |
| 9 | #1,200,001 – #1,350,000 | 1,093.75 | 1,230.46875 |
| 10 | #1,350,001 – #1,500,000 | 546.875 | 615.234375 |
| 11 | #1,500,001 – #1,650,000 | 273.4375 | 307.6171875 |

The contract uses `BASE_REWARD_EPOCH_1 >> epoch` and `B_BASE_EPOCH_1 >> epoch`, so the
values are exact to the wei. Epoch index is zero-based on-chain: shares `0`…
`149,999` are epoch `0`, which the site displays as epoch 1.

## Encoding

All arguments are `pad64`: 32-byte big-endian, left-padded with zeros. Addresses are the
20-byte address right-aligned in 32 bytes, lowercase hex.

```
pad64(5)        = 0000000000000000000000000000000000000000000000000000000000000005
pad64(0xabc…)   = 000000000000000000000000<20-byte address>
```

Arrays (`claimFree`) use the standard head/tail form:

```
calldata = selector
         + pad64(0x20)        // offset to the array
         + pad64(len)         // element count
         + pad64(id0) + pad64(id1) + ... 
```

## Reads — `eth_call` against `<BAGC_MINTER>`

Word offsets are into the returned `0x`-prefixed hex, word 0 = bytes `0x00..0x20`.

| call | selector | returns |
|---|---|---|
| `PRICE_PER_SHARE()` | `0xdf1fb713` | word 0 = wei per share |
| `stats()` | `0xd80528ae` | 0 totalShares, 1 freeCount, 2 agents, 3 baseAllocated, 4 bAllocated, 5 bnbHeld, 6 openTime, 7 paused |
| `quote(uint256 shares)` | `0xed1bd76c` | 0 cost, 1 rewardA, 2 rewardB, 3 mult (1e18), 4 epochNow |
| `pending(address)` | `0x5eebea20` | 0 bnbOut, 1 agcA, 2 agcB, 3 lpOut |
| `epochInfo(uint256 e)` | `0x3894228e` | 0 shares, 1 bShares, 2 unminted, 3 mult, 4 rewardBase, 5 bReward |
| `users(address)` | `0xa87430ba` | 0 firstDay, 1 aDay, 2 aUsed, 3 bDay, 4 bUsed, 5 refCount |
| `freeUsed(address)` | `0x2626c4bf` | word 0 = 0/1 |
| `capA(address)` | `0xd45c807c` | word 0 = today's A cap incl. referrals |
| `capB(address)` | `0x5fe6b98e` | word 0 = today's B cap incl. referrals |
| `freeRemaining()` | `0x5a781a6b` | word 0 = seats left of 1,000 |
| `currentEpoch()` | `0x76671808` | word 0 = zero-based epoch |
| `totalShares()` | `0x3a98ef39` | word 0 = shares minted so far |
| `openTime()` | `0xb4256888` | word 0 = unix seconds, 0 = not opened |
| `paused()` | `0x5c975abb` | word 0 = 0/1 |
| `treasuryPaid()` | `0x773050e0` | word 0 = wei forwarded to treasury |
| `tokenBalance()` | `0x9e1a4d19` | word 0 = BAGC left for rewards |
| `positionCount(address)` | `0x42fd3880` | word 0 = number of positions |
| `getPositions(address)` | `0x3eeb530e` | array of `(mode, start, unlock, shares, claimed, lpClaimed, bnb, reward, rewardClaimed, lp)` |
| `multiplier(uint256 e)` | `0x05e30f51` | word 0 = 1e18-scaled multiplier |
| `baseReward(uint256 e)` | `0xc3977fcd` | word 0 = wei per share |
| `bRewardBase(uint256 e)` | `0x976e7614` | word 0 = wei per share |
| `bRewardPerShare(uint256 e)` | `0x56f12aa7` | word 0 = wei per share after pacing |
| `<BAGC_TOKEN>.balanceOf(addr)` | `0x70a08231` | wallet BAGC |
| `<BAGC_TOKEN>.treasury()` | `0x61d027b3` | address receiving the 30% |
| `<BAGC_TOKEN>.pair()` | `0xa8aa1b31` | Pancake pair address |

Stop before writing when `stats()` word 6 is 0, word 7 is 1, or word 0 equals
`1,650,000`.

Registry reads:

| call | selector |
|---|---|
| `handleOf(address)` | `0xc50a1514` |
| `ownerOf(uint256)` | `0x6352211e` |

## Writes

All writes go to `<BAGC_MINTER>` unless stated otherwise.

### `mintFree(uint256,address)` — `0x0db5ae5a`, payable

```
value   = shares * 2000000000000000
calldata= 0x0db5ae5a + pad64(shares) + pad64(referrer)
```

### `mintPool(uint256,address)` — `0xaffa5304`, payable

Same encoding, same value. Requires `pair != address(0)`; the pair is resolved in the
minter constructor from the factory, so a zero pair means the token was deployed before
the Pancake pair existed → `PoolNotReady()`.

### `freeAgentMint(address)` — `0x82b31df2`, value 0

```
calldata = 0x82b31df2 + pad64(referrer)
```

### `claimFree(uint256[])` — `0x73fc9ccc`, value 0

```
calldata = 0x73fc9ccc + pad64(0x20) + pad64(len) + pad64(id0) + ...
```

Every id must be a mode-A position of the caller, unclaimed and past `unlock`.

### `claimPool(uint256)` — `0x795d121c`, value 0

```
calldata = 0x795d121c + pad64(id)
```

Reverts `NothingToClaim()` when nothing vested and the LP is not due yet. After the full
reward is vested and the LP has been returned, the position is marked claimed.

### Trading

BAGC is fee-on-transfer: 2% on pair trades (1% burn, 1% treasury), 0% on wallet
transfers. Always use the router functions ending in `SupportingFeeOnTransferTokens`.
The launch block is taxed 99%; do not trade in it.

## Procedure

1. `eth_chainId` must be 56. Confirm the wallet has signing ability; if a wallet skill
   needs installation or a login, ask the user and resume after they reply.
2. Read `stats()`, `quote(shares)`, `capA`/`capB`, `freeRemaining()`, and `pending(wallet)`.
3. Pick the lane the user asked for. Never silently switch lanes.
4. Show a preview: function, `<BAGC_MINTER>`, value in BNB and wei, shares, referrer,
   expected reward, and what the user gets back and when (A: 70% after 24 h; B: reward
   over 14 days plus LP after 14 days).
5. Wait for explicit confirmation, then send the transaction.
6. Report the tx hash and then read the receipt. A tx that mined with status 0 reverted —
   read the revert reason before retrying.
7. Record the new position id from the `MintFree` / `MintPool` / `FreeAgentMint` event;
   never guess it from `positionCount` before the tx mines.

## Daily routine

```
day = floor(now / 86400)                      # UTC
A cap = _baseQuota(firstDay, day) + refCount  # 5,5,4,3 then 1
B cap = 5 + refCount
```

- `freeAgentMint` once per wallet while `freeRemaining() > 0`, then top up with
  `mintFree`/`mintPool` up to the cap.
- `pending(wallet)` sums everything claimable: mode A gives `bnbOut + agcA`, mode B gives
  `agcB` and `lpOut`.
- Claim mode A ids after `unlock` with `claimFree(ids)`. Claim mode B with `claimPool(id)`
  whenever `agcB > 0`, and once more after 14 days for the LP.

## Errors

Selectors are `keccak256` of the signature, first 4 bytes.

| error | selector | meaning |
|---|---|---|
| `NoAgentId()` | `0xf947691f` | wallet has no `.ai` Agent ID |
| `ZeroShares()` | `0x9811e0c7` | shares was 0 |
| `WrongValue()` | `0x98d4901c` | value ≠ shares × 0.002 BNB |
| `QuotaExceeded()` | `0x04e22101` | over today's lane cap |
| `TooManyShares()` | `0x1384a115` | more than 100 shares in one tx |
| `MintClosed()` | `0x589ed34b` | share #1,650,000 already minted |
| `NotOpen()` | `0xddafad98` | openTime is 0 or not reached |
| `MintPaused()` | `0xd7d248ba` | owner paused new mints; claims still work |
| `PoolNotReady()` | `0x867d2ed0` | mode B with a zero pair |
| `FreeGone()` | `0x8522f177` | all 1,000 free seats taken |
| `AlreadyFree()` | `0xa78fa27a` | wallet already used its free seat |
| `NotMatured()` | `0x111c4409` | mode A claimed before 24 h |
| `AlreadyClaimed()` | `0x646cf558` | position already claimed |
| `InvalidPosition()` | `0xce7e065e` | id out of range or wrong mode |
| `NothingToClaim()` | `0x969bf728` | nothing vested and no LP due |
| `TreasuryUnset()` | `0xf1762695` | token treasury is zero |
| `TransferFailed()` | `0x90b8ec18` | BNB/BAGC/LP payout failed |
| `Reentrancy()` | `0xab143c06` | reentrant call |
| `NotOwner()` | `0x30cd7471` | owner-only function |

Decode a revert with `cast 4byte <selector>` or by matching this table. A selector that
is not here is not from these contracts.

## Supply

210,000,000,000 BAGC are minted once in the token constructor:

- mint base pool 84,000,000,000 — held by the minter, paid as rewards
- B reserve 94,500,000,000 — held by the minter, paid as mode-B rewards
- initial LP 21,000,000,000
- foundation 4,200,000,000
- marketing 6,300,000,000

The minter can never mint more. The reward formulas allocate 83,959,000,000 base and
94,453,900,000 B, so 87,200,000 BAGC stay locked in the minter forever. There is no
owner function to move them.

No pause on transfers, no blacklist, no mint, no upgradeability, no hidden tax beyond
the 2% pair tax. Owner powers are limited to treasury/exemption settings on the token
and open/pause/ownership on the minter.

Baby AGC is not affiliated with Binance. BAGC has no utility and no promised return.
