Beanstalk
  • Agronomics Handbook
  • Farmers' Almanac
  • Whitepaper
  • Contract Addresses
  • 🌱Overview
    • Introduction
    • Development Ethos
    • EIP-2535 Diamond
    • App Storage
    • Internal Balances
  • 🌾Protocol
    • Overview
    • Louper
    • Sun
      • Season Facet
    • Silo
      • Silo Facet
      • BDV Facet
      • Whitelist Facet
      • Convert Facet
      • Convert Getters Facet
      • Enroot Facet
      • Approval Facet
      • Metadata Facet
      • Migration Facet
      • Legacy Claim Withdrawal Facet
    • Field
      • Field Facet
      • Fundraiser Facet
    • Barn
      • Fertilizer Facet
      • Unripe Facet
    • Market
      • Marketplace Facet
    • Farm
      • Farm Facet
      • Depot Facet
      • Token Facet
      • Token Support Facet
      • Curve Facet
    • Diamond
      • Diamond Cut Facet
      • Diamond Loupe Facet
      • Ownership Facet
      • Pause Facet
  • 📜Misc.
    • Technical Recordings
    • Upgrade History
    • FAQ
    • Terminology Discrepancies
Powered by GitBook
On this page
  • What are Internal Balances?
  • Relevant Contracts
  • To / From
  • Transferring Internal / External Balances
  • Sending Internal / External Balances
  • Receiving Internal / External Balances
Edit on GitHub
Export as PDF
  1. Overview

Internal Balances

PreviousApp StorageNextOverview

Last updated 7 months ago

What are Internal Balances?

Beanstalk uses an Internal Balances system largely inspired by . With Internal Balances, Beanstalk is able to store an any ERC-20 token on behalf of a user. Beanstalk stores that the user has that ERC-20 token in . All functions within Beanstalk that either use a user's ERC-20 tokens or send ERC-20 tokens to a user can send/receive the ERC-20 tokens from the user's Internal Balance and/or External Balance (the user's wallet).

Internal Balances can significantly reduce transaction costs for using tokens that remain in Beanstalk. As more protocols utilize Internal Balances, the gas savings can compound.

In the Beanstalk ecosystem, Internal Balances are referred to as Farm Balances. Similarly, External Balances (balances in the user's wallet) are referred to as Circulating Balances. See .

Relevant Contracts

To / From

LibTransfer uses the following structs in order to denote the location(s) from which tokens will be used in a function.

enum From {
    EXTERNAL,
    INTERNAL,
    EXTERNAL_INTERNAL,
    INTERNAL_TOLERANT
}
  • EXTERNAL: Beanstalk will receive tokens from the user's External Balance;

  • INTERNAL: Beanstalk will receive tokens from the user's Internal Balance;

  • EXTERNAL_INTERNAL: Beanstalk will receive tokens from the user's Internal Balance and will receive from their External Balance if there is not enough in the Internal Balance; and

  • INTERNAL_TOLERANT: Beanstalk will receive tokens from the user's Internal Balance and will not fail if there is not enough in their Internal Balance.

enum To {
    EXTERNAL,
    INTERNAL
}
  • EXTERNAL Beanstalk will send tokens to the user's External Balance; and

  • INTERNAL Beanstalk will send tokens to the user's Internal Balance.

Transferring Internal / External Balances

function transferToken(
    IERC20 token,
    address recipient,
    uint256 amount,
    LibTransfer.From fromMode,
    LibTransfer.To toMode
) external payable;

Sending Internal / External Balances

A function that sends ERC-20 tokens to users can implement Internal Balances by adding the To enum in LibTransfer to a function's signature.

Then call sendToken in LibTransfer instead of directly calling the ERC-20 function transferFrom.

function sendToken(
    IERC20 token,
    uint256 amount,
    address recipient,
    To mode
) internal;

Receiving Internal / External Balances

A function that receives ERC-20 tokens from users can implement Internal Balances by adding the From enum in LibTransfer to a function's signature.

Then call receiveToken in LibTransfer instead of directly calling the ERC-20 function transfer.

function receiveToken(
    IERC20 token,
    uint256 amount,
    address recipient,
    To mode
) internal;

At any time, a user can transfer, add or remove ERC-20 tokens from their Internal Balance through the transferToken function in the . transferToken is a general transfer method that allows full control of the tokens start/end location (i.e internal to internal, internal to external, external to internal, external to external).

For protocols that are building on top of Beanstalk and want to interact with Internal Balances, they can utilize the functions given in , rather than the library itself.

🌱
Balancer's Vault
AppStorage
Terminology Discrepancies
LibTransfer.sol
LibBalance.sol
TokenFacet
TokenFacet