# How to verify whether a BREMO market exists yourself

This guide explains how to independently confirm whether a BREMO market exists
on Ethereum mainnet, and if one does, how to confirm the canonical pool address
so you never trade against an imposter pool. It is a companion to
[VERIFY.md](VERIFY.md), which covers the token supply itself.

It covers three venues, Uniswap V3, Uniswap V2 and Sushiswap V2, and at each
venue it checks BREMO against three quote tokens, WETH, USDC and USDT. Nine
lookups at Uniswap V3, since it has three fee tiers, and three at each V2
venue. That is the same scope the project's own automated check uses, so you
can hold this page to the same standard we hold ourselves to.

Checking more than one quote token is not padding. A pool is a pair, so a
BREMO/USDC pool is a completely different entry in the factory's mapping than a
BREMO/WETH pool, and asking only about WETH would return nothing while a
BREMO/USDC market traded in plain sight. Anyone can open a market without our
involvement, and someone selling fake BREMO has a reason to prefer a stablecoin
quote, because a dollar price reads to a buyer as a real listing.

That list is also the honest bound of this guide. Uniswap V4 is not checked
here and is not checked by our automated run either, so treat it as unchecked
rather than empty. The section on unchecked venues near the end explains why,
and what you can do about it.

Read this before you trade. Trading is irreversible.

## Status as of the last check

CORRECTED 2026-08-05. Everything in this section was true when it was written
and is now out of date, which is exactly the failure this document warns about
two sections below. A BREMO market now exists: a Uniswap v3 BREMO/WETH pool at
0x44c9D9761f8039cD0e17F040bF06b546b6f3933D, created and funded on
2026-07-31 by the wallet that deployed the token, holding
99,999.999999999985 BREMO against 0.000296248332821778 WETH when checked on
2026-08-05. The 0.05 and 1 percent v3 tiers, Uniswap V2 and Sushiswap V2 still
return the zero address. Do not read the paragraphs below as current. The live
answer, recomputed daily by chain/scripts/market-check.py, is published at
https://bremo.tech/market.json. The project publishes no price, promises no
return and does not encourage anyone to buy.

What this section said on 2026-07-26, kept because deleting it would hide the
fact that it went stale:

There was no BREMO market. That was verified against Ethereum mainnet on
2026-07-26 at block 25620327, and it is a read from the chain rather than an
assumption. It was checked across all three venues named above rather than
Uniswap V3 alone, and against all three quote tokens rather than WETH alone.
All fifteen combinations came back empty.

At Uniswap V3, the real factory answers normally on the free public endpoint
the project monitors, a positive control against a known pool passes on every
check, and asked about BREMO the factory returns the zero address on all three
fee tiers (0.05 percent, 0.3 percent, 1 percent) against each of WETH, USDC and
USDT. At Uniswap V2 and Sushiswap V2, each factory likewise passes its own
positive control and then returns the zero address for BREMO against each of
the same three quote tokens, so no pair exists at either. No empty unseeded
pair exists at any venue either.

The deployer wallet also holds far too little ETH gas to have seeded a pool.
Until a pool exists on-chain with real liquidity, BREMO cannot be bought or
sold anywhere, and anyone offering to sell you BREMO does not speak for the
project.

## How fresh is that, and what if this file is old

The date and block above are a floor, not a promise. They record when the check
was last run, not that nothing has changed since. Read them the way you would
read a timestamp on a bank balance.

This cuts both ways, and the second direction is the one people get wrong.

If this file is old and still says no market exists, do not use that line to
dismiss a real market. Anyone can create a pool at any time, without the
project's involvement or consent, and no wording in a document can prevent it.
A stale sentence here is not evidence about the current state of the chain.

If this file is old and something elsewhere claims a market exists, do not take
that on trust either. The chain settles the question and nothing else does.

