Financiar as pernas

O financiamento é uma simples TransferChecked para o escrow da perna, de modo que qualquer carteira ou sistema de custódia capaz de enviar uma transferência de token pode financiar uma perna. Somente a leitura do registro da negociação antes do financiamento exige o cliente DvP. O programa verifica os saldos do escrow apenas na liquidação; nada verifica a transferência quando ela chega, portanto cada parte lê o registro da negociação antes de transferir.

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

Verificar os termos

A criação de um registro não exige permissão, e os endereços de escrow derivam apenas do registro e do mint, nunca dos termos. Uma transferência para um escrow pode, portanto, chegar vinculada a termos com os quais você nunca concordou, incluindo destinos de liquidação que redirecionam os recursos 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 derivado dos seus próprios campos (fetchSwapDvpChecked executa apenas as duas primeiras verificações). Os leitores simples fetchSwapDvp e decodeSwapDvp não fazem nenhuma dessas verificações. As verificações de partes, valores, prazos e destinos ficam a cargo de quem chama, comparando com a 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 registro foi criado pela sua contraparte ou pela autoridade de liquidação, compare cada campo com os termos que você acordou fora do ledger. Se você mesmo o criou, esta leitura confirma que ele chegou como foi enviado.

Transferir para o escrow

Financie a perna exatamente no valor acordado. O programa limita a liquidação a amount_x e devolve qualquer excedente à parte da perna, portanto o excedente não se perde, mas gera uma segunda transferência na liquidação e pode falhar com alguns transfer hooks (veja as observações abaixo).

Use TransferChecked, não uma Transfer sem verificação. Mints do Token-2022 com extensões que dependem da mint account, como Pausable, rejeitam uma transferência que não a informe, 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 dinheiro 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, portanto um Settle enviado com base em uma transferência de financiamento que não foi concluída falha com LegNotFunded e nada é movimentado; o custo é um Settle com falha e uma nova tentativa. Considere uma perna financiada quando a sua transferência estiver finalized.

Observações

  • Pernas em SOL encapsulado. O programa lê o saldo de um escrow nativo após sincronizá-lo, de modo que os lamports enviados a um escrow de SOL encapsulado por 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ção de acesso. Em um mint com Default Account State congelado, o escrow é criado congelado e a transferência falha até que o emissor o descongele ou o autorize. A visão geral descreve a interação com o Token ACL.
  • Transfer hooks. Financie escrows com hook exatamente no valor acordado. Se um excedente forçar um reembolso na liquidação, o reembolso reutiliza as contas de hook da perna com um destino e um valor diferentes, o que alguns hooks rejeitam. A recuperação é Reclaim, refinanciar no valor exato e liquidar novamente.
  • Financiamento após o vencimento. Nada impede uma transferência após expiry_timestamp. Ela chega, a liquidação deixa de ser possível, e a parte da perna a recupera com Reclaim enquanto a negociação está aberta ou com Recover depois que ela é encerrada. Veja desfazer uma negociação.
  • Quem financia primeiro. O programa não define a sequência das duas pernas. A ordem é uma questão entre as partes; qualquer lado pode reaver 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.