> ## Content Index
> Fetch the complete content index at: https://blog.arbitrum.foundation/llms.txt
> Use this file to discover other available public pages before exploring further.

# Build Your First Robinhood Chain App
- URL: https://blog.arbitrum.foundation/build-your-first-dapp-on-robinhood-chain/
- Published: 2026-07-21T14:53:31.000Z
- Updated: 2026-07-21T14:53:31.000Z
- Author: Ben Greenberg
- Tags: Robinhood Chain, Builder Posts

A chain becomes very interesting when there is something useful to compose with.

Robinhood Chain gives you the familiar EVM path first: Solidity contracts, Foundry deploys, viem reads, wagmi writes, ERC-20 approvals. The part worth learning is not a new VM. It is the asset layer you can build against once the contracts are live.

The demo featured here is an index basket app. A user deposits Stock Tokens, receives an ERC-20 basket share, sees that share priced from Chainlink feeds, and can redeem back into the underlying components.

![A user interacts with a frontend that approves Stock Tokens and calls the basket contract, while the factory deploys baskets and Chainlink feeds provide pricing.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/basket-dapp-architecture.png)

You can run it locally, deploy it to Robinhood Chain testnet, fork-test the mainnet configuration, and inspect the live walkthrough at [robinhood-chain-dapp.vercel.app](https://robinhood-chain-dapp.vercel.app/?ref=blog.arbitrum.foundation) with the source at [github.com/hummusonrails/robinhood-chain-dapp-example](https://github.com/hummusonrails/robinhood-chain-dapp-example?ref=blog.arbitrum.foundation).

## The chain is custom, your app path is not

Robinhood Chain is a custom Arbitrum Chain built on the Arbitrum stack. It uses Ethereum blobs for data availability and ETH as the gas token.

For you, that means the first deploy looks like an EVM deploy:

```bash
export PRIVATE_KEY=0x<your_private_key>
export RH_RPC_URL=https://rpc.testnet.chain.robinhood.com

forge create src/MyContract.sol:MyContract \
  --rpc-url $RH_RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast

```

This is where the Arbitrum stack matters. Robinhood gets a dedicated chain with custom block production, pricing, infrastructure, and product controls. Builders still get the Ethereum contract model and tooling.

![Arbitrum as a platform: Arbitrum One is the credibly neutral public chain with deep shared liquidity, while Arbitrum Chains give teams the flexible, feature-rich execution environment Robinhood Chain runs on.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/arbitrum-as-a-platform.png)

That split is the whole reason the app path stays familiar while the chain is bespoke. Robinhood Chain runs on Arbitrum Nitro, the same technology as Arbitrum One, deployed as a dedicated chain. You inherit the parts you would not want to rebuild without doing anything:

![What the Arbitrum stack buys you for free: Ethereum settlement with fraud proofs and a trustless canonical bridge, ETH gas with tiny fees, ERC-4337 and EIP-7702 account abstraction on day one, and Stylus for Rust contracts alongside Solidity.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/Screenshot-2026-07-07-at-18.07.12.png)

State roots settle to Ethereum with fraud proofs, gas is paid in ETH, ERC-4337 and EIP-7702 account abstraction are live at canonical addresses, and Stylus lets a Solidity contract call a Rust one. None of that is work you take on to get a custom chain.

## Stock Tokens are ERC-20s with one extra accounting layer

![Raw ERC-20 balances remain stable for contracts, while the UI multiplier converts them into share-equivalent display amounts and can update after corporate actions.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/stock-token-display-accounting.png)

Stock Tokens are ERC-20 tokens. You can read balances, transfer, approve, and compose them the same way you would any other token.

```solidity
IERC20 nvda = IERC20(NVDA_TOKEN_ADDRESS);

uint256 balance = nvda.balanceOf(user);
nvda.approve(spender, amount);
nvda.transfer(recipient, amount);

```

The extra piece is corporate actions.

Stock Tokens implement ERC-8056, the Scaled UI Amount extension. Raw token balances do not rebase when a split or dividend adjustment changes the economic relationship between one token and the underlying equity. Instead, the token exposes a `uiMultiplier()`.

```solidity
interface IScaledUIAmount {
    function uiMultiplier() external view returns (uint256);
    function balanceOfUI(address account) external view returns (uint256);
    function totalSupplyUI() external view returns (uint256);
    function newUIMultiplier() external view returns (uint256);
    function effectiveAt() external view returns (uint256);
}

```

The display conversion is:

```solidity
underlyingShares = rawBalance * uiMultiplier / 1e18;

```

That lets protocols keep using raw ERC-20 units while wallets and UIs show share-equivalent amounts. If a split changes the multiplier, your accounting does not suddenly mutate under your contract.

## The basket app is small on purpose

The sample app you can start learning from has two contracts and no owner.

The interactive walkthrough prices one share live in the browser from the same Chainlink reads the contract uses: multiply each feed by the units backing a share, then sum.

![The live math behind one TRIO share: 0.4 TSLA plus 0.3 AMZN plus 0.3 NFLX, each priced from its Chainlink feed, summing to the value returned by sharePriceUsd() onchain.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/Screenshot-2026-07-07-at-18.08.45.png)

| Contract      | Role                                            | Control Surface           |
| ------------- | ----------------------------------------------- | ------------------------- |
| BasketFactory | Deploys and records baskets                     | Permissionless            |
| BasketToken   | Holds components, mints, redeems, prices shares | No owner, no upgrade path |

The factory does not custody anything. It deploys a basket and records the address.

```solidity
function createBasket(
    string calldata name,
    string calldata symbol,
    BasketToken.Component[] calldata components,
    uint256 maxPriceAge
) external returns (address basket) {
    basket = address(new BasketToken(name, symbol, components, maxPriceAge));
    _baskets.push(basket);
    isBasket[basket] = true;
    emit BasketCreated(basket, msg.sender, name, symbol);
}

```

Each basket stores a fixed list of components. A component is a token, a feed, and the raw amount of that token backing one basket share.

```solidity
struct Component {
    address token;
    address feed;
    uint256 unitsPerShare;
}

```

The mainnet demo basket uses TSLA, NVDA, and AAPL Stock Tokens with their Chainlink feeds:

```solidity
function _mainnetComponents()
    internal
    pure
    returns (BasketToken.Component[] memory c)
{
    c = new BasketToken.Component[](3);
    c[0] = BasketToken.Component(MAINNET_TSLA, MAINNET_TSLA_FEED, 0.4e18);
    c[1] = BasketToken.Component(MAINNET_NVDA, MAINNET_NVDA_FEED, 0.3e18);
    c[2] = BasketToken.Component(MAINNET_AAPL, MAINNET_AAPL_FEED, 0.3e18);
}

```

One `TRIO` share is backed by `0.4 TSLA`, `0.3 NVDA`, and `0.3 AAPL`.

On testnet, the demo uses real faucet Stock Tokens for TSLA, AMZN, and NFLX with mock Chainlink feeds. That is because the testnet gives you Stock Tokens to build with, while the production Stock Token feeds live on mainnet.

## Minting is the ERC-20 path you already know

![Minting starts with component approvals, then the basket pulls Stock Tokens and mints shares; redeeming burns shares and transfers components back.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/mint-and-redeem-settlement-flow.png)

From the frontend, minting is two steps: approve each component token, then call the basket.

```javascript
await writeContract({
  address: stockTokenAddress,
  abi: erc20Abi,
  functionName: "approve",
  args: [basketAddress, amount],
});

await writeContract({
  address: basketAddress,
  abi: basketTokenAbi,
  functionName: "mint",
  args: [shares, account],
});

```

Onchain, the basket pulls the required component amounts and mints shares in the same transaction.

```solidity
function mint(uint256 shares, address to) external nonReentrant {
    if (shares == 0) revert ZeroShares();

    uint256 count = _components.length;
    for (uint256 i = 0; i < count; i++) {
        Component memory c = _components[i];
        uint256 amount = Math.mulDiv(
            c.unitsPerShare,
            shares,
            SHARE_UNIT,
            Math.Rounding.Ceil
        );

        IERC20(c.token).safeTransferFrom(msg.sender, address(this), amount);
    }

    _mint(to, shares);
    emit Minted(msg.sender, to, shares);
}

```

The rounding direction matters. Mint rounds up so a minter cannot underpay the basket reserves by dust.

Redeem is the mirror image. Burn first, transfer components out, round down so reserves cannot be overdrawn.

```solidity
function redeem(uint256 shares, address to) external nonReentrant {
    if (shares == 0) revert ZeroShares();
    if (to == address(0)) revert ZeroAddress();

    _burn(msg.sender, shares);

    uint256 count = _components.length;
    for (uint256 i = 0; i < count; i++) {
        Component memory c = _components[i];
        uint256 amount = Math.mulDiv(
            c.unitsPerShare,
            shares,
            SHARE_UNIT,
            Math.Rounding.Floor
        );

        IERC20(c.token).safeTransfer(to, amount);
    }

    emit Redeemed(msg.sender, to, shares);
}

```

Notice what redeem does not do. It does not read an oracle. It does not check a price. It does not ask the factory for permission.

That separation is deliberate. Pricing tells the UI what a share is worth. Redemption returns the tokens held by the contract.

## The repo gives you the full deploy path

Start locally:

```bash
git clone --recurse-submodules https://github.com/hummusonrails/robinhood-chain-dapp-example.git
cd robinhood-chain-dapp-example

pnpm install
anvil
pnpm run deploy:local
pnpm run smoke
pnpm run dev

```

The local deploy creates mock Stock Tokens, mock Chainlink feeds, the factory, and a demo `Tech Trio` basket. It also writes `apps/frontend/.env.local`, so the frontend can read the deployed addresses.

For testnet, get ETH and Stock Tokens from the Robinhood Chain faucet, then run:

```bash
PRIVATE_KEY=$YOUR_TESTNET_KEY pnpm run deploy:testnet

```

One Foundry script handles local, testnet, and mainnet by switching on `block.chainid`.

```solidity
function run() external {
    vm.startBroadcast();

    BasketFactory factory = new BasketFactory();
    console2.log("FACTORY=%s", address(factory));

    BasketToken.Component[] memory components;
    if (block.chainid == 4663) {
        components = _mainnetComponents();
    } else if (block.chainid == 46630) {
        components = _testnetComponents();
    } else {
        components = _localComponents();
    }

    address basket =
        factory.createBasket("Tech Trio", "TRIO", components, MAX_PRICE_AGE);

    console2.log("DEMO_BASKET=%s", basket);
    console2.log("CHAIN_ID=%s", block.chainid);

    vm.stopBroadcast();
}

```

The testnet deployment behind the live walkthrough is:

| Contract           | Address                                    |
| ------------------ | ------------------------------------------ |
| BasketFactory      | 0xC1940D5fd58ce735A44a53f910852B12250F6a14 |
| BasketToken (TRIO) | 0x7633e0920Ea46A8Ec54F61C95adECD391c01Edd4 |

For mainnet, the same script uses the real TSLA, NVDA, and AAPL Stock Tokens with their Chainlink feeds:

```bash
PRIVATE_KEY=$YOUR_MAINNET_KEY scripts/deploy.sh mainnet

```

Before spending mainnet gas, run the fork tests:

```bash
pnpm run test:contracts
pnpm run test:fork

```

The fork test creates the basket against live Robinhood Chain mainnet state, gives a test account Stock Token balances inside the fork, mints, checks backing, redeems, and verifies the supply returns to zero.

```solidity
function test_mintAndRedeem_withRealStockTokens() public {
    deal(TSLA, alice, 1e18);
    deal(NVDA, alice, 1e18);
    deal(AAPL, alice, 1e18);

    vm.startPrank(alice);
    IERC20Metadata(TSLA).approve(address(basket), type(uint256).max);
    IERC20Metadata(NVDA).approve(address(basket), type(uint256).max);
    IERC20Metadata(AAPL).approve(address(basket), type(uint256).max);

    basket.mint(2e18, alice);
    assertEq(basket.balanceOf(alice), 2e18);
    assertEq(IERC20Metadata(TSLA).balanceOf(address(basket)), 0.8e18);

    basket.redeem(2e18, alice);
    assertEq(basket.totalSupply(), 0);
    assertEq(IERC20Metadata(TSLA).balanceOf(alice), 1e18);
    vm.stopPrank();
}

```

That is the development loop you want for this kind of app: mocks for speed, testnet for wallet flow, fork tests for live integration assumptions, mainnet only after the path is boring.

The testnet deploy behind the live walkthrough is a real session. Five contracts, priced in ETH, verified on Blockscout, for a fraction of a cent of gas.

![A recorded testnet deployment on Robinhood Chain: an estimated 0.000122 ETH for the whole five-contract script, with all contracts verified on Blockscout and addresses handed to the frontend.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/Screenshot-2026-07-07-at-18.10.31.png)

That price comes from how the Arbitrum stack orders and settles work. Transactions arrive first come, first served into roughly 250ms blocks, get batched, and post to Ethereum as blob data.

![The life of a transaction on Robinhood Chain: your transaction hits the first-come-first-served sequencer, lands in a ~250ms block, is compressed into a batch, and settles to Ethereum for blob data availability. The fee is L2 execution gas plus the L1 data fee.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/Screenshot-2026-07-07-at-18.11.46.png)

## What changes when the ERC-20 tracks a market asset

A Stock Token still fits the ERC-20 interface, but the surrounding assumptions change.

| Concern           | Generic ERC-20 Habit                 | Stock Token Pattern                                                 |
| ----------------- | ------------------------------------ | ------------------------------------------------------------------- |
| User balance      | Show balanceOf                       | Show balanceOfUI or apply uiMultiplier for share-equivalent display |
| Price             | Maybe no canonical feed              | Read the per-token Chainlink feed on mainnet                        |
| Corporate actions | Often ignored                        | Track multiplier updates and pending effective times                |
| Valuation         | Token price only                     | Feed price already includes the multiplier                          |
| Staleness         | Crypto feeds may update continuously | Stock feeds follow market hours                                     |
| Exit path         | Often price-gated                    | Prefer collateral redemption that does not depend on oracle reads   |

> “... Robinhood Chain lays the groundwork for an ecosystem that will define the future of tokenized real-world assets and enable builders to tap into DeFi liquidity within the Ethereum ecosystem.”
> 
> Johann Kerbrat, SVP and GM of Crypto and International at Robinhood

Read that as an engineering prompt, not a slogan. If equities, ETFs, feeds, and lending markets become normal onchain components, then app design gets more interesting than “deploy another token.” You can build products where ownership, pricing, collateral, and settlement are all programmable.

## From an app to your own Arbitrum chain

The basket is one app on Robinhood Chain. Robinhood Chain is one chain on Arbitrum. That nesting is the point: the same stack meets you wherever you are on the path.

You can ship an app on Arbitrum One first and tap into deep shared liquidity, lean on the team for deployment and go-to-market, and compose with the 1,000+ protocols already deployed. When your product needs its own blockspace, pricing, and controls, the same stack graduates you to a custom Arbitrum Chain, exactly the move Robinhood made.

![Arbitrum as a launch partner: start with a deployment on Arbitrum One, lean on a trusted team and deep liquidity across 1,000+ deployed protocols, and graduate to your own Arbitrum Chain when your product needs it.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/arbitrum-launch-partner.png)

The economics travel with you. Because Robinhood Chain settles to Ethereum as blob data on the Arbitrum stack, the cost to transact keeps trending down, recently around a tenth of a cent per transaction.

![Token Terminal data on the median transaction fee for Robinhood Chain, around $0.00127 per transaction and trending down, powered by Arbitrum and Ethereum.](https://storage.ghost.io/c/d4/cc/d4cc8040-691e-4dd2-8282-0c08d45fc5a8/content/images/2026/07/x-post_1.5x_postspark_2026-07-07_18-16-58.png)

Whether you stay as an app or become a chain, the contract model, the tooling, and the settlement guarantees are the same ones you used on day one.

## Start with the working system

The index basket is not the only app to build on Robinhood Chain. It is a useful first one to explore because it touches the surfaces your own app will probably need:

- Stock Token reads, approvals, and transfers
- ERC-8056 display logic
- Chainlink Stock Token feeds
- Mint and redeem flows
- Local mocks
- Robinhood Chain testnet deployment
- Blockscout verification
- Mainnet fork tests
- A Next.js frontend using wagmi and viem

The useful pattern is not “copy this basket forever.” It is the shape of the work: keep contracts small, separate pricing from settlement, treat real-world asset details as part of the protocol surface, and test the same assumptions from local mocks to live mainnet state.

Explore the fully functional index basket app deployed on Robinhood Chain with its interactive developer walkthrough and open source code on GitHub: [robinhood-chain-dapp.vercel.app](https://robinhood-chain-dapp.vercel.app/?ref=blog.arbitrum.foundation) and [github.com/hummusonrails/robinhood-chain-dapp-example](https://github.com/hummusonrails/robinhood-chain-dapp-example?ref=blog.arbitrum.foundation).