Quantum Audit Logo

Is Paxos Gold Safe?

On-chain security analysis — is it a scam or legit?

Is this your token? Publish your own audit on this page →

Paxos Gold PAXG
0x4580…af78
Ethereum Not verifiedLast checked 3d ago 1 audit on record
Executive SummaryAI Copilot

The audit of the PAXG token implementation (0x7da4c5d9eca180a03765a6d27196f2a0380fa543) revealed a critical storage collision within its custom freezing mechanism, which directly overwrites a deprecated but existing storage variable. The contract also employs complex and risky assembly-based storage migration during upgrades. While leveraging OpenZeppelin's upgradeable access control, the overall storage architecture and upgrade process present significant security risks.

1 Critical1 High1 Medium1 Low1 Informational
Volume 24h
$420.0K
Liquidity
$16.11M
Price
$4476.3600
Token Age
6y
Top 10 Holders
33.6%

Security Findings

Critical

Critical Storage Collision: Freezing Mechanism Overwrites `supplyControllerDeprecated`

C-01The `PAXG` contract defines `_PAXG_FROZEN_SLOT = 7` for its custom freezing mechanism, which uses inline assembly (`sstore(slot, 1)`/`sstore(slot, 0)`). However, in the inherited `BaseStorageV3` contract, storage slot 7 is occupied by the `address public supplyControllerDeprecated;` variable. This means that any call to `_freeze` or `_unfreeze` will directly overwrite or read from the `supplyControllerDeprecated` variable, leading to severe data corruption, unexpected behavior, and potential loss of critical state or control. This is a direct and unmitigated storage collision (7.2 Code Security, 7.7 Upgrades).
IssueThe `PAXG` contract defines `_PAXG_FROZEN_SLOT = 7` for its custom freezing mechanism, which uses inline assembly (`sstore(slot, 1)`/`sstore(slot, 0)`). However, in the inherited `BaseStorageV3` contract, storage slot 7 is occupied by the `address public supplyControllerDeprecated;` variable. This means that any call to `_freeze` or `_unfreeze` will directly overwrite or read from the `supplyControllerDeprecated` variable, leading to severe data corruption, unexpected behavior, and potential loss of critical state or control. This is a direct and unmitigated storage collision (7.2 Code Security, 7.7 Upgrades).
FixImmediately rectify the storage collision. The `_PAXG_FROZEN_SLOT` must be changed to a slot that is guaranteed to be unused and will not collide with any current or future inherited storage variables. A safer approach would be to use Solidity's native `mapping(address => bool) internal frozenAddresses;` and ensure it's placed at a non-colliding slot, avoiding direct assembly for this purpose.
StatusUnresolved
High

Complex and Risky Assembly-Based Storage Migration

H-01The `_migratePAXGStorage` function directly manipulates storage slots (4, 5, 6, 8, 14, 15) using inline assembly. While intended for migration during upgrades, direct `sload`/`sstore` operations are highly error-prone and bypass Solidity's type safety and storage layout guarantees. A single byte offset error or misunderstanding of the previous storage layout could lead to irreversible data corruption or loss of critical state. This is a high-risk operation, especially in an upgradeable context (7.2 Code Security, 7.7 Upgrades).
IssueThe `_migratePAXGStorage` function directly manipulates storage slots (4, 5, 6, 8, 14, 15) using inline assembly. While intended for migration during upgrades, direct `sload`/`sstore` operations are highly error-prone and bypass Solidity's type safety and storage layout guarantees. A single byte offset error or misunderstanding of the previous storage layout could lead to irreversible data corruption or loss of critical state. This is a high-risk operation, especially in an upgradeable context (7.2 Code Security, 7.7 Upgrades).
FixThoroughly review and refactor the `_migratePAXGStorage` function. If possible, replace assembly-based slot manipulation with safer, Solidity-native storage management patterns or leverage well-tested migration libraries. If assembly is unavoidable, ensure exhaustive testing, formal verification, and clear documentation of the exact storage layout being migrated from and to. Consider using a `bytes32` constant for each slot to improve readability and reduce magic numbers.
StatusUnresolved
Medium

Inconsistent Freezing Mechanisms and Deprecated Storage

