Quantum Audit Logo

Is ShopinX Token Safe?

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

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

ShopinX Token SPX
0xca56…3827
BNB Chain Not verifiedLast checked 3d ago 1 audit on record
Executive SummaryAI Copilot

The ShopinX Token contract implements an ERC20 token with custom locking and vesting functionalities. The contract utilizes OpenZeppelin's battle-tested libraries and `Ownable2Step` for enhanced ownership management. However, the audit identified a critical vulnerability related to the owner's ability to indefinitely freeze user funds, alongside other medium and low-severity issues concerning permanent owner control and vesting calculation precision. These findings highlight significant centralization risks and potential for fund access issues.

1 Critical1 Medium2 Low
Volume 24h
$985.2K
Liquidity
$135.5K
Price
$0.05732
Token Age
1mo
Top 10 Holders
77.5%

Security Findings

Critical

Owner Can Indefinitely Freeze User Funds

C-01The `setLock` function, callable by the contract owner, allows freezing an account's tokens for a duration up to `MAX_LOCK_DURATION` (4 years). While a single call is limited, the owner can repeatedly call `setLock` just before the existing lock expires, effectively freezing an account's entire token balance indefinitely. This grants the owner unilateral power to prevent users from accessing their funds, posing a severe centralization risk and potential for denial of service.
IssueThe `setLock` function, callable by the contract owner, allows freezing an account's tokens for a duration up to `MAX_LOCK_DURATION` (4 years). While a single call is limited, the owner can repeatedly call `setLock` just before the existing lock expires, effectively freezing an account's entire token balance indefinitely. This grants the owner unilateral power to prevent users from accessing their funds, posing a severe centralization risk and potential for denial of service.
FixImplement a mechanism to prevent indefinite freezing. Options include: 1) A global maximum cumulative lock duration for any single account. 2) Requiring explicit consent from the account holder to freeze their existing balance. 3) Limiting `setLock` only to tokens transferred by the owner, not existing user balances. 4) Transitioning ownership to a multi-signature wallet or DAO with strict governance rules for such powerful functions.
StatusUnresolved
Medium

Permanent Owner Role

M-01The `renounceOwnership` function is explicitly overridden to revert, preventing the contract owner from relinquishing their administrative privileges. This design choice establishes a permanent single point of control, increasing the centralization risk. If the owner's private key is compromised or the owner becomes malicious, there is no on-chain mechanism to remove their control over critical functions like `setLock`, `removeLock`, `transferWithLock`, and `transferWithVesting`.
IssueThe `renounceOwnership` function is explicitly overridden to revert, preventing the contract owner from relinquishing their administrative privileges. This design choice establishes a permanent single point of control, increasing the centralization risk. If the owner's private key is compromised or the owner becomes malicious, there is no on-chain mechanism to remove their control over critical functions like `setLock`, `removeLock`, `transferWithLock`, and `transferWithVesting`.
FixConsider allowing ownership to be renounced or transferred to a more decentralized entity, such as a multi-signature wallet or a DAO. If a permanent owner is intended, ensure robust security measures are in place for the owner's private key and consider a time-locked transfer mechanism for ownership changes.
StatusUnresolved
Low

Vesting Calculation Precision Loss

L-01The `vestedAmount` function uses integer division in its calculations, particularly for `vestedFromCurrent`. When `v.totalAmount` or `v.stepPercent` are small, or `PERCENT_BASE * stepSeconds` is large, integer division can truncate fractional results to zero. This may lead to minor precision loss, causing users to receive slightly less than their mathematically precise vested amount, especially for small token values or very granular vesting schedules.
IssueThe `vestedAmount` function uses integer division in its calculations, particularly for `vestedFromCurrent`. When `v.totalAmount` or `v.stepPercent` are small, or `PERCENT_BASE * stepSeconds` is large, integer division can truncate fractional results to zero. This may lead to minor precision loss, causing users to receive slightly less than their mathematically precise vested amount, especially for small token values or very granular vesting schedules.
FixWhile often acceptable for minor discrepancies, consider using a fixed-point math library or adjusting the calculation order to minimize precision loss. For example, multiply before dividing where possible, or ensure intermediate values are large enough to retain precision before final division. Clearly document this behavior if no changes are made.
StatusUnresolved
Low

