Financieren is een gewone TransferChecked naar de escrow van de leg, dus elke wallet of
bewaarsysteem dat een tokentransfer kan versturen, kan een leg financieren. Alleen het uitlezen van
het trade-record vóór de financiering vereist de DvP-client. Het programma controleert de
escrow-saldi pas bij de afwikkeling; niets controleert de transfer op het moment dat deze binnenkomt,
dus elke partij leest het trade-record uit voordat er wordt overgemaakt.
Deze pagina vervolgt op een trade aanmaken; de client en de ondertekenaars blijven dezelfde.
De voorwaarden controleren
Het aanmaken van een record is permissionless, en de escrow-adressen worden afgeleid van het
record en de mint alleen, nooit van de voorwaarden. Een transfer naar een escrow kan
daarom terechtkomen bij voorwaarden waarmee je nooit akkoord bent gegaan, inclusief afwikkelbestemmingen
die de opbrengst van je tegenpartij omleiden naar een derde adres.
Lees vóór het financieren het SwapDvp-account uit en controleer het aan de hand van de afgesproken
trade.
verifySwapDvp in TypeScript en verify::decode_swap_dvp_account in Rust
bevestigen dat het account eigendom is van het DvP-programma, precies 458 bytes groot is en
zich bevindt op het adres dat uit de eigen velden wordt afgeleid (fetchSwapDvpChecked voert alleen de
eerste twee controles uit). De gewone readers fetchSwapDvp en decodeSwapDvp
voeren geen van deze controles uit. De controles op partijen, bedragen, tijdstippen en bestemmingen worden
door de aanroeper uitgevoerd aan de hand van de afgesproken trade.
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");}
Als het record is aangemaakt door je tegenpartij of de afwikkelautoriteit, vergelijk dan elk veld met de voorwaarden die je buiten de ledger hebt afgesproken. Als je het zelf hebt aangemaakt, bevestigt deze uitlezing dat het is aangekomen zoals verzonden.
Overmaken naar de escrow
Financier de leg met exact het afgesproken bedrag. Het programma begrenst de afwikkeling op
amount_x en stuurt elk overschot terug naar de partij van de leg, dus een overschot gaat niet verloren,
maar het voegt bij de afwikkeling een tweede transfer toe en kan bij sommige transfer
hooks mislukken (zie de opmerkingen hieronder).
Gebruik TransferChecked, niet een ongecontroleerde Transfer. Token-2022-mints met
extensies die afhankelijk zijn van het mint account, zoals Pausable, weigeren een transfer
die dit niet meegeeft, en een mint met een transfer hook vereist dat de accounts van de hook
worden opgelost en op dezelfde manier worden toegevoegd als bij elke andere transfer van dat
token.
De partij van de assetleg, die ondertekent als userASigner, financiert 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]);
De partij van de cashleg doet hetzelfde voor escrow B met userBAtaB, mintB,
userBSigner, t.amountB en { programAddress: tokenProgramB }.
Een financieringstransfer die op confirmed wordt gezien,
kan nog steeds worden vervangen. Het programma leest het escrow-saldo onchain uit bij de
afwikkeling, dus een Settle die wordt verstuurd terwijl de financieringstransfer niet is aangekomen, mislukt
met LegNotFunded en er beweegt niets; de kosten zijn een mislukte Settle en een nieuwe poging.
Beschouw een leg pas als gefinancierd wanneer de transfer finalized is.
Opmerkingen
- Wrapped SOL-legs. Het programma leest het saldo van een native escrow uit na synchronisatie, dus lamports die met een systeemtransfer naar een wrapped-SOL-escrow worden gestuurd, worden meegeteld. Stuur nooit SOL naar een escrow voor een andere mint: het programma kan het niet terugsturen, en het gaat naar wie het account sluit.
- Gated mints. Bij een mint met Default Account State frozen wordt de escrow bevroren aangemaakt en mislukt de transfer totdat de uitgever deze ontdooit of toelaat. Het overzicht beschrijft de interactie met Token ACL.
- Transfer hooks. Financier escrows met hooks met exact het afgesproken bedrag. Als een overschot bij de afwikkeling een terugbetaling afdwingt, hergebruikt die terugbetaling de hook-accounts van de leg met een andere bestemming en een ander bedrag, wat sommige hooks weigeren. Het herstel is Reclaim, opnieuw financieren met het exacte bedrag en opnieuw afwikkelen.
- Financieren na de vervaldatum. Niets voorkomt een transfer na
expiry_timestamp. Die komt aan, afwikkeling is niet meer mogelijk, en de partij van de leg haalt het terug met Reclaim zolang de trade open is of met Recover nadat deze is gesloten. Zie een trade ongedaan maken. - Wie financiert eerst. Het programma bepaalt niet de volgorde van de twee legs. De volgorde is een zaak van de partijen; elke kant kan zijn eigen leg op elk moment vóór de afwikkeling terugvorderen, tenzij een mint authority (freeze, pause of transfer hook) de escrow blokkeert.
Volgende stappen
- De trade afwikkelen: de afwikkelautoriteit wisselt beide legs uit in één transactie
- Een trade ongedaan maken: een gefinancierde leg terugkrijgen wanneer de trade niet wordt afgewikkeld
Is this page helpful?