So do not resolve it from this section at all. Resolve it from Ethereum, using
Method 1 below, which takes about a minute and needs nothing installed. Run the
positive control first in every case. A check that cannot prove it is pointed at
the right factory cannot tell you anything about BREMO, and a zero address from
a wrong address is not a real answer.

An earlier version of this section said the factory reported no contract code
on free public endpoints and that its answers could therefore not be trusted in
either direction. That was our own bug, not a property of the network, and the
correction below explains it in full. Free public endpoints are fine for this
check. What matters is that you ask the right address and prove it with a
control first.

The live page at https://bremo.tech/trade publishes the canonical pool address
the moment a pool is live and verified. This document explains how to check
that page's claim against the chain for yourself, rather than trusting it.

## The addresses you need

- BREMO ERC-20 token: `0x93CfAE1cfa7AAA1f7D4b8Af85697a600a8dAdC2C`
- WETH, quote token: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`
- USDC, quote token and also the control pair: `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`
- USDT, quote token: `0xdAC17F958D2ee523a2206206994597C13D831ec7`
- Uniswap V3 factory: `0x1F98431c8aD98523631AE4a59f267346ea31F984`
- Uniswap V2 factory: `0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f`
- Sushiswap V2 factory: `0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac`

Confirm the BREMO address against the token address printed on
https://bremo.tech/trade and on the transparency page. An imposter token with
a different address is the most common scam. The token symbol alone means
nothing; only the contract address is authoritative.

## Correction, 2026-07-24: check your factory address before you blame the node

An earlier version of this document told you that free public RPC endpoints
serve a degraded state in which the Uniswap V3 factory reports no contract
code, and it advised you to distrust free endpoints for this check. That was
wrong, and the correction is worth reading, because the same mistake is easy to
repeat.

The factory address that earlier version used ended in `31394F`. The real
mainnet Uniswap V3 factory address ends in `31F984`. Nothing is deployed at the
`31394F` address, so `eth_getCode` correctly returned `0x` for it and every
call against it returned nothing. The endpoints were healthy the entire time.
We were reading an empty address and blaming the messenger.

What settled it: on 2026-07-24, four independent endpoints all reported
`chainId` 1 at the same block, and on every one of them USDC, WETH, the Uniswap
V2 factory, the Uniswap V3 SwapRouter and the BREMO token all returned real
code, while only the `31394F` address was empty. A healthy node does not hide
one contract and show the rest. The correct factory address was then read from
the Uniswap V3 SwapRouter's own `factory()` getter, which is set at deployment
and cannot be edited.

The general lesson, which applies to your own verification too: if a contract
looks absent on several independent healthy endpoints, the address is far more
likely to be wrong than every node is to be broken.

The danger here is asymmetric and worth stating plainly. `getPool` returning
zero because you asked the wrong address does not prove there is no pool, and
it does not prove a published address is fake. It only proves you did not
actually ask the question. If you treat that zero as fact, you could wrongly
dismiss a genuine pool, or believe you verified something you did not.

Protect yourself by testing your setup against a known answer before you trust
it about BREMO:

- Prefer Method 1 (Etherscan), which reads canonical state through the block
  explorer.
- If you use a direct RPC call, run a positive control first. Ask the same
  factory for the well-known USDC/WETH 0.05 percent pool. It must return
  `0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640`. If it returns anything else,
  your factory address, your chain, or your endpoint is wrong, and no answer it
  gives you about BREMO means anything. The Method 2 code below does this for
  you. A control that must return a specific known value is a much stronger
  guard than merely checking that some code exists, which is what the earlier
  version did and why the bug survived as long as it did.

## Method 1: Etherscan, no tools required

1. Open the Uniswap V3 factory on Etherscan:
   https://etherscan.io/address/0x1F98431c8aD98523631AE4a59f267346ea31F984#readContract
2. Find the `getPool` function.
3. Enter the BREMO address, one quote token address from the list above (order
   does not matter), and a fee value:
   - `500` for the 0.05 percent tier
   - `3000` for the 0.3 percent tier
   - `10000` for the 1 percent tier
4. Click Query. If the result is
   `0x0000000000000000000000000000000000000000`, no pool exists on that tier.
   If it returns a real address, that is the pool the factory itself created
   for this exact token pair and fee. It cannot be faked, because only the
   factory can populate this mapping.
5. Compare the returned address to the one published on
   https://bremo.tech/trade. They must match exactly. If they do not, stop and
   do not trade.
6. Repeat steps 3 to 5 for the other two quote tokens. Three fee tiers times
   three quote tokens is nine queries at this venue. A zero for BREMO/WETH says
   nothing at all about BREMO/USDC, because they are separate entries in the
   factory's mapping.

## Method 2: A direct RPC call

Using any public Ethereum RPC (for example https://ethereum-rpc.publicnode.com)
and a library such as ethers.js:

```js
const { ethers } = require("ethers");
const provider = new ethers.JsonRpcProvider("https://ethereum-rpc.publicnode.com");
const FACTORY = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
const BREMO   = "0x93CfAE1cfa7AAA1f7D4b8Af85697a600a8dAdC2C";
const WETH    = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const USDT    = "0xdAC17F958D2ee523a2206206994597C13D831ec7";

