> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Backtest a token position by replaying historical blocks

> Fork at a past block, take a position in a yield-bearing token, and replay real mainnet history with Network Mirror Mode to measure realized yield.

[Network Mirror Mode](/virtual-environments/network-mirror-mode) replays the parent network's real blocks onto a Virtual Environment. When the Virtual Environment is forked at a **past block**, that replay covers real history: every mainnet transaction from the fork point onward re-executes on your private copy, in order. This how-to uses that replay to backtest a position: fork at a past date, acquire a yield-bearing token, replay history forward, and read the yield the position actually earned over the period.

The worked example is the Franklin OnChain U.S. Government Money Fund token (`BENJI`) on Ethereum Mainnet. The same workflow applies to any yield-bearing token.

<Note>
  Network Mirror Mode is available on the paid plan. To enable it for your account, [contact our sales team](https://tenderly.co/contact-us).
</Note>

<Steps>
  ### Create the Virtual Environment at a past block

  Create a new Virtual Environment in your project. In the creation form, set:

  * **Networks**: Ethereum Mainnet
  * **Network mode**: **Network mirror** (full block-by-block mainnet replay)
  * Uncheck **Start from latest block**, set the reference point type to **Block Number**, and enter the block number for the date the position starts. The **Fork from block** column shows the block each selected network forks at.

  <Frame caption="Create Virtual Environment form: Network mirror mode selected, Start from latest block unchecked, and a past block number set as the reference point.">
    <img src="https://mintcdn.com/tenderly/AwV2r8yQqTyCkRCK/images/testnets/mirror-backtest-create.webp?fit=max&auto=format&n=AwV2r8yQqTyCkRCK&q=85&s=eee8be67183659b356bdaf46dad8203b" alt="Create Virtual Environment form with Ethereum Mainnet, Network mirror mode, and a past fork block number entered" width="1600" height="1330" data-path="images/testnets/mirror-backtest-create.webp" />
  </Frame>

  Create the Virtual Environment, open it, and go to the **Network sync** tab. The **Network sync status** panel shows the mainnet head, the Virtual Environment head (sitting at your fork block), and how many blocks behind mainnet the Virtual Environment is. That gap is the stretch of history the replay will cover.

  <Frame caption="Network sync status panel: mainnet head, Virtual Environment head at the fork block, and the blocks-behind counter.">
    <img src="https://mintcdn.com/tenderly/AwV2r8yQqTyCkRCK/images/testnets/mirror-backtest-sync-status.webp?fit=max&auto=format&n=AwV2r8yQqTyCkRCK&q=85&s=0cb57769a10ffac34ebbf7a652f02f59" alt="Network sync status panel showing Mainnet head 25,638,816, Virtual Environment head 25,634,161, and 4,655 blocks behind mainnet" width="1600" height="1000" data-path="images/testnets/mirror-backtest-sync-status.webp" />
  </Frame>

  ### Fund the wallet and take the position

  Real network state as of the fork block is live on the Virtual Environment, so the fund's token contract and any pools it trades in are already there.

  [Admin RPC cheatcodes are disabled while sync is active](/virtual-environments/network-mirror-mode#cheatcode-behavior), so do all setup before starting the replay. Confirm sync is paused: the status panel shows **Start auto-sync** rather than a running timer.

  1. Use **RPC Cheatcodes** in the top right to fund the investor wallet: [`tenderly_setBalance`](/virtual-environments/admin-rpc#tenderly_setbalance) for gas ETH and [`tenderly_setErc20Balance`](/virtual-environments/admin-rpc#tenderly_seterc20balance) for the stablecoin to invest.
  2. Acquire the fund token the way an investor would: swap for it, or subscribe through the fund's onchain flow. The wallet now holds the position as of the fork date.

  ### Track the position balance

  Still on the **Network sync** tab, switch the lower panel from **Sync operations** to **State drift**, then open the **Balance** sub-tab.

  Click **Track balance** and fill in the **Track wallet balance** dialog:

  * **Wallet**: the investor wallet
  * **Token**: the fund token (`BENJI`: `0x3DDc84940Ab509C11B20B76B466933f40b750dc9`)

  A card appears showing the wallet, the token, and a **Diff** counter. It reads "No balance drift data yet" until blocks replay.

  <Frame caption="Track wallet balance dialog: the investor wallet and the BENJI fund token.">
    <img src="https://mintcdn.com/tenderly/AwV2r8yQqTyCkRCK/images/testnets/mirror-backtest-track-dialog.webp?fit=max&auto=format&n=AwV2r8yQqTyCkRCK&q=85&s=b59d880652741ac8ac914a80c078958b" alt="Track wallet balance dialog with a wallet address and the BENJI token on Mainnet selected" width="528" height="304" data-path="images/testnets/mirror-backtest-track-dialog.webp" />
  </Frame>

  ### Replay history forward

  In the **Network sync status** panel:

  1. Open the speed dropdown next to the sync button and select **4×** (one block every 3 seconds; see the [speed settings](/virtual-environments/network-mirror-mode#time-controls)).
  2. Press **Start auto-sync**.

  The Virtual Environment replays real mainnet blocks onto the fork. The Virtual Environment head climbs, the blocks-behind counter shrinks, and every real transaction from the period re-executes in order, including the fund's onchain yield distributions.

  On the **Balance** card, each yield payout that replays steps the tracked balance up on the chart. Let the replay run until it covers the period you want to measure, then press **Stop auto-sync**.

  <Frame caption="Balance card after the replay: the tracked BENJI balance steps up at the block where the fund's distribution re-executes.">
    <img src="https://mintcdn.com/tenderly/AwV2r8yQqTyCkRCK/images/testnets/mirror-backtest-drift-step.webp?fit=max&auto=format&n=AwV2r8yQqTyCkRCK&q=85&s=1c7dceeba8d7b143abca2a721c2a0403" alt="State drift Balance card showing a flat BENJI balance line stepping up sharply at block 25,634,222" width="700" height="380" data-path="images/testnets/mirror-backtest-drift-step.webp" />
  </Frame>

  ### Read the realized yield

  The **Balance** card now holds the result:

  * The chart plots the tracked balance at each replayed block. Every distribution appears as a step up; the difference between the balance at the start and at the end of the replayed window is the realized yield for the period. For a fund with a \$1.00 NAV, that is the yield in dollars.
  * Hover the chart to read the balance at any block along the way.
  * The **Diff** counter shows how far the tracked balance has diverged from mainnet at the same block height. It stays `0.000` while the replay re-executes mainnet history unchanged, and moves when transactions you sent on the Virtual Environment change the position relative to mainnet.

  To annualize, with gain *G* on principal *P* over *D* days of replayed history: `APY ≈ (1 + G/P)^(365/D) − 1`.

  ### Compare scenarios (optional)

  * **Rewind** unwinds the last synced blocks so you can re-run a stretch of history.
  * **Sync block** advances exactly one block, which is useful for landing on a single yield distribution and reading it in isolation.
  * Create a second Virtual Environment at a different fork block or with a different position size to compare outcomes side by side.
</Steps>

## Practical notes

* **Yield appears when the fund's real yield transactions replay.** A rebasing token's held balance grows automatically. For a fund that distributes to registered holders, track a holder position so the distributions land on it.
* **Cheatcodes pause with sync.** Do all setup (funding, entering the position) while sync is paused, then start the replay.
* **One network per environment.** Network Mirror Mode runs against a single parent network; it isn't combined with [multichain Virtual Environments](/virtual-environments/multichain/overview).
* **Replay is bounded by real blocks.** Covering a long period means replaying many blocks. To capture yield quickly, fork shortly before a known distribution, or replay a representative window and annualize.

## Next steps

* Track a storage slot instead of a balance (**State drift → State → Track variable**) to follow any contract variable over the replayed period.
* Point a dapp's RPC at the Virtual Environment to drive the same replay from your own UI. See [Stage dapps](/virtual-environments/ci-cd/stage-dapps).
* Read the [Network Mirror Mode](/virtual-environments/network-mirror-mode) concept page for sync mechanics, time controls, and cheatcode behavior.
