Financiar as pernas

Financiar uma perna é uma simples TransferChecked para o escrow da perna, pelo que qualquer carteira ou sistema de custódia capaz de enviar uma transferência de tokens pode financiá-la. Apenas a leitura do registo da negociação antes do financiamento exige o cliente DvP. O programa verifica os saldos do escrow somente na liquidação; nada valida a transferência quando ela chega, por isso cada parte lê o registo da negociação antes de transferir.

Esta página dá continuidade a criar uma negociação; o cliente e os signatários continuam os mesmos.

Verificar os termos

Criar um registo não requer permissões, e os endereços de escrow derivam apenas do registo e do mint, nunca dos termos. Uma transferência para um escrow pode portanto chegar associada a termos com os quais nunca concordou, incluindo destinos de liquidação que redirecionam os fundos da sua contraparte para um terceiro endereço. Antes de financiar, leia a conta SwapDvp e confira-a com a negociação acordada.

verifySwapDvp em TypeScript e verify::decode_swap_dvp_account em Rust confirmam que a conta pertence ao programa DvP, tem exatamente 458 bytes e está no endereço que os seus próprios campos derivam (fetchSwapDvpChecked executa apenas as duas primeiras verificações). Os leitores simples fetchSwapDvp e decodeSwapDvp não executam nenhuma destas verificações. As verificações de partes, montantes, prazos e destinos são feitas pelo chamador em relação à negociação 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");
}

Se o registo foi criado pela sua contraparte ou pela autoridade de liquidação, compare cada campo com os termos que acordou fora do ledger. Se foi você quem o criou, esta leitura confirma que ele chegou tal como foi enviado.

Transferir para o escrow

Financie a perna exatamente com o montante acordado. O programa limita a liquidação a amount_x e devolve qualquer excedente à parte da perna, pelo que o excedente não se perde, mas acrescenta uma segunda transferência na liquidação e pode falhar com alguns transfer hooks (consulte as notas abaixo).

Use TransferChecked, e não uma Transfer sem verificação. Os mints Token-2022 com extensões que dependem da mint account, como Pausable, rejeitam uma transferência que não a forneça, e um mint com transfer hook exige que as contas do hook sejam resolvidas e anexadas da mesma forma que em qualquer outra transferência desse token.

A parte da perna de ativo, assinando como userASigner, financia o 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]);

A parte da perna de numerário faz o mesmo para o escrow B com userBAtaB, mintB, userBSigner, t.amountB e { programAddress: tokenProgramB }.

Uma transferência de financiamento vista em confirmed ainda pode ser substituída. O programa lê o saldo do escrow on-chain na liquidação, por isso uma instrução Settle enviada com base numa transferência de financiamento que não chegou falha com LegNotFunded e nada é movimentado; o custo é uma Settle falhada e uma nova tentativa. Considere uma perna como financiada quando a sua transferência estiver finalized.

Notas

  • Pernas em SOL embrulhado (wrapped SOL). O programa lê o saldo de um escrow nativo depois de o sincronizar, por isso os lamports enviados para um escrow de wrapped SOL através de uma transferência do sistema são contabilizados. Nunca envie SOL para um escrow de qualquer outro mint: o programa não consegue devolvê-lo, e ele vai para quem fechar a conta.
  • Mints com restrições. Num mint com Default Account State congelado, o escrow é criado congelado e a transferência falha até o emissor o descongelar ou o admitir. A visão geral descreve a interação com o Token ACL.
  • Transfer hooks. Financie escrows com hooks exatamente com o montante acordado. Se um excedente obrigar a um reembolso na liquidação, o reembolso reutiliza as contas do hook da perna com um destino e um montante diferentes, o que alguns hooks rejeitam. A recuperação consiste em Reclaim, voltar a financiar com o montante exato e liquidar novamente.
  • Financiar após o vencimento. Nada impede uma transferência após expiry_timestamp. Ela chega, a liquidação já não é possível, e a parte da perna recupera o valor com Reclaim enquanto a negociação estiver aberta ou com Recover depois de ela fechar. Consulte desfazer uma negociação.
  • Quem financia primeiro. O programa não ordena as duas pernas. A ordem é decidida pelas partes; qualquer um dos lados pode recuperar a sua própria perna a qualquer momento antes da liquidação, a menos que uma autoridade do mint (congelamento, pausa ou transfer hook) bloqueie o escrow.

Próximos passos

Is this page helpful?

Índice

Editar Página
© 2026 Fundação Solana. Todos os direitos reservados.