// Positive control first. Ask the same factory for a pool whose address is
// already public and stable. If this does not come back exactly right, your
// factory address, chain, or endpoint is wrong, and nothing it tells you about
// BREMO is meaningful. This catches a wrong constant, which merely checking
// that some code exists does not.
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const EXPECTED_CONTROL_POOL = "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640";

const factoryProbe = new ethers.Contract(
  FACTORY,
  ["function getPool(address,address,uint24) view returns (address)"],
  provider
);
const control = await factoryProbe.getPool(USDC, WETH, 500);
if (control.toLowerCase() !== EXPECTED_CONTROL_POOL.toLowerCase()) {
  throw new Error(
    "Control check failed: expected " + EXPECTED_CONTROL_POOL + " but got " +
    control + ". Check the factory address and the chain before trusting any " +
    "getPool result, and do not read a zero answer as proof of no pool."
  );
}

const factory = new ethers.Contract(
  FACTORY,
  ["function getPool(address,address,uint24) view returns (address)"],
  provider
);
// Ask about every quote token, not just WETH. A pool is a pair, so BREMO/USDC
// is a different mapping entry than BREMO/WETH and a zero for one says nothing
// about the other. Anyone can open either without asking us.
const QUOTES = { WETH, USDC, USDT };

for (const [quote, quoteAddress] of Object.entries(QUOTES)) {
  for (const fee of [500, 3000, 10000]) {
    console.log(quote, fee, await factory.getPool(BREMO, quoteAddress, fee));
  }
}
```

Only once the control check above has passed is the result meaningful: a zero
address means no pool on that tier for that quote token, and a nonzero address
is the canonical pool for that pair and fee tier. Note that the bar is the control passing, not merely the
factory having code at it. Confirming that some code exists is the weaker test
that let the wrong-address bug survive, because a wrong address can still hold
a real but unrelated contract. You can then check the pool has real depth by
reading its `liquidity()` value; a pool that exists but reports zero liquidity
cannot be traded meaningfully. If the guard above throws, switch to Method 1 or a
reputable endpoint and try again. Never conclude anything from a degraded
endpoint.

## Method 3: Check the other venues, not just Uniswap V3

Uniswap V3 is not the whole of Ethereum. Opening a market is permissionless, so
anyone can create a BREMO pair at another venue at any time, without the
project's involvement and without our knowledge. This matters in both
directions. A zero answer from the V3 factory proves only that there is no V3
pool; on its own it is not proof that no market exists. And if a market ever
does open somewhere else, checking V3 alone would never show it to you.

So if what you want to know is whether a BREMO market exists at all, check the
other two venues as well. Uniswap V2 and Sushiswap V2 share the same interface,
`getPair`, which takes the two token addresses and no fee tier.

On Etherscan, no tools required, repeat these steps for each of the two V2
factory addresses listed above:

1. Open the factory address on Etherscan and go to Contract, then Read
   Contract.
2. Find the `getPair` function.
3. Enter the BREMO address and one quote token address (order does not matter)
   and click Query.
4. A result of `0x0000000000000000000000000000000000000000` means no pair
   exists at that venue for that pair. A real address means a pair exists, and
   you should then run Method 4 against it before trusting it, because an
   existing pair can still be empty.
5. Repeat for the other two quote tokens. Three queries per venue, six across
   the two V2 venues.

By direct RPC, with a control for each venue:

```js
const V2_FACTORIES = {
  uniswap_v2:   "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
  sushiswap_v2: "0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac"
};
const V2_FACTORY_ABI = ["function getPair(address,address) view returns (address)"];
const PAIR_ABI = [
  "function token0() view returns (address)",
  "function token1() view returns (address)"
];

