Skip to main contentA-REX Foundation

Whitepaper · 08

Фреймворк безопасности

Модель угроз, инварианты, управление доступом, граница доверия хуков, управление ключами принудительного исполнения, безопасность обновлений и состояние аудита эталонной реализации A-REX Core.

Профиль безопасности в одном абзаце

У эталонного токена одна точка контроля (_update), фиксированный порядок вычисления, блокировка реентерабельности вокруг всей последовательности хуков, ролевые полномочия, никогда не вытекающие из балансов, хранилище ERC-7201 и небольшая поверхность: восемь внешних функций, изменяющих состояние, помимо ERC-1155. Наиболее мощные возможности — заморозка, принудительный перевод, администрирование хуков, обновления — вынесены в отдельные роли, предназначенные для мультиподписей и таймлоков, и каждое их использование является событием.

Инварианты

ИнвариантОбеспечиваетсяТестируется
totalSupply(id) равно сумме балансов для idOpenZeppelin ERC1155Supply; transform сжигает, затем эмитирует через _updateтесты родословной (разделение, объединение, переработка)
status == 255 терминаленsetBatchStatus откатывается с ARexInvalidStatusTransitionтесты статусов
Погашенную партию нельзя эмитировать или переводить, можно только сжигать_updateтест погашенной партии
amount ≤ balance − frozen для перемещений по инициативе держателя_update; forcedTransfer снижает frozen до balance − amountтесты заморозки и принудительных переводов
Ни один хук не может повторно войти в функцию, изменяющую балансблокировка в хранилище устанавливается до проверок и снимается после уведомленийтест ReentrantHook
Каждое изменение баланса оценивается как отдельная операция со своими data_update считывает и очищает контекст операции до любой проверки или внешнего вызоваOpContext.test.js
Хуки вычисляются в порядке регистрации; удаление сохраняет порядоксдвиг массива в removeHookтест порядка
Отклонённая операция не меняет ни одного баланса и не генерирует переводапроверки выполняются до super._updateтест отказа (число выполнений не меняется)
Полномочия никогда не вытекают из балансакаждая функция, меняющая состояние, защищена ролью или одобрением ERC-1155тесты «владение токенами ничего не даёт»
canTransfer == (transferCheck == 0)canTransfer определён именно тактесты конформности

Модель угроз

Участники и возможности

УчастникМожетНе может
Держательпереводить незамороженные единицы допущенным получателям; сжигать; переформировывать партии того же товара и единицы измерения с сохранением количества на собственный аккаунт (to == from)менять статус, эмитировать, перерабатывать в другой товар, переформировывать партии на другой аккаунт, перемещать замороженные единицы
Одобренный операторто же, что держатель, для одобрившего аккаунтавсё, чего не может держатель
ISSUER_ROLEсоздавать партииперемещать чужие токены
TRANSFORMER_ROLEперерабатывающие преобразования и преобразования с выходами на другой аккаунт для токенов, находящихся у держателя роли или одобренных для негопреобразовывать токены без одобрения
STATUS_ROLEменять статус (включая погашение), обновлять метаданныеперемещать токены
ENFORCER_ROLEзамораживать любое количество; принудительно переводить любые токеныобходить хуки (они выполняются с OP_FORCED_TRANSFER)
HOOK_ADMIN_ROLEдобавлять и удалять хукинапрямую менять балансы
PAUSER_ROLEостанавливать всё, кроме принудительных переводов—
UPGRADER_ROLEзаменять реализацию— (это абсолютная власть; см. управление ключами)
ATTEST_ADMIN_ROLEрешать, какие эмитенты пользуются доверием по каждой теме аттестаций; в эталонных релизах до 2.0.0-alpha.5 также отзывать любую аттестацию; начиная с 2.0.0-alpha.6 отзывает только эмитент или отзывающая сторона, которой он делегировал это право (ADR-019, Предложено: административного отзыва НЕ СЛЕДУЕТ допускать в 2.x, и его НЕ ДОЛЖНО быть начиная с 3.0)аттестовать от имени эмитента
Доверенный эмитентаттестовать партии по своим темам; отзывать собственные аттестации или делегировать право отзывааттестовать по теме, по которой ему не доверяют
Контракт хукаотклонять операции; наблюдать за ними; отвечать о допускеповторно входить; менять балансы

Сценарии

