# yoGateway Integration Guide

## Overview

The [**yoGateway**](https://basescan.org/address/0xF1EeE0957267b1A474323Ff9CfF7719E964969FA) 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.&#x20;

yoGateway is available on **Base, Ethereum and Arbitrum** to handle deposits and redemptions on each chain independently. This means if you integrate yoGateway on Base, your users will receive their yoVault tokens on Base and can only be redeemed on Base. &#x20;

Ping us on our [Discord](http://discord.gg/yoprotocol) or [Telegram](https://t.me/yo_protocol) to get your unique partner ID or if you have further questions.&#x20;

## Contract Addresses

<table><thead><tr><th width="144.61328125">Contract</th><th>Address</th></tr></thead><tbody><tr><td>YoGateway</td><td>0xF1EeE0957267b1A474323Ff9CfF7719E964969FA</td></tr></tbody></table>

***

## Instantiation

*Solidity:*

```solidity
IYoGateway gateway = IYoGateway(0xF1EeE0957267b1A474323Ff9CfF7719E964969FA);
```

*JS/Ethers:*

```js
import { ethers } from "ethers";

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

{% file src="<https://2576447856-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fwkm0XGONc7sDuNeJww6d%2Fuploads%2FV3ddkwPFPLhUJDniJYS7%2FyoGatewayAbi.json?alt=media&token=16dcdeb0-473d-4884-b721-3b3faf59cc7b>" %}

***

## Quoting

### Convert Assets → Shares

*Solidity:*

```solidity
uint256 shares = gateway.quotePreviewDeposit(yoVault, assets);
```

*JS/Ethers:*

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

### Convert Shares → Assets

*Solidity:*

```solidity
uint256 assets = gateway.quotePreviewWithdraw(yoVault, shares);
```

*JS/Ethers:*

```js
const assets = await gateway.quotePreviewWithdraw(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*

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

JS/Ethers:

```javascript
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:

```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:*

```js
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 using quotePreviewDeposit() first to pass the result as the amount of shares
  signer.address,                 // receiver, recipient of shares
  1234                            // your unique partnerId
);

await tx.wait();
```

***

## Redeeming Shares

*Solidity:*

```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:*

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

await tx.wait();
```

***

## Function Recap

| Action                  | Quote Function         | Execution Function |
| ----------------------- | ---------------------- | ------------------ |
| Deposit (assets→shares) | `quotePreviewDeposit`  | `deposit`          |
| Redeem (shares→assets)  | `quotePreviewWithdraw` | `redeem`           |

***

## Notes

1. **Decimals must be respected when parsing values**

   * WETH / yoETH: <mark style="color:red;">18</mark>
   * cbBTC / yoBTC: <mark style="color:red;">8</mark>
   * USDC / yoUSD: <mark style="color:red;">6</mark>
   * USDT / yoUSDT: <mark style="color:red;">6</mark>
   * EURC / yoEUR: <mark style="color:red;">6</mark>
   * XAUT / yoGOLD: <mark style="color:red;">6</mark>

   \
   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`**.
3. **Slippage protection calculations** must be net of fees. Currently, the protocol does not charge any deposit or withdrawal fees, so the impact of fees is obviated in the examples quoted.<br>

***

### 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.

```js
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"); // use an Ethereum or Base RPC provider. mainnet.base.org used as an example
  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.quotePreviewDeposit(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.quotePreviewWithdraw(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);
});
```
