Receive and claim ETH yield
Overview
Blast is an L2 that modifies the native ETH token to be rebasing. Blast users and smart contracts can earn ~4% from beacon chain staking yield.
EOAs automatically receive ETH yield via rebasing.
Smart contract accounts have three Yield Modes for their rebasing mode:
- Void (DEFAULT): ETH balance never changes; no yield is earned
- Automatic: native ETH balance rebases (increasing only)
- Claimable: ETH balance never changes; yield accumulates separately
Smart contracts must interact with the Blast yield contract located at 0x4300000000000000000000000000000000000002
to change their Yield Mode.
Yield Modes
Void Yield (DEFAULT)
Smart contract accounts default to Disabled yield in order to maintain compatibility with existing Ethereum Mainnet dapps and EVM-compatible L2 dapps. Any normal dapp can be deployed to Blast and Just Work™ without any changes needed.
Automatic Yield
If 1 ETH is deposited to a dapp with Automatic yield enabled, the dapp’s balance will grow to 1.04 ETH in a year. This is useful for dapps that want to pass yield on to their users such that there’s no opportunity cost for the user to deposit ETH to the dapp.
interface IBlast{
// See IBlast interface source code below
}
contract MyContract {
constructor() {
IBlast(0x43...02).configureAutomaticYield() //contract balance will grow automatically
}
}
Claimable Yield
If 1 ETH is deposited to a dapp with Claimable yield enabled, the dapp’s balance will remain at 1 ETH even after a year. The dapp will accrue a yield balance of 0.04 ETH which can be claimed asynchronously.
interface IBlast{
// See IBlast interface source code below
}
contract MyContract {
constructor() {
IBlast(0x43...02).configureClaimableYield()
}
function claimYield(address recipient, uint256 amount) external {
//This function is public meaning anyone can claim the yield
IBlast(0x43...02).claimYield(address(this), recipient, amount);
}
function claimAllYield(address recipient) external {
//This function is public meaning anyone can claim the yield
IBlast(0x43...02).claimAllYield(address(this), recipient);
}
}
Governor
The governor is the address that’s allowed to claim the contract’s yield and gas, which might be the contract’s own address, its owner, or anything else.
By default, the governor is the contract’s own address.
After contract creation, only the governor can reconfigure the contract’s yield and gas mode.
interface IBlast{
// See IBlast interface source code below
}
contract MyContract {
constructor(address gov) {
IBlast(0x43...02).configureClaimableYield()
IBlast(0x43...02).configureGovernor(gov) //only this address can claim yield
}
}
FAQ
Can an EOA forward its yield to another address?
An Automatic yield mode EOA or contract cannot forward its yield to another account. On yield distribution events, the balance of an automatically rebasing account will automatically increase.
A Claimable account’s yield is not counted as part of the EVM balance. The yield must be claimed via the Blast pre-deploy’s claimYield()
or claimAllYield()
functions. Both these interfaces allow the caller to specify a recipient for the yield. In this way, yield accumulating to a Claimable account can be claimed to another address directly. Note that this does not happen automatically — a contract call must be made to claim. Additionally, an EOA can set its governor to another address, which would allow that address to make these claimYield
calls without any interactions from the EOA.
How often do balances update due to yield?
On mainnet, ETH balances will update approximately daily. On testnet, ETH balances will update hourly at a rate of ~0.01% per day.
IBlast Interface
In the interface below, when you see a function like configureX
with corresponding configureXOnBehalf
version, the difference is that configureX
configures the caller and configureXOnBehalf
configures the contract corresponding to the contractAddress
parameter.
enum YieldMode {
AUTOMATIC,
VOID,
CLAIMABLE
}
enum GasMode {
VOID,
CLAIMABLE
}
interface IBlast{
// configure
function configureContract(address contractAddress, YieldMode _yield, GasMode gasMode, address governor) external;
function configure(YieldMode _yield, GasMode gasMode, address governor) external;
// base configuration options
function configureClaimableYield() external;
function configureClaimableYieldOnBehalf(address contractAddress) external;
function configureAutomaticYield() external;
function configureAutomaticYieldOnBehalf(address contractAddress) external;
function configureVoidYield() external;
function configureVoidYieldOnBehalf(address contractAddress) external;
function configureClaimableGas() external;
function configureClaimableGasOnBehalf(address contractAddress) external;
function configureVoidGas() external;
function configureVoidGasOnBehalf(address contractAddress) external;
function configureGovernor(address _governor) external;
function configureGovernorOnBehalf(address _newGovernor, address contractAddress) external;
// claim yield
function claimYield(address contractAddress, address recipientOfYield, uint256 amount) external returns (uint256);
function claimAllYield(address contractAddress, address recipientOfYield) external returns (uint256);
// claim gas
function claimAllGas(address contractAddress, address recipientOfGas) external returns (uint256);
function claimGasAtMinClaimRate(address contractAddress, address recipientOfGas, uint256 minClaimRateBips) external returns (uint256);
function claimMaxGas(address contractAddress, address recipientOfGas) external returns (uint256);
function claimGas(address contractAddress, address recipientOfGas, uint256 gasToClaim, uint256 gasSecondsToConsume) external returns (uint256);
// read functions
function readClaimableYield(address contractAddress) external view returns (uint256);
function readYieldConfiguration(address contractAddress) external view returns (uint8);
function readGasParams(address contractAddress) external view returns (uint256 etherSeconds, uint256 etherBalance, uint256 lastUpdated, GasMode);
}