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 agreedconst expectedExpiry = 1_798_761_600n; // as agreed, unix secondsif (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
- Liquidar a negociação: a autoridade de liquidação troca ambas as pernas numa única transação
- Desfazer uma negociação: recuperar uma perna financiada quando a negociação não é liquidada
Is this page helpful?