// Verify each venue's control from first principles rather than against a
// hardcoded expected pair address. Ask the factory for USDC/WETH, then confirm
// the thing it handed back is nonzero, has contract code, and that its own
// token0/token1 really are USDC and WETH. Only then does its answer about
// BREMO mean anything.
async function controlPasses(factory) {
  const pair = await factory.getPair(USDC, WETH);
  if (pair === ethers.ZeroAddress) return false;
  if ((await provider.getCode(pair)) === "0x") return false;
  const p = new ethers.Contract(pair, PAIR_ABI, provider);
  const [t0, t1] = [await p.token0(), await p.token1()];
  const got = [t0.toLowerCase(), t1.toLowerCase()].sort().join(",");
  const want = [USDC.toLowerCase(), WETH.toLowerCase()].sort().join(",");
  return got === want;
}

for (const [name, address] of Object.entries(V2_FACTORIES)) {
  const factory = new ethers.Contract(address, V2_FACTORY_ABI, provider);
  if (!(await controlPasses(factory))) {
    console.log(name, "UNCHECKED: control failed, draw no conclusion");
    continue;
  }
  for (const [quote, quoteAddress] of Object.entries({ WETH, USDC, USDT })) {
    console.log(name, quote, await factory.getPair(BREMO, quoteAddress));
  }
}
```

Two things about that control are deliberate, and worth copying into your own
checks.

First, it proves the returned pair really is USDC/WETH instead of comparing
against an address written into the script. A mistyped constant is exactly the
failure that hid a broken Uniswap V3 check here for several cycles, as the
correction section above describes, and a control that derives its own answer
cannot fail that way.

Second, note what the loop does when a control fails: it prints UNCHECKED and
draws no conclusion, rather than reporting no market. This is the opposite of
how Method 2 treats an unverified run, and both are correct, because the risk
runs the other way in each case. When you are deciding whether to trade, an
unverified result must be read as no confirmed pool, because the danger is
trading against a market you never actually verified. When you are deciding
whether the statement "no market exists" is true, an unverified result must be
read as not established, because the danger is repeating a no-market claim on a
run that never checked. Never let a venue you failed to reach quietly count as
a venue that came back empty.

## What this guide does not check, and why we say so

The rule in the paragraph above applies to us as much as to you, so here is
where our own coverage stops.

Uniswap V4 is not checked, by this guide or by the project's automated run.
Treat it as unchecked, not as empty. Nothing here entitles anyone, including
us, to say that no BREMO market exists on V4.

The reason is structural rather than an oversight we are about to fix in an
afternoon. V3 and V2 pools can be enumerated because a pair plus a fee tier is
the whole key, so a fixed number of questions covers the venue completely. V4
holds all pools in a single contract and keys each one by a struct that
includes a hooks address, which is an arbitrary contract chosen freely by
whoever creates the pool. There is no bounded list of hooks addresses to
iterate, so there is no finite set of questions that proves absence the way
nine getPool calls do at V3. A check is still possible and worth building, but
only an honest partial one: query the standard no-hook combinations through the
singleton and read their state, then report exactly that and claim nothing
beyond it. Publishing that as though it settled V4 would be the same error this
guide warns about everywhere else.

Two practical consequences while it is outstanding. First, read every no-market
statement we publish as bounded by the venues and quote tokens named at the top
of this page. Second, if you are about to trade, absence of a check is not
evidence of absence of a pool, so verify the specific pool address you were
given using Method 4 rather than reasoning from any coverage claim, ours
included.

The same caution applies in the other direction to venues nobody has thought of
yet. Opening a market is permissionless everywhere. A guide can tell you how to
check the places we know about, and can tell you honestly where it stops, but
it can never hand you a complete list.

## Method 4: Confirm a live pool has real, tradeable liquidity

A pool address existing is not the same as a pool you can safely trade. Anyone
can create an empty Uniswap pool for any pair. An empty or near-empty pool has
no depth, and a single small trade can move its price by any amount, which is
how a lookalike market fools buyers. So once getPool returns a nonzero address,
confirm the pool is genuine and has depth before trusting it.

On Etherscan, no tools required:

1. Open the returned pool address on Etherscan and go to Contract, then Read
   Contract.
2. Read `token0` and `token1`. One must equal the BREMO token address and the
   other must equal the quote token you actually queried, both matching the
   addresses above exactly. If either differs, this is not the pool you asked
   for, and in particular do not accept a pool whose second token is some other
   token that merely looks like the one you wanted.
3. Read `fee`. It must equal the fee tier you queried (500, 3000, or 10000).
4. Read `liquidity`. A value of 0 means the pool has no depth and cannot be
   traded meaningfully, no matter what any page or listing claims.
5. Read `slot0` if you want the current pool state. A live pool returns a
   nonzero `sqrtPriceX96`.

By direct RPC, using the same guarded pattern as Method 2, once you have the
pool address:

```js
const pool = new ethers.Contract(
  POOL_ADDRESS,
  [
    "function token0() view returns (address)",
    "function token1() view returns (address)",
    "function fee() view returns (uint24)",
    "function liquidity() view returns (uint128)"
  ],
  provider
);
console.log(await pool.token0(), await pool.token1(), await pool.fee());
console.log("liquidity:", (await pool.liquidity()).toString());
```

The pool is only worth trusting if `token0` and `token1` are exactly BREMO and
the quote token you queried, `fee` matches the tier, and `liquidity` is a large
nonzero number. Any other result means the pool is fake, empty, or for a
different pair. When in doubt, do not trade.

If the address came from a V2 venue in Method 3, the same principle applies but
the function names differ. A V2 pair has no `fee` and no `liquidity`. Read
`token0` and `token1` exactly as above, then read `getReserves`, which returns
the amount of each token held by the pair. Two reserves of zero, or reserves so
small that any ordinary trade would consume most of one side, mean the pair
exists but has no real depth and cannot be traded meaningfully. Treat that the
same as no market, whatever the pair's existence is being used to imply.

## Why this matters

Anyone can deploy a token called BREMO and create a pool for it, at any venue,
without asking anyone. The factory queries above are what separate the real
token and its real pool from a lookalike. The chain does not lie. Verify the
token address, verify the pool address through the factory that created it, and
confirm both against the published page before you commit any funds.

Remember which way the burden runs. The project publishes a canonical pool
address only when a pool is live and verified, and no market speaks for the
project unless its address appears on https://bremo.tech/trade and matches
on-chain. A pool existing somewhere is not the project endorsing it.

## A reminder on framing

The number used to seed the initial pool ratio is a starting ratio, not a
valuation and not a guarantee of any future price. Once a market exists, the
price is only ever what a buyer and a seller agree to at that moment, and it
can move to zero. Nothing in this document is investment advice.
