Skip to main contentA-REX Core

Livre blanc · 08

Cadre de sécurité

Modèle de menaces, invariants, contrôle d'accès, frontière de confiance des hooks, gestion des clés de mise en application, sûreté des mises à niveau et posture d'audit de l'implémentation de référence d'A-REX Core.

La posture de sécurité en un paragraphe

Le jeton de référence possède un seul point de passage obligé (_update), un ordre d'évaluation fixe, un verrou de réentrance autour de toute la séquence de hooks, une autorité fondée sur les rôles qui n'est jamais dérivée des soldes, un stockage ERC-7201 et une surface réduite : huit fonctions externes modifiant l'état en plus d'ERC-1155. Les capacités les plus puissantes — gel, transfert forcé, administration des hooks, mises à niveau — sont des rôles distincts destinés à des multisigs et à des timelocks, et chacun de leurs usages est un événement.

Invariants

InvariantGaranti parTesté par
totalSupply(id) est égal à la somme des soldes pour idOpenZeppelin ERC1155Supply ; transform détruit puis émet via _updatetests de filiation (fractionnement, fusion, traitement)
status == 255 est terminalsetBatchStatus annule la transaction avec ARexInvalidStatusTransitiontests de statut
Un lot retiré ne peut être ni émis ni transféré, seulement détruit_updatetest du lot retiré
amount ≤ balance − frozen pour les mouvements initiés par le détenteur_update ; forcedTransfer abaisse frozen à balance − amounttests de gel et de transfert forcé
Aucun hook ne peut ré-entrer dans une fonction modifiant les soldesverrou de stockage posé avant les vérifications, levé après les notificationstest ReentrantHook
Les hooks sont évalués dans l'ordre d'enregistrement ; la suppression préserve l'ordredécalage du tableau dans removeHooktest d'ordre
Une opération rejetée ne modifie aucun solde et n'émet aucun transfertles vérifications s'exécutent avant super._updatetest de rejet (compteur d'exécutions inchangé)
L'autorité ne dérive jamais du soldechaque fonction modifiant l'état est conditionnée à un rôle ou à une approbation ERC-1155tests « détenir des jetons ne confère rien »
canTransfer == (transferCheck == 0)canTransfer est défini ainsitests de conformité

Modèle de menaces

Acteurs et capacités

ActeurPeutNe peut pas
Détenteurtransférer des unités non gelées à des destinataires éligibles ; détruire ; réorganiser des lots de même denrée et de même unité avec quantité conservéemodifier le statut, émettre, traiter pour obtenir une autre denrée, déplacer des unités gelées
Opérateur approuvécomme le détenteur, pour le compte qui l'approuvetout ce qu'un détenteur ne peut pas faire
ISSUER_ROLEcréer des lotsdéplacer les jetons d'autrui
TRANSFORMER_ROLEeffectuer des transformations de traitement sur les jetons qu'il détient ou pour lesquels il est approuvétransformer des jetons sans approbation
STATUS_ROLEmodifier le statut (y compris retirer), mettre à jour les métadonnéesdéplacer des jetons
ENFORCER_ROLEgeler n'importe quel montant ; forcer n'importe quel transfertcontourner les hooks (ils s'exécutent avec OP_FORCED_TRANSFER)
HOOK_ADMIN_ROLEajouter/retirer des hooksmodifier directement les soldes
PAUSER_ROLEtout interrompre sauf les transferts forcés—
UPGRADER_ROLEremplacer l'implémentation— (c'est un pouvoir total ; voir la gestion des clés)
Contrat de hookrejeter des opérations ; les observer ; répondre sur l'éligibilitéré-entrer ; modifier les soldes

Scénarios

Hook malveillant ou défectueux (déni de service). Un hook qui rejette toujours bloque tous les transferts du jeton ; un hook qui annule la transaction dans check produit le même effet. Atténuation : HOOK_ADMIN_ROLE peut retirer n'importe quel hook à tout moment (ordre préservé) ; PAUSER_ROLE peut tout interrompre pendant l'enquête ; les transferts forcés s'exécutent toujours, de sorte que la mise en application n'est pas perdue. L'enregistrement vérifie la prise en charge d'ERC-165 et des drapeaux non nuls, et rejette les EOA. Recommandation : auditer les hooks avant de les enregistrer ; en garder un petit nombre ; placer l'administrateur derrière un timelock afin que les changements de hooks soient visibles avant leur prise d'effet.

Réentrance d'un hook. Le onExecuted d'un hook rappelle safeTransferFrom. Atténuation : le verrou ; l'appel annule la transaction avec ARexReentrantCall. Notez que le callback de réception d'ERC-1155 (onERC1155Received) s'exécute après la levée du verrou, comme dans tout jeton ERC-1155 ; l'état du jeton est alors définitif.

Clé de mise en application compromise. Quiconque détient ENFORCER_ROLE peut déplacer n'importe quels jetons. Atténuation : multisig avec une procédure documentée (ordonnance judiciaire, contrat de nantissement, avis de sanctions) ; chaque action émet ForcedTransfer/Frozen ; les hooks peuvent exiger une référence d'ordonnance dans les données de transfert (OP_FORCED_TRANSFER n'est pas exempté des hooks). Envisager un timelock pour la mise en application non urgente.

Compromission du rôle de mise à niveau. Compromission totale. Atténuation : multisig plus timelock ; validations de mise à niveau d'OpenZeppelin en CI ; stockage ERC-7201 pour éviter les accidents de disposition.

Abus de statut. STATUS_ROLE peut retirer un lot détenu par d'autres. C'est intentionnel — un entrepôt, un inspecteur ou un régulateur déclarant un lot impropre — et cela doit être communiqué aux détenteurs. Atténuation : l'attribuer à une institution responsable ; chaque changement est un événement accompagné d'un motif.

Fraude de l'émetteur. ISSUER_ROLE peut créer un lot qui n'existe pas physiquement. Le jeton ne peut pas l'empêcher ; il le rend imputable (issuer, originRef, metadataHash) et permet d'exiger avant tout transfert, via AttestationHook, des attestations de parties indépendantes (entrepôt, inspecteur, registre).

Substitution de métadonnées. setBatchMetadata modifie le hash et l'URI. Atténuation : accès réservé à un rôle ; les événements BatchMetadataUpdated et URI conservent l'historique ; les documents antérieurs restent vérifiables par rapport aux hashes antérieurs.

Front-running de transferCheck. Une vérification préalable peut devenir obsolète avant l'exécution de la transaction (l'état d'un hook change). La transaction réévalue ; le pire cas est un revert avec un code précis.

Griefing de gaz via les hooks. Chaque hook ajoute un appel externe par identifiant concerné et par phase. Un hook avec des boucles non bornées rend les transferts inabordables. Atténuation : règles d'écriture des hooks (check borné), revue avant l'enregistrement.

Confiance envers les hooks pouvant être mis à niveau. Un hook déployé derrière un proxy peut modifier la politique de transfert sans aucun changement sur le jeton. Atténuation : traiter les clés d'administration des hooks avec le même soin que HOOK_ADMIN_ROLE ; privilégier des hooks immuables en production.

Modèle de contrôle d'accès

AccessControl d'OpenZeppelin avec huit rôles sur le jeton et un sur le registre d'attestations ; DEFAULT_ADMIN_ROLE les administre tous. Disposition recommandée en production :

RôleTitulaire
DEFAULT_ADMIN_ROLE, UPGRADER_ROLE, HOOK_ADMIN_ROLEmultisig de gouvernance derrière un timelock
ENFORCER_ROLEmultisig de mise en application (conformité + juridique)
PAUSER_ROLEclé de réponse aux incidents (rapide)
ISSUER_ROLE, STATUS_ROLE, TRANSFORMER_ROLEservices opérationnels au moindre privilège, avec rotation des clés
ATTEST_ADMIN_ROLEautorité de certification ou plateforme

initialize accorde tout à un seul administrateur par commodité ; la liste de contrôle de déploiement exige une redistribution avant la production.

Sémantique de la mise en application et de la pause

  • La pause bloque les émissions, les transferts, les destructions et les transformations ; elle ne bloque pas les transferts forcés, de sorte qu'un ordre légal peut être exécuté pendant un incident.
  • Les transferts forcés ignorent canSend/canReceive et la vérification du solde gelé, abaissent le montant gelé à ce qui reste, et exécutent tout de même les hooks avec OP_FORCED_TRANSFER. Les hooks de référence renvoient OK pour cette opération ; un hook qui régit la mise en application peut exiger des références d'ordonnance dans data.
  • Le gel peut dépasser le solde (ERC-7943), de sorte qu'une sûreté peut couvrir les dépôts futurs.

Sûreté des mises à niveau

  • UUPS ; _authorizeUpgrade conditionné par UPGRADER_ROLE.
  • Structure de stockage ERC-7201 à espace de noms ; ajouts uniquement.
  • Les validations du plugin de mises à niveau d'OpenZeppelin s'exécutent dans les tests et devraient s'exécuter en CI avant toute transaction de mise à niveau.
  • Le paramètre optimizer.runs = 1 par fichier maintient l'implémentation sous EIP-170 ; une modification qui la fait dépasser la limite échoue à la compilation avec un avertissement et au déploiement avec un revert.

Sécurité des dépendances et du build

  • OpenZeppelin Contracts et Contracts-Upgradeable épinglés à 5.3.0 ; fichier de verrouillage versionné ; la CI utilise npm ci.
  • Solidity 0.8.22, viaIR, EVM paris (aucune dépendance au stockage transitoire, déployable sur des chaînes qui n'ont pas adopté Cancun).
  • Aucune bibliothèque externe liée ; aucun delegatecall en dehors du proxy UUPS.

Posture d'audit

  • 46 tests sur l'implémentation de référence, les hooks et les extensions couvrent chaque invariant ci-dessus, y compris une exécution d'invariants aléatoire à graine fixée.
  • Le gaz et la taille sont mesurés par des scripts du dépôt.
  • Un audit par un tiers de ARexToken, ARexAttestations et des hooks de référence est une condition préalable déclarée pour un participant d'ancrage en production et pour la soumission de l'ERC (voir Évolutions futures).
  • La vérification formelle des invariants du pipeline figure sur la feuille de route ; les invariants sont suffisamment petits pour être énoncés sous forme de propriétés.

Risques résiduels que le standard ne supprime pas

  • L'existence physique et la qualité d'un lot sont attestées, non prouvées ; le jeton rend les affirmations imputables, non vraies.
  • La disponibilité des métadonnées off-chain dépend du stockage choisi ; le hash garantit l'intégrité, non la disponibilité.
  • La gouvernance des hooks et des modules ne vaut que ce que valent les clés qui la contrôlent.