Introduction
We express our gratitude to the Revolve team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Revolve Gold Token (RXUT) is a gold-backed ERC-20 token, designed to represent ownership of physical gold on-chain. The core user-facing actions are minting tokens against gold serial numbers, burning tokens to redeem physical gold, and transferring tokens under compliance-enforced restrictions.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for Revolve |
| Audited By | Khrystyna Tkachuk |
| Approved By | Kornel Światłowski |
| Website | www.revolveinc.org→ |
| Changelog | 12/06/2026 - Preliminary Report |
| 17/06/2026 - Final Report | |
| Platform | Base |
| Language | Solidity |
| Tags | ERC20, Permit Token, Centralization, Upgradable |
| Methodology | https://docs.hacken.io/methodologies/smart-contracts→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Revolve
- Audited By
- Khrystyna Tkachuk
- Approved By
- Kornel Światłowski
- Website
- www.revolveinc.org→
- Changelog
- 12/06/2026 - Preliminary Report
- 17/06/2026 - Final Report
- Platform
- Base
- Language
- Solidity
- Tags
- ERC20, Permit Token, Centralization, Upgradable
Review Scope | |
|---|---|
| Repository | https://github.com/revolve-technical_Revolve-Gold-Contracts→ |
| Commit | 6cac3f3 |
| Fianl Commit | d6669f1 |
Review Scope
- Commit
- 6cac3f3
- Fianl Commit
- d6669f1
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Functional requirements are partially missed.
Technical description is not provided.
Inline comments are present.
NatSpec comments are not sufficient.
Code quality
The code leverages OpenZeppelin contracts and follows established patterns.
The development environment is configured.
Test coverage
Code coverage of the project is 84% (branch coverage).
Deployment and basic user interactions are covered with tests.
Negative cases coverage is present.
Interactions by several users are not tested thoroughly.
System Overview
The system consists of a single upgradeable smart contract, RevolveGoldToken, deployed behind a UUPS proxy on Base. The contract inherits from OpenZeppelin's upgradeable library suite — ERC20Upgradeable, ERC20PermitUpgradeable (EIP-2612), PausableUpgradeable, AccessControlDefaultAdminRulesUpgradeable, UUPSUpgradeable, and ReentrancyGuardUpgradeable — and uses the ERC-7201 namespaced storage pattern to avoid storage collisions across upgrades. Token precision is set to 6 decimals.
Access control is organized around seven distinct roles. The DEFAULT_ADMIN_ROLE governs role assignments and is protected by OpenZeppelin's built-in two-step admin transfer mechanism with a 2-day timelock delay (DEFAULT_ADMIN_TRANSFER_DELAY = 2 days) enforced by AccessControlDefaultAdminRulesUpgradeable. The MASTER_MINTER_ROLE (intended to be a secure admin wallet or multisig) manages per-minter allowances and can only set allowances for addresses that hold MINTER_ROLE and are not blacklisted. The MINTER_ROLE (intended to be a Revolve backend-controlled hot wallet on Base) enables allowance-bounded minting against gold serial numbers; minter allowances are automatically zeroed when MINTER_ROLE is revoked via the _revokeRole override. The PAUSER_ROLE can halt and resume all transfers and minting. The COMPLIANCE_ROLE manages an address blacklist with the ability to clawback tokens from blacklisted accounts to a configurable clawbackTreasury address. The RESCUE_ROLE is authorized to recover accidentally sent ERC-20 tokens or native ETH from the contract. Blacklist enforcement is applied on transfer, transferFrom, mint (both caller and recipient), and burn operations.
Burning is permissionless — any non-blacklisted token holder may invoke burn to destroy tokens and specify a settlement method string for physical gold redemption. The settlementMethod parameter is emitted as metadata only; no on-chain validation of allowed values, KYC requirements, or minimum burn thresholds is enforced — those controls are handled off-chain through Revolve policy and operations. A cumulative totalMintedAmount counter is maintained as a historical gross mint volume metric; for reserve validation and live outstanding supply, totalSupply is the canonical reference. The contract provides rescue functions (rescueTokens, rescueETH) gated by RESCUE_ROLE for recovering accidentally sent ERC-20 tokens or native ETH, with an explicit safeguard preventing rescue of the RXUT token itself and a zero-address check on the recipient. Reentrancy protection is applied to transfer, transferFrom, rescueTokens, and rescueETH.
Files in Scope
RevolveGoldToken.sol — Upgradeable ERC-20 token (UUPS proxy pattern) representing gold-backed assets with 6-decimal precision and EIP-2612 permit support. Implements role-based access control with seven roles governing allowance-bounded minting, burning with settlement metadata, address blacklisting, token clawback to a configurable treasury, pause/unpause functionality, timelock-protected two-step admin transfer (2-day delay), dedicated rescue role for ERC-20/ETH recovery, and upgrade authorization.
Privileged roles
RevolveGoldToken.sol:
DEFAULT_ADMIN_ROLE (inherited from AccessControlDefaultAdminRulesUpgradeable): Top-level administrative role granted during
initialize. Admin role for UPGRADER_ROLE, MASTER_MINTER_ROLE, MINTER_ROLE, PAUSER_ROLE, COMPLIANCE_ROLE, and RESCUE_ROLE; can grant and revoke all of them. Admin transfer is protected by a 2-day timelock delay enforced by OpenZeppelin'sAccessControlDefaultAdminRules.Can call
beginDefaultAdminTransferto initiate a two-step admin transfer with a mandatory 2-day delay before acceptance.Can call
grantRoleto grant any non-admin role to any address.Can call
revokeRoleto revoke any role from any holder. When revokingMINTER_ROLE, the target's minter allowance is automatically zeroed.Can call
renounceRoleto renounce its own role (subject to the built-in delay rules).Can call
setClawbackTreasuryto configure the address to which clawed-back tokens are sent.
pendingDefaultAdmin (set via
beginDefaultAdminTransfer): Address nominated by the current DEFAULT_ADMIN_ROLE holder to become the new default admin.Can call
acceptDefaultAdminto accept the DEFAULT_ADMIN_ROLE grant after the 2-day delay has elapsed.
UPGRADER_ROLE: Authorized to perform UUPS proxy upgrades.
Can trigger
_authorizeUpgradeto authorize a new implementation contract for the proxy.
MASTER_MINTER_ROLE: Controls minting allowances for individual minters.
Can call
setMinterAllowanceto set or modify the minting allowance for any minter address.
MINTER_ROLE: Permitted to mint new tokens within an assigned allowance.
Can call
mintto mint tokens to any non-blacklisted address, up to the caller's remaining minter allowance (each mint decrements the allowance).
PAUSER_ROLE: Controls the pausability of the contract.
Can call
pauseto pause all token transfers, minting, and burning.Can call
unpauseto resume all token transfers, minting, and burning.
COMPLIANCE_ROLE: Manages the blacklist and can seize tokens from blacklisted addresses.
Can call
blacklistto add an address to the blacklist, preventing it from sending, receiving, or burning tokens.Can call
unBlacklistto remove an address from the blacklist, restoring normal token operations for that address.Can call
clawbackto transfer tokens from a blacklisted address to the caller's own address.
RESCUE_ROLE: Authorized to recover accidentally sent assets from the contract.
Can call
rescueTokensto recover any ERC-20 token (other than RXUT itself) held by the contract to a specified non-zero address.Can call
rescueETHto recover native ETH held by the contract to a specified non-zero address.
Potential Risks
Centralized Minter Allowance Configuration: The MASTER_MINTER_ROLE can invoke setMinterAllowance to assign arbitrary minting quotas to any MINTER_ROLE holder at any time, with no upper bound, cooldown, or governance approval requirement. This concentration enables rapid, unchecked expansion of minting capacity, which could result in supply inflation if the master minter key is compromised.
No On-Chain Minimum Burn Amount or KYC Enforcement: The burn function accepts any non-zero amount with an arbitrary settlementMethod string. No on-chain validation of settlement method values, minimum redemption thresholds, or KYC status is enforced. Off-chain redemption processing must treat all burn events and settlement method strings as untrusted input and filter dust-amount burns that may be used to spam the redemption pipeline.
Absence of Time-Lock Mechanisms for Critical Operations: Without time-locks on critical operations, there is no buffer to review or revert potentially harmful actions, increasing the risk of rapid exploitation and irreversible changes.
Forced Token Seizure: The COMPLIANCE_ROLE can invoke clawback to forcibly transfer tokens from any blacklisted address to the caller's own address. The combined blacklist and clawback sequence — both gated exclusively by COMPLIANCE_ROLE — enables unilateral seizure of user funds without any on-chain approval from the affected holder or an independent adjudicator. The clawback can be performed when the contract is paused.
Single Points of Failure and Control: The project is fully or partially centralized, introducing single points of failure and control. This centralization can lead to vulnerabilities in decision-making and operational processes, making the system more susceptible to targeted attacks or manipulation.
Flexibility and Risk in Contract Upgrades: The project's contracts are upgradable, allowing the administrator to update the contract logic at any time. While this provides flexibility in addressing issues and evolving the project, it also introduces risks if upgrade processes are not properly managed or secured, potentially allowing for unauthorized changes that could compromise the project's integrity and security.
Absence of Upgrade Delay or Governance Window: The _authorizeUpgrade function in RevolveGoldToken imposes no timelock, mandatory waiting period, or multi-party approval before a new implementation takes effect. An authorized upgrader can deploy a malicious implementation and execute the upgrade atomically, leaving no window for token holders or external monitors to detect and respond to the change.
Absence of On-Chain Proof-of-Reserves: The RevolveGoldToken is described as a token backed by physical gold, and the totalMintedAmount field tracks gross mints intended for proof-of-reserve reference. However, no on-chain oracle, attestation, or verification mechanism exists to link the circulating RXUT supply to verified physical gold holdings. The gold-backing claim is entirely dependent on off-chain assurances that cannot be independently validated by on-chain participants.
Monotonically Increasing totalMintedAmount Can Theoretically Cause Minting DoS: The totalMintedAmount storage variable is incremented on every mint() call but is never decremented on burn(). Because Solidity 0.8+ uses checked arithmetic, if the accumulator were to reach type(uint256).max, all subsequent mint() calls would revert on the $.totalMintedAmount += amount overflow, permanently bricking the minting function. In practice this is extremely unlikely: with 6-decimal precision, uint256 can represent approximately 1.16 × 10^71 tokens, while all gold ever mined amounts to roughly 6.8 × 10^9 troy ounces (6.8 × 10^15 raw units). Even under a hypothetical perpetual mint-burn cycle where the full circulating supply is minted and burned repeatedly, reaching the overflow would require on the order of 10^61 such cycles — a number that exceeds any physically conceivable transaction volume over any timeframe. Nevertheless, the risk is architecturally present because the counter is unbounded and irreversible: unlike totalSupply() (which self-corrects on burn), totalMintedAmount can only grow. A future contract upgrade that introduces higher-frequency minting patterns or changes the token's decimal precision could narrow the margin, though it would remain astronomically large.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2026-1784 | Misleading totalMintedAmount Comment and Documentation Misrepresent Proof of Reserves Capability | fixed | Low | |
| F-2026-1782 | Clawback Transfers Seized Funds to Caller Instead of a Designated Treasury | fixed | Low | |
| F-2026-1782 | Missing Blacklist Check on Caller in mint() Function | fixed | Low | |
| F-2026-1782 | Lack of Timelock Delay for Default Admin Role Transfer | fixed | Low | |
| F-2026-1782 | Lack of Explicit Cancellation Mechanism for Pending Admin Transfer | fixed | Low | |
| F-2026-1782 | BRIDGE_ROLE Enables Unlimited Minting Without Allowance Validation | fixed | Low | |
| F-2026-1783 | Inconsistent Granular Role Separation | fixed | Observation | |
| F-2026-1783 | Lack of Event Emitting for Emergency Withdraw Operations | fixed | Observation | |
| F-2026-1783 | Redundant receive Function | fixed | Observation | |
| F-2026-1780 | Floating Pragma | fixed | Observation |
Appendix 1. Definitions
Severities
When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.
Reference on how risk scoring is done is available through the repository in our Github organization:
Severity | Description |
|---|---|
Critical | Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation. |
High | High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation. |
Medium | Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category. |
Low | Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution. |
Severity
- Critical
Description
- Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.
Severity
- High
Description
- High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.
Severity
- Medium
Description
- Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.
Severity
- Low
Description
- Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
Potential Risks
The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.
Appendix 2. Scope
The scope of the project includes the following smart contracts from the provided repository:
Scope Details | |
|---|---|
| Repository | https://github.com/revolve-technical_Revolve-Gold-Contracts→ |
| Commit | 6cac3f3482d710d60276e11ed96f13e40bee13d6 |
| Final Commit | d6669f1a798b498701d0e85b7ca1e7708c79a377 |
| Whitepaper | N/A |
| Requirements | README.md |
| Technical Requirements | README.md |
Scope Details
- Commit
- 6cac3f3482d710d60276e11ed96f13e40bee13d6
- Final Commit
- d6669f1a798b498701d0e85b7ca1e7708c79a377
- Whitepaper
- N/A
- Requirements
- README.md
- Technical Requirements
- README.md
Assets in Scope
Appendix 3. Additional Valuables
Additional Recommendations
The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.
To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:
Detecting changes to ownership or critical permissions.
Monitoring large or unexpected transactions and minting events.
Pausing operations when irregularities are identified.
These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.
Frameworks and Methodologies
This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment →, and the Penetration Testing Execution Standard (PTES) →, These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.