Potential Truncation in Vesting `totalAmount`

L-02The `totalAmount` field within the `VestingInfo` struct is defined as `uint128`, and the `amount` parameter in `transferWithVesting` is explicitly cast to `uint128`. While the current `INITIAL_SUPPLY` (10^27) fits within `uint128` (max ~3.4 x 10^38), if future vesting amounts were to exceed `type(uint128).max`, the value would be silently truncated without a revert. This could lead to a loss of funds or incorrect vesting schedules if very large amounts are ever intended for vesting.
IssueThe `totalAmount` field within the `VestingInfo` struct is defined as `uint128`, and the `amount` parameter in `transferWithVesting` is explicitly cast to `uint128`. While the current `INITIAL_SUPPLY` (10^27) fits within `uint128` (max ~3.4 x 10^38), if future vesting amounts were to exceed `type(uint128).max`, the value would be silently truncated without a revert. This could lead to a loss of funds or incorrect vesting schedules if very large amounts are ever intended for vesting.
FixIf there's any possibility of vesting amounts exceeding `uint128` maximum, consider changing `VestingInfo.totalAmount` to `uint256` to prevent potential truncation. Alternatively, add a `require(amount <= type(uint128).max, 'Amount too large for vesting')` check in `transferWithVesting` to explicitly prevent such an overflow.
StatusUnresolved

Category Ratings

TechnicalMedium6/10

The contract is built upon robust OpenZeppelin ERC20 standards, including `ERC20Burnable` and `ERC20Permit`, and uses Solidity 0.8.27, benefiting from checked arithmetic. The `_update` override correctly integrates custom locking and vesting logic to prevent transfers of restricted tokens (7.2 Code Security). However, a critical flaw exists where the owner can indefinitely freeze user funds by repeatedly calling `setLock`, despite a `MAX_LOCK_DURATION` per call (7.3 Access Control). Additionally, minor precision loss in `vestedAmount` calculations and a potential `uint128` truncation for vesting amounts were noted (7.2 Code Security).

GovernanceHigh3/10

The token has a fixed `INITIAL_SUPPLY` and no further minting capabilities, which is a positive economic control (7.4 Economic). The `Ownable2Step` pattern enhances security for ownership transfers (7.5 Governance). However, the owner's ability to indefinitely freeze any account's tokens via `setLock` introduces a critical centralization risk, allowing potential denial of service for user funds (7.4 Economic). Furthermore, the `renounceOwnership` function is explicitly reverted, making the owner role permanent and preventing decentralization of control (7.5 Governance).

UpgradesMedium6/10

This contract is not designed as an upgradeable proxy. Therefore, traditional upgrade safety concerns (7.7 Upgrades) related to proxy patterns are not applicable. Any changes to the contract's logic would require a new deployment and migration of assets, which is a standard practice for non-upgradeable contracts.

Security Checklist

Contract VerifiedPass
Ownership RenouncedFail
No Mint FunctionPass
Liquidity LockedPass
Not a ProxyPass
HoneypotNoneBuy Tax0.0%Sell Tax0.0%

Holder Composition

77.5% in wallets0.0% in contracts
Effective Concentration77.5%

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

LP Locked88.3% · TeamFinance
Top-1 Unlocked Holder5.2%

Key Addresses

Deployer
0xaa66…3750
Unlocked LP Held By
0x799a…77bc0xf7a7…9dff0x1da1…15c40xab8a…01db0x0a6e…e7a00xddec…cb520xb262…eeed0xe1a7…113f0xfebe…384c

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 — owner is a contract (governance/executor, not an EOA)
  • Top-10 concentration > 70% (77.5% total → 77.5% effective; 77.5% in EOAs, 0.0% in contracts — extreme)
  • 1 Critical finding(s) from audit
  • 1 Medium finding(s) from audit
  • 2 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

XPULSHigh RiskHana Token (HANA)High RiskUpstarty (UPY)High RiskOrizon (ORI)High Risk牛来 (NIULAI)High RiskRandyHigh Risk

Would You Like a More Detailed Audit of ShopinX Token?

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

Get Detailed Audit