Supply to a Pool
Enable a user to supply assets into a Teller ERC4626 pool.
Addresses you’ll need per pool
asset
: ERC20 you deposit (e.g. WBTC)vault
: Teller Pool (ERC4626 vault mints/burns shares)
The following code example is in typescript. These smart contract integrations can be generalized to any codebase.
Minimal ABIs
// ERC20 (approve/allowance/balanceOf/decimals)
export const erc20Abi = [
{ type:'function', name:'decimals', stateMutability:'view', inputs:[], outputs:[{type:'uint8'}]},
{ type:'function', name:'balanceOf', stateMutability:'view', inputs:[{type:'address'}], outputs:[{type:'uint256'}]},
{ type:'function', name:'allowance', stateMutability:'view', inputs:[{type:'address'},{type:'address'}], outputs:[{type:'uint256'}]},
{ type:'function', name:'approve', stateMutability:'nonpayable', inputs:[{type:'address'},{type:'uint256'}], outputs:[{type:'bool'}]},
] as const;
// ERC4626 (deposit/redeem/convertToAssets/balanceOf)
export const erc4626Abi = [
{ type:'function', name:'deposit', stateMutability:'nonpayable', inputs:[{type:'uint256','name':'assets'},{type:'address','name':'receiver'}], outputs:[{type:'uint256'}] },
{ type:'function', name:'redeem', stateMutability:'nonpayable', inputs:[{type:'uint256','name':'shares'},{type:'address','name':'receiver'},{type:'address','name':'owner'}], outputs:[{type:'uint256'}] },
{ type:'function', name:'convertToAssets', stateMutability:'view', inputs:[{type:'uint256','name':'shares'}], outputs:[{type:'uint256'}]},
{ type:'function', name:'balanceOf', stateMutability:'view', inputs:[{type:'address'}], outputs:[{type:'uint256'}]},
] as const;
SUPPLY (approve asset → vault.deposit)
import { useAccount } from 'wagmi';
import { parseUnits } from 'viem';
export async function supply({
client, // wagmi config or public client via useWriteContract
account,
asset,
vault,
amountStr, // e.g. "100"
assetDecimals, // read once and cache
}: {
client: any;
account: `0x${string}`;
asset: `0x${string}`;
vault: `0x${string}`;
amountStr: string;
assetDecimals: number;
}) {
const amount = parseUnits(amountStr, assetDecimals);
// 1) Check allowance; approve if needed (exact, or +1.1x if you prefer a cushion)
const current = await client.readContract({
address: asset, abi: erc20Abi, functionName: 'allowance',
args: [account, vault],
}) as bigint;
if (current < amount) {
await client.writeContract({
address: asset, abi: erc20Abi, functionName: 'approve',
args: [vault, amount], // or Math.ceil(amount * 1.1n) if you want 10% cushion
});
}
// 2) Deposit assets → receive shares
await client.writeContract({
address: vault, abi: erc4626Abi, functionName: 'deposit',
args: [amount, account],
});
}
READS for UI: balances
Supplied in Teller pool (shares held, not staked)
export async function readVaultBalances({ client, vault, user }:{
client:any; vault:`0x${string}`; user:`0x${string}`;
}) {
const shares = await client.readContract({
address: vault, abi: erc4626Abi, functionName: 'balanceOf', args: [user],
}) as bigint;
const assets = await client.readContract({
address: vault, abi: erc4626Abi, functionName: 'convertToAssets', args: [shares],
}) as bigint;
return { shares, assets }; // shares in vault token decimals; assets in underlying decimals
}
Last updated