{"version":3,"sources":["../../../src/vaults/withdraw/withdraw.ts"],"sourcesContent":["/**\n * @file Withdraw functionality for Nucleus vaults\n * @module vaults/withdraw\n */\n\nimport { type Address, parseUnits } from \"viem\";\nimport { getRateInQuoteAndSharesAndWantAssetDecimals } from \"../../api/accountant\";\nimport { getErc20Decimals } from \"../../api/erc20\";\nimport { getAssetSlippage } from \"../../api/solver-slippage\";\nimport { type ChainId, toChainId } from \"../../api/vault-config\";\nimport {\n  ATOMIC_QUEUE_CONTRACT_ADDRESS,\n  DEFAULT_APPROVAL_AMOUNT,\n  DEFAULT_DEADLINE,\n  DEFAULT_WITHDRAW_SLIPPAGE,\n} from \"../../constants\";\nimport { AtomicQueueAbi } from \"../../contracts/atomic-queue-abi\";\nimport { BoringVaultAbi } from \"../../contracts/boring-vault-abi\";\nimport { tryCatch } from \"../../utils/try-catch\";\nimport {\n  type BridgeTransactionData,\n  prepareBridgeTransactionData,\n} from \"../bridge\";\nimport type { VaultKey } from \"../config\";\nimport { getVaultByKey } from \"../index\";\nimport type { TokenKey } from \"../tokens\";\nimport { calculateAtomicPrice, prepareUserRequest } from \"./utils\";\n\n/**\n * Arguments for an atomic request to the AtomicQueue contract\n * @typedef {Object} AtomicRequestArgs\n * @property {Address} offer - Address of the token being offered (shares token address)\n * @property {Address} want - Address of the token being requested (want token address)\n * @property {UserRequest} userRequest - User request details\n */\nexport type AtomicRequestArgs = {\n  offer: Address; // sharesTokenAddress\n  want: Address; // wantTokenAddress\n  userRequest: UserRequest; // userRequest\n};\n\n/**\n * Options for an atomic request\n * @typedef {Object} AtomicRequestOptions\n * @property {Address} atomicQueueContractAddress - Address of the AtomicQueue contract\n * @property {number} chainId - ID of the destination chain\n */\nexport type AtomicRequestOptions = {\n  atomicQueueContractAddress: Address; // atomicQueueContractAddress\n  chainId: ChainId; // destinationChainId\n};\n\n/**\n * User request details for an atomic swap\n * @typedef {Object} UserRequest\n * @property {number} deadline - Unix timestamp when the request expires\n * @property {bigint} atomicPrice - Rate in quote with fee applied\n * @property {bigint} offerAmount - Amount of shares token to redeem\n * @property {boolean} inSolve - Whether the request is in solve mode (always false for new requests)\n */\nexport type UserRequest = {\n  deadline: bigint; // deadline\n  atomicPrice: bigint; // rateInQuoteWithFee\n  offerAmount: bigint; // redeemAmount\n  inSolve: boolean; // false\n};\n\n/**\n * Parameters for preparing a withdrawal transaction from a vault\n * @interface PrepareWithdrawTransactionDataParams\n * @property {ChainId} chainId - ID of the chain where the withdrawal will occur\n * @property {number} [deadline] - Unix timestamp when the request expires (optional)\n * @property {number} offerAmount - Amount of vault shares to withdraw\n * @property {number} [slippage] - Maximum acceptable slippage percentage (optional)\n * @property {Address} userAddress - Ethereum address of the user making the withdrawal\n * @property {VaultKey} vaultKey - Unique identifier for the vault\n * @property {TokenKey} wantTokenSymbol - Symbol of the token the user wants to receive\n */\ninterface PrepareWithdrawTransactionDataParams {\n  chainId: ChainId;\n  deadline?: number;\n  offerAmount: string;\n  slippage?: number;\n  userAddress: Address;\n  vaultKey: VaultKey;\n  wantTokenSymbol: TokenKey;\n}\n\n/**\n * Result object containing transaction data for a withdrawal operation\n * @interface WithdrawTransactionData\n * @property {typeof AtomicQueueAbi} abi - ABI for the AtomicQueue contract\n * @property {Address} address - Address of the AtomicQueue contract\n * @property {'updateAtomicRequest'} functionName - Name of the function to call\n * @property {[Address, Address, UserRequest]} args - Arguments for the updateAtomicRequest function:\n *   [offer, want, userRequest]\n * @property {number} chainId - ID of the chain where the transaction should be executed\n */\ninterface WithdrawTransactionData {\n  abi: typeof AtomicQueueAbi;\n  address: Address;\n  functionName: \"updateAtomicRequest\";\n  args: [offer: Address, want: Address, userRequest: UserRequest];\n  chainId: number;\n}\n\n/**\n * Prepares the transaction data needed to withdraw assets from a vault\n *\n * This function calculates the appropriate exchange rate with slippage protection\n * and prepares a user request for the AtomicQueue contract. It returns a transaction\n * object that can be used with viem or ethers.js to execute the withdrawal.\n *\n * @example\n * ```typescript\n * const withdrawData = await prepareWithdrawData({\n *   vaultKey: 'bobaeth',\n *   chainId: 1, // Ethereum mainnet\n *   userAddress: '0x1234...',\n *   wantAsset: TokenKey.WETH,\n *   redeemAmount: BigInt('1000000000000000000'), // 1 token\n *   deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now\n *   slippage: 0.01, // 1% slippage\n * });\n * ```\n *\n * @param {PrepareWithdrawTransactionParams} params - Parameters for the withdraw operation\n * @param {VaultKey} params.vaultKey - Unique identifier for the vault\n * @param {ChainId} params.chainId - ID of the chain where the withdrawal will occur\n * @param {Address} params.userAddress - Ethereum address of the user making the withdrawal\n * @param {TokenKey} params.wantAsset - Key of the asset the user wants to receive\n * @param {bigint} params.offerAmount - Amount of vault tokens to redeem (in base units)\n * @param {number} [params.deadline] - Unix timestamp when the request expires\n * @param {number} [params.slippage] - Maximum acceptable slippage in basis points (bps).\n *                                     e.g., 20 for 0.2%, 50 for 0.5%\n *\n * @returns {Promise<WithdrawTransactionData>} Promise resolving to the prepared transaction data\n * @throws {Error} If the vault key is invalid, if contracts are not properly configured,\n *                 or if the specified chain or token is not supported\n */\nconst prepareWithdrawTransactionData = async ({\n  vaultKey,\n  chainId,\n  wantTokenSymbol,\n  offerAmount,\n  deadline = DEFAULT_DEADLINE,\n  slippage,\n}: PrepareWithdrawTransactionDataParams): Promise<WithdrawTransactionData> => {\n  const vault = await getVaultByKey(vaultKey);\n  const normalizedChainId = toChainId(chainId);\n  if (!vault) {\n    throw new Error(`Invalid vault key: ${vaultKey}`);\n  }\n\n  if (!vault.contracts) {\n    throw new Error(`Contracts not configured for vault ${vaultKey}`);\n  }\n\n  // Check if contracts exist\n  if (!vault.contracts.boringVault) {\n    throw new Error(\n      `BoringVault contract not configured for vault ${vaultKey}`\n    );\n  }\n  const boringVaultAddress = vault.contracts.boringVault;\n\n  if (!vault.contracts.accountant) {\n    throw new Error(`Accountant contract not configured for vault ${vaultKey}`);\n  }\n  const accountantAddress = vault.contracts.accountant;\n\n  // Updated chain validation\n  const destinationChain =\n    vault.withdraw.sourceChains[normalizedChainId].destinationChains[\n      normalizedChainId\n    ];\n  const wantTokens = destinationChain.wantTokens;\n  if (!!wantTokens && !wantTokens[wantTokenSymbol]) {\n    throw new Error(\n      `Invalid want token \"${wantTokenSymbol}\" for vault ${vaultKey}. ` +\n        `Allowed tokens are: ${Object.keys(wantTokens).join(\", \")}`\n    );\n  }\n\n  const wantAssetAddress = wantTokens[wantTokenSymbol].address;\n  if (!wantAssetAddress) {\n    throw new Error(`Invalid want token symbol: ${wantTokenSymbol}`);\n  }\n\n  const [wantAssetDecimals, sharesAssetDecimals, rateInQuote] =\n    await getRateInQuoteAndSharesAndWantAssetDecimals({\n      sharesAssetAddress: boringVaultAddress,\n      wantAssetAddress: wantAssetAddress,\n      accountantAddress: accountantAddress,\n      chainId: normalizedChainId,\n    });\n\n  if (wantAssetDecimals.status === \"failure\") {\n    throw new Error(wantAssetDecimals.error.message);\n  }\n\n  if (rateInQuote.status === \"failure\") {\n    throw new Error(rateInQuote.error.message);\n  }\n\n  if (sharesAssetDecimals.status === \"failure\") {\n    throw new Error(sharesAssetDecimals.error.message);\n  }\n\n  const formattedOfferAmount = parseUnits(\n    offerAmount,\n    sharesAssetDecimals.result\n  );\n\n  const {\n    data: solverSlippage,\n    error: solverSlippageError,\n    success: solverSlippageSuccess,\n  } = await tryCatch(\n    getAssetSlippage(normalizedChainId, boringVaultAddress, wantAssetAddress)\n  );\n  if (!solverSlippageSuccess) {\n    throw new Error(\n      `Error getting solver slippage: ${solverSlippageError.message}`\n    );\n  }\n  const effectiveSlippage = slippage ?? solverSlippage;\n\n  const atomicPrice = calculateAtomicPrice(\n    rateInQuote.result,\n    wantAssetDecimals.result,\n    effectiveSlippage\n  );\n\n  const userRequest = prepareUserRequest(\n    formattedOfferAmount,\n    atomicPrice,\n    deadline\n  );\n\n  return {\n    abi: AtomicQueueAbi,\n    address: ATOMIC_QUEUE_CONTRACT_ADDRESS,\n    functionName: \"updateAtomicRequest\",\n    args: [boringVaultAddress, wantAssetAddress, userRequest],\n    chainId: normalizedChainId,\n  };\n};\n\n/**\n * Parameters for preparing a cross-chain bridge and withdrawal transaction\n * @interface PrepareBridgeAndWithdrawTransactionDataParams\n * @extends {Omit<PrepareWithdrawTransactionDataParams, 'chainId'>}\n * @property {ChainId} sourceChainId - Chain ID where shares currently exist\n * @property {ChainId} destinationChainId - Chain ID where assets will be withdrawn\n * @property {number} offerAmount - Amount of vault shares to withdraw\n * @property {number} [deadline] - Unix timestamp when the request expires (optional)\n * @property {number} [slippage] - Maximum acceptable slippage percentage (optional)\n * @property {Address} userAddress - Ethereum address of the user making the withdrawal\n * @property {VaultKey} vaultKey - Unique identifier for the vault\n * @property {TokenKey} wantTokenSymbol - Symbol of the token the user wants to receive\n */\ninterface PrepareBridgeAndWithdrawTransactionDataParams\n  extends Omit<PrepareWithdrawTransactionDataParams, \"chainId\"> {\n  sourceChainId: ChainId;\n  destinationChainId: ChainId;\n}\n\n/**\n * Combined result containing both bridge and withdrawal transaction data\n * @interface BridgeAndWithdrawResult\n */\ninterface BridgeAndWithdrawTransactionData {\n  bridgeTransactionData: BridgeTransactionData; // Data for bridging shares to destination chain\n  withdrawTransactionData: WithdrawTransactionData; // Data for withdraw request on destination chain\n}\n\n/**\n * Prepares transaction data for cross-chain withdrawals from a vault\n *\n * This function handles both:\n * 1. Bridging vault shares from source chain to destination chain\n * 2. Creating a withdraw request on the destination chain\n *\n * The withdraw request can be submitted before the bridge completes - the solver\n * will wait for bridged shares to arrive before processing the request.\n *\n * @example\n * ```typescript\n * const result = await prepareBridgeAndWithdrawData({\n *   vaultKey: 'bobaeth',\n *   sourceChainId: 42161, // Arbitrum\n *   destinationChainId: 1, // Ethereum\n *   userAddress: '0x1234...',\n *   wantTokenSymbol: TokenKey.ETH,\n *   offerAmount: 1.5, // 1.5 shares\n *   deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour\n *   slippage: 0.005 // 0.5%\n * });\n * ```\n *\n * @param {PrepareBridgeAndWithdrawParams} params - Parameters for the cross-chain withdraw\n * @returns {Promise<BridgeAndWithdrawResult>} Transaction data for both bridge and withdraw operations\n * @throws {Error} If vault configuration is invalid or if preparing either transaction fails\n */\nconst prepareBridgeAndWithdrawTransactionData = async ({\n  deadline = DEFAULT_DEADLINE,\n  destinationChainId,\n  offerAmount,\n  slippage = DEFAULT_WITHDRAW_SLIPPAGE,\n  sourceChainId,\n  userAddress,\n  vaultKey,\n  wantTokenSymbol,\n}: PrepareBridgeAndWithdrawTransactionDataParams): Promise<BridgeAndWithdrawTransactionData> => {\n  const vault = await getVaultByKey(vaultKey);\n  if (!vault) {\n    throw new Error(`Invalid vault key: ${vaultKey}`);\n  }\n\n  const {\n    data: withdrawTransactionData,\n    error: withdrawError,\n    success: withdrawSuccess,\n  } = await tryCatch(\n    prepareWithdrawTransactionData({\n      vaultKey,\n      chainId: destinationChainId,\n      userAddress,\n      wantTokenSymbol,\n      offerAmount,\n      deadline,\n      slippage,\n    })\n  );\n\n  if (!withdrawSuccess) {\n    throw new Error(withdrawError.message);\n  }\n\n  const { args } = withdrawTransactionData;\n  const [, , userRequest] = args;\n  const { offerAmount: bridgeAmount } = userRequest;\n\n  const {\n    data: bridgeTransactionData,\n    error: bridgeError,\n    success: bridgeSuccess,\n  } = await tryCatch(\n    prepareBridgeTransactionData({\n      vaultKey,\n      bridgeAmount: bridgeAmount,\n      sourceChainId,\n      destinationChainId,\n      userAddress,\n    })\n  );\n\n  if (!bridgeSuccess) {\n    throw new Error(bridgeError.message);\n  }\n\n  return {\n    bridgeTransactionData: bridgeTransactionData,\n    withdrawTransactionData: withdrawTransactionData,\n  };\n};\n\ninterface PrepareApproveWithdrawTokenParams {\n  vaultKey: VaultKey;\n  withdrawAmount?: string;\n  chainId: ChainId;\n}\n\ninterface ApproveWithdrawTokenTransactionData {\n  abi: typeof BoringVaultAbi;\n  address: Address;\n  functionName: \"approve\";\n  args: [Address, bigint];\n}\n\nconst prepareApproveWithdrawToken = async ({\n  vaultKey,\n  withdrawAmount,\n  chainId,\n}: PrepareApproveWithdrawTokenParams): Promise<ApproveWithdrawTokenTransactionData> => {\n  const normalizedChainId = toChainId(chainId);\n  const vault = await getVaultByKey(vaultKey);\n\n  if (!vault) {\n    throw new Error(`Invalid vault key: ${vaultKey}`);\n  }\n\n  if (!vault.contracts) {\n    throw new Error(`Contracts not configured for vault ${vaultKey}`);\n  }\n\n  if (!vault.contracts.boringVault) {\n    throw new Error(`Teller contract not configured for vault ${vaultKey}`);\n  }\n  const withdrawAssetAddress = vault.contracts.boringVault;\n\n  const {\n    data: withdrawAssetDecimals,\n    error: withdrawAssetDecimalsError,\n    success: withdrawAssetDecimalsSuccess,\n  } = await tryCatch(\n    getErc20Decimals({\n      chainId: normalizedChainId,\n      tokenAddress: withdrawAssetAddress,\n    })\n  );\n\n  if (!withdrawAssetDecimalsSuccess) {\n    throw new Error(\n      `Error getting withdraw asset decimals. ${withdrawAssetDecimalsError.name}: ${withdrawAssetDecimalsError.message}`\n    );\n  }\n\n  if (!withdrawAssetDecimals) {\n    throw new Error(`Invalid withdraw token symbol: ${withdrawAssetAddress}`);\n  }\n\n  const withdrawAmountAsBitInt = withdrawAmount\n    ? parseUnits(withdrawAmount, withdrawAssetDecimals)\n    : DEFAULT_APPROVAL_AMOUNT;\n\n  return {\n    abi: BoringVaultAbi,\n    address: withdrawAssetAddress,\n    functionName: \"approve\",\n    args: [ATOMIC_QUEUE_CONTRACT_ADDRESS, withdrawAmountAsBitInt],\n  };\n};\n\nexport {\n  prepareApproveWithdrawToken,\n  prepareBridgeAndWithdrawTransactionData,\n  prepareWithdrawTransactionData,\n};\n\nexport type {\n  ApproveWithdrawTokenTransactionData,\n  BridgeAndWithdrawTransactionData,\n  PrepareBridgeAndWithdrawTransactionDataParams,\n  PrepareWithdrawTransactionDataParams,\n  WithdrawTransactionData,\n};\n"],"mappings":"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","names":[]}