Вредоносный или ошибочный хук (отказ в обслуживании). Хук, всегда отклоняющий операции, блокирует все переводы токена; хук, откатывающийся в check, делает то же самое. Снижение риска: HOOK_ADMIN_ROLE может в любой момент удалить любой хук (порядок сохраняется); PAUSER_ROLE может приостановить работу на время расследования; принудительные переводы по-прежнему выполняются, поэтому принудительное исполнение не теряется. Регистрация проверяет поддержку ERC-165 и ненулевые флаги и отклоняет EOA. Рекомендация: проводить аудит хуков до регистрации; сохранять их число небольшим; размещать администратора за таймлоком, чтобы изменения хуков были видны до вступления в силу.

Повторный вход через хук. onExecuted хука обращается обратно к safeTransferFrom. Снижение риска: блокировка; вызов откатывается с ARexReentrantCall. Следует учесть, что обратный вызов получателя ERC-1155 (onERC1155Received) выполняется после снятия блокировки, как в любом токене ERC-1155; к этому моменту состояние токена окончательно.

Контекст операции в обратных вызовах получателя. Контракт-получатель запускает перевод или сжигание изнутри onERC1155Received. Этот вложенный вызов — OP_TRANSFER или OP_BURN со своими data, а не часть операции, доставившей токены. До 2.0.0-alpha.2 включительно эталонный токен хранил внешнюю операцию в хранилище, пока внешний вызов не завершится, поэтому вложенный вызов после forcedTransfer выполнялся как OP_FORCED_TRANSFER (в обход приостановки, допуска и замороженных балансов), а после transform — как OP_TRANSFORM, который хуки, проверяющие только OP_TRANSFER, пропускали. Снижение риска: _update считывает и очищает контекст операции до любой проверки или внешнего вызова, поэтому вызов из обратного вызова оценивается как самостоятельная операция; OpContext.test.js использует получателя, который переводит и сжигает токены изнутри своего обратного вызова.

Передача через переформирование партий. Оба звена transform запускают хуки с OP_TRANSFORM. Если бы держатель мог переформировать партии на другой аккаунт, товар переходил бы из рук в руки без проверок хуков, которые контролируют только OP_TRANSFER, например обязательной аттестации перед продажей или единиц, заблокированных для доставки. Снижение риска: без TRANSFORMER_ROLE переформирование разрешено только при to == from; переформированный товар попадает к другому держателю обычным переводом, который проходит все правила перевода (ADR-007, поправка от 2026-10-20).

Обход блокировки сжиганием или переформированием. Состояние хука, привязанное к id партии, не переходит вместе с лотом на его выходы. Хук, который блокирует единицы и проверяет только OP_TRANSFER, не мешает держателю сжечь заблокированные единицы или переформировать их на месте в новый id, на который блокировка не распространяется. Снижение риска: DeliveryHook отклоняет с IN_TRANSIT любое сжигание или входное звено transform, которое опустило бы баланс ниже заблокированных единиц; принудительные переводы остаются без ограничений, а после изъятия хук возвращает код, а не откатывается. Хукам, резервирующим единицы, следует проверять OP_BURN и OP_TRANSFORM, а не только OP_TRANSFER.

Компрометация ключа принудительного исполнения. Тот, кто держит ENFORCER_ROLE, может переместить любые токены. Снижение риска: мультиподпись с документированной процедурой (судебное постановление, договор залога, уведомление о санкциях); каждое действие генерирует ForcedTransfer/Frozen; хуки могут требовать ссылку на распоряжение в данных перевода (OP_FORCED_TRANSFER не освобождён от хуков). Для несрочного принудительного исполнения стоит рассмотреть таймлок.

Компрометация ключа обновления. Полная компрометация. Снижение риска: мультиподпись плюс таймлок; проверки обновлений OpenZeppelin в CI; хранилище ERC-7201, исключающее случайные ошибки раскладки.

Злоупотребление статусом. STATUS_ROLE может погасить партию, принадлежащую другим. Это сделано намеренно — склад, инспектор или регулятор объявляет лот непригодным — и должно раскрываться держателям. Снижение риска: назначать подотчётному учреждению; каждое изменение — это событие с указанием причины.

Мошенничество эмитента. ISSUER_ROLE может создать партию, которой физически не существует. Токен не может этому помешать; он делает это прослеживаемым до конкретной стороны (issuer, originRef, metadataHash) и позволяет требовать до перевода аттестаций независимых сторон (склад, инспектор, реестр) через AttestationHook.

