Il finanziamento è un semplice TransferChecked verso l'escrow della leg, quindi qualsiasi wallet o sistema di
custodia in grado di inviare un trasferimento di token può finanziare una leg. Solo la lettura del
record dello scambio prima del finanziamento richiede il client DvP. Il programma controlla
i saldi dell'escrow solo al momento del regolamento; nulla verifica il trasferimento quando arriva,
quindi ogni parte legge il record dello scambio prima di trasferire.
Questa pagina prosegue da creare uno scambio; il client e i firmatari vengono riutilizzati.
Verifica i termini
La creazione di un record è permissionless, e gli indirizzi di escrow derivano
dal solo record e dal mint, mai dai termini. Un trasferimento verso un escrow può
quindi arrivare a fronte di termini che non hai mai concordato, comprese destinazioni di regolamento
che reindirizzano i proventi della tua controparte a un terzo indirizzo.
Prima di finanziare, leggi l'account SwapDvp e confrontalo con lo scambio
concordato.
verifySwapDvp in TypeScript e verify::decode_swap_dvp_account in Rust
confermano che l'account appartiene al programma DvP, è esattamente di 458 byte e
si trova all'indirizzo derivato dai suoi stessi campi (fetchSwapDvpChecked esegue solo
le prime due verifiche). I lettori semplici fetchSwapDvp e decodeSwapDvp
non eseguono nessuna di queste verifiche. I controlli su parti, importi, tempistiche e destinazioni vengono
eseguiti dal chiamante rispetto allo scambio concordato.
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 il record è stato creato dalla tua controparte o dall'autorità di regolamento, confronta ogni campo con i termini concordati fuori dal ledger. Se lo hai creato tu stesso, questa lettura conferma che è arrivato come inviato.
Trasferisci nell'escrow
Finanzia la leg esattamente con l'importo concordato. Il programma limita il regolamento a
amount_x e restituisce l'eventuale eccedenza alla parte della leg, quindi l'eccedenza non va persa,
ma aggiunge un secondo trasferimento al regolamento e può fallire con alcuni transfer
hook (vedi le note qui sotto).
Usa TransferChecked, non un Transfer non verificato. I mint Token-2022 con
estensioni che dipendono dal mint account, come Pausable, rifiutano un trasferimento
che non lo fornisce, e un mint con un transfer hook richiede che gli account
dell'hook siano risolti e aggiunti allo stesso modo di qualsiasi altro trasferimento di quel
token.
La parte della leg dell'asset, firmando come userASigner, finanzia l'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 della leg in contanti fa lo stesso per l'escrow B con userBAtaB, mintB,
userBSigner, t.amountB e { programAddress: tokenProgramB }.
Un trasferimento di finanziamento visto a livello confirmed
può comunque essere sostituito. Il programma legge il saldo dell'escrow onchain al
momento del regolamento, quindi un Settle inviato a fronte di un trasferimento di finanziamento che non è andato a buon fine
fallisce con LegNotFunded e nulla si muove; il costo è un Settle fallito e un nuovo tentativo.
Considera una leg finanziata quando il suo trasferimento è finalized.
Note
- Leg in SOL wrapped. Il programma legge il saldo di un escrow nativo dopo averlo sincronizzato, quindi i lamport inviati a un escrow di SOL wrapped tramite un trasferimento di sistema vengono conteggiati. Non inviare mai SOL a un escrow di un altro mint: il programma non può restituirli, e vanno a chi chiude l'account.
- Mint con restrizioni. Su un mint con Default Account State impostato su frozen, l'escrow viene creato congelato e il trasferimento fallisce finché l'emittente non lo sblocca o lo ammette. La panoramica descrive l'interazione con Token ACL.
- Transfer hook. Finanzia gli escrow con hook esattamente con l'importo concordato. Se un'eccedenza rende necessario un rimborso al regolamento, il rimborso riutilizza gli account dell'hook della leg con una destinazione e un importo diversi, cosa che alcuni hook rifiutano. Il recupero consiste in Reclaim, nuovo finanziamento con l'importo esatto e nuovo regolamento.
- Finanziamento dopo la scadenza. Nulla impedisce un trasferimento dopo
expiry_timestamp. Il trasferimento arriva, il regolamento non è più possibile e la parte della leg lo recupera con Reclaim finché lo scambio è aperto o con Recover dopo la sua chiusura. Vedi annullare uno scambio. - Chi finanzia per primo. Il programma non stabilisce una sequenza tra le due leg. L'ordine è una questione tra le parti; ciascun lato può recuperare la propria leg in qualsiasi momento prima del regolamento, a meno che una mint authority (freeze, pause o transfer hook) non blocchi l'escrow.
Prossimi passi
- Regola lo scambio: l'autorità di regolamento scambia entrambe le leg in un'unica transazione
- Annulla uno scambio: recuperare una leg finanziata quando lo scambio non viene regolato
Is this page helpful?