Contract Addresses
Address of record for every deployed BTR contract; integrations read this page. One section per chain, generated from the chain’s deploy manifest and deployment records and regenerated after every deploy: deploy metadata, core contracts, linked libraries, pools with their LP receipts and yield hooks, roles, timelock delays, mark signers and the public RPC. Live mainnets first, then testnets, then planned chains, which list no addresses. Tokens and feed IDs are in Asset Registry, pool rosters and leg parameters in Pool Composition. Verify every address before sending funds: cross-check the block explorer link on each row.
ABIs are served at GET /v1/abis/<ContractName> (API & SDK Reference §2.1), the endpoint @btr-protocol/sdk fetchAbi uses, and track current source. Do not wire integrations to the SDK’s CONTRACTS[chainId]: it holds placeholders, not deployments.
Network: Monad, chainId 143
Status: live mainnet. Native gas MON, wrapped WMON; block time 400 ms.
Explorer: https://monadvision.com
Redeployed 2026-10-01 by the mainnet deploy key through the CREATE3 factory; the earlier Monad fleet is superseded and is not an address of record. It still holds some reserved CREATE3 addresses (the old factory at 0xbbbbbbbb323d…d9b3, one retired pool, dust only). oracle, poolFactory and verifierP in the record are one address by design: PoolFactory is the fleet upgrader, the feed read surface (getFeed) and the primary-tier verifier. Assets are the real Monad tokens, not mocks. Gating of deposits and swaps: launch configuration.
Custody today
Pre-arm. The AccessControl owner is still the deployer EOA, and quorumPolicyArmed() is false. The owner Safe from the roles table below exists but holds no role yet.
| Role | Holder | State |
|---|---|---|
| Owner | deployer EOA | Single key. setPerms is instant and owner, treasury and factory changes skip their timelock while unarmed |
| Treasury pointer | treasury Safe | Set |
| Guardian | guardian Safe | Set; the only guardian |
| Risk steward | none | The queued rotation to the steward Safe matured 2026-10-02 and expired 2026-10-09 unexecuted |
transferOwnership is disabled by design. Rotation is requestOwnershipHandover() from the owner Safe, then completeOwnershipHandover(safe) from the deployer within 48 h, then armQuorumPolicy([guardianSafe]) from the Safe. Arming is irreversible and moves every later owner, treasury and factory change onto the timelocks in Admin. Until then the deployer key is the trust root for this chain, and the Safes in the roles table are the target, not the current custody.
This section changes in the same commit as the handover.
Deploy metadata
| Field | Value |
|---|---|
| Chain ID | 143 |
| Class | mainnet |
| Native symbol | MON |
| Wrapped native | WMON |
| Block time | 400 ms |
| Deploy block | 109600711 |
| Deployer EOA | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 |
Core contracts
| Contract | Address | Notes |
|---|---|---|
| AccessControl | 0xbbbbbbbb3473f8433A8A1a044E8a102D39dC8779 | Owner, guardian and role registry for the whole stack. No upgrade path |
| Admin (UUPS proxy) | 0xbbbbbbbb3f4840848D747b7085C89bf5D9E2E4f0 | Risk parameters, curves, timelocked operations. Pool bakes this address in as an immutable |
| Admin (implementation) | 0x572288d1378AB3Bd3eaecbd0682B9E513501D434 | Logic behind the Admin proxy |
| Flash (UUPS proxy) | 0xbbbbbbbb17d75FF66b3A9521c919a210637F3eCf | Flash-loan entry and pool-wide inflight guard. Pool bakes this address in as an immutable |
| Flash (implementation) | 0x399d335D47eB2589b1692b4adB32f315581E6Db8 | Logic behind the Flash proxy |
| PoolFactory | 0xbbbbbbbbbd5e955E20F323cA1F95f8191fD0E0BF | Deploys pools and alone may upgrade them; implementation() is the code every pool runs. Also the feed read surface (getFeed) and the primary-tier verifier |
| Reference-tier verifier | 0xBccAE41A5df0f9241454198d4565426Abf41cA83 | EIP-712 verifyingContract of the reference tier: a derived address with no code, never used for quoting |
| MarkStoreP8 (logic) | 0x04425AE3b46CbC324B476EB2FfA5537Bfdcd0F6A | Mark-store logic the Pool implementation runs; the store lives in the Pool implementation |
| Router | 0xbbbbbbbbb9687Ae7E49AE486e2e5C6408d2AA7fe | Executes an off-chain chosen path across pools in one transaction |
| CoopArb | 0xbbbbbbb0F8C5D06406A6Ff39ABe1d514e25adE2e | Cooperative arbitrage: external-leg trade plus Pool.swapCoop in one transaction. Stateless, non-upgradeable |
| Treasury | 0x0E7A1152074492649a126DC1b931B635bf54c8Fb | Pulls the protocol share that CoopArb holds |
Linked libraries (fixed code, no upgrade path):
| Library | Address |
|---|---|
| PricingLib | 0xd3488f96E70CBc41D8Bbe830C6c8544765E90B16 |
| PoolLiquidityLib | 0x67D99c763cB9Ed206515944aBe0D77156b04DC46 |
| PoolConfigLib | 0x35a0FAa70AFA08048269dCcA7B1278d017207097 |
| NUQuarticLib | 0xc1912C1570960cEF293BDeE587d561dbFa3680fA |
| AdminParamsLib | 0xB80970F51aC19031dbe5B9015F785348A18189FA |
Pools
| Pool | Code | Address |
|---|---|---|
| Pool implementation | – | 0x154be75fff18c9dFdD15D7F902B64a7b93B2A638 |
| Core | C | 0xbbbbbbb04f5b762A4CdD1d89E341e2537e3267e4 |
Every pool is an ERC-1967 proxy whose implementation slot only PoolFactory can write, so one timelocked executeReferenceUpgrade moves all of them. Other pools: officialPools(i) for i < getOfficialPoolsCount() lists BTR’s; enumerate every registered pool from PoolCreated events net of PoolDeregistered, or per token with getPoolsForToken(token), and confirm one with isPool(addr).
Core: LP receipts and yield hooks
| Leg | LP receipt | Yield hook |
|---|---|---|
| USDC | 0x09fFC8792cCd722417ECB3b6Ca58c0CE730bb429 | 0xbbbbbbb05E438f76770F4109a1feDBE7d04c0bE6 (Aave v3) |
| WMON | 0x88C8057a4064993Da10E964D4c817cFc259e90B6 | 0xbbbbbbb0B455a22D784eC890c1D28Cff7CBA2fB8 (ERC-4626 vault adapter) |
| CBBTC | 0xDdFcC77047a63980E421E16BFef9bC97C7D9c713 | 0xbbbbbbb0BEaAcf66068BdBa8E2a318492F752353 (ERC-4626 vault adapter) |
| WBTC | 0xB539D6e377368fF820129F9dC5C36057f7fB36b6 | – |
| WETH | 0x157a21A8dbBEee969d774053EB7D23c42816DeC2 | 0xbbbbbbb0CeF7E9E50E39df822eca27d108f1D7ef (Aave v3) |
| XAUT0 | 0xfe233c927F474d35f85B6802DE6BAa795E23a97C | – |
Roles
| Role | Address | Custody | Powers |
|---|---|---|---|
| Owner | 0xb6cC92E2c63aB6bdaD6bD333892e3990F808f618 | 3-of-4 Safe | Holds every timelocked lane; un-halts, upgrades, rotates roles |
| Treasury | 0x0E7A1152074492649a126DC1b931B635bf54c8Fb | 3-of-4 Safe | Receives the protocol share |
| Guardian | 0x3F617767c1985f0953c1Fcb4426C650EE5c4A625 | 1-of-3 Safe | Fail-safe only: halt, tighten, cancel. Cannot un-halt, upgrade or move value |
| Risk steward | 0xECc0Ac71b881c6b2bD9Bbe098558b656DC3AA915 | 1-of-3 Safe | Moves risk parameters inside the steward fences |
| Depositor | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Depositor | 0xaB7Bb2F7E39eaED8e5543220f43fa545ea780760 | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Depositor | 0xD4cD9eE834971a462bEcf5E7088594f656A572A7 | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Swapper | 0xaB7Bb2F7E39eaED8e5543220f43fa545ea780760 | – | Swap lane: can trade SWAP_GATED legs |
| Swapper | 0xD4cD9eE834971a462bEcf5E7088594f656A572A7 | – | Swap lane: can trade SWAP_GATED legs |
| Deployer EOA | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 | – | Signs the deploy ceremony |
Roles are the deploy manifest’s targets; read AccessControl for the holders in force. Guardians halt and never un-halt: Access Control §2.
Timelock delays
Schedule PROD_DELAYS, fixed at deploy (Access Control §3).
| Tier | Delay |
|---|---|
| GOVERNANCE | 7d |
| LISTING | 1d |
| TUNING | 1h |
Mark signers
Wire version 8. A push needs the threshold of signers on the tier’s roster and a submitting address on its relayer list (Mark Relayer).
| Feed class | Max deviation (bps) | TTL |
|---|---|---|
| stable | 50 | 1h |
| fx | 75 | 1h |
| volatile | 100 | 7min |
| equity | 100 | 10min |
Coop arbitrage
| Venue | Address |
|---|---|
| Tycho router | 0xbbbbbbb0D9624972f8aeE649A55C8a6535eDB8D3 |
| Uniswap v4 PoolManager | 0x188d586Ddcf52439676Ca21A244753fA19F9Ea8e |
| Kuru router | 0xd651346d7c789536ebf06dc72aE3C8502cd695CC |
| Morpho Blue | 0xD5D960E8C380B724a48AC59E2DfF1b2CB4a1eAee |
| V3 factories | 0x204FAca1764B154221e35c0d20aBb3c525710498<br>0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865 |
Operator: 0xd1b33b54A6Fa47a58593eAe935898E429179a488.
Terms: discBps 3000 (max 3000); rebateBps 5000 (min 2000, max 9000).
RPC
Public endpoint: https://gm.monad.at.htw.tech. The failover list is served with the chain registry (GET /v1/chains).
Network: Arc Testnet, chainId 5042002
Status: live public testnet. Native gas USDC; block time 500 ms.
Explorer: https://testnet.arcscan.app
Hub token USDC.b, the mintable 18-decimal faucet twin of Circle’s USDC. Native USDC (0x3600…) is Circle’s testnet gas token: not faucet-mintable, not the base, not a listed leg. The owner is a single testnet key; the quorum policy is never armed because Arc has no Safe. Every pool asset except Circle’s EURC is a BTR mock minted through the on-app faucet under daily caps (Asset Registry).
Deployed 2026-09-27 by the mainnet deploy key through the CREATE3 factory, so every singleton and pool sits on its mainnet address and runs the source these docs describe. Stable core opened at block 64299445, crypto core at 64303621. The Forex and Equity cores are defined in the manifest but not created: the FX legs wait for signed marks on their currencies, the equity legs for their price source. Their tokens and feed lanes are registered; no pool lists them.
The earlier Arc fleet (pools 0x8e33…5BFE, 0xACe9…24F5, 0xCbB8…C232, 0xD98A…85e3) is halted and abandoned in place. It is not an address of record; do not integrate against it.
Native gas is USDC at 18 decimals while the ERC-20 view of the same balance at 0x3600000000000000000000000000000000000000 has 6, and there is no wrapped native token. A transfer of the entire balance therefore reverts TransferFromFailed, and the app reserves a gas buffer on that input.
Block production and ordering
Block production on Arc is a permissioned validator set with Circle-gated membership and a single block assembler; the intra-block ordering rule is undocumented. maxPriorityFeePerGas = 0 is the documented recommendation, so no priority-fee auction runs, and no third-party ordering privilege is sold. The only announced MEV path routes proceeds to validator and staker rewards and to burn, not to applications. This describes BTR’s rights on Arc; it does not mean Arc has no MEV: an opaque assembler still holds an unpriced ordering option and latency races persist. BTR has no ordering right to sell there. Permitted responses on Arc: lower the per-feed min_push_gap_s or the overshoot page threshold, raise the fee floor or the staleness premium, or escalate to Circle. Revisit only if Arc ships an application-addressable ordering primitive. Toxic-flow policy this responds to: Toxic Flow Mitigation §8.
Deploy metadata
| Field | Value |
|---|---|
| Chain ID | 5042002 |
| Class | testnet |
| Native symbol | USDC |
| Block time | 500 ms |
| Deploy block | 64219592 |
| Deployer EOA | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 |
Core contracts
| Contract | Address | Notes |
|---|---|---|
| AccessControl | 0xbbbBBB289736272E5fb64f284D176Ffb49d6C6cF | Owner, guardian and role registry for the whole stack. No upgrade path |
| Admin (UUPS proxy) | 0xBbbBBb226988e555e7a175D8e07Eef61CDa84CD2 | Risk parameters, curves, timelocked operations. Pool bakes this address in as an immutable |
| Admin (implementation) | 0xa5859ABBeC3a44AD33D84C8baDaf0de5472339f2 | Logic behind the Admin proxy |
| Flash (UUPS proxy) | 0xBBBBBBBb1bCF78304ECbe4c7fC7c21244Bb55D3a | Flash-loan entry and pool-wide inflight guard. Pool bakes this address in as an immutable |
| Flash (implementation) | 0x504447524Cf3953E0894185C2f45145F64639A64 | Logic behind the Flash proxy |
| PoolFactory | 0xbBBbBBBb323D7f7E51976b8A8DF2Bb4B4608d9B3 | Deploys pools and alone may upgrade them; implementation() is the code every pool runs. Also the feed read surface (getFeed) and the primary-tier verifier |
| Reference-tier verifier | 0x27cf4711937B0154ba70D020eD238D941b586966 | EIP-712 verifyingContract of the reference tier: a derived address with no code, never used for quoting |
| MarkStoreP8 (logic) | 0x138F360aCAc96727ACc1a38E4EF6d1704ee5edc1 | Mark-store logic the Pool implementation runs; the store lives in the Pool implementation |
| Router | 0xBBBbbbbBB698143c38935b29b65B72eBe18C393c | Executes an off-chain chosen path across pools in one transaction |
| TestnetFaucet | 0x482178f9d6A5cf33E044e4B00076E4799a7080c8 | Rate-limited mock-token claims |
| Treasury | 0xc4B4635B76ed49A7239291F6fbB33455D059a5B9 | Pulls the protocol share that CoopArb holds |
Linked libraries (fixed code, no upgrade path):
| Library | Address |
|---|---|
| PricingLib | 0xd3488f96E70CBc41D8Bbe830C6c8544765E90B16 |
| PoolLiquidityLib | 0x67D99c763cB9Ed206515944aBe0D77156b04DC46 |
| PoolConfigLib | 0x94b0274c8d55b7d686868937ad58d61398AeC7AC |
| NUQuarticLib | 0xc1912C1570960cEF293BDeE587d561dbFa3680fA |
| AdminParamsLib | 0xB80970F51aC19031dbe5B9015F785348A18189FA |
Pools
| Pool | Code | Address |
|---|---|---|
| Pool implementation | – | 0xECB9d44832dFdED469D091627D1463Eb4A28a00E |
| Stable | S | 0xbbbBbbB9B0335cc991924E1F5b59f0d4D88f1dE0 |
| Forex | F | not created |
| Crypto | X | 0xbbBbBBbb09Fb9E10d8C178433368e32E89aBAd4b |
| Equity | E | not created |
Every pool is an ERC-1967 proxy whose implementation slot only PoolFactory can write, so one timelocked executeReferenceUpgrade moves all of them. Other pools: officialPools(i) for i < getOfficialPoolsCount() lists BTR’s; enumerate every registered pool from PoolCreated events net of PoolDeregistered, or per token with getPoolsForToken(token), and confirm one with isPool(addr).
Stable: LP receipts
Crypto: LP receipts
Roles
| Role | Address | Custody | Powers |
|---|---|---|---|
| Owner | 0xBEa0C3a274898B823f35538A19F27f0398C44fC7 | – | Holds every timelocked lane; un-halts, upgrades, rotates roles |
| Treasury | 0xc4B4635B76ed49A7239291F6fbB33455D059a5B9 | – | Receives the protocol share |
| Guardian | 0xE64e348258d6c6407BeEe7d80c6D82FBd827808C | – | Fail-safe only: halt, tighten, cancel. Cannot un-halt, upgrade or move value |
| Depositor | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Depositor | 0xBEa0C3a274898B823f35538A19F27f0398C44fC7 | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Depositor | 0x57b3771F6b772C52E81646Aa007D1Ab28d91B3Fe | – | Deposit lane: can fund DEPOSIT_GATED legs |
| Deployer EOA | 0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3 | – | Signs the deploy ceremony |
Roles are the deploy manifest’s targets; read AccessControl for the holders in force. Guardians halt and never un-halt: Access Control §2.
Timelock delays
Schedule TESTNET_DELAYS, fixed at deploy (Access Control §3).
| Tier | Delay |
|---|---|
| GOVERNANCE | 6h |
| LISTING | 2h |
| TUNING | 1h |
Mark signers
Wire version 8. A push needs the threshold of signers on the tier’s roster and a submitting address on its relayer list (Mark Relayer).
| Feed class | Max deviation (bps) | TTL |
|---|---|---|
| stable | 50 | 1h |
| fx | 75 | 1h |
| volatile | 100 | 10min |
| equity | 100 | 10min |
RPC
Public endpoint: https://rpc.blockdaemon.testnet.arc.io. The failover list is served with the chain registry (GET /v1/chains).
Network: BNB Chain, chainId 56
Status: planned. Native gas BNB, wrapped WBNB; block time 450 ms.
Explorer: https://bscscan.com
Deploy metadata
| Field | Value |
|---|---|
| Chain ID | 56 |
| Class | mainnet |
| Native symbol | BNB |
| Wrapped native | WBNB |
| Block time | 450 ms |
No BTR contracts are deployed on BNB Chain yet, so there is nothing to integrate against: build on a live chain and switch the chainId when this section lists addresses. Planned configuration: Deployments Overview.
Reading these tables
Applies to every chain section.
- Core contracts are one deploy per chain.
AdminandFlashare UUPS proxies; pools arePoolProxycontracts; everything else is fixed code, so a redeploy changes its address. Upgrade paths: Upgradeability. - There is no oracle contract of its own. Marks live in one store inside the Pool implementation’s storage, run by the
MarkStoreP8logic;PoolFactoryserves the reads (getFeedfor the primary tier,feedOf(id, 2)for the reference tier). The reference tier backs the depeg band and the volatile-asset ref band, never a swap quote (Mark Relayer). Its pairs: Asset Registry. - Every pool is an ERC-1967
PoolProxy, not an immutable clone and not a beacon proxy: each holds its implementation in its own slot, writable only byPoolFactory. A pool’s address is permanent; its code is not. One owner transaction,PoolFactory.executeReferenceUpgrade()after theGOVERNANCEtier delay (7 days in production), callsupgradeToon every proxy the factory minted and moves every live pool on that chain to a new implementation at once. Vetoable by the owner or any guardian (cancelReferenceUpgrade); expires 7 days after maturity. See Admin. - Testnet pool assets are BTR mocks unless the chain’s section says otherwise (Deployments §1).
- Feed identity is MITCH:
feedId = bytes32(uint256(tickerId)), the packed instrument id (script/lib/MitchLib.sol; ids indeployments/<slug>.manifest.json). It is content-derived, so it carries the instrument type and is the same id on every chain.
Upgradeability
Three upgrade paths.
- Pool fleet (largest): the
PoolFactoryfleet upgrade, its row above and Admin. MonitorReferencePoolUpgradeRequested/ReferencePoolUpgradedonPoolFactory. A pool logic change ships as a new implementation address plus a fleet upgrade: an in-place upgrade of every existing pool. AdminandFlash: UUPS proxies over the sharedUpgradeGatebase (timelockedrequestUpgrade/executeUpgrade; a directupgradeToAndCallis rejected even from the authority). Table addresses are the proxies, which is whatPoolbakes in as immutables; implementations are tracked separately asadminImpl/flashImpl.- No upgrade path:
AccessControl(Ownable, rotatable owner, fixed code),PoolFactory(holds the fleet implementation pointer, own code fixed), theLPTokenimplementation and the five linked libraries (PricingLib,PoolConfigLib,PoolLiquidityLib,NUQuarticLib,AdminParamsLib). The mark store has no path of its own: it lives in the Pool implementation and moves with path 1, which copies it across withmigrateFrom.
Governance-critical DEX parameter changes, risk config, curves and feed additions route through Admin’s timelock rather than through a contract upgrade, so the deployed code for those paths does not change at all; see Admin.
Keeper on-chain touchpoints
Per chain, the oracle keeper is the only regular non-admin writer against the stack. It calls publishMarks() on the Pool implementation, the store: each segment carries one tier’s lanes and a k-of-n EIP-712 quorum of at least 2-of-3, and the submitting address must be on that tier’s relayer list. It pushes on a deviation-or-heartbeat trigger per lane. Trust model and signer set: Mark Relayer.
Deterministic addresses
Singletons are deployed through the BTR CREATE3 factory at 0x815d9297bB4dFf9eCaEB7C53017E0DE40300C75e. It is placed from a frozen initcode and the public salt keccak256('btr.create3.factory.v1') through the deterministic-deployment proxy 0x4e59b44847b379578588920cA78FbF26c0B4956C, so it lands at that address on any chain it is deployed to. On a new chain it is step 1 of the launch ceremony. An address out of the factory is f(factory, deployer, salt) and does not depend on bytecode, so a role keeps its address across chains and contract generations.
AccessControl, Admin and Flash (proxies), PoolFactory, Router and the pools come out of the factory; implementations, the mark-store logic and TestnetFaucet are plain CREATE deployments and follow the deployer’s nonce.
Pools go through the same factory, but PoolFactory is the sender rather than a deploy key, so a pool address is f(factory, poolFactory, salt). The base token and the token roster are mutable pool state and are not in the address: a base migration or a listing never moves a pool. PoolFactory.predictPool(salt) returns the address from the chain alone.
Two things follow for anyone integrating:
- A role’s address is a constant on a chain deployed through the factory: treat a change to one of these rows as an incident, not a migration.
GET /v1/venuesserves the same records as this page (API & SDK Reference §4.3). - An address with a disclosed salt can be recomputed.
effSalt = keccak256(deployer ++ salt)for a singleton,keccak256(poolFactory ++ salt)for a pool; proxy =keccak256(0xff ++ 0x815d9297bB4dFf9eCaEB7C53017E0DE40300C75e ++ effSalt ++ 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f)[12:]; the contract is the proxy’s nonce-1CREATEaddress. Mainnet deployer:0x0a37aEc263CbA0aaBC09Bac56A0F2074a22E69A3.
Salts of addresses not yet minted stay private until used, since a salt plus a leaked deployer key would squat the address. Treat anything that appears at one of the vanity addresses on a chain without a section here as not ours.