Redeem
bulkWithdraw
bulkWithdraw
TypeScript Example
Note: This example assumes you have a walletClient configured in your code base. Please refer to https://viem.sh/docs/clients/wallet for detailed documentation.
import {
parseUnits,
isAddress,
type Address,
} from "viem";
import { publicClient, walletClient } from "./client"; // Assumes client.ts is in the same folder
// --- ABIs ---
const tellerAbi = [
/* ... (start of ABI) ... */
{
inputs: [
{ internalType: "contract ERC20", name: "withdrawAsset", type: "address" },
{ internalType: "uint256", name: "shareAmount", type: "uint256" },
{ internalType: "uint256", name: "minimumAssets", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
],
name: "bulkWithdraw",
outputs: [{ internalType: "uint256", name: "assetsOut", type: "uint256" }],
stateMutability: "nonpayable",
type: "function",
},
/* ... (rest of the ABI) ... */
] as const;
const accountantAbi = [
{
inputs: [{ internalType: "address", name: "asset", type: "address" }],
name: "getRateInQuote",
outputs: [{ internalType: "uint256", name: "rate", type: "uint256" }],
stateMutability: "view",
type: "function",
},
] as const;
// --- Main Withdraw Function ---
async function makeBulkWithdraw({
tellerAddress,
accountantAddress,
withdrawAssetAddress,
shareAmount, // The amount of shares to withdraw, as a string
slippageBps = 50, // 50 bps = 0.5%
recipient,
}: {
tellerAddress: Address;
accountantAddress: Address;
withdrawAssetAddress: Address;
shareAmount: string;
slippage?: number;
recipient: Address;
}) {
if (!isAddress(tellerAddress) || tellerAddress === "0x...") {
console.error("A valid teller contract address is required.");
return;
}
try {
// 1. Convert the human-readable share amount to its base unit (uint256)
const parsedShareAmount = parseUnits(shareAmount, 6);
// 2. Fetch the rate from the blockchain to calculate expected output
console.log("Fetching current rate from accountant...");
const rate = await publicClient.readContract({
abi: accountantAbi,
address: accountantAddress,
functionName: "getRateInQuote",
args: [withdrawAssetAddress],
});
console.log(`Rate received: ${rate}`);
// 3. Calculate the minimumAssets value using our helper
const minimumAssets = calculateMinimumAssetsOut(
parsedShareAmount,
rate,
slippageBps,
);
console.log(`Calculated minimum assets to receive: ${minimumAssets}`);
// 4. Use `writeContract` to send the transaction
const hash = await walletClient.writeContract({
abi: tellerAbi,
address: tellerAddress,
functionName: "bulkWithdraw",
args: [withdrawAssetAddress, parsedShareAmount, minimumAssets, recipient],
});
console.log(`Transaction sent! Hash: ${hash}`);
console.log("Waiting for transaction to be mined...");
// 5. Wait for the transaction to be included in a block
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("Transaction was successfully mined!");
console.log(`- Block Number: ${receipt.blockNumber}`);
console.log(
`- View on Etherscan: https://etherscan.io/tx/${receipt.transactionHash}`,
);
} catch (err) {
console.error("Error sending bulk withdraw transaction:", err);
}
}
// --- Execution Example ---
/* ... (start of Withdrawl function) ... */
// Call the function to withdraw 100 shares
await makeBulkWithdraw({
tellerAddress: myTellerAddress,
accountantAddress: myAccountantAddress,
withdrawAssetAddress: usdcAddress,
shareAmount: "100.0", // The number of shares to burn
recipient: recipientAddress,
slippageBps: 50, // Optional: 0.5% slippage
});
/* ... (rest of Withdrawl function) ... */
TypeScript Helper Functions
const calculateMinimumAssetsOut = (
shareAmount: bigint,
rate: bigint,
slippage: number, // In bps (e.g., 50 for 0.5%)
): bigint => {
// Convert bps to WAD format (multiply by WAD/10000)
const slippageAsBigInt = (BigInt(slippage) * WAD.bigint) / 10000n;
// Calculate ideal asset amount without slippage
// idealAssets = shareAmount * rate (with WAD precision)
const wantAssetsOut = (shareAmount * rate) / WAD.bigint;
// Calculate the amount to subtract for slippage tolerance
const slippageAmount = (idealAssetsOut * slippageAsBigInt) / WAD.bigint;
// Return asset amount minus slippage buffer
return wantAssetsOut - slippageAmount;
};
Last updated