YoGateway Integration Guide

Overview

The YoGateway contract is the single entry point for interacting with YO's ERC-4626 vaults. It provides a unified interface for deposits and redemptions across all YO vaults and automatically manages:

  • Asset transfers

  • Allowances and approvals

  • Vault interactions

It also enables:

  • Partner attribution tracking

  • Real-time quoting for assets ↔ shares

  • Built-in slippage protection

In this way, partners can integrate with one single interface and add support for all existing and future YO vaults at once.

Ping us on our Discord or Telegram to get your unique partner ID.

Contract Addresses

Contract
Address

YoGateway

0xF1EeE0957267b1A474323Ff9CfF7719E964969FA

yoETH

0x3a43aec53490cb9fa922847385d82fe25d0e9de7

yoUSD

0x0000000f2eb9f69274678c76222b35eec7588a65

yoBTC

0xbcbc8cb4d1e8ed048a6276a5e94a3e952660bcbc


Instantiation

Solidity:

IYoGateway gateway = IYoGateway(0xF1EeE0957267b1A474323Ff9CfF7719E964969FA);

JS/Ethers:

import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://mainnet.base.org");
const gateway = new ethers.Contract(
  "0xF1EeE0957267b1A474323Ff9CfF7719E964969FA",
  YoGatewayAbi,
  provider
);

Quoting

Convert Assets → Shares

Solidity:

uint256 shares = gateway.quoteConvertToShares(yoVault, assets);

JS/Ethers:

const shares = await gateway.quoteConvertToShares(yoVault, ethers.parseUnits("1", decimals));

Convert Shares → Assets

Solidity:

uint256 assets = gateway.quoteConvertToAssets(yoVault, shares);

JS/Ethers:

const assets = await gateway.quoteConvertToAssets(yoVault, ethers.parseUnits("1", decimals));

Allowance Helpers

The Gateway exposes helper functions to query allowances granted to the Gateway itself, either for redeeming shares or for depositing assets.

Solidity

gateway.getShareAllowance(yoVault, owner);
gateway.getAssetAllowance(yoVault, owner);

JS/Ethers:

const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const yoETH = "0x3a43aec53490cb9fa922847385d82fe25d0e9de7";
const asset = "0x4200000000000000000000000000000000000006";

const shareAllowance = await gateway.getShareAllowance(yoVault, signer.address);
const assetAllowance = await gateway.getAssetAllowance(asset, signer.address);

Depositing Assets

Solidity:

gateway.deposit(
    yoVault,       // yoVault address
    assets,        // amount of assets
    minSharesOut,  // slippage protection, quote first to pass the result as the amount of shares
    receiver,      // recipient of shares
    partnerId      // attribution
);

JS/Ethers:

const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const gatewayWithSigner = gateway.connect(signer);

const tx = await gatewayWithSigner.deposit(
  yoVault,                        // yoVault address
  ethers.parseUnits("1.0", 18),   // 1 WETH
  ethers.parseUnits("0.99", 18),  // minSharesOut, quote first to pass the result as the amount of shares
  signer.address,                 // receiver, recipient of shares
  1234                            // partnerId
);

await tx.wait();

Redeeming Shares

Solidity:

gateway.redeem(
    yoVault,        // yoVault address
    shares,         // shares to redeem
    minAssetsOut,   // slippage protection, quote first to pass the result as the amount of shares
    receiver,       // recipient of assets
    partnerId       // attribution
);

JS/Ethers:

const tx = await gatewayWithSigner.redeem(
  yoVault,                        // yoVault address
  ethers.parseUnits("1.0", 18),   // shares to redeem
  ethers.parseUnits("0.99", 18),  // minAssetsOut, quote first to pass the result as the amount of shares
  signer.address,                 // receiver of assets
  1234                            // partnerId
);

await tx.wait();

Function Recap

Action
Quote Function
Execution Function

Deposit (assets→shares)

quoteConvertToShares

deposit

Redeem (shares→assets)

quoteConvertToAssets

redeem


Notes

  1. Decimals must be respected when parsing values

    • WETH / yoETH: 18

    • cbBTC / yoBTC: 8

    • USDC / yoUSD: 6

    Example: ethers.parseUnits("1.0", 18)

  2. Redemption Liquidity

    • When calling redeem(), if the target vault does not have sufficient liquidity, the redemption will remain pending for up to 24 hours.

    • Once filled, the vault will send assets directly to the specified receiver.


End-to-End Example (Deposit + Redeem with min-out estimation)

Below is a complete example using yoETH that covers: quoting, estimating minSharesOut and minAssetsOut via quoteConvertTo*, checking allowances, depositing, and redeeming.

import { ethers } from "ethers";
import YoGatewayAbi from "./abis/YoGateway.json" assert { type: "json" };
import ERC20Abi from "./abis/ERC20.json" assert { type: "json" };

async function main() {
  const provider = new ethers.JsonRpcProvider("https://mainnet.base.org");
  const signer = new ethers.Wallet(PRIVATE_KEY, provider);

  const gatewayAddr = "0xF1EeE0957267b1A474323Ff9CfF7719E964969FA";
  const yoETH = "0x3a43aec53490cb9fa922847385d82fe25d0e9de7";

  const gateway = new ethers.Contract(gatewayAddr, YoGatewayAbi, signer);

  // ERC20 reference for WETH (asset of yoETH)
  const WETH = "0x4200000000000000000000000000000000000006"; // canonical WETH on Base
  const weth = new ethers.Contract(WETH, ERC20Abi, signer);

  // ---- STEP 1: QUOTE & DEPOSIT ----
  const depositAssets = ethers.parseUnits("1.0", 18);   // 1 WETH
  const quotedShares = await gateway.quoteConvertToShares(yoETH, depositAssets);
  const minSharesOut = quotedShares * 99n / 100n;       // 1% slippage buffer

  console.log("Quoted shares for deposit:", quotedShares.toString());
  console.log("minSharesOut:", minSharesOut.toString());

  // Approve WETH to Gateway if needed
  const currentAssetAllowance = await gateway.getAssetAllowance(yoETH, signer.address);
  if (currentAssetAllowance < depositAssets) {
    const approveTx = await weth.approve(gatewayAddr, depositAssets);
    await approveTx.wait();
  }

  // Deposit WETH into yoETH
  const depositTx = await gateway.deposit(yoETH, depositAssets, minSharesOut, signer.address, 1234);
  await depositTx.wait();
  console.log("Deposit confirmed:", depositTx.hash);

  // ---- STEP 2: QUOTE & REDEEM ----
  const redeemShares = ethers.parseUnits("0.5", 18);    // redeem half the shares
  const quotedAssets = await gateway.quoteConvertToAssets(yoETH, redeemShares);
  const minAssetsOut = quotedAssets * 99n / 100n;       // 1% slippage buffer

  console.log("Quoted assets for redemption:", quotedAssets.toString());
  console.log("minAssetsOut:", minAssetsOut.toString());

  // Approve yoETH shares to Gateway if needed
  const sharesAllowance = await gateway.getShareAllowance(yoETH, signer.address);
  if (sharesAllowance < redeemShares) {
    const approveSharesTx = await (new ethers.Contract(yoETH, ERC20Abi, signer)).approve(gatewayAddr, redeemShares);
    await approveSharesTx.wait();
  }

  // Redeem yoETH shares back into WETH
  const redeemTx = await gateway.redeem(yoETH, redeemShares, minAssetsOut, signer.address, 1234);
  const receipt = await redeemTx.wait();
  console.log("Redeem submitted:", receipt.hash);
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});

Last updated