Quantum Audit Logo

Is Metronome Synth USD Safe?

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

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

Metronome Synth USD MSUSD
0xab5e…befa
Ethereum Not verifiedLast checked 3d ago 1 audit on record
How is this score calculated? → Critical Risk
Executive SummaryAI Copilot

The SyntheticToken contract serves as an upgradeable ERC-20 token implementation, designed to interact within a broader DeFi ecosystem involving PoolRegistry, Pools, DebtTokens, and a ProxyOFT. The contract demonstrates good practices such as using OpenZeppelin's `Initializable` for upgradeability, custom error handling, and correct `_msgSender()` usage in a proxy context. However, the audit identified areas of concern, including significant centralized control by the governor, complex access control logic relying on external contracts, and a default uncapped total supply. A critical part of the token's logic, the `_transfer` function, was not provided in the audit scope, limiting a full assessment of token movement security.

2 High2 Medium1 Low1 Informational
Volume 24h
$288.8K
Liquidity
$3.86M
Price
$0.4659
Token Age
10mo
Top 10 Holders
98.1%

Security Findings

High

Centralized Control by Governor

H-01The `_poolRegistry.governor()` address, as defined by the `onlyGovernor` modifier, holds extensive control over critical parameters and the operational status of the SyntheticToken. This includes the ability to update `maxAmoSupply`, `maxTotalSupply`, `maxBridgedInSupply`, `maxBridgedOutSupply`, `proxyOFT`, `amo`, and `isActive`. Such centralized control (7.3 Access Control, 7.5 Governance) represents a single point of failure; a compromise of the governor's private key or its controlling entity could lead to severe economic damage, unauthorized minting/burning, or freezing of token operations.
IssueThe `_poolRegistry.governor()` address, as defined by the `onlyGovernor` modifier, holds extensive control over critical parameters and the operational status of the SyntheticToken. This includes the ability to update `maxAmoSupply`, `maxTotalSupply`, `maxBridgedInSupply`, `maxBridgedOutSupply`, `proxyOFT`, `amo`, and `isActive`. Such centralized control (7.3 Access Control, 7.5 Governance) represents a single point of failure; a compromise of the governor's private key or its controlling entity could lead to severe economic damage, unauthorized minting/burning, or freezing of token operations.
FixEnsure the `_poolRegistry.governor()` is controlled by a robust, multi-signature wallet with a high threshold for execution. Implement strict operational procedures and access controls for the multisig signers. Consider time-locks for critical parameter changes to allow for community review and reaction time.
StatusUnresolved
High

Complex External Access Control Logic

H-02The access control modifiers `onlyIfCanBurn`, `onlyIfCanMint`, and `onlyIfCanSeize` rely on complex internal functions (`_isMsgSenderDebtToken`, `_isMsgSenderPool`) that involve multiple external calls to `_poolRegistry`, `IManageable`, `IPool`, and `IDebtToken` interfaces (7.3 Access Control, 7.6 External). This intricate dependency chain increases the attack surface and introduces significant risk. A misconfiguration, bug, or malicious behavior in any of these external contracts could lead to unauthorized minting, burning, or seizing of tokens, bypassing the intended access controls. For example, if `IManageable(sender_).pool()` returns an unexpected address or if `_pool.doesDebtTokenExis…
IssueThe access control modifiers `onlyIfCanBurn`, `onlyIfCanMint`, and `onlyIfCanSeize` rely on complex internal functions (`_isMsgSenderDebtToken`, `_isMsgSenderPool`) that involve multiple external calls to `_poolRegistry`, `IManageable`, `IPool`, and `IDebtToken` interfaces (7.3 Access Control, 7.6 External). This intricate dependency chain increases the attack surface and introduces significant risk. A misconfiguration, bug, or malicious behavior in any of these external contracts could lead to unauthorized minting, burning, or seizing of tokens, bypassing the intended access controls. For example, if `IManageable(sender_).pool()` returns an unexpected address or if `_pool.doesDebtTokenExis…
FixThoroughly audit all external contracts (`IPoolRegistry`, `IPool`, `IDebtToken`, `IProxyOFT`) that interact with SyntheticToken's access control logic. Implement robust validation and sanity checks on return values from external calls. Consider simplifying the access control logic if possible, or clearly document the expected behavior and security assumptions of each external dependency.
StatusUnresolved
Medium

