Skip to main content
Dolomite powers token markets for the assets it supports. Apps can deposit USD1 into a Dolomite market to earn yield.

Markets powered by Dolomite

Dolomite organizes each supported asset into its own market, giving users a clear way to supply, borrow, and manage positions across a range of tokens. Each market is built around a specific supported asset, making it easy to understand what users are interacting with when they deposit or withdraw. In this guide, USD1 is accessed through its Dolomite market.

Resources

Dolomite

Explore Markets powered by Dolomite.

Get started with Privy

Set up Privy and create embedded wallets for your app.

Deposit USD1 into a Dolomite market

1

1. Configure addresses

Set up the USD1 token address, the Dolomite Deposit Router, and the USD1 market ID. The example below uses Ethereum Mainnet:
const USD1_ADDRESS = '0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d';
const DOLOMITE_DEPOSIT_ROUTER = '0xf8b2c637A68cF6A17b1DF9F8992EeBeFf63d2dFf';
const USD1_MARKET_ID = 1n; // Dolomite market ID for USD1
const ACCOUNT_NUMBER = 0n; // Default account number
const CHAIN_ID = 1; // Ethereum Mainnet
2

2. Approve the Dolomite router to spend USD1

Use viem’s encodeFunctionData to encode the approval, and Privy’s useSendTransaction to send it:
import {encodeFunctionData, maxUint256, erc20Abi} from 'viem';
import {useSendTransaction} from '@privy-io/react-auth';

const {sendTransaction} = useSendTransaction();

const data = encodeFunctionData({
  abi: erc20Abi,
  functionName: 'approve',
  args: [DOLOMITE_DEPOSIT_ROUTER as `0x${string}`, maxUint256]
});

const tx = await sendTransaction({
  to: USD1_ADDRESS as `0x${string}`,
  data,
  chainId: CHAIN_ID
});
3

3. Deposit USD1 into the market

Use viem to encode the depositWei call and Privy’s useSendTransaction to send it:
import {encodeFunctionData, parseUnits} from 'viem';
import {useSendTransaction} from '@privy-io/react-auth';

const {sendTransaction} = useSendTransaction();

const depositRouterAbi = [
  {
    type: 'function',
    name: 'depositWei',
    inputs: [
      {name: '_isolationModeMarketId', type: 'uint256'},
      {name: '_toAccountNumber', type: 'uint256'},
      {name: '_marketId', type: 'uint256'},
      {name: '_amountWei', type: 'uint256'},
      {name: '_eventFlag', type: 'uint8'}
    ],
    outputs: [],
    stateMutability: 'nonpayable'
  }
] as const;

const depositAmount = parseUnits('100', 18); // 100 USD1 (18 decimals)

const data = encodeFunctionData({
  abi: depositRouterAbi,
  functionName: 'depositWei',
  args: [
    0n, // _isolationModeMarketId: 0 for standard deposits
    ACCOUNT_NUMBER, // _toAccountNumber: 0 for the default account
    USD1_MARKET_ID, // _marketId: Dolomite market ID for USD1
    depositAmount, // _amountWei: amount of USD1 in wei
    0 // _eventFlag: 0 (None)
  ]
});

const tx = await sendTransaction({
  to: DOLOMITE_DEPOSIT_ROUTER as `0x${string}`,
  data,
  chainId: CHAIN_ID
});

Withdraw USD1 from a Dolomite market

Call withdrawWei on the Dolomite Deposit Router to pull USD1 back from the market to the user’s wallet. Pass the full wei amount to withdraw, or use a max value to exit entirely.
import {encodeFunctionData, parseUnits} from 'viem';
import {useSendTransaction} from '@privy-io/react-auth';

const {sendTransaction} = useSendTransaction();

const depositRouterAbi = [
  {
    type: 'function',
    name: 'withdrawWei',
    inputs: [
      {name: '_isolationModeMarketId', type: 'uint256'},
      {name: '_fromAccountNumber', type: 'uint256'},
      {name: '_marketId', type: 'uint256'},
      {name: '_amountWei', type: 'uint256'},
      {name: '_balanceCheckFlag', type: 'uint8'}
    ],
    outputs: [],
    stateMutability: 'nonpayable'
  }
] as const;

const withdrawAmount = parseUnits('100', 18); // 100 USD1 (18 decimals)

const data = encodeFunctionData({
  abi: depositRouterAbi,
  functionName: 'withdrawWei',
  args: [
    0n, // _isolationModeMarketId: 0 for standard withdrawals
    ACCOUNT_NUMBER, // _fromAccountNumber: 0 for the default account
    USD1_MARKET_ID, // _marketId: Dolomite market ID for USD1
    withdrawAmount, // _amountWei: amount of USD1 in wei
    1 // _balanceCheckFlag: 1 (From) — validates sender balance post-withdrawal
  ]
});

const tx = await sendTransaction({
  to: DOLOMITE_DEPOSIT_ROUTER as `0x${string}`,
  data,
  chainId: CHAIN_ID
});

Key integration tips

  1. Always approve first: Your app must grant ERC-20 approval to the Dolomite Deposit Router before any deposit.
  2. USD1 uses 18 decimals: Use parseUnits('100', 18) for amounts.
  3. Market IDs identify assets: The _marketId parameter (1 for USD1 in this example) tells Dolomite which market to deposit into or withdraw from. Dolomite uses ascending numerical market IDs rather than token addresses to identify markets. Use _isolationModeMarketId = 0 for standard (non-isolated) assets.
  4. Account number: Dolomite tracks balances per account number. Use 0 for the default account, or pass a custom value to support multiple sub-accounts per wallet.
  5. Balance check flag: On withdrawal, _balanceCheckFlag = 1 checks that the sender’s balance remains non-negative after the operation. Use 0 to skip checks on both sides.
  6. Supported chains: This guide uses Ethereum Mainnet. Dolomite is also deployed on Arbitrum — market IDs and router addresses differ per chain.

Conclusion

Privy makes it straightforward to build secure access to markets powered by Dolomite. For advanced use cases, refer to Dolomite, or reach out in Slack.
Your app is now ready to deposit USD1 into a Dolomite market using Privy embedded wallets!