Местоположение, скрытое в ссылке на происхождение. Хеш, геохеш или любое другое кодирование координат участка в originRef выглядит анонимным, но его можно вычислить заново, подобрав участок, и его никогда нельзя удалить из реестра. Снижение риска: originRef — это ссылка на доказательство или случайная ссылка; геолокация остаётся офчейн (для EUDR — в Информационной системе ЕС). Проект, предложенный вместе с ADR-019 (Предложено), делает правило «никогда не выводится из местоположения» требованием уровня MUST; это уже было решением ADR-008.

Непроверенные ссылки на исходные партии. Партия, изготовленная из партии другого токена, указывает её в списке upstream своих метаданных. Это утверждение эмитента последующего звена: он может назвать партию, которой никогда не владел, или не указать ту, которой владел. Снижение риска: индексаторы, аудиторы и инструменты отзыва сверяют каждую ссылку с исходным токеном (партия существует, хеш метаданных совпадает, перевод эмитенту действительно состоялся, если указан хеш транзакции) и показывают ссылки, которые проверить не удалось, как непроверенные.

Подмена метаданных. setBatchMetadata изменяет хеш и URI. Снижение риска: доступ ограничен ролью; события BatchMetadataUpdated и URI сохраняют историю; более ранние документы остаются проверяемыми по более ранним хешам.

Front-running transferCheck. Предварительная проверка может устареть до исполнения транзакции (состояние хука изменяется). Транзакция вычисляет всё заново; худший случай — откат с точным кодом.

Gas griefing через хуки. Каждый хук добавляет по одному внешнему вызову на каждый затронутый id на каждой фазе. Хук с неограниченными циклами делает переводы непосильными по стоимости. Снижение риска: правила разработки хуков (ограниченный check), проверка перед регистрацией.

Доверие к обновляемым хукам. Хук, развёрнутый за прокси, может изменить политику переводов без каких-либо изменений в токене. Снижение риска: обращаться с административными ключами хука с такой же заботой, как с HOOK_ADMIN_ROLE; для промышленной эксплуатации предпочитать неизменяемые хуки.

Модель управления доступом

OpenZeppelin AccessControl с восемью ролями у токена и одной — у реестра аттестаций; DEFAULT_ADMIN_ROLE администрирует их все. Рекомендуемая схема для промышленной эксплуатации:

РольДержатель
DEFAULT_ADMIN_ROLE, UPGRADER_ROLE, HOOK_ADMIN_ROLEмультиподпись управления за таймлоком
ENFORCER_ROLEмультиподпись принудительного исполнения (комплаенс + юристы)
PAUSER_ROLEключ реагирования на инциденты (быстрый)
ISSUER_ROLE, STATUS_ROLE, TRANSFORMER_ROLEоперационные сервисы с минимальными привилегиями, с ротацией ключей
ATTEST_ADMIN_ROLEуправление токеном: оно решает, каким эмитентам доверять по каждой теме, но не то, что они аттестуют

initialize из соображений удобства выдаёт все роли одному администратору; контрольный список развёртывания требует перераспределения перед промышленной эксплуатацией.

Семантика принудительного исполнения и приостановки

  • Приостановка блокирует эмиссию, переводы, сжигание и преобразования; она не блокирует принудительные переводы, поэтому законное распоряжение может быть исполнено во время инцидента.
  • Принудительные переводы пропускают canSend/canReceive и проверку замороженного баланса, уменьшают замороженное количество до остатка и всё равно запускают хуки с OP_FORCED_TRANSFER. Эталонные хуки возвращают OK для этой операции; хук, регулирующий принудительное исполнение, может требовать ссылки на распоряжения в data.
  • Заморозка может превышать баланс (ERC-7943), поэтому обременение может охватывать будущие зачисления.

Возможности в стандарте, политика в профилях

ADR-019 (Предложено) проводит одну границу через все функции принудительного исполнения. Стандарт фиксирует, что существует и что гарантируется: роли, события, что именно останавливает приостановка, коды AREX:PAUSED и AREX:SANCTIONED, кто может отозвать аттестацию, и правила конфиденциальности. Профиль политики, который ведётся для каждой юрисдикции и каждой организации и версионируется с датами, как нормативный акт, определяет, кто может использовать каждую возможность и на каких условиях:

