Відкат угоди

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

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

У кожному випадку з escrow повертається все, що він містить, учаснику відповідної ноги: escrow A — на token account user_a для mint_a, escrow B — на token account user_b для mint_b, незалежно від того, хто його профінансував. 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 — будь-яка зі сторін. Обидві інструкції повертають усе, що містить кожен escrow, учаснику відповідної ноги та закривають запис і обидва escrow, а 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 закривають обидва escrow token account, тож звичайний переказ на закритий escrow завершується помилкою. Депозит потрапляє після закриття, лише якщо щось спершу заново створює escrow, наприклад, транзакція фінансування, яка містить інструкцію create-idempotent associated token account перед переказом і перебувала в обробці, коли контрагент надіслав Reject. Тоді токени опиняються в escrow, угоди якого вже не існує: запис видалено, тому Reclaim не може його знайти, а tombstone нонса не дозволяє створити нову угоду за тією самою адресою й перехопити депозит.

Щоб скористатися RecoverDvp, учасник ноги надає початкові вхідні дані для seed (розрахунковий авторитет, обидві сторони, обидва mint, нонс). Програма повторно виводить адресу запису, вимагає його tombstone як доказ існування угоди, переказує весь вміст escrow на власний token account підписанта та закриває його, повертаючи rent за escrow підписанту. Ногу підписанта визначає те, хто підписує: 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 разом з кожним ордером, доки угода не буде закрита, а баланси escrow не буде підтверджено як порожні.

Примітки

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

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

Is this page helpful?

Зміст

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