Как устроено
Проблема
Заголовок раздела «Проблема»На депозитном адресе лежат токены пользователя, но нет нативной монеты, чтобы заплатить за газ. Классический sweep сначала отправляет на адрес немного ETH или BNB на газ, а потом переводит с него токены: две транзакции на депозит, отдельный кошелёк для пополнений и газовая «пыль» на каждом адресе.
EIP-7702 позволяет обычному адресу (EOA) выполнять код контракта, сохраняя собственный ключ. Адрес подписывает авторизацию: «в этой сети выполнять код по такому-то адресу». После этого любая транзакция может вызвать депозитный адрес, и он выполнит код, на который делегирован.
Portuna Sweep даёт каждому вашему горячему кошельку (котлу) небольшой контракт — делегат, который умеет ровно одно: переводить токены или нативную монету адреса в этот горячий кошелёк, когда об этом просит ваш собственный контракт — батчер. Каждый депозитный адрес один раз авторизует делегат. Дальше одна транзакция с вашего газ-кошелька сметает сразу много депозитных адресов, и ни одному из них газ не нужен.
Из чего состоит
Заголовок раздела «Из чего состоит»| Часть | Что это |
|---|---|
| Депозитный адрес | Обычный EOA. Его ключ — в вашей кастоди и подписывает только авторизацию. После первого sweep у адреса есть делегация: его код — 0xef0100 и адрес делегата. Токены и нативную монету он принимает как любой адрес. |
| Горячий кошелёк | Адрес, куда приходят средства. Любой адрес, которым вы управляете. Регистрируется один раз в каждой сети. |
| Делегат | Контракт SweepDelegate одного горячего кошелька — код, который выполняют ваши депозитные адреса. Горячий кошелёк и ваш батчер зашиты в его байткод, поэтому он отправляет средства только в этот кошелёк и только по вызову вашего батчера. Без владельца, без хранилища, без обновлений. |
| Батчер | Ваш контракт SweepBatcher. Вызвать его может только ваш газ-кошелёк. Он сметает список депозитных адресов одной транзакцией; адрес, на котором что-то пошло не так, не останавливает остальные. |
| Фабрика | Общий контракт SweepFactory, который разворачивает батчеры и делегаты. У неё нет владельца, а вызвавший её всегда становится газ-кошельком того, что она развернула, поэтому развернуть контракты от вашего имени нельзя. |
| Газ-кошелёк | Адрес, который Portuna создаёт для вас, один и тот же во всех сетях. Вы пополняете его нативной монетой сети; с него оплачиваются развёртывание ваших контрактов и каждый батч, на нём же копятся комиссии. |
Ваши батчер и делегаты принадлежат только вам: транзакция другого партнёра их не вызовет. Все три контракта
создаются через CREATE2, поэтому их адреса следуют из их кода. Вы можете посчитать их сами и убедиться, что в сети
лежит открытый код: см. Проверка делегата.
Один sweep по шагам
Заголовок раздела «Один sweep по шагам»- Вы запрашиваете sweep:
POST /v1/sweepsс депозитным адресом, токеном и — для первого sweep адреса — его подписанной авторизацией. API сразу проверяет авторизацию: нужная сеть, делегат вашего горячего кошелька, подписал сам депозитный адрес. - Сервис собирает батч. Задания одного горячего кошелька, которые к этому моменту в очереди, идут вместе — до размера батча сети. Сервис читает код и nonce депозитных адресов, симулирует весь батч и выкидывает то, что упало бы.
- В сеть уходит одна транзакция — с вашего газ-кошелька на ваш батчер. Первый sweep везёт свою авторизацию в той же транзакции: сеть сначала ставит делегат на адрес, потом батчер его вызывает. Повторным sweep авторизация не нужна.
- После подтверждений каждое задание становится
swept,failedилиrejected— со своей долей газа и комиссией. Итог приходит на ваш вебхук. См. Статусы, подтверждения и реорги.
Один горячий кошелёк на адрес
Заголовок раздела «Один горячий кошелёк на адрес»Адрес выполняет один делегат за раз, поэтому сметается в один горячий кошелёк. Чтобы сметать его в другой, подпишите авторизацию на делегат того кошелька и пришлите её со следующим sweep; такой sweep стоит примерно как первый. Чтобы вернуть адрес в обычный, снимите делегацию.
Сети и токены
Заголовок раздела «Сети и токены»Сметать можно токены из списка сети и её нативную монету. В тестнетах:
| Сеть | Chain ID | Нативная монета | Токены |
|---|---|---|---|
| Sepolia | 11155111 | ETH | тестовый USDT 0x5B74f75040584b133Ff1EB67eEe646B0da26e39C |
| BSC testnet | 97 | BNB | тестовый USDT 0x5B74f75040584b133Ff1EB67eEe646B0da26e39C |
В запросе токен — это его тикер (в любом регистре), адрес контракта или native для монеты сети. Любой другой токен
получит unknown_token, а sweep переводит только запрошенный токен: аирдропы и неизвестные токены на адресе
остаются нетронутыми. Мейннет — Ethereum и BSC — скоро.