BFactory
BFactory deploys BTokens and Mercury pools on Ethereum, covering createBToken, createPool, create2 addresses, custom errors, and JSON ABI for launch and indexing.
Overview
BFactory deploys new BToken instances and creates pools. Only the recorded bToken deployer may createPool for that bToken. Entry points:
- createBToken: deploy a minimal ERC-20 bToken and mint the total supply to the caller
- createPool: connect a bToken to a reserve, Uniswap v4 pool, BLV, fees, and optional initial credit (Merkle claim + collateral/debt) via
CreateParams - precomputeBTokenAddress: predict the create2 address of a bToken before deployment (salted per deployer)
createPool is payable for native-reserve funding; the Relay routes the shared component stack as for other Component calls.
Factory functions
createBToken
Deploys a new bToken. The full _totalSupply is transferred to msg.sender. The deployer is recorded in protocol state; only that address may call createPool for that bToken.
function createBToken(string memory _name, string memory _symbol, uint256 _totalSupply, bytes32 _salt) external returns (BToken bToken_)| Parameter | Type | Description |
|---|---|---|
_name | string | bToken name |
_symbol | string | bToken symbol |
_totalSupply | uint256 | Full supply to mint to msg.sender (subject to on-chain min/max) |
_salt | bytes32 | Salt for create2; combined with msg.sender in the hash |
Returns: BToken, the new bToken instance
createPool
CreateParams bundles bToken reference, pool reserves, active and BLV prices, creator, fee split, optional hook deployment, fee percentages, and optional initial credit (Merkle root, collateral, debt). The pool cannot already be initialized, and the caller must be the recorded deployer for params.bToken.
function createPool(CreateParams calldata params) public payable| Parameter | Type | Description |
|---|---|---|
params | CreateParams | BToken, reserve, initial prices, fee splits, optional hook, optional initial credit, etc. (see on-chain BFactory.CreateParams) |
precomputeBTokenAddress
Create2 address for the bToken that createBToken would deploy with the same name, symbol, total supply, salt, and deployer. Use the same _deployer you will use as msg.sender on createBToken.
function precomputeBTokenAddress(string memory _name, string memory _symbol, uint256 _totalSupply, bytes32 _salt, address _deployer) external view returns (address computedAddress_)| Parameter | Type | Description |
|---|---|---|
_name | string | Must match the planned createBToken call |
_symbol | string | Must match the planned createBToken call |
_totalSupply | uint256 | Must match the planned createBToken call |
_salt | bytes32 | Must match the planned createBToken call |
_deployer | address | Address that will call createBToken (use msg.sender when you deploy) |
Returns: address (computedAddress_): the address the bToken would have at that create2 address
Events
- BTokenCreated: bToken address, name, symbol, decimals, total supply, creator.
- PoolCreated: bToken, reserve, creator, fee recipient, fee and price parameters, pool id and capital totals (including initial credit when used).
Errors
| Error | Description |
|---|---|
NotDeployer | Caller is not the recorded deployer for this bToken |
NotApprovedReserve | Reserve token is not allowlisted for use |
PoolAlreadyInitialized | createPool called when a pool already exists for this bToken |
TotalSupplyTooLow | createBToken supply below the protocol minimum |
TotalSupplyTooHigh | createBToken supply above the protocol maximum |
InvalidName | bToken name fails validation |
InvalidSymbol | bToken symbol fails validation |
InvalidFeeRecipient | Fee recipient address is invalid |
InvalidCreator | Creator address or role is invalid |
InvalidCreatorFee | Creator fee pct or related value is invalid |
UnauthorizedCreditPositionCreation | Initial credit setup is not permitted for this call |
InvalidInitialCollateralOrDebt | Initial credit collateral or debt is inconsistent |
InsolventInitialCreditPosition | Initial credit position would be insolvent |
InvalidPoolSupply | Pool bToken / reserve supply inputs are invalid |
InvalidSalt | Salt does not meet create2 / validation rules |
InvalidConvexityExp | Convexity exponent for the curve is out of range |
ABI
[
{
"type": "function",
"name": "LABEL",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "pure"
},
{
"type": "function",
"name": "ROUTES",
"inputs": [],
"outputs": [
{
"name": "routes_",
"type": "bytes4[]",
"internalType": "bytes4[]"
}
],
"stateMutability": "pure"
},
{
"type": "function",
"name": "VERSION",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "pure"
},
{
"type": "function",
"name": "createBToken",
"inputs": [
{
"name": "_name",
"type": "string",
"internalType": "string"
},
{
"name": "_symbol",
"type": "string",
"internalType": "string"
},
{
"name": "_totalSupply",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_salt",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [
{
"name": "bToken_",
"type": "address",
"internalType": "contract BToken"
}
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "createPool",
"inputs": [
{
"name": "params",
"type": "tuple",
"internalType": "struct BFactory.CreateParams",
"components": [
{
"name": "bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "initialPoolBTokens",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "reserve",
"type": "address",
"internalType": "address"
},
{
"name": "initialPoolReserves",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "initialActivePrice",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "initialBLV",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "creator",
"type": "address",
"internalType": "address"
},
{
"name": "feeRecipient",
"type": "address",
"internalType": "address"
},
{
"name": "creatorFeePct",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "swapFeePct",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "createHook",
"type": "bool",
"internalType": "bool"
},
{
"name": "claimMerkleRoot",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "initialCollateral",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "initialDebt",
"type": "uint256",
"internalType": "uint256"
}
]
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"type": "function",
"name": "precomputeBTokenAddress",
"inputs": [
{
"name": "_name",
"type": "string",
"internalType": "string"
},
{
"name": "_symbol",
"type": "string",
"internalType": "string"
},
{
"name": "_totalSupply",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_salt",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "_deployer",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "computedAddress_",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "supportsInterface",
"inputs": [
{
"name": "_interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "pure"
},
{
"type": "event",
"name": "BTokenCreated",
"inputs": [
{
"name": "bTokenAddress",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "name",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "symbol",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "decimals",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "totalSupply",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "creator",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"type": "event",
"name": "Initialized",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "activePrice",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "blvPrice",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "swapFeePct",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"type": "event",
"name": "PoolCreated",
"inputs": [
{
"name": "bTokenAddress",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "reserveAddress",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "creator",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "feeRecipient",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "creatorFeePct",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "initialActivePrice",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "initialBlvPrice",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "totalReserves",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "totalBTokens",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "totalCollateral",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "totalDebt",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "poolId",
"type": "bytes32",
"indexed": false,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"type": "error",
"name": "AlreadyInitialized",
"inputs": []
},
{
"type": "error",
"name": "Component_NotPermitted",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_Paused",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_Reentrant",
"inputs": []
},
{
"type": "error",
"name": "InsolventInitialCreditPosition",
"inputs": []
},
{
"type": "error",
"name": "InvalidActivePrice",
"inputs": []
},
{
"type": "error",
"name": "InvalidBLVPrice",
"inputs": []
},
{
"type": "error",
"name": "InvalidConvexityExp",
"inputs": []
},
{
"type": "error",
"name": "InvalidCreator",
"inputs": []
},
{
"type": "error",
"name": "InvalidCreatorFee",
"inputs": []
},
{
"type": "error",
"name": "InvalidFeeRecipient",
"inputs": []
},
{
"type": "error",
"name": "InvalidInitialCollateralOrDebt",
"inputs": []
},
{
"type": "error",
"name": "InvalidInitialDebt",
"inputs": []
},
{
"type": "error",
"name": "InvalidName",
"inputs": []
},
{
"type": "error",
"name": "InvalidPoolSupply",
"inputs": []
},
{
"type": "error",
"name": "InvalidSalt",
"inputs": []
},
{
"type": "error",
"name": "InvalidSwapFeePct",
"inputs": []
},
{
"type": "error",
"name": "InvalidSymbol",
"inputs": []
},
{
"type": "error",
"name": "NativeLib_AmountMismatch",
"inputs": []
},
{
"type": "error",
"name": "NativeLib_NotWrapped",
"inputs": []
},
{
"type": "error",
"name": "NotApprovedReserve",
"inputs": []
},
{
"type": "error",
"name": "NotDeployer",
"inputs": []
},
{
"type": "error",
"name": "PoolAlreadyInitialized",
"inputs": []
},
{
"type": "error",
"name": "TotalSupplyTooHigh",
"inputs": []
},
{
"type": "error",
"name": "TotalSupplyTooLow",
"inputs": []
},
{
"type": "error",
"name": "UnauthorizedCreditPositionCreation",
"inputs": []
}
]BCredit
BCredit is Mercury credit on Ethereum, with 0% borrow, leverage, deleverage, repay, LTV and BLV-backed solvency, events, errors, and JSON ABI for builders.
BLens
BLens is the read-only Mercury lens on Ethereum, covering market price, BLV, premium, circulating supply, credit previews, pool state, and full JSON ABI for UIs and bots.