This workflow demonstrates a complete round-trip bridge operation of using Berachain USDC to minting Reservoir rUSD stablecoin on Ethereum Mainnet where the protocol exists, then bridging and depositing rUSD into a yield-bearing Euler position. Route Mechanics: This bundle orchestrates a complete crosschain yield strategy through multiple atomic operations:
  • Bridge USDC from Berachain to Ethereum using Stargate protocol
  • Check USDC balance on Ethereum after successful bridge completion
  • Mint rUSD using the bridged USDC through Reservoir’s minting contract
  • Bridge newly minted rUSD back to Berachain via Stargate bridge
  • Check rUSD balance on Berachain after the return bridge
  • Deposit rUSD into Euler V2 vault for automated yield generation
mintOnBeraFromMainnet.ts
  // Chain IDs
  const BERACHAIN_ID = 80094;
  const ETHEREUM_ID = 1;

  // Common addresses
  const WALLET_ADDRESS = "0x93621DCA56fE26Cdee86e4F6B18E116e9758Ff11"; // User wallet

  // Token addresses
  const USDC_BERACHAIN = "0x549943e04f40284185054145c6E4e9568C1D3241";
  const USDC_ETHEREUM = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
  const RUSD_ETHEREUM = "0x09D4214C03D01F49544C0448DBE3A27f768F2b34";

  // Protocol addresses
  const RESERVOIR_MINTING_CONTRACT =
    "0x4809010926aec940b550D34a46A52739f996D75D";

  const client = new EnsoClient({
    apiKey: process.env.ENSO_API_KEY || "your-api-key-here",
  });

  const usdcBeraToEthPools = await client.getLayerZeroPool({
    chainId: BERACHAIN_ID,
    token: USDC_BERACHAIN,
    destinationChainId: ETHEREUM_ID + "",
  });

  const rusdEthToBeraPools = await client.getLayerZeroPool({
    chainId: ETHEREUM_ID,
    token: RUSD_ETHEREUM,
    destinationChainId: BERACHAIN_ID + "",
  });

  if (!(usdcBeraToEthPools.length && usdcBeraToEthPools.length)) {
    throw new Error("Required pools not available");
  }

  const bundle = await client.getBundleData(
    {
      chainId: BERACHAIN_ID,
      fromAddress: WALLET_ADDRESS,
      spender: WALLET_ADDRESS,
      routingStrategy: "router",
    },
    [
      {
        protocol: "stargate",
        action: "bridge",
        args: {
          primaryAddress: usdcBeraToEthPools[0].pool as Address,
          destinationChainId: ETHEREUM_ID,
          tokenIn: USDC_BERACHAIN,
          amountIn: parseUnits("1000", 6).toString(), // 1000 USDC
          receiver: WALLET_ADDRESS,
          callback: [
            // Step 1: Check USDC balance on Ethereum after bridge
            {
              protocol: "enso",
              action: "balance",
              args: {
                token: USDC_ETHEREUM,
              },
            },
            // Step 2: Mint e-rUSD using bridged USDC
            {
              protocol: "reservoir",
              action: "deposit",
              args: {
                primaryAddress: RESERVOIR_MINTING_CONTRACT,
                tokenIn: USDC_ETHEREUM,
                tokenOut: RUSD_ETHEREUM,
                amountIn: { useOutputOfCallAt: 0 }, // Use USDC from balance check
                receiver: WALLET_ADDRESS,
              },
            },
            // Step 3: Bridge newly minted e-rUSD back to Berachain
            {
              protocol: "stargate",
              action: "bridge",
              args: {
                primaryAddress: rusdEthToBeraPools[0].pool as Address,
                destinationChainId: BERACHAIN_ID,
                tokenIn: RUSD_ETHEREUM,
                amountIn: { useOutputOfCallAt: 1 }, // Use e-rUSD from minting
                receiver: WALLET_ADDRESS,
              },
            },
          ],
        },
      },
    ]
  );
Important considerations
  • This bundle executes multiple crosschain operations atomically - if any step fails, the entire transaction reverts
  • LayerZero bridge fees apply for both USDC and rUSD transfers between chains
  • Gas costs for Ethereum minting and Berachain vault deposit are calculated upfront
  • Bridge timing may vary based on network congestion on both chains

Resources:

Updated