BStaking
BStaking stakes bTokens on Ethereum to earn protocol fees, including deposit, withdraw, lock periods, claim, view functions, events, errors, and JSON ABI for integrations.
Overview
BStaking handles user staking of bTokens and a pro-rata share of protocol fees. A reward accumulator streams pool fees and pays them in the reserve asset (e.g., ETH/WETH) so each staker’s claim grows with the pool, not a fixed rate. The main drivers are:
- Share of total stake: your staked amount over total staked
- Time staked: rewards accrue over time with your position
- Trading volume: more fees in the pool mean more to distribute to stakers
The pattern is designed to stay fair for both early and late stakers: see getAccumulator, getEarned, and getCurrentRate below.
Functions
Staking Functions
deposit
Stakes bTokens to earn rewards. The bToken must already have a pool (initialized).
function deposit(BToken _bToken, address _user, uint256 _amount) external| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The bToken to stake |
_user | address | User receiving the stake position |
_amount | uint256 | Amount of bTokens to stake |
withdraw
Withdraw staked bTokens.
function withdraw(BToken _bToken, address _user, uint256 _amount) external| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The staked bToken |
_user | address | User withdrawing |
_amount | uint256 | Amount to withdraw |
withdrawMax
Withdraw all staked bTokens the user can currently withdraw (subject to any lock rules).
function withdrawMax(BToken _bToken, address _user) external returns (uint256 amount_)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The staked bToken |
_user | address | User withdrawing |
Returns:
amount_: bTokens actually withdrawn (full staked amount if not locked)
withdrawAndClaim
Withdraw _amount of staked bTokens and claim any pending rewards in one call.
function withdrawAndClaim(BToken _bToken, address _user, uint256 _amount) external| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The staked bToken |
_user | address | User withdrawing and receiving rewards |
_amount | uint256 | bToken amount to withdraw from stake |
Rewards Functions
claim
Claim accumulated rewards.
function claim(BToken _bToken, address _user) external returns (uint256 amount_)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The staked bToken |
_user | address | User claiming rewards |
Returns:
amount_: Reserve tokens claimed
View Functions
getEarned
Get unclaimed rewards for a user in the reserve asset.
function getEarned(BToken _bToken, address _user) external view returns (uint256)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | The staked bToken |
_user | address | User to query |
Returns: uint256, reserve-denominated rewards not yet claimed (normalized to reserve decimals in-state)
getAccumulator
Get the current global reward accumulator for that pool (used in reward math).
function getAccumulator(BToken _bToken) external view returns (uint256)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | Pool to query |
Returns: uint256, accumulator value (per pool’s reward accounting)
getCurrentRate
Get the current reward distribution rate (how quickly rewards are streamed to the accumulator).
function getCurrentRate(BToken _bToken) external view returns (uint256)| Parameter | Type | Description |
|---|---|---|
_bToken | BToken | Pool to query |
Returns: uint256, rate in reward accounting units (see on-chain BStaking for exact scaling)
Events
event Deposit(BToken bToken, address user, uint256 amount, State.StakedAccount post);
event Withdraw(BToken bToken, address user, uint256 amount, State.StakedAccount post);
event Claim(BToken bToken, address user, uint256 amount);
event Liquidate(BToken bToken, address user, uint256 amount, State.StakedAccount post);Errors
| Error | Description |
|---|---|
BStaking_StakeIsLocked | Attempting to withdraw during lock period |
BStaking_BTokenNotInitialized | BToken pool not initialized |
Usage Example
// Stake 1000 bTokens
bToken.approve(address(bstaking), 1000e18);
bstaking.deposit(bToken, msg.sender, 1000e18);
// Check earned rewards
uint256 earned = bstaking.getEarned(bToken, msg.sender);
// Claim rewards
uint256 claimed = bstaking.claim(bToken, msg.sender);
// Withdraw and claim in one tx
bstaking.withdrawAndClaim(bToken, msg.sender, 500e18);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": "claim",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
},
{
"name": "_asNative",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [
{
"name": "amount_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "deposit",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "getAccumulator",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
}
],
"outputs": [
{
"name": "accumulator_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "newYield_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokensPerSecond_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getCurrentRate",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getEarned",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "liquidate",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_user",
"type": "address",
"internalType": "address"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "supportsInterface",
"inputs": [
{
"name": "_interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "pure"
},
{
"type": "function",
"name": "sync",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "withdraw",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "withdrawAndClaim",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
},
{
"name": "_amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "withdrawMax",
"inputs": [
{
"name": "_bToken",
"type": "address",
"internalType": "contract BToken"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "event",
"name": "Claim",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"type": "event",
"name": "Deposit",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.StakedAccount",
"components": [
{
"name": "amount",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "locked",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "earned",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "userAccumulator",
"type": "uint256",
"internalType": "uint256"
}
]
}
],
"anonymous": false
},
{
"type": "event",
"name": "Liquidate",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.StakedAccount",
"components": [
{
"name": "amount",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "locked",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "earned",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "userAccumulator",
"type": "uint256",
"internalType": "uint256"
}
]
}
],
"anonymous": false
},
{
"type": "event",
"name": "Withdraw",
"inputs": [
{
"name": "bToken",
"type": "address",
"indexed": false,
"internalType": "contract BToken"
},
{
"name": "user",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "post",
"type": "tuple",
"indexed": false,
"internalType": "struct State.StakedAccount",
"components": [
{
"name": "amount",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "locked",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "earned",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "userAccumulator",
"type": "uint256",
"internalType": "uint256"
}
]
}
],
"anonymous": false
},
{
"type": "error",
"name": "BStaking_BTokenNotInitialized",
"inputs": []
},
{
"type": "error",
"name": "BStaking_StakeIsLocked",
"inputs": []
},
{
"type": "error",
"name": "Component_NotPermitted",
"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": []
}
]Related
- Staking Guide : How to stake
- BLens Contract : View staking state
BSwap
BSwap is the Mercury AMM for bTokens on Ethereum, with n=2 power-law curve, exact in/out trades, quotes, fees, events, errors, and full JSON ABI for viem, ethers, and integrations.
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.