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:

  1. Share of total stake: your staked amount over total staked
  2. Time staked: rewards accrue over time with your position
  3. 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
ParameterTypeDescription
_bTokenBTokenThe bToken to stake
_useraddressUser receiving the stake position
_amountuint256Amount of bTokens to stake

withdraw

Withdraw staked bTokens.

function withdraw(BToken _bToken, address _user, uint256 _amount) external
ParameterTypeDescription
_bTokenBTokenThe staked bToken
_useraddressUser withdrawing
_amountuint256Amount 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_)
ParameterTypeDescription
_bTokenBTokenThe staked bToken
_useraddressUser 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
ParameterTypeDescription
_bTokenBTokenThe staked bToken
_useraddressUser withdrawing and receiving rewards
_amountuint256bToken amount to withdraw from stake

Rewards Functions

claim

Claim accumulated rewards.

function claim(BToken _bToken, address _user) external returns (uint256 amount_)
ParameterTypeDescription
_bTokenBTokenThe staked bToken
_useraddressUser 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)
ParameterTypeDescription
_bTokenBTokenThe staked bToken
_useraddressUser 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)
ParameterTypeDescription
_bTokenBTokenPool 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)
ParameterTypeDescription
_bTokenBTokenPool 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

ErrorDescription
BStaking_StakeIsLockedAttempting to withdraw during lock period
BStaking_BTokenNotInitializedBToken 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": []
  }
]