BCredit
BCredit is Mercury credit on Ethereum, with 0% borrow, leverage, deleverage, repay, BLV-backed solvency, preview functions, events, errors, and JSON ABI for builders.
Overview
BCredit handles 0% interest borrowing and leverage against bToken collateral. Collateral is valued at BLV, debt is denominated in the reserve asset, and new debt pays an origination fee. Credit account reads live on BLens through creditAccount.
Borrowing functions
borrow
Borrow reserves against the caller's unlocked staked bToken collateral. The contract locks the collateral required to keep the account solvent at BLV.
function borrow(BToken _bToken, uint256 _amount, address _recipient) external| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The bToken collateral market |
_amount | uint256 | Reserve amount to borrow |
_recipient | address | Address that receives borrowed reserves |
borrowNative
Borrow reserves and unwrap the native reserve when supported.
function borrowNative(BToken _bToken, uint256 _amount, address _recipient) externalrepay
Repay reserve debt for _recipient. The caller pays _reservesIn, and the protocol unlocks collateral based on the repayment.
function repay(BToken _bToken, uint256 _reservesIn, address _recipient) external| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The bToken credit market |
_reservesIn | uint256 | Reserve amount to repay |
_recipient | address | Credit account receiving the repayment |
repayWithNative
Repay with native ETH when the market reserve supports native wrapping.
function repayWithNative(BToken _bToken, address _recipient) external payableLeverage functions
leverage
Create or increase a leveraged position by buying additional bToken collateral with borrowed reserves.
function leverage(
BToken _bToken,
uint256 _totalCollateral,
uint256 _collateralIn,
uint256 _maxSwapReservesIn
) external returns (uint256 debt_)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The bToken to leverage |
_totalCollateral | uint256 | Target total collateral after leverage |
_collateralIn | uint256 | Existing collateral supplied by the user |
_maxSwapReservesIn | uint256 | Maximum reserves the internal buy may spend |
Returns:
debt_: New debt added to the caller's account
deleverage
Reduce leverage by selling bToken collateral for reserves and applying the proceeds to debt.
function deleverage(
BToken _bToken,
uint256 _collateralToSell,
uint256 _minSwapReservesOut
) external returns (uint256 collateralRedeemed_, uint256 debtRepaid_, uint256 refund_)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The leveraged bToken |
_collateralToSell | uint256 | Collateral to sell into the curve |
_minSwapReservesOut | uint256 | Minimum reserves from the sale |
Returns:
collateralRedeemed_: bToken collateral unlocked or returneddebtRepaid_: Reserve debt repaidrefund_: Reserve refund when sale proceeds exceed debt
Preview functions
function getMaxBorrow(BToken _bToken, address _user) external view returns (uint256 maxBorrow_)
function getBorrowForCollateral(BToken _bToken, uint256 _collateral) external view returns (uint256 borrowAmount_, uint256 fee_)
function previewBorrow(BToken _bToken, address _user, uint256 _borrowAmount) external view returns (uint256 collateral_, uint256 debt_, uint256 fee_)
function previewDepositAndBorrow(BToken _bToken, address _user, uint256 _depositAmount, uint256 _borrowAmount) external view returns (uint256 collateral_, uint256 debt_, uint256 fee_)
function previewRepay(BToken _bToken, address _recipient, uint256 _reservesIn) external view returns (uint256 collateralRedeemed_, uint256 debtRepaid_)
function previewRebalanceCollateral(BToken _bToken, uint256 _collateral, uint256 _debt) external view returns (uint256 unlocked_)Use BLens.creditAccount(BToken _bToken, address _user) to read a user's current collateral and debt.
Credit claims
claimCredit installs Merkle-proven credit positions, used for migration and launch flows with precomputed credit accounts.
function claimCredit(
BToken _bToken,
address[] calldata _users,
uint128[] calldata _collaterals,
uint128[] calldata _debts,
bytes32[][] calldata _proofs
) externalEvents
event Borrow(BToken bToken, address user, uint256 borrowed, uint256 fee, State.CreditAccount post);
event Repay(BToken bToken, address user, uint256 collateralRedeemed, uint256 debtRepaid, State.CreditAccount post);
event CreditClaim(BToken bToken, address[] users, uint128[] collaterals, uint128[] debts);
event Leverage(BToken bToken, address user, uint256 collateralAdded, uint256 debtAdded, uint256 collateralIn, uint256 reservesIn, State.CreditAccount post);
event Deleverage(BToken bToken, address user, uint256 collateralRedeemed, uint256 debtRepaid, uint256 collateralSold, uint256 refund, State.CreditAccount post);Errors
| Error | Description |
|---|---|
BCredit_RepaidMoreThanDebt | Repaying more than owed |
BCredit_CannotRepayContract | Repayment recipient cannot be the relay itself |
BCredit_Leverage_ZeroCollateral | Leverage with no target collateral |
BCredit_Leverage_InvalidStakedAmount | Supplied collateral is not below target collateral |
BCredit_Leverage_BorrowAmountTooLow | Borrowed amount cannot fund the leverage buy |
BCredit_Deleverage_InvalidCollateralToSell | Invalid deleverage amount |
BCredit_Deleverage_Undercollateralized | Operation would leave the position undercollateralized |
BCredit_InvalidClaim | Invalid Merkle credit claim |
Usage Example
// Borrow reserves against currently unlocked stake
bcredit.borrow(bToken, 900e18, msg.sender);
// Preview and execute leverage
(uint256 targetCollateral, uint256 maxIn,,) = blens.quoteLeverage(
bToken,
1000e18,
1e18
);
bcredit.leverage(bToken, targetCollateral, 1000e18, maxIn);
// Repay reserve debt
reserve.approve(address(bcredit), 900e18);
bcredit.repay(bToken, 900e18, msg.sender);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": "borrow",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "borrowNative",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "claimCredit",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_users",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "_collaterals",
"type": "uint128[]",
"internalType": "uint128[]"
},
{
"name": "_debts",
"type": "uint128[]",
"internalType": "uint128[]"
},
{
"name": "_proofs",
"type": "bytes32[][]",
"internalType": "bytes32[][]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "deleverage",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_collateralToSell",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_minSwapReservesOut",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "collateralRedeemed_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "debtRepaid_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "refund_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "getBorrowForCollateral",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_collateral",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "borrowAmount_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "fee_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getMaxBorrow",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "maxBorrow_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "leverage",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_totalCollateral",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_collateralIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_maxSwapReservesIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "debt_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "previewBorrow",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
},
{
"name": "_borrowAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "collateral_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "debt_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "fee_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "previewDepositAndBorrow",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
},
{
"name": "_depositAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_borrowAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "collateral_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "debt_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "fee_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "previewRebalanceCollateral",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_collateral",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_debt",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "unlocked_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "previewRepay",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_recipient",
"type": "address",
"internalType": "address"
},
{
"name": "_reservesIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "collateralRedeemed_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "debtRepaid_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "repay",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_reservesIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "repayWithNative",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"type": "function",
"name": "supportsInterface",
"inputs": [
{
"name": "_interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "pure"
},
{
"type": "event",
"name": "Borrow",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "borrowed",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "fee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.CreditAccount",
"components": [
{
"name": "collateral",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "debt",
"type": "uint128",
"internalType": "uint128"
}
]
}
],
"anonymous": false
},
{
"type": "event",
"name": "CreditClaim",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "users",
"type": "address[]",
"indexed": false,
"internalType": "address[]"
},
{
"name": "collaterals",
"type": "uint128[]",
"indexed": false,
"internalType": "uint128[]"
},
{
"name": "debts",
"type": "uint128[]",
"indexed": false,
"internalType": "uint128[]"
}
],
"anonymous": false
},
{
"type": "event",
"name": "Deleverage",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "collateralRedeemed",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "debtRepaid",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "collateralSold",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "refund",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.CreditAccount",
"components": [
{
"name": "collateral",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "debt",
"type": "uint128",
"internalType": "uint128"
}
]
}
],
"anonymous": false
},
{
"type": "event",
"name": "Distributed",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "reserve",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "totalAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "protocolFee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "creatorFee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "stakingFee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"type": "event",
"name": "Leverage",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "collateralAdded",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "debtAdded",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "collateralIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "reservesIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.CreditAccount",
"components": [
{
"name": "collateral",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "debt",
"type": "uint128",
"internalType": "uint128"
}
]
}
],
"anonymous": false
},
{
"type": "event",
"name": "Repay",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "collateralRedeemed",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "debtRepaid",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.CreditAccount",
"components": [
{
"name": "collateral",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "debt",
"type": "uint128",
"internalType": "uint128"
}
]
}
],
"anonymous": false
},
{
"type": "error",
"name": "BCredit_AlreadyClaimed",
"inputs": []
},
{
"type": "error",
"name": "BCredit_CannotRepayContract",
"inputs": []
},
{
"type": "error",
"name": "BCredit_Deleverage_InvalidCollateralToSell",
"inputs": []
},
{
"type": "error",
"name": "BCredit_Deleverage_Undercollateralized",
"inputs": []
},
{
"type": "error",
"name": "BCredit_InsufficientCollateral",
"inputs": []
},
{
"type": "error",
"name": "BCredit_InvalidClaim",
"inputs": []
},
{
"type": "error",
"name": "BCredit_InvalidClaimLength",
"inputs": []
},
{
"type": "error",
"name": "BCredit_InvalidProof",
"inputs": []
},
{
"type": "error",
"name": "BCredit_Leverage_BorrowAmountTooLow",
"inputs": []
},
{
"type": "error",
"name": "BCredit_Leverage_InvalidStakedAmount",
"inputs": []
},
{
"type": "error",
"name": "BCredit_Leverage_ZeroCollateral",
"inputs": []
},
{
"type": "error",
"name": "BCredit_NoClaimMerkleRoot",
"inputs": []
},
{
"type": "error",
"name": "BCredit_RebalanceCollateral_Undercollateralized",
"inputs": []
},
{
"type": "error",
"name": "BCredit_RepaidMoreThanDebt",
"inputs": []
},
{
"type": "error",
"name": "BCredit_SystemClaim_Undercollateralized",
"inputs": []
},
{
"type": "error",
"name": "BCredit_UserClaim_Undercollateralized",
"inputs": []
},
{
"type": "error",
"name": "CollateralLib_InsufficientStake",
"inputs": []
},
{
"type": "error",
"name": "Component_NotPermitted",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_Insolvent",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_InsufficientSettledReserves",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_InvalidCirculatingSupply",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_Paused",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_Reentrant",
"inputs": []
},
{
"type": "error",
"name": "GuardLib_ReserveAccountingMismatch",
"inputs": []
},
{
"type": "error",
"name": "NativeLib_AmountMismatch",
"inputs": []
},
{
"type": "error",
"name": "NativeLib_NotWrapped",
"inputs": []
}
]Related
- Borrowing Guide : How to borrow
- Multiply : How to use leverage
- BLens Contract : Credit account reads and leverage quote
- BLV Mechanics: Why loans are 0% interest
BStaking
BStaking stakes bTokens to earn reserve-denominated protocol fees, including deposit, withdraw, claim, accumulator views, events, errors, and JSON ABI for integrations.
BLens
BLens is the read-only Mercury lens on Ethereum, covering active price, BLV, circulating supply, pool state, staking state, credit accounts, quote state, and full JSON ABI for UIs and bots.