Skip to main contentA-REX Foundation

Decision records · ADR-016

ADR-016: UUPS upgradeability with ERC-7201 storage and a per-file optimizer setting

The reference token is a UUPS proxy with ERC-7201 namespaced storage, compiled with optimizer.runs = 1 so that it fits EIP-170 at 24,136 bytes.

Accepted
Document ID
ADR-016
Date
2026-09-21
FieldValue
IDADR-016
Subject areaImplementation
StatusAccepted
Date2026-09-21
OwnersA-REX Contributors
Related requirementsNFR-07, NFR-08 (SDD §3)
Supersedes / superseded by—

Context

During the alpha the reference token must be upgradeable, because production feedback will change it. It must also fit the EIP-170 limit, and it must not repeat the earlier code base's storage-layout comments that did not match the actual layout.

Issue

How should the reference token be made upgradeable, safe to upgrade and small enough to deploy?

Assumptions

  • OpenZeppelin 5 uses ERC-7201 namespaced storage throughout.
  • Upgrades go through governance with a timelock.

Constraints

  • EIP-170 (24,576 bytes).
  • Solidity 0.8.22, EVM paris, OpenZeppelin 5.3.0 (C-05).

Alternatives considered

AlternativeForAgainstOutcome
Transparent proxyWell knownExtra admin contract; more gas per callRejected
Immutable tokenSimplest trust modelNo fixes during the alphaDeferred (fine for third-party implementations)
UUPS + ERC-7201 + optimizer.runs = 1 for ARexToken onlySafe layout, small proxy, fits the limitSlightly higher runtime gas from the low optimizer settingAccepted

Decision

ARexToken is UUPS-upgradeable; _authorizeUpgrade requires UPGRADER_ROLE; state lives in the ERC-7201 namespace arex.storage.token; hardhat.config.js compiles this one file with optimizer.runs = 1.

Argument

UUPS keeps the upgrade logic in the implementation and the proxy minimal; ERC-7201 makes layout collisions structurally unlikely; a per-file optimizer setting fits the limit without changing the rest of the build.

Consequences

Positive

  • Upgrades validated by the OpenZeppelin plugin.
  • The token deploys on every EVM chain.

Negative

  • UPGRADER_ROLE is total power over the token.

Obligations it creates

  • UPGRADER_ROLE sits behind a multisig and a timelock.
  • TokenStorage is append-only; validate before every upgrade.

Implementation and evidence

WhatWhere
Implementationcontracts/reference/core/ARexToken.sol, hardhat.config.js
Upgrade authorizationtest/standard/ARexToken.test.js: is upgradeable through UUPS by UPGRADER_ROLE only
Validated upgradetest/standard/ImplementationGuide.test.js, step 15
  • ADR-009: Attestations implemented in a companion contract
  • ADR-015: Oracle rounds keyed by round number, not wall clock