Відкат угоди

Чотири інструкції повертають кошти без розрахунку: Reclaim, Cancel і Reject, поки угода відкрита, та Recover для депозиту, що надходить після її закриття. Жодна з них не перевіряє термін дії. Заморожений ескроу або змінений mint усе одно можуть утримувати частину угоди, як описано в примітках наприкінці.

ІнструкціяПідписантОбсягУгода після виконання
ReclaimDvpuser_a або user_bВласна частина підписантаЛишається відкритою
CancelDvpРозрахунковий органОбидві частиниЗакрита
RejectDvpuser_a або user_bОбидві частиниЗакрита
RecoverDvpuser_a або user_bЧастина підписанта, після закриттяУже закрита

У кожному випадку з ескроу повертається все, що в ньому є, стороні відповідної частини: ескроу A — на token account користувача user_a для mint_a, ескроу B — на token account користувача user_b для mint_b, незалежно від того, хто його поповнив. Memo program account передається для акаунтів повернення коштів, які вимагають memo.

Ця сторінка продовжує попередні кроки: клієнт і підписанти з створення угоди, userAAtaA і userBAtaB з поповнення частин, а також MEMO_PROGRAM_ID і authority з розрахунку угоди переносяться далі.

Повернення частини

Reclaim повертає частину підписанта й залишає угоду відкритою, тож частину можна поповнити знову. Використовуйте його, коли проблема з частиною контрагента; Cancel і Reject закривають усю угоду.

import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo";
import { getReclaimDvpInstruction } from "./dvp";
// The asset-leg party takes its asset back.
const reclaimInstruction = getReclaimDvpInstruction({
signer: userASigner,
swapDvp,
mint: mintA,
dvpSourceAta: escrowA,
signerDestAta: userAAtaA,
tokenProgram: tokenProgramA,
memoProgram: MEMO_PROGRAM_ADDRESS,
});
await client.sendTransaction([reclaimInstruction]);

Cancel або Reject

Cancel підписує розрахунковий орган, а Reject — будь-яка зі сторін. Обидві інструкції повертають усе, що міститься в кожному ескроу, стороні відповідної частини, і закривають запис та обидва ескроу, а rent закритих акаунтів надходить підписанту. Ці дві інструкції приймають однакові акаунти; відрізняється лише підписант.

import { getCancelDvpInstruction, getRejectDvpInstruction } from "./dvp";
const unwindAccounts = {
swapDvp,
mintA,
mintB,
dvpAtaA: escrowA,
dvpAtaB: escrowB,
userAAtaA,
userBAtaB,
tokenProgramA,
tokenProgramB,
memoProgram: MEMO_PROGRAM_ADDRESS,
legAExtrasCount: 0,
};
// Signed by the settlement authority:
const cancelInstruction = getCancelDvpInstruction({
settlementAuthority: authoritySigner,
...unwindAccounts,
});
// Or signed by either party:
const rejectInstruction = getRejectDvpInstruction({
signer: userBSigner,
...unwindAccounts,
});

Акаунти повернення коштів (userAAtaA, userBAtaB) повинні існувати для будь-якої частини з ненульовим балансом; неініціалізований акаунт повернення спричиняє збій переказу токенів і відкочує інструкцію. Частина, яку ніколи не поповнювали, не потребує переказу й допускає відсутній акаунт.

Повернення пізнього депозиту

Settle, Cancel і Reject закривають обидва token accounts ескроу, тому звичайний переказ на закритий ескроу завершується помилкою. Депозит потрапляє на ескроу після закриття, лише якщо щось спершу його перестворює — наприклад, транзакція поповнення, яка містить інструкцію create-idempotent associated token account перед переказом і була в обробці, коли контрагент надіслав Reject. Тоді токени опиняються в ескроу, угоди якого вже не існує: запису немає, тому Reclaim не може його знайти, а nonce tombstone не дозволяє створити нову угоду за тією самою адресою й перехопити депозит.

Щоб скористатися RecoverDvp, сторона частини надає вихідні вхідні дані seed (розрахунковий орган, обидві сторони, обидва mint, nonce). Програма повторно виводить адресу запису, вимагає його tombstone як доказ існування угоди, переказує вміст ескроу на власний token account підписанта та закриває його, повертаючи підписанту rent ескроу. Частина підписанта визначається тим, яка сторона підписує: mint_a для user_a, mint_b для user_b.

import { getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";
import { DVP_SWAP_PROGRAM_PROGRAM_ADDRESS, getRecoverDvpInstruction } from "./dvp";
const [nonceTombstone] = await getProgramDerivedAddress({
programAddress: DVP_SWAP_PROGRAM_PROGRAM_ADDRESS,
seeds: ["nonce", getAddressEncoder().encode(swapDvp)],
});
const recoverInstruction = getRecoverDvpInstruction({
signer: userASigner,
swapDvp,
nonceTombstone,
mint: mintA,
dvpEscrowAta: escrowA,
signerDestAta: userAAtaA,
tokenProgram: tokenProgramA,
memoProgram: MEMO_PROGRAM_ADDRESS,
settlementAuthority,
userA,
userB,
mintA,
mintB,
nonce,
});
await client.sendTransaction([recoverInstruction]);

Відновлення залежить від того, чи зберігає сторона параметри створення. Система, що поповнює угоди, зберігає вхідні дані seed разом із кожним ордером, доки угоду не буде закрито, а баланси ескроу — підтверджено як порожні.

Примітки

  • Заморожені частини. Для mint із обмеженим доступом заморожений ескроу блокує переказ токенів, який виконують ці інструкції, доки freeze authority не розморозить його. Див. огляд.
  • Зміни mint після створення. Шляхи відкату пропускають перевірки розширень і mint authority, щоб власні перевірки програми не блокували відновлення. Правила самої Token Program і далі діють. Mint можна закрити лише за нульової пропозиції, тому він не може змінитися, поки в ескроу є баланс, але mint, закритий і перестворений як NonTransferable або з комісією за переказ до надходження пізнього депозиту, може зробити цей депозит непереказуваним або таким, що обкладається комісією. Це залежність від mint authority, наведена в розділі підтримувані токени.

Наступні кроки

Is this page helpful?

Зміст

Редагувати сторінку