M-01The contract exhibits an inconsistent approach to address freezing. `PAXG` implements its own freezing logic using `_PAXG_FROZEN_SLOT` (which critically collides with `supplyControllerDeprecated`). Simultaneously, `BaseStorageV3` defines a `mapping(address => bool) internal frozen;` at slot 6, along with `_isFrozen` and `_setFrozen` functions that operate on it. Although `_migratePAXGStorage` clears slot 6, the continued presence of these functions and the `frozen` mapping creates ambiguity and could lead to misinterpretation or accidental use of the deprecated freezing mechanism, resulting in inconsistent state or unexpected behavior (7.1 Architecture, 7.2 Code Security).
IssueThe contract exhibits an inconsistent approach to address freezing. `PAXG` implements its own freezing logic using `_PAXG_FROZEN_SLOT` (which critically collides with `supplyControllerDeprecated`). Simultaneously, `BaseStorageV3` defines a `mapping(address => bool) internal frozen;` at slot 6, along with `_isFrozen` and `_setFrozen` functions that operate on it. Although `_migratePAXGStorage` clears slot 6, the continued presence of these functions and the `frozen` mapping creates ambiguity and could lead to misinterpretation or accidental use of the deprecated freezing mechanism, resulting in inconsistent state or unexpected behavior (7.1 Architecture, 7.2 Code Security).
FixConsolidate the freezing logic into a single, well-defined mechanism. Remove or clearly mark as `internal pure` or `private` any deprecated freezing functions or storage variables that are no longer intended for use. Ensure that all parts of the system consistently refer to the intended freezing state. If `BaseStorageV3`'s `frozen` mapping is truly deprecated, its functions (`_isFrozen`, `_setFrozen`) should be removed or overridden to revert.
StatusUnresolved
Low

Truncation Risk in `_setBalanceData`

L-01The `_setBalanceData` function in `BaseStorageV3` casts `uint256` inputs (`balance`, `shares`) to `uint64` using `StorageLib.toUint64Balance` and `StorageLib.toUint64Shares`. If the input `uint256` values exceed `type(uint64).max`, they will be silently truncated. While this might be an intentional design choice for specific tokenomics, it introduces a potential for loss of precision or unexpected behavior if not carefully managed by all calling functions (7.2 Code Security).
IssueThe `_setBalanceData` function in `BaseStorageV3` casts `uint256` inputs (`balance`, `shares`) to `uint64` using `StorageLib.toUint64Balance` and `StorageLib.toUint64Shares`. If the input `uint256` values exceed `type(uint64).max`, they will be silently truncated. While this might be an intentional design choice for specific tokenomics, it introduces a potential for loss of precision or unexpected behavior if not carefully managed by all calling functions (7.2 Code Security).
FixImplement explicit checks (e.g., `require(balance <= type(uint64).max, "Balance exceeds uint64 limit")`) before casting `uint256` values to `uint64` within `StorageLib.toUint64Balance` and `StorageLib.toUint64Shares`. This ensures that truncation is prevented or explicitly handled, providing clearer error messages and preventing unexpected state changes.
StatusUnresolved
Info

Legacy Proxy Pattern Used

I-01The contract uses `AdminUpgradeabilityProxy`, which is an older OpenZeppelin proxy pattern. While functional, newer patterns like UUPS (e.g., `UUPSUpgradeable`) offer better decentralization of upgrade control by allowing the implementation contract to manage upgrades, rather than relying on a separate proxy admin contract (7.1 Architecture, 7.7 Upgrades).
IssueThe contract uses `AdminUpgradeabilityProxy`, which is an older OpenZeppelin proxy pattern. While functional, newer patterns like UUPS (e.g., `UUPSUpgradeable`) offer better decentralization of upgrade control by allowing the implementation contract to manage upgrades, rather than relying on a separate proxy admin contract (7.1 Architecture, 7.7 Upgrades).
FixConsider migrating to a UUPS proxy pattern in future upgrades. UUPS proxies allow the implementation contract to manage its own upgrades, which can simplify the upgrade process and potentially enhance decentralization by removing the need for a separate proxy admin address to initiate upgrades.
StatusUnresolved

Category Ratings

