Quantum Audit Logo

Is StorjToken Safe?

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

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

StorjToken STORJ
0xb64e…b8ac
Ethereum Not verifiedLast checked 3d ago 1 audit on record
Executive SummaryAI Copilot

The CentrallyIssuedToken contract implements a standard ERC20 token with burn and migration-based upgrade functionalities. It utilizes SafeMath for arithmetic operations, mitigating common integer overflow/underflow risks. However, the contract exhibits a high degree of centralization through the `upgradeMaster` role, which controls critical upgrade parameters. Several code security patterns, such as the `approve` function's front-running mitigation and the use of `throw` statements, are outdated or introduce usability issues. The upgrade mechanism itself includes important checks for the `UpgradeAgent` but relies heavily on the trustworthiness of the `upgradeMaster`.

1 High2 Medium1 Low2 Informational
Volume 24h
$16.3K
Liquidity
$77.7K
Price
$0.03089
Token Age
6y
Top 10 Holders
63.5%

Security Findings

High

Centralized Control by upgradeMaster

H-01The `upgradeMaster` address holds significant power, including the ability to set the `upgradeAgent` (which facilitates token migration) and to change the `upgradeMaster` address itself. This single point of control introduces a high centralization risk, as a compromised or malicious `upgradeMaster` could lead to unauthorized token migrations or loss of control over the upgrade process. This impacts 7.3 Access Control and 7.5 Governance.
IssueThe `upgradeMaster` address holds significant power, including the ability to set the `upgradeAgent` (which facilitates token migration) and to change the `upgradeMaster` address itself. This single point of control introduces a high centralization risk, as a compromised or malicious `upgradeMaster` could lead to unauthorized token migrations or loss of control over the upgrade process. This impacts 7.3 Access Control and 7.5 Governance.
FixImplement a multi-signature wallet or a decentralized governance mechanism (e.g., a DAO) to control the `upgradeMaster` role. This would require multiple approvals for critical administrative actions, significantly reducing the risk associated with a single point of failure.
StatusUnresolved
Medium

Outdated `approve` Front-Running Mitigation Pattern

M-01The `approve` function includes a check `if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;` which forces users to first set an allowance to zero before increasing it to a new non-zero value. While this pattern attempts to mitigate a specific front-running attack where an attacker can sandwich an `approve` transaction to drain funds, it introduces a cumbersome user experience and does not fully eliminate all front-running scenarios. Modern ERC20 best practices recommend using `increaseAllowance` and `decreaseAllowance` functions. This impacts 7.2 Code Security and 7.4 Economic.
IssueThe `approve` function includes a check `if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;` which forces users to first set an allowance to zero before increasing it to a new non-zero value. While this pattern attempts to mitigate a specific front-running attack where an attacker can sandwich an `approve` transaction to drain funds, it introduces a cumbersome user experience and does not fully eliminate all front-running scenarios. Modern ERC20 best practices recommend using `increaseAllowance` and `decreaseAllowance` functions. This impacts 7.2 Code Security and 7.4 Economic.
FixConsider replacing the current `approve` logic with `increaseAllowance` and `decreaseAllowance` functions. This provides a safer and more user-friendly way to manage token allowances without requiring a two-step approval process.
StatusUnresolved
Medium

Deprecated `throw` Statements and `assert` Usage

M-02The contract extensively uses `throw` for error handling and `assert` within the `SafeMath` library. In modern Solidity, `require()` and `revert()` are the preferred mechanisms for handling errors related to invalid user input or state, while `assert()` is typically reserved for checking internal invariants. Using `throw` and `assert` for general error conditions can lead to higher gas costs on failure compared to `require`/`revert` in newer EVM versions. This impacts 7.2 Code Security.
IssueThe contract extensively uses `throw` for error handling and `assert` within the `SafeMath` library. In modern Solidity, `require()` and `revert()` are the preferred mechanisms for handling errors related to invalid user input or state, while `assert()` is typically reserved for checking internal invariants. Using `throw` and `assert` for general error conditions can lead to higher gas costs on failure compared to `require`/`revert` in newer EVM versions. This impacts 7.2 Code Security.
FixRefactor the code to replace `throw` statements with `require()` or `revert()` for external input validation and state checks. While `assert` in `SafeMath` is acceptable for invariant checks, consider updating the library to use `revert()` for clarity and consistency if possible.
StatusUnresolved
Low

Inconsistent `onlyPayloadSize` Modifier Usage

L-01The `transfer` function uses the `onlyPayloadSize` modifier, which is an outdated pattern intended to prevent short address attacks. This modifier is generally not effective against modern attacks and can cause unexpected issues. Furthermore, the `transferFrom` function, which also takes address and value arguments, does not use this modifier, leading to inconsistency in the contract's defensive patterns. This impacts 7.2 Code Security.
IssueThe `transfer` function uses the `onlyPayloadSize` modifier, which is an outdated pattern intended to prevent short address attacks. This modifier is generally not effective against modern attacks and can cause unexpected issues. Furthermore, the `transferFrom` function, which also takes address and value arguments, does not use this modifier, leading to inconsistency in the contract's defensive patterns. This impacts 7.2 Code Security.
FixRemove the `onlyPayloadSize` modifier from the `transfer` function. This pattern is largely ineffective and can introduce unnecessary complexity or compatibility issues. Modern Solidity compilers and best practices do not recommend its use.
StatusUnresolved
Info