Missing `_transfer` Function Implementation

M-01The provided source code snippet for the `SyntheticToken` contract is truncated, specifically omitting the implementation of the crucial `_transfer` function. This function is called by `transfer`, `transferFrom`, and `seize`, making it central to all token movements (7.2 Code Security). Without its full implementation, a complete security assessment of token balance updates, reentrancy risks, and other potential vulnerabilities related to token transfers cannot be performed. This represents a significant gap in the audit coverage.
IssueThe provided source code snippet for the `SyntheticToken` contract is truncated, specifically omitting the implementation of the crucial `_transfer` function. This function is called by `transfer`, `transferFrom`, and `seize`, making it central to all token movements (7.2 Code Security). Without its full implementation, a complete security assessment of token balance updates, reentrancy risks, and other potential vulnerabilities related to token transfers cannot be performed. This represents a significant gap in the audit coverage.
FixProvide the complete source code for the `_transfer` function and any other omitted parts of the contract. A full audit of these critical components is necessary to ensure the integrity of token transfers and overall contract security.
StatusUnresolved
Medium

`maxTotalSupply` Default to `type(uint256).max`

M-02In the `initialize` function, the `maxTotalSupply` variable is set to `type(uint256).max`. While this effectively means an uncapped total supply, it could be a misconfiguration if a specific total supply limit is intended for the token's economic model (7.4 Economic). If a cap is desired later, it would require a governor action to update, and the implications of an uncapped supply should be fully understood and documented to prevent unexpected economic behavior or potential hyperinflation if minting mechanisms are not tightly controlled.
IssueIn the `initialize` function, the `maxTotalSupply` variable is set to `type(uint256).max`. While this effectively means an uncapped total supply, it could be a misconfiguration if a specific total supply limit is intended for the token's economic model (7.4 Economic). If a cap is desired later, it would require a governor action to update, and the implications of an uncapped supply should be fully understood and documented to prevent unexpected economic behavior or potential hyperinflation if minting mechanisms are not tightly controlled.
FixClarify the intended economic model for the SyntheticToken's total supply. If a specific cap is desired, set `maxTotalSupply` to that value during initialization or ensure the governor has a clear mandate and process to set it. If an uncapped supply is intentional, document this decision and its implications for the token's long-term stability.
StatusUnresolved
Low

Cumulative Bridged Supply Variables

L-01The `totalBridgedIn` and `totalBridgedOut` variables are cumulative sums, which can grow indefinitely. While `bridgedInSupply()` and `bridgedOutSupply()` correctly return the net difference, the cumulative variables themselves could reach very large numbers over time. Although `uint256` provides ample capacity, it's important to ensure that any off-chain or monitoring systems correctly interpret these cumulative values versus the net supply (7.4 Economic). The current checks against `maxBridgedOutSupply` correctly use the net `bridgedOutSupply()`, mitigating direct overflow risks for the limits.
IssueThe `totalBridgedIn` and `totalBridgedOut` variables are cumulative sums, which can grow indefinitely. While `bridgedInSupply()` and `bridgedOutSupply()` correctly return the net difference, the cumulative variables themselves could reach very large numbers over time. Although `uint256` provides ample capacity, it's important to ensure that any off-chain or monitoring systems correctly interpret these cumulative values versus the net supply (7.4 Economic). The current checks against `maxBridgedOutSupply` correctly use the net `bridgedOutSupply()`, mitigating direct overflow risks for the limits.
FixEnsure that all external systems and integrations interacting with `totalBridgedIn` and `totalBridgedOut` are aware of their cumulative nature and differentiate them from the net `bridgedInSupply()` and `bridgedOutSupply()` values. No direct code change is required if the current logic is fully understood and intended.
StatusUnresolved
Info

Correct `_msgSender()` Usage in Proxy Context

I-01The contract correctly utilizes `_msgSender()` (likely inherited from OpenZeppelin's `ContextUpgradeable` via `SynthContext`) to retrieve the original caller in an upgradeable proxy environment (7.1 Architecture, 7.2 Code Security). This is a best practice for upgradeable contracts deployed behind proxies, ensuring that access control and other sender-dependent logic correctly identify the external account initiating the transaction, rather than the proxy contract itself.
IssueThe contract correctly utilizes `_msgSender()` (likely inherited from OpenZeppelin's `ContextUpgradeable` via `SynthContext`) to retrieve the original caller in an upgradeable proxy environment (7.1 Architecture, 7.2 Code Security). This is a best practice for upgradeable contracts deployed behind proxies, ensuring that access control and other sender-dependent logic correctly identify the external account initiating the transaction, rather than the proxy contract itself.
FixMaintain this pattern for all sender-dependent logic within the contract and any future upgrades.
StatusResolved

Category Ratings

TechnicalMedium5/10

The technical architecture of the SyntheticToken contract (7.1 Architecture) is based on an upgradeable ERC-20 standard, utilizing OpenZeppelin's `Initializable` and `SyntheticTokenStorageV2` for robust upgrade management. Code security (7.2 Code Security) benefits from custom error handling and safe `unchecked` arithmetic where appropriate, such as in `decreaseAllowance`. Access control (7.3 Access Control) is implemented through custom modifiers like `onlyGovernor`, `onlyIfCanBurn`, `onlyIfCanMint`, and `onlyIfCanSeize`, which correctly use `_msgSender()` in the proxy context. However, the complex logic within `_isMsgSenderDebtToken` and `_isMsgSenderPool` relies heavily on external contract interactions, increasing the attack surface and potential for misconfiguration. The absence of the `_transfer` function in the provided code snippet prevents a complete technical security assessment of token movement.

GovernanceHigh1/10

The economic model (7.4 Economic) of the SyntheticToken includes mechanisms for tracking bridged-in/out supply and an AMO supply, with configurable maximum limits. However, the `maxTotalSupply` is initialized to `type(uint256).max`, effectively uncapping the total supply by default, which could be a misconfiguration if a specific cap is desired. Governance (7.5 Governance) is highly centralized, with the `_poolRegistry.governor()` possessing extensive control over critical parameters such as `maxAmoSupply`, `maxTotalSupply`, `proxyOFT`, `amo`, and the token's active status. While common in managed DeFi protocols, this central authority represents a significant single point of failure. External dependencies (7.6 External) are significant due to interactions with `IPoolRegistry`, `IPool`, `IDebtToken`, and `IProxyOFT` for core functionality and access control.

UpgradesHigh1/10

The contract is designed as an upgradeable proxy implementation (7.7 Upgrades), inheriting `Initializable` from OpenZeppelin and using `SyntheticTokenStorageV2`, indicating a structured approach to storage management across upgrades. The `initialize` function ensures proper setup for the first deployment. The use of a `TransparentUpgradeableProxy` with a multisig admin (as per prefill) provides a secure mechanism for future upgrades. This setup generally mitigates common upgrade-related risks, provided storage layout compatibility is strictly maintained in subsequent versions.

Security Checklist

Contract VerifiedPass
Ownership Renounced?
No Mint FunctionFail
Liquidity LockedFail
Not a ProxyFail
HoneypotNoneBuy Tax0.0%Sell Tax0.0%

Proxy Upgrade Controls

Proxy TypeEip1967 Transparent
AdminOZ ProxyAdmin → Multisig 3-of-5
ImplementationVerified source
Upgrades (30d)0 · stable

Holder Composition

7.5% in wallets90.6% in contracts
Effective Concentration43.8%

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

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 Holder100.0%
Top-3 Unlocked100.0%

Key Addresses

Deployer
0x421a…7dbe
Unlocked LP Held By
0x8d38…a01d

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

What Raised This Score

  • Ownership status UNKNOWN (owner could not be resolved)
  • Mintable supply — no cap found, dilution unbounded
  • Proxy contract (upgradeable — admin can replace logic)
  • Top-10 concentration > 30% (98.1% total → 43.8% effective; 7.5% in EOAs, 90.6% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 100.0% (independent LP — depth risk, pool = 89% of DEX liquidity)
  • LP top3 unlocked holders = 100.0% (independent LP — depth risk, pool = 89% of DEX liquidity)
  • 2 High finding(s) from audit
  • 2 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

NEXOCritical RiskCronos (CRO)Critical RiskEpic Chain (EPIC)Critical RiskAZTECCritical RiskCoW Protocol Token (COW)Critical RiskMetronome Synth ETH (MSETH)Critical Risk

Would You Like a More Detailed Audit of Metronome Synth USD?

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

Get Detailed Audit