Fondear los tramos

Fondear es un simple TransferChecked al escrow del tramo, por lo que cualquier billetera o sistema de custodia que pueda enviar una transferencia de tokens puede fondear un tramo. Solo la lectura de la cuenta de la operación antes de fondear requiere el cliente DvP. El programa comprueba los saldos del escrow únicamente en la liquidación; nada verifica la transferencia cuando llega, por lo que cada parte lee la cuenta de la operación antes de transferir.

Esta página continúa desde crear una operación; el cliente y los firmantes se mantienen.

Verifica los términos

Crear un registro no requiere permisos, y las direcciones de escrow se derivan únicamente del registro y del mint, nunca de los términos. Por lo tanto, una transferencia a un escrow puede llegar asociada a términos que nunca acordaste, incluidos destinos de liquidación que redirigen los fondos de tu contraparte a una tercera dirección. Antes de fondear, lee la cuenta SwapDvp y compárala con la operación acordada.

verifySwapDvp en TypeScript y verify::decode_swap_dvp_account en Rust confirman que la cuenta pertenece al programa DvP, tiene exactamente 458 bytes y se encuentra en la dirección que derivan sus propios campos (fetchSwapDvpChecked realiza solo las dos primeras comprobaciones). Los lectores simples fetchSwapDvp y decodeSwapDvp no realizan ninguna de ellas. Las comprobaciones de partes, importes, plazos y destinos las realiza quien llama, contrastándolas con la operación acordada.

import { unwrapOption } from "@solana/kit";
import { verifySwapDvp } from "./dvp";
const trade = await verifySwapDvp(client.rpc, swapDvp);
const t = trade.data;
const expectedAmountA = 1_000_000_000n;
const expectedAmountB = 998_500_000n;
const expectedEarliestSettlement: bigint | null = null; // as agreed
const expectedExpiry = 1_798_761_600n; // as agreed, unix seconds
if (
t.userA !== userA ||
t.userB !== userB ||
t.mintA !== mintA ||
t.mintB !== mintB ||
t.settlementAuthority !== settlementAuthority ||
t.tokenProgramA !== tokenProgramA ||
t.tokenProgramB !== tokenProgramB ||
t.amountA !== expectedAmountA ||
t.amountB !== expectedAmountB ||
unwrapOption(t.earliestSettlementTimestamp) !== expectedEarliestSettlement ||
t.expiryTimestamp !== expectedExpiry ||
t.userASettlementDestination !== userA ||
t.userBSettlementDestination !== userB
) {
throw new Error("Stored terms do not match the agreed trade; do not fund");
}
if (t.expiryTimestamp <= BigInt(Math.floor(Date.now() / 1000)) + 60n) {
throw new Error("Trade expires too soon to fund safely");
}

Si el registro fue creado por tu contraparte o por la autoridad de liquidación, compara cada campo con los términos que acordaste fuera del libro mayor. Si lo creaste tú mismo, esta lectura confirma que llegó tal como se envió.

Transferir al escrow

Fondea el tramo exactamente con el importe acordado. El programa limita la liquidación a amount_x y devuelve cualquier excedente a la parte del tramo, por lo que el excedente no se pierde, pero añade una segunda transferencia en la liquidación y puede fallar con algunos transfer hooks (consulta las notas más abajo).

Usa TransferChecked, no un Transfer sin verificación. Los mints de Token-2022 con extensiones que dependen de la mint account, como Pausable, rechazan una transferencia que no la incluya, y un mint con transfer hook requiere que las cuentas del hook se resuelvan y se añadan igual que en cualquier otra transferencia de ese token.

La parte del tramo del activo, firmando como userASigner, fondea el escrow A:

import {
findAssociatedTokenPda,
getTransferCheckedInstruction,
} from "@solana-program/token-2022";
const [userAAtaA] = await findAssociatedTokenPda({
mint: mintA,
owner: userA,
tokenProgram: tokenProgramA,
});
const [userBAtaB] = await findAssociatedTokenPda({
mint: mintB,
owner: userB,
tokenProgram: tokenProgramB,
});
const fundAssetLeg = getTransferCheckedInstruction({
source: userAAtaA,
mint: mintA,
destination: escrowA,
authority: userASigner,
amount: t.amountA,
decimals: 6,
}, { programAddress: tokenProgramA });
await client.sendTransaction([fundAssetLeg]);

La parte del tramo de efectivo hace lo mismo para el escrow B con userBAtaB, mintB, userBSigner, t.amountB y { programAddress: tokenProgramB }.

Una transferencia de fondeo vista en confirmed aún puede ser reemplazada. El programa lee el saldo del escrow onchain en la liquidación, por lo que un Settle enviado frente a una transferencia de fondeo que no llegó falla con LegNotFunded y no se mueve nada; el costo es un Settle fallido y un reintento. Considera un tramo como fondeado cuando su transferencia esté en finalized.

Notas

  • Tramos de SOL envuelto (wrapped SOL). El programa lee el saldo de un escrow nativo tras sincronizarlo, por lo que los lamports enviados a un escrow de wrapped SOL mediante una transferencia del sistema se contabilizan. Nunca envíes SOL a un escrow de ningún otro mint: el programa no puede devolverlo, y va a parar a quien cierre la cuenta.
  • Mints restringidos. En un mint con Default Account State en estado congelado, el escrow se crea congelado y la transferencia falla hasta que el emisor lo descongele o lo admita. La descripción general explica la interacción con Token ACL.
  • Transfer hooks. Fondea los escrows con hooks exactamente con el importe acordado. Si un excedente obliga a un reembolso en la liquidación, el reembolso reutiliza las cuentas del hook del tramo con un destino e importe distintos, lo que algunos hooks rechazan. La recuperación consiste en Reclaim, volver a fondear con el importe exacto y liquidar de nuevo.
  • Fondeo tras el vencimiento. Nada impide una transferencia después de expiry_timestamp. Esta llega, la liquidación ya no es posible, y la parte del tramo la recupera con Reclaim mientras la operación está abierta o con Recover una vez cerrada. Consulta deshacer una operación.
  • Quién fondea primero. El programa no establece un orden entre los dos tramos. El orden depende de las partes; cualquiera de ellas puede reclamar su propio tramo en cualquier momento antes de la liquidación, salvo que una autoridad del mint (congelación, pausa o transfer hook) bloquee el escrow.

Próximos pasos

Is this page helpful?

Tabla de Contenidos

Editar Página