Internal Balances
Beanstalk uses an Internal Balances system largely inspired by Balancer's Vault. 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
AppStorage
. 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 Terminology Discrepancies.
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; andINTERNAL_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; andINTERNAL
Beanstalk will send tokens to the user's Internal Balance.
At any time, a user can transfer, add or remove ERC-20 tokens from their Internal Balance through the
transferToken
function in the TokenFacet
. 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).function transferToken(
IERC20 token,
address recipient,
uint256 amount,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable;
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;
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;
For protocols that are building on top of Beanstalk and want to interact with Internal Balances, they can utilize the functions given in
TokenFacet
, rather than the library itself.Last modified 30d ago