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
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
Deposit (assets→shares)
quoteConvertToShares
deposit
Redeem (shares→assets)
quoteConvertToAssets
redeem
Notes
Decimals must be respected when parsing values
WETH / yoETH: 18
cbBTC / yoBTC: 8
USDC / yoUSD: 6
Example:
ethers.parseUnits("1.0", 18)
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