> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cdp.coinbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Query B20 Events

> Query Base B20 native token events with the SQL API, including transfers, memos, mints, policy updates, and factory deployments.

The [B20 native token standard](https://docs.base.org/base-chain/specs/upgrades/beryl/b20) ships with the Base Beryl upgrade. CDP SQL API indexes **all B20-related events** on Base Mainnet and Base Sepolia so you can query them with standard SQL—no custom indexer required.

<Note>
  B20 data is available once the Beryl upgrade activates on each network:

  | Network      | Activation                 |
  | ------------ | -------------------------- |
  | Base Sepolia | June 18, 2026              |
  | Base Mainnet | June 25, 2026 at 18:00 UTC |
</Note>

## Where B20 data lives

B20 events are decoded into the existing [`base.events`](/data/sql-api/schema#base-events) table (or `base_sepolia.events` on testnet). Each row uses the same schema as other decoded logs: `event_name`, `event_signature`, `parameters`, `address`, `block_timestamp`, and more.

Query B20 activity by filtering on:

* **`event_signature`** — the canonical event ABI (preferred over `event_name` for performance; put this first in `WHERE` clauses for best query performance)
* **`address`** — a specific B20 token contract, or the singleton B20 Factory / Policy Registry contract when querying factory or policy-registry events

For token-level events, filter on the token's address once you know which B20 you are tracking. B20 token addresses are deterministic and share a recognizable prefix derived from the B20 address scheme.

## Indexed event types

### B20 token events

These events are emitted by individual B20 token precompiles:

| Event               | Signature                                   |
| ------------------- | ------------------------------------------- |
| Transfer            | `Transfer(address,address,uint256)`         |
| Approval            | `Approval(address,address,uint256)`         |
| Memo                | `Memo(address,bytes32)`                     |
| BurnedBlocked       | `BurnedBlocked(address,address,uint256)`    |
| RoleGranted         | `RoleGranted(bytes32,address,address)`      |
| RoleRevoked         | `RoleRevoked(bytes32,address,address)`      |
| RoleAdminChanged    | `RoleAdminChanged(bytes32,bytes32,bytes32)` |
| LastAdminRenounced  | `LastAdminRenounced(address)`               |
| Paused              | `Paused(address,uint8[])`                   |
| Unpaused            | `Unpaused(address,uint8[])`                 |
| PolicyUpdated       | `PolicyUpdated(bytes32,uint64,uint64)`      |
| SupplyCapUpdated    | `SupplyCapUpdated(address,uint256,uint256)` |
| ContractURIUpdated  | `ContractURIUpdated()`                      |
| NameUpdated         | `NameUpdated(address,string)`               |
| SymbolUpdated       | `SymbolUpdated(address,string)`             |
| EIP712DomainChanged | `EIP712DomainChanged()`                     |

Asset-variant tokens also emit:

| Event                | Signature                                    |
| -------------------- | -------------------------------------------- |
| MultiplierUpdated    | `MultiplierUpdated(uint256)`                 |
| ExtraMetadataUpdated | `ExtraMetadataUpdated(string,string)`        |
| Announcement         | `Announcement(address,string,string,string)` |
| EndAnnouncement      | `EndAnnouncement(string)`                    |

### B20 Factory events

Token creation events are emitted by the singleton B20 Factory precompile:

| Event      | Signature                                             |
| ---------- | ----------------------------------------------------- |
| B20Created | `B20Created(address,uint8,string,string,uint8,bytes)` |

### Policy Registry events

B20 transfer policies are managed through the Policy Registry precompile at `0x8453000000000000000000000000000000000002`. Query these events with that address and the matching `event_signature`:

| Event              | Signature                                         |
| ------------------ | ------------------------------------------------- |
| PolicyCreated      | `PolicyCreated(uint64,address,uint8)`             |
| PolicyAdminStaged  | `PolicyAdminStaged(uint64,address,address)`       |
| PolicyAdminUpdated | `PolicyAdminUpdated(uint64,address,address)`      |
| AllowlistUpdated   | `AllowlistUpdated(uint64,address,bool,address[])` |
| BlocklistUpdated   | `BlocklistUpdated(uint64,address,bool,address[])` |

For the full B20 interface specification, see the [Base Standard Library](https://github.com/base/base-std).

## Example queries

<Tip>
  Try these in the [SQL Playground](https://portal.cdp.coinbase.com/onchain-tools/sql-api) before integrating programmatically.
</Tip>

### Recent B20 token transfers

Replace `{token_address}` with the B20 token you are tracking:

```sql theme={null}
SELECT
  block_timestamp,
  transaction_hash,
  parameters['from'] AS from_address,
  parameters['to'] AS to_address,
  parameters['value'] AS amount
FROM base.events
WHERE event_signature = 'Transfer(address,address,uint256)'
  AND address = '{token_address}'
  AND action = 'added'
ORDER BY block_timestamp DESC
LIMIT 100;
```

### New B20 tokens created

Track deployments from the B20 Factory precompile at `0xB20f000000000000000000000000000000000000`:

```sql theme={null}
SELECT
  block_timestamp,
  transaction_hash,
  parameters['token'] AS token_address,
  parameters['name'] AS name,
  parameters['symbol'] AS symbol,
  parameters['decimals'] AS decimals
FROM base.events
WHERE event_signature = 'B20Created(address,uint8,string,string,uint8,bytes)'
  AND address = '0xB20f000000000000000000000000000000000000'
  AND action = 'added'
ORDER BY block_timestamp DESC
LIMIT 50;
```

### Transfers with payment memos

B20 memo operations emit a `Memo` event immediately after the primary operation event. Join adjacent logs in the same transaction:

```sql theme={null}
SELECT
  t.block_timestamp,
  t.transaction_hash,
  t.address AS token_address,
  t.parameters['from'] AS from_address,
  t.parameters['to'] AS to_address,
  t.parameters['value'] AS amount,
  m.parameters['memo'] AS memo
FROM base.events t
JOIN base.events m
  ON t.transaction_hash = m.transaction_hash
  AND m.address = t.address
  AND m.log_index = t.log_index + 1
WHERE t.event_signature = 'Transfer(address,address,uint256)'
  AND m.event_signature = 'Memo(address,bytes32)'
  AND t.address = '{token_address}'
  AND t.action = 'added'
  AND m.action = 'added'
ORDER BY t.block_timestamp DESC
LIMIT 100;
```

### Policy and compliance activity

Monitor when an issuer updates transfer policies on a token:

```sql theme={null}
SELECT
  block_timestamp,
  transaction_hash,
  address AS token_address,
  parameters['policyScope'] AS policy_scope,
  parameters['oldPolicyId'] AS old_policy_id,
  parameters['newPolicyId'] AS new_policy_id
FROM base.events
WHERE event_signature = 'PolicyUpdated(bytes32,uint64,uint64)'
  AND address = '{token_address}'
  AND action = 'added'
ORDER BY block_timestamp DESC
LIMIT 50;
```

## Query tips

Follow the [SQL API best practices](/data/sql-api/best-practices) when querying B20 data:

1. **Filter on indexed columns** — use `event_signature`, `address`, and `block_timestamp` in your `WHERE` clause.
2. **Scope to active logs** — add `action = 'added'` to exclude re-orged events, or aggregate by `log_id` if you need re-org-safe totals.
3. **Use network prefixes** — query `base_sepolia.events` on testnet and `base.events` on mainnet.
4. **Join memos by log index** — memo events follow their parent operation at `log_index + 1` within the same transaction and contract (`m.address = t.address`).

## Learn more

* [B20 specification](https://docs.base.org/base-chain/specs/upgrades/beryl/b20) — Base docs for the token standard
* [Accept B20 payments](https://docs.base.org/apps/guides/accept-b20-payments) — match payments to orders with onchain memos
* [Schema reference](/data/sql-api/schema) — full `base.events` column definitions
* [Quickstart](/data/sql-api/quickstart) — run your first SQL API query
