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:

  1. createBToken: deploy a minimal ERC-20 bToken and mint the total supply to the caller
  2. createPool: connect a bToken to a reserve, Uniswap v4 pool, BLV, fees, and optional initial credit (Merkle claim + collateral/debt) via CreateParams
  3. 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_)
ParameterTypeDescription
_namestringbToken name
_symbolstringbToken symbol
_totalSupplyuint256Full supply to mint to msg.sender (subject to on-chain min/max)
_saltbytes32Salt 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
ParameterTypeDescription
paramsCreateParamsBToken, 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_)
ParameterTypeDescription
_namestringMust match the planned createBToken call
_symbolstringMust match the planned createBToken call
_totalSupplyuint256Must match the planned createBToken call
_saltbytes32Must match the planned createBToken call
_deployeraddressAddress 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

ErrorDescription
NotDeployerCaller is not the recorded deployer for this bToken
NotApprovedReserveReserve token is not allowlisted for use
PoolAlreadyInitializedcreatePool called when a pool already exists for this bToken
TotalSupplyTooLowcreateBToken supply below the protocol minimum
TotalSupplyTooHighcreateBToken supply above the protocol maximum
InvalidNamebToken name fails validation
InvalidSymbolbToken symbol fails validation
InvalidFeeRecipientFee recipient address is invalid
InvalidCreatorCreator address or role is invalid
InvalidCreatorFeeCreator fee pct or related value is invalid
UnauthorizedCreditPositionCreationInitial credit setup is not permitted for this call
InvalidInitialCollateralOrDebtInitial credit collateral or debt is inconsistent
InsolventInitialCreditPositionInitial credit position would be insolvent
InvalidPoolSupplyPool bToken / reserve supply inputs are invalid
InvalidSaltSalt does not meet create2 / validation rules
InvalidConvexityExpConvexity 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": []
  }
]