TechnicalMedium4/10

The technical architecture benefits from inheriting OpenZeppelin's upgradeable access control (7.3 Access Control) and standard ERC-20 token functionalities (7.1 Architecture). However, a critical flaw exists where the custom freezing mechanism directly collides with an existing storage variable (7.2 Code Security). The reliance on complex inline assembly for storage migration (7.2 Code Security, 7.7 Upgrades) introduces significant risk, bypassing Solidity's type safety and storage guarantees. Additionally, the presence of multiple deprecated storage variables and inconsistent freezing logic contributes to code complexity and potential for error (7.1 Architecture).

GovernanceHigh2/10

The contract implements a centralized control model with an owner/admin role for critical operations, including pausing transfers and managing freezing (7.3 Access Control, 7.8 Operations). It also defines specific roles for claim operators and managers, indicating a structured approach to reward distribution (7.5 Governance). While this centralization provides operational flexibility, it concentrates power, posing a medium economic risk (7.4 Economic) as malicious or compromised administrators could impact token holders.

UpgradesHigh1/10

The contract utilizes an `AdminUpgradeabilityProxy` pattern, allowing for future logic upgrades (7.7 Upgrades). However, the upgrade process involves a highly complex and risky `_migratePAXGStorage` function that directly manipulates storage slots using assembly (7.7 Upgrades, 7.2 Code Security). This manual storage migration is extremely error-prone and, combined with the critical storage collision identified, makes upgrades a high-risk operation. The use of a legacy proxy pattern also presents a minor architectural concern (7.1 Architecture).

Security Checklist

Contract VerifiedPass
Ownership RenouncedFail
No Mint FunctionFail
Liquidity LockedFail
Not a ProxyFail

Proxy Upgrade Controls

Proxy TypeZeppelin Os Legacy
AdminTimelock · 24h delay
ImplementationVerified source
Upgrades (30d)0 · stable

Holder Composition

33.6% in wallets0.0% in contracts
Effective Concentration33.6%

Share held by contracts — treasury, vesting, bridge or staking — is discounted against share held by wallets when the score is computed: a contract cannot decide to sell the way an anonymous holder can, though it can still be drained or voted to sell. Effective concentration is the figure the risk score is actually calculated from.

Liquidity Depth

Show 4 more pairsShow less

The 11 remaining pairs hold $1.34M between them and are not listed.

The risk score reads depth across every pair. The volume figure and the volume-to-liquidity ratio elsewhere on this page describe only the pair this audit analysed, so the two are not directly comparable.

LP Distribution

Top-1 Unlocked Holder78.3%
Top-3 Unlocked98.2%

Key Addresses

Deployer
0x36c2…b537
Unlocked LP Held By
0x6a80…a6800xf83f…1a410x45ed…9e3c0xd404…39450x386e…c2790x0333…852f0xbd3c…5d510xe8fe…42d90xcc2b…4b1f0xdd10…813e

No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.

What Raised This Score

  • Ownership NOT renounced — Timelock 24h delay
  • Mintable supply — no cap found, dilution unbounded
  • Proxy contract (upgradeable — admin can replace logic)
  • Top-10 concentration > 30% (33.6% total → 33.6% effective; 33.6% in EOAs, 0.0% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 78.3% (independent LP — depth risk, pool = 56% of DEX liquidity)
  • LP top3 unlocked holders = 98.2% (independent LP — depth risk, pool = 56% of DEX liquidity)
  • 1 Critical finding(s) from audit
  • 1 High finding(s) from audit
  • 1 Medium finding(s) from audit
  • 1 Low finding(s) from audit

Each factor is an on-chain fact recorded at the time of this analysis. The score is computed from them by a deterministic function, so the same contract returns the same score for anyone who runs the audit. How scores are computed

Related Audits

Illuvium (ILV)High RiskRailHigh RiskTether Gold (XAUT)High RiskSustainable Aviation Fuel (SAF)High RiskMatrix (MTX)High RiskAnimecoin (ANIME)High Risk

Would You Like a More Detailed Audit of Paxos Gold?

Our AI-powered scanner gives you a deeper, real-time smart contract analysis — free, with every scoring factor shown.

Get Detailed Audit