Overview
If you’re building a product that indexes ETH balances on Blast, it’s important that you understand how Blast’s account model differs from other EVM chains. Instead of representing ETH balances as integer values, Blast represents them in terms of shares. Each account has some number of shares associated with it and that number is multiplied by a global share price to determine its ETH balance. In this way, Blast account balances are capable of automatically rebasing as new yield is reported and the global share price increases. For the most accurate indexing of account balances, we recommend saving individual account shares along with the global share price instead of saving account balances directly. At read time an account’s balance can then be derived by multiplying its shares with the global share price. The rest of this document describes how to accurately index every account’s ETH balance on Blast using this method.If you only need to index a small number of account balances and would prefer to avoid this custom indexing logic, you can opt out of rebasing on those accounts (see yield modes below) and index their balances as you would normally.
Yield Modes
Blast accounts support three different yield modes, giving the user / builder control over how they want to handle rebasing when new yield is reported:Yield Mode | Description |
---|---|
AUTOMATIC | ETH balance automatically rebases (increasing only) |
VOID | ETH balance never changes in response to yield; no yield is earned |
CLAIMABLE | Yield accumulates separately and can be claimed to any recipient address |
Defaults
By default, all accounts on Blast are set toAUTOMATIC
yield mode, which means their ETH balances will rebase automatically.
However, when a smart contract is deployed to an address, the account is switched to VOID
mode. In practice, this means that smart contract accounts default to VOID
mode and EOAs default to AUTOMATIC
mode.
We say “in practice” because it is possible (but very uncommon) for ETH to be held by an account before a smart contract is deployed to it.
0x4300000000000000000000000000000000000002
.
See our article on Receiving and claiming ETH Yield for details.
Blast’s Account Model
Blast uses a modified version ofop-geth
(blast-geth
) to represent balances in terms of shares and enable all accounts to update as yield is reported. More specifically, blast-geth
modifies the underlying StateAccount
struct that represents account state to accomplish this:
op-geth (Upstream)
blast-geth
Flags
field and the Fixed
, Shares
, and Remainder
fields store the data required to calculate account balances in each of the three yield modes as follows:
In In this mode,
AUTOMATIC
mode, balances increase automatically as yield is reported to the L2:account.remainder
will be a dusty value to enable wei-level precision.It will always be the case that
account.remainder < sharePrice
(otherwise, account.shares
would just be higher).BALANCE
opcode behaves the same as it normally does, so smart contracts don’t need to consider their account’s shares.
To remain EVM compatible, Blast’s share system guarantees wei-level precision, allowing accounts with rebasing balances to transfer precise amounts of wei to accounts with non-rebasing balances and vice versa.
Global Share Price
The global share price that determines how much ETH each share is worth is stored in the SharesBase predeploy at address0x4300000000000000000000000000000000000000
.
This contract tracks the share price, the total number of shares, and the total amount of ETH that has yet to be reflected in the share price. You can read the current ETH share price by calling SharesBase::price()
as demonstrated below using cast call
or the eth_call
RPC:
In these examples we pipe the output into
awk
and jq
for styling purposes to show the units of the return value.NewPrice(uint256 price)
event emitted by this contract to get the new global share price whenever an update occurs. Generally, this update happens every day at midnight UTC, but this schedule is not guaranteed in code and may be subject to change.
Indexing Account Shares
As mentioned above, for the most accurate results it is recommended that you index account shares instead of account balances directly. For the most part, this works the same way as indexing balances on ETH mainnet: we first identify which accounts were touched in the transactions within a given block and then re-fetch the balances of those accounts on that block. Usually, these ETH balances are re-fetched using theeth_getBalance
RPC method, but on Blast we need to be able to read and save the account’s shares
value instead. Blast nodes expose a new RPC method, eth_getBalanceValues
, to support indexing the flags
, shares
, remainder
, and fixed
fields for accounts.
eth_getBalanceValues
This RPC method exposes the Blast-specific fields of the StateAccount
struct.
Request
Same as
eth_getBalance
Same as
eth_getBalance
; hex or “latest”
, “pending”
, etcUnique request identifier
Response
String representing RPC version number
Object containing
fixed
, flags
, remainder
, and shares
Unique request identifier
Edge Cases
On Ethereum mainnet,selfdestruct
allows ETH to be sent to a beneficiary address without triggering any code at that address. As a result, the beneficiary account’s balance changes without there being any call
made. Indexers must handle this edge case to ensure perfect accounting.
Blast introduces a similar edge case that indexers should be aware of. Accounts set to CLAIMABLE
yield mode can claim accumulated yield to an arbitrary beneficiary address. This claim operation works the same as selfdestruct
in that it can increase an arbitrary account’s balance without a call
.
While this edge case is exceptionally rare and not particularly important to handle, we include it here for completeness.