Перейти до основного вмісту
Change page

Стандарт асинхронних токенізованих сховищ ERC-7540

Вступ

ERC-7540 розширює стандарт токенізованих сховищ ERC-4626, додаючи підтримку асинхронних процесів депозиту та викупу. Він запроваджує патерн «запит-потім-затребування»: користувачі спочатку подають запит (блокуючи свої активи або частки), а потім затребують результат після того, як сховище його обробить.

Це необхідно, коли сховище не може здійснити остаточну фіксацію миттєво в одній транзакції, наприклад:

  • Протоколи активів реального світу (RWA), такі як токенізовані казначейські зобов'язання, приватне кредитування та інші активи з циклами остаточної фіксації T+1 або T+2
  • Недостатньо забезпечене кредитування, де оцінка кредитоспроможності відбувається позамережево
  • Кросчейн-стратегії сховищ, де використання мостів спричиняє затримки
  • Токени ліквідного стейкінгу (LST) з періодами розблокування

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

Передумови

Щоб краще зрозуміти цю сторінку, ми рекомендуємо спочатку прочитати про стандарти токенів, ERC-20 та ERC-4626.

ERC-4626 проти ERC-7540

У ERC-4626 остаточна фіксація депозиту відбувається атомарно: інвестор надсилає активи та отримує частки назад в одній транзакції.

ERC-4626 synchronous deposit flow

ERC-7540 розділяє це на два етапи. Інвестор спочатку викликає requestDeposit(), щоб заблокувати активи, а потім чекає, поки менеджер сховища обробить запит. Після виконання інвестор викликає deposit(), щоб затребувати свої частки. Обмінні курси визначаються під час виконання, а не під час запиту.

ERC-7540 asynchronous deposit flow

Процес викупу працює так само: requestRedeem() блокує частки, і після виконання інвестор викликає redeem(), щоб затребувати активи.

Функції та особливості ERC-7540

ERC-7540 успадковує повний інтерфейс ERC-4626, але перепрофільовує deposit/mint/withdraw/redeem як функції затребування. Нові функції requestDeposit та requestRedeem обробляють початковий етап запиту.

Кожен запит проходить через три стани: очікує на розгляд (поданий, очікує на обробку), доступний для затребування (виконаний та оцінений) і затребуваний (інвестор забрав свої частки або активи).

Request lifecycle: Pending, Claimable, Claimed

Процес запиту на депозит

requestDeposit

function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId)

Переказує assets від owner до сховища та подає запит на депозит. Адреса controller отримує контроль над запитом. Повертає requestId, що ідентифікує пакет запитів.

pendingDepositRequest

function pendingDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets)

Повертає суму assets у запиті на депозит, що очікує на розгляд (ще не доступний для затребування), для вказаних controller та requestId.

claimableDepositRequest

function claimableDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets)

Повертає суму assets у доступному для затребування (виконаному, але ще не затребуваному) запиті на депозит для вказаних controller та requestId.

Затребування депозитів

Щойно запит на депозит стає доступним для затребування, користувач викликає стандартну функцію ERC-4626 deposit або mint, щоб затребувати свої частки. У ERC-7540 ці функції більше не переказують активи (це вже відбулося під час запиту). Вони лише карбують частки для одержувача.

Процес запиту на викуп

requestRedeem

function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId)

Блокує shares від owner та подає запит на викуп. Адреса controller отримує контроль над запитом.

pendingRedeemRequest

function pendingRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares)

Повертає суму shares у запиті на викуп, що очікує на розгляд, для вказаних controller та requestId.

claimableRedeemRequest

function claimableRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares)

Повертає суму shares у доступному для затребування запиті на викуп для вказаних controller та requestId.

Затребування викупів

Щойно запит на викуп стає доступним для затребування, користувач викликає стандартну функцію ERC-4626 redeem або withdraw, щоб затребувати свої активи.

Управління операторами

ERC-7540 включає патерн оператора (з ERC-6909 (відкривається в новій вкладці)), який дозволяє третім сторонам керувати запитами від імені користувача.

setOperator

function setOperator(address operator, bool approved) external returns (bool)

Схвалює або скасовує дозвіл для operator діяти від імені msg.sender для запитів на депозит/викуп та затребувань.

isOperator

function isOperator(address controller, address operator) external view returns (bool)

Повертає інформацію про те, чи схвалено operator діяти від імені controller.

Ідентифікатори запитів

Ідентифікатори запитів розрізняють різні пакети запитів. Усі запити, що мають однаковий requestId, є взаємозамінними: вони переходять між станами разом і отримують однаковий обмінний курс.

Коли сховище повертає requestId = 0 для всіх запитів, лише адреса controller розрізняє стан запиту. Кілька запитів від одного контролера агрегуються.

Події

Подія DepositRequest

ПОВИННА генеруватися, коли запит на депозит подається через requestDeposit.

event DepositRequest(
    address indexed controller,
    address indexed owner,
    uint256 indexed requestId,
    address sender,
    uint256 assets
)

Подія RedeemRequest

ПОВИННА генеруватися, коли запит на викуп подається через requestRedeem.

event RedeemRequest(
    address indexed controller,
    address indexed owner,
    uint256 indexed requestId,
    address sender,
    uint256 shares
)

Подія OperatorSet

ПОВИННА генеруватися, коли оператор схвалюється або скасовується через setOperator.

event OperatorSet(
    address indexed controller,
    address indexed operator,
    bool approved
)

Функції попереднього перегляду

Функції попереднього перегляду повинні скасовувати транзакцію лише для асинхронних процесів, оскільки обмінний курс невідомий до виконання запиту. У сховищі з асинхронним депозитом previewDeposit та previewMint ПОВИННІ скасовувати транзакцію, тоді як previewRedeem та previewWithdraw продовжують працювати як у ERC-4626 (і навпаки для сховища з асинхронним викупом). Це ключова поведінкова відмінність від ERC-4626.

Додаткові матеріали