ВозможностьФиксируется стандартомЗадаётся профилем политики
Заморозка и принудительный переводsetFrozenTokens, forcedTransfer, их события, отдельная роль, отделённая от администрирования, хуки выполняются с OP_FORCED_TRANSFERможно ли вообще включать роль, кто её держит и со сколькими подписантами, какую правовую ссылку должно содержать каждое использование, кого уведомлять
Приостановкачто останавливает приостановка, AREX:PAUSED, принудительные переводы по-прежнему разрешеныкто может приостанавливать и возобновлять работу, какие подтверждение и обоснование требуются, кому сообщается
СанкцииAREX:SANCTIONED и смысл canSend / canReceiveкакие официальные списки применяются (ООН, OFAC, ЕС, OFSI или их сочетание), как они поддерживаются в актуальном состоянии и то, что совпадение подтверждает человек, прежде чем аккаунт будет помечен
Отзыв аттестацииотзывает эмитент, может отзывать отзывающая сторона, которой он делегировал это право; административной роли не следует делать это в 2.x, и она не должна делать это начиная с 3.0; повторная аттестация никогда не заменяет запись другого эмитента и не восстанавливает отозваннуюкаким эмитентам токен доверяет по каждой теме; как оператор фиксирует спор
Конфиденциальность происхожденияoriginRef не содержит координат или идентификаторов физических лиц и не выводится из местоположениякакую ссылку использует эмитент и где офчейн хранится геолокация

Тогда изменение закона становится обновлением профиля, а не новым контрактом или новой версией стандарта.

Безопасность обновлений

  • UUPS; _authorizeUpgrade защищён UPGRADER_ROLE.
  • Структура хранилища ERC-7201 с пространством имён; только добавление полей.
  • Проверки плагина OpenZeppelin upgrades выполняются в тестах и должны выполняться в CI перед любой транзакцией обновления.
  • Параметр optimizer.runs = 1 на уровне файла удерживает реализацию в пределах EIP-170; изменение, выводящее её за этот предел, приводит к предупреждению при компиляции и к откату при развёртывании.

Безопасность зависимостей и сборки

  • OpenZeppelin Contracts и Contracts-Upgradeable зафиксированы на версии 5.3.0; lock-файл закоммичен; CI использует npm ci.
  • Solidity 0.8.22, viaIR, EVM paris (без зависимости от transient storage, можно развёртывать в сетях, не принявших Cancun).
  • Внешние библиотеки не подключаются; delegatecall вне прокси UUPS не используется.

Состояние аудита

  • 46 тестов эталонной реализации, хуков и расширений покрывают каждый из перечисленных выше инвариантов, включая рандомизированный прогон инвариантов с зафиксированным seed.
  • Газ и размер измеряются скриптами из репозитория.
  • Аудит ARexToken, ARexAttestations и эталонных хуков третьей стороной заявлен как предварительное условие для якорного участника в промышленной эксплуатации и для подачи ERC (см. Дальнейшее развитие).
  • Формальная верификация инвариантов конвейера включена в дорожную карту; инварианты достаточно невелики, чтобы формулироваться как свойства.

Бюллетени безопасности

БюллетеньЗатрагиваетИсправлено вПроблемы
AREX-2026-001эталонная реализация до 2.0.0-alpha.2 включительно2.0.0-alpha.3контекст операции просачивался в обратные вызовы получателя ERC-1155; переформирование партий без роли позволяло передать товар другому держателю в обход хуков OP_TRANSFER; блокировки DeliveryHook можно было обойти сжиганием или переформированием

2.0.0-alpha.3 заменяет 2.0.0-alpha.2. Развёрнутые прокси токена обновляются до новой реализации через UPGRADER_ROLE; схема хранилища не меняется. DeliveryHook не обновляемый: разверните новую версию, зарегистрируйте её через registerHook, удалите старую через removeHook и заново запланируйте активные доставки, так как их блокировки хранятся в хранилище старого хука. Интеграции, которые разделяют или объединяют партии сразу на аккаунт покупателя, должны переформировывать на месте и затем переводить или использовать аккаунт с TRANSFORMER_ROLE. Интерфейсы стандарта не меняются.

Остаточные риски, которые стандарт не устраняет

  • Физическое существование и качество лота аттестуются, но не доказываются; токен делает утверждения приписываемыми конкретной стороне, но не истинными.
  • Доступность офчейн-метаданных зависит от выбранного хранилища; хеш гарантирует целостность, но не доступность.
  • Управление хуками и модулями надёжно лишь настолько, насколько надёжны контролирующие его ключи.