Il finanziamento è un semplice TransferChecked verso l'escrow della gamba, quindi qualsiasi wallet o sistema di
custodia in grado di inviare un trasferimento di token può finanziare una gamba. Solo la lettura del
record dell'operazione prima del finanziamento richiede il client DvP. Il programma controlla i
saldi degli escrow solo al regolamento; nulla verifica il trasferimento quando arriva,
quindi ogni parte legge il record dell'operazione prima di trasferire.
Questa pagina prosegue da crea un'operazione; il client e i firmatari restano invariati.
Verificare i termini
La creazione di un record non richiede autorizzazioni, e gli indirizzi degli escrow derivano
dal record e dal mint soltanto, mai dai termini. Un trasferimento verso un escrow può
quindi arrivare a fronte di termini che non hai mai concordato, incluse destinazioni di regolamento
che reindirizzano i proventi della tua controparte verso un terzo indirizzo.
Prima di finanziare, leggi l'account SwapDvp e confrontalo con l'operazione
concordata.
verifySwapDvp in TypeScript e verify::decode_swap_dvp_account in Rust
confermano che l'account appartenga al programma DvP, abbia esattamente 458 byte e
si trovi all'indirizzo derivato dai propri 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, tempi e destinazioni sono
eseguiti dal chiamante rispetto all'operazione concordata.
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.
Trasferire nell'escrow
Finanzia la gamba esattamente per l'importo concordato. Il programma limita il regolamento a
amount_x e restituisce l'eventuale eccedenza alla parte della gamba, quindi un'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 gamba 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 gamba in contanti fa lo stesso per l'escrow B con userBAtaB, mintB,
userBSigner, t.amountB e { programAddress: tokenProgramB }.
Un trasferimento di finanziamento visto a confirmed
può ancora essere sostituito. Il programma legge il saldo dell'escrow onchain al
regolamento, quindi un Settle inviato a fronte di un trasferimento di finanziamento non andato a buon fine
fallisce con LegNotFunded e nulla si muove; il costo è un Settle fallito e un nuovo tentativo.
Considera una gamba finanziata quando il suo trasferimento è finalized.
Note
- Gambe in SOL wrapped. Il programma legge il saldo di un escrow nativo dopo averlo sincronizzato, quindi i lamport inviati a un escrow wrapped-SOL tramite un trasferimento di sistema vengono conteggiati. Non inviare mai SOL a un escrow per qualsiasi 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 per l'importo concordato. Se un'eccedenza rende necessario un rimborso al regolamento, il rimborso riutilizza gli account dell'hook della gamba con una destinazione e un importo diversi, cosa che alcuni hook rifiutano. Il rimedio è Reclaim, rifinanziare con l'importo esatto e regolare di nuovo.
- Finanziamento oltre la scadenza. Nulla impedisce un trasferimento dopo
expiry_timestamp. Arriva a destinazione, il regolamento non è più possibile e la parte della gamba lo recupera con Reclaim mentre l'operazione è aperta o con Recover dopo la sua chiusura. Vedi annullare un'operazione. - Chi finanzia per primo. Il programma non stabilisce una sequenza tra le due gambe. L'ordine è una questione tra le parti; ciascun lato può recuperare la propria gamba in qualsiasi momento prima del regolamento, a meno che un'autorità del mint (freeze, pause o transfer hook) non blocchi l'escrow.
Passaggi successivi
- Regolare l'operazione: l'autorità di regolamento scambia entrambe le gambe in un'unica transazione
- Annullare un'operazione: recuperare una gamba finanziata quando l'operazione non viene regolata
Is this page helpful?