Модель безопасности
Ключи остаются у вас
Заголовок раздела «Ключи остаются у вас»Ключи депозитных адресов не покидают вашу кастоди. Ваш HSM, KMS или MPC подписывает для каждого адреса одно — авторизацию EIP-7702, и к Portuna попадает только подпись. Горячие кошельки (котлы) — ваши собственные адреса: их ключей сервис тоже не держит.
Что разрешает авторизация
Заголовок раздела «Что разрешает авторизация»Авторизация заставляет депозитный адрес выполнять в одной сети код делегата вашего горячего кошелька. Этот код маленький и неизменный:
- он переводит токены или нативную монету адреса только в горячий кошелёк, зашитый в его байткод;
- он срабатывает только по вызову вашего батчера, а батчер выполняется только для вашего газ-кошелька;
- у него нет владельца, административных функций, хранилища и способа обновиться — ничего из этого не поменяется потом;
- адрес по-прежнему принимает токены и нативную монету и сохраняет свой ключ: с него можно отправлять транзакции.
Ещё не применённую авторизацию может отправить в сеть кто угодно, не только Portuna: так устроен EIP-7702. Но и тогда
она поставит только ваш делегат, который платит только в ваш горячий кошелёк. Подписывайте только на delegate,
который API вернул для вашего горячего кошелька, и сначала проверяйте его командой
verify-delegate.
Авторизация привязана:
- к одной сети: API не принимает
chain_id0, иначе подпись действовала бы во всех сетях; - к одному nonce: если адрес отправит любую транзакцию раньше, чем авторизация будет применена, она перестанет действовать, и нужно подписать новую.
Чтобы отменить делегацию, адрес подписывает авторизацию на нулевой адрес: см. Снятие делегации.
Контракты, которые можно проверить
Заголовок раздела «Контракты, которые можно проверить»Код контрактов открыт, а создаются они через CREATE2, поэтому каждый адрес — это хэш точного кода, который по нему
лежит. Если адрес, посчитанный из кода, совпадает с адресом в сети и там есть код, значит, в сети именно этот код —
с вашими горячим кошельком и газ-кошельком внутри. Команда verify-delegate из SDK делает всю проверку: см.
Проверка делегата и Контракты.
Изоляция партнёров
Заголовок раздела «Изоляция партнёров»У каждого партнёра свои газ-кошелёк, батчер и делегаты. Делегат слушается только батчера своего партнёра, а батчер — только его газ-кошелька, поэтому один партнёр не может запустить, перенаправить или заблокировать sweep другого. Сервис со своей стороны:
- принимает авторизацию, только если её подписал сам депозитный адрес, на делегат горячего кошелька из запроса и для сети запроса;
- проверяет делегацию каждого адреса и симулирует каждый батч перед отправкой;
- сметает только токены из списка сети;
- доверяет только receipt своих транзакций и событиям вашего собственного батчера.
Ни один наш контракт или адрес не общий для нескольких партнёров, так что ни на одной странице обозревателя они не видны вместе. Но код у всех одинаковый и открытый, поэтому упорный аналитик может найти все развёртывания по байткоду.
Ваш газ-кошелёк
Заголовок раздела «Ваш газ-кошелёк»Газ-кошелёк — единственный адрес, за который подписывает сервис: на нём лежит нативная монета, которую вы вносите на газ. Его ключи хранятся в отдельном сервисе подписи, который подписывает только транзакции этого протокола: развёртывание ваших контрактов, ваши батчи, снятия делегации и вывод начисленных комиссий — в пределах потолков газа и цены газа и дневного бюджета в каждой сети. Держите на нём запас на несколько дней, не больше, и задайте алерт о низком балансе.
API-ключи и вебхуки
Заголовок раздела «API-ключи и вебхуки»- API-ключ показывается один раз и хранится только в виде хэша. Держите его на бэкенде; отозванный ключ перестаёт
работать сразу. Тестовые ключи (
ptn_test_) работают только в тестнетах, боевые (ptn_live_) — только в мейннете. - Вебхуки уходят только на публичные адреса по
https, редиректы не выполняются. Каждая доставка подписана HMAC-SHA256 с меткой времени: проверяйте подпись, прежде чем доверять ей.