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.

On-chain security analysis — is it a scam or legit?
Is ShopinX Token Safe?
Not verified
This record has not gone through deep verification and is not being monitored. The score is a dated snapshot — the token’s risk can change at any time.Own this token? Put it under verification →The ShopinX Token contract implements an ERC20 token with custom locking and vesting functionalities.
Read the full analysis- Ownership not renounced — owner is a contract
- Top-10 concentration > 70%
- 1 Critical finding(s) from audit
- 1 Medium finding(s) from audit
- 2 Low finding(s) from audit
Exact factors
- 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
Security Checklist
as of audit · Sep 4Holders
as of audit · Sep 4, 2026- Walletsanonymous holders, free to sell77.5%
- Everyone elsethe rest of the supply22.5%
How holder types affect the score
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.
Holder balances as recorded by the audit of Sep 4, 2026
Liquidity
as of audit · Sep 4The risk score reads depth across every pair.
The LP tokens of the analysed pool are locked or burned.
0x799a…77bc0xf7a7…9dff0x1da1…15c40xab8a…01db0x0a6e…e7a00xddec…cb520xb262…eeed0xe1a7…113f0xfebe…384cNo privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
CriticalOwner Can Indefinitely Freeze User Funds
The 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.C-01
Issue
The 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.
Fix
Implement 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.
Status
Unresolved
MediumPermanent Owner Role
The 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.M-01
Issue
The 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.
Fix
Consider 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.
Status
Unresolved
LowVesting Calculation Precision Loss
The 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.L-01
Issue
The 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.
Fix
While 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.
Status
Unresolved
LowPotential Truncation in Vesting totalAmount
The 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.L-02
totalAmountIssue
The 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.
Fix
If 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.
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The 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).
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).
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.
It is strongly recommended to address the critical vulnerability allowing indefinite freezing of funds.
This could involve implementing a maximum cumulative lock duration or requiring user consent for freezing existing balances. The permanent owner role should also be reconsidered; if decentralization is a future goal, a mechanism for transferring ownership to a multisig or DAO should be explored. Finally, review the vesting calculation for precision and ensure uint128 casting for vesting amounts cannot lead to unexpected truncations under any foreseeable circumstances.
Contract & Record
Free for any token on the record. It links to this page and always shows the current score and the date it was checked.
- Sep 3, 202666High
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
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 Is this your token? Publish your own audit on this page