Redundant `canUpgrade` Function

I-01The `canUpgrade()` function in `UpgradeableToken` always returns `true`. This makes the `UpgradeState.NotAllowed` branch in `getUpgradeState()` unreachable and renders the `canUpgrade()` function itself redundant. If there are no conditions under which an upgrade should be disallowed, the function serves no practical purpose. This impacts 7.1 Architecture.
IssueThe `canUpgrade()` function in `UpgradeableToken` always returns `true`. This makes the `UpgradeState.NotAllowed` branch in `getUpgradeState()` unreachable and renders the `canUpgrade()` function itself redundant. If there are no conditions under which an upgrade should be disallowed, the function serves no practical purpose. This impacts 7.1 Architecture.
FixEither remove the `canUpgrade()` function if it's not intended to ever return `false`, or implement actual conditions within it that determine whether an upgrade is allowed. If removed, adjust `getUpgradeState()` accordingly.
StatusUnresolved
Info

Missing Event for `setUpgradeMaster`

I-02The `setUpgradeMaster` function allows the current `upgradeMaster` to transfer its administrative role to a new address. This is a critical administrative action, but no event is emitted to log this change on-chain. The absence of an event makes it difficult to track changes in the `upgradeMaster` role, hindering transparency and auditability of administrative actions. This impacts 7.2 Code Security and 7.8 Operations.
IssueThe `setUpgradeMaster` function allows the current `upgradeMaster` to transfer its administrative role to a new address. This is a critical administrative action, but no event is emitted to log this change on-chain. The absence of an event makes it difficult to track changes in the `upgradeMaster` role, hindering transparency and auditability of administrative actions. This impacts 7.2 Code Security and 7.8 Operations.
FixEmit an event (e.g., `UpgradeMasterChanged(address indexed oldMaster, address indexed newMaster)`) whenever the `upgradeMaster` address is updated. This provides an on-chain record of the change, improving transparency and making administrative actions easier to monitor and audit.
StatusUnresolved

Category Ratings

TechnicalLow8/10

The technical architecture (7.1 Architecture) is a multi-inheritance pattern for an ERC20 token with burn and upgrade features. Code security (7.2 Code Security) benefits from SafeMath for arithmetic, preventing overflows/underflows. However, the contract uses deprecated `throw` statements and `assert` for general error handling, which can be less gas-efficient than `require`/`revert`. The `approve` function's front-running mitigation pattern (M-01) is outdated and can cause usability issues. Additionally, the `onlyPayloadSize` modifier is inconsistently applied and generally not recommended (L-01). Access control (7.3 Access Control) for administrative functions like `setUpgradeAgent` and `setUpgradeMaster` is appropriately restricted to the `upgradeMaster`.

GovernanceHigh1/10

The economic model (7.4 Economic) is a standard centrally issued token with a burn mechanism. The initial supply is minted to a single owner in the constructor. A significant governance risk (7.5 Governance) is the high centralization around the `upgradeMaster` address (H-01). This address has the sole authority to set the `upgradeAgent` for token migration and can also transfer its own master role. This single point of control introduces a substantial risk if the `upgradeMaster` key is compromised or acts maliciously. The `approve` function's front-running vulnerability (M-01) also presents an economic risk to users.

UpgradesMedium6/10

The contract implements a token migration upgrade pattern (7.7 Upgrades), where users actively transfer their tokens to a new `UpgradeAgent` contract. The `setUpgradeAgent` function includes important checks, such as verifying the `isUpgradeAgent()` interface and ensuring `originalSupply()` matches `totalSupply`, which are good practices to prevent misconfiguration. However, the entire upgrade process is controlled by a single `upgradeMaster` address (H-01), creating a centralized point of failure. There is also no event emitted when the `upgradeMaster` itself is changed (I-02), hindering transparency for this critical administrative action.

Security Checklist

Contract VerifiedPass
Ownership Renounced?
No Mint FunctionPass
Liquidity LockedFail
Not a ProxyPass

Holder Composition

58.4% in wallets5.1% in contracts
Effective Concentration60.4%

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 Holder95.2%
Top-3 Unlocked97.6%

Key Addresses

Deployer
0x00f6…ef0b
Unlocked LP Held By
0x3cbe…8e990x50a5…5a3e0xe2e6…0be90xa406…2d990xa118…3cd80x4018…cc940x9fbc…b3010xf873…2cfe0x1698…9e7d0x2e52…ec6a

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)
  • Top-10 concentration > 50% (63.5% total → 60.4% effective; 58.4% in EOAs, 5.1% in contracts — heavy)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 95.2% (independent LP — depth risk, pool = 64% of DEX liquidity)
  • LP top3 unlocked holders = 97.6% (independent LP — depth risk, pool = 64% of DEX liquidity)
  • 1 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

FOXHigh RiskMorphoHigh RiskUniswap (UNI)High RiskBeamHigh RiskSuperVerse (SUPER)High RiskRelicsHigh Risk

Would You Like a More Detailed Audit of StorjToken?

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

Get Detailed Audit