import { playgroundHelper } from "../../helpers/helpers"; import { createPublicClient, encodeFunctionData, http, serializeTransaction, } from "viem"; import { arbitrum } from "viem/chains"; import { chainAdapters, contracts, MPCSignature, utils } from "chainsig.js"; import { stablecoinVaultConstants } from "../constants"; // ERC4626 vault redeem process: // Redeem vault shares to receive USDC back const SHARES_TO_REDEEM = "987059532586498237"; // (18 decimals) const VAULT_ADDRESS = stablecoinVaultConstants.MORPHO_BLUE_ARB_VAULT_ADDRESS; const REDEEM_POLICY_ID = "morpho_blue_arb_usdc_redeem"; const CHAIN_SIG_DERIVED_ADDRESS = stablecoinVaultConstants.ARBITRUM_CHAINSIG_DERIVED_ADDRESS; // Create Arbitrum client const client = createPublicClient({ chain: arbitrum, transport: http(), }); // Setup chain signature contract and adapter for transaction broadcasting const chainSigContract = new contracts.ChainSignatureContract({ networkId: "mainnet", contractId: "v1.signer", }); // setup chain adapter const evmChain = new chainAdapters.evm.EVM({ publicClient: client, contract: chainSigContract, }); async function redeemFromVault(): Promise { console.log("=== Vault Redeem ==="); const redeemTxRequest = await client.prepareTransactionRequest({ account: CHAIN_SIG_DERIVED_ADDRESS, to: VAULT_ADDRESS, data: encodeFunctionData({ abi: stablecoinVaultConstants.vaultAbi, functionName: "redeem", args: [ SHARES_TO_REDEEM, CHAIN_SIG_DERIVED_ADDRESS, // receiver CHAIN_SIG_DERIVED_ADDRESS // owner ], }), type: "eip1559", }); const redeemSerializedTx = serializeTransaction(redeemTxRequest); console.log("Proposing vault redeem transaction..."); // Execute redeem transaction via chain signature policy const redeemSignatures = await playgroundHelper.account.callFunction({ contractId: playgroundHelper.vaultContractId, methodName: "propose_execution", args: { policy_id: REDEEM_POLICY_ID, function_args: redeemSerializedTx, deadline_hours: 0, }, gas: 50000000000000n, // 50 TGas }); // Sign and broadcast redeem transaction console.log("Broadcasting redeem transaction..."); const signedRedeemTx = evmChain.finalizeTransactionSigning({ transaction: redeemTxRequest, rsvSignatures: redeemSignatures.map((v) => utils.cryptography.toRSV(v)), }); const { hash: redeemHash } = await evmChain.broadcastTx(signedRedeemTx); console.log("Redeem transaction hash:", redeemHash); return redeemHash; } async function main() { console.log("Starting ERC4626 vault redeem process..."); console.log("Derived Arbitrum address:", CHAIN_SIG_DERIVED_ADDRESS); try { // Redeem vault shares for USDC const redeemHash = await redeemFromVault(); console.log("\n=== ERC4626 vault redeem process completed successfully! ==="); console.log(`Redeemed ${SHARES_TO_REDEEM} vault shares from ${VAULT_ADDRESS}`); console.log(`Redeem tx: ${redeemHash}`); } catch (error) { console.error("Error during redeem process:", error); throw error; } } // Execute the main function main().catch(console.error);