The audit covers an ERC-20 token implementation, including SafeMath, Ownable, Claimable, and HasNoEther contracts. The contract utilizes standard patterns for token functionality and access control. Key findings include an outdated Solidity compiler version and the inherent ERC-20 allowance race condition. The contract's design for ownership transfer and Ether handling is generally sound, though some areas could be improved for robustness and security.

On-chain security analysis — is it a scam or legit?
Is COTI 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 audit covers an ERC-20 token implementation, including SafeMath, Ownable, Claimable, and HasNoEther contracts.
Read the full analysis- Ownership not renounced — owner is an EOA
- Mintable supply — no cap found, dilution unbounded
- Top-10 concentration > 30%
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- LP top1 unlocked holder = 90.7%
- LP top3 unlocked holders = 99.1%
- 2 High finding(s) from audit
- 2 Medium finding(s) from audit
- 1 Low finding(s) from audit
Exact factors
- Ownership NOT renounced — owner is an EOA (single private key)
- Mintable supply — no cap found, dilution unbounded
- Top-10 concentration > 30% (47.0% total → 47.0% effective; 47.0% 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 = 90.7% (independent LP — depth risk, pool = 93% of DEX liquidity)
- LP top3 unlocked holders = 99.1% (independent LP — depth risk, pool = 93% 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
Security Checklist
as of audit · Sep 4Holders
as of audit · Sep 4, 2026- Walletsanonymous holders, free to sell47.0%
- Everyone elsethe rest of the supply53.0%
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 4- Uniswap v2WETHAnalysed$176.7K92.9%
- SushiswapWETH$11.0K5.8%
- Uniswap v3WETH$1.5K0.8%
- Balancer v3USDT$1.0K0.5%
The risk score reads depth across every pair.
The LP tokens of the analysed pool are not locked or burned, so whoever holds them can withdraw that liquidity.
0xf941…67be0xe6e5…c64b0x4d54…ed650x6ae9…4d500x2679…ffac0xaf96…262d0x1f57…9d300x3283…80d10x1900…46240x74c6…0785No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
HighERC-20 approve Race Condition Vulnerability
The approve function in the StandardToken contract is susceptible to a known ERC-20 race condition. If a user approves an allowance for a spender, and then attempts to change that allowance, a malicious spender could front-run the second transaction to spend the original allowance before the new allowance is set. This could result in the spender being able to spend both the old and new allowances. While increaseApproval is provided as a mitigation, the base approve function remains vulnerable.H-01
approve Race Condition VulnerabilityIssue
The approve function in the StandardToken contract is susceptible to a known ERC-20 race condition. If a user approves an allowance for a spender, and then attempts to change that allowance, a malicious spender could front-run the second transaction to spend the original allowance before the new allowance is set. This could result in the spender being able to spend both the old and new allowances. While increaseApproval is provided as a mitigation, the base approve function remains vulnerable.
Fix
It is recommended to deprecate the direct approve function or strongly advise users to always set the allowance to zero before setting a new non-zero allowance. Encourage the use of increaseApproval and decreaseApproval functions, which are designed to prevent this race condition.
Status
Unresolved
HighOutdated Solidity Compiler Version
The contract is compiled with Solidity version 0.4.24. This version is significantly outdated and no longer actively maintained. Newer compiler versions (e.g., 0.8.x) include numerous bug fixes, security enhancements, and gas optimizations that address known vulnerabilities and improve overall contract robustness. Deploying with an old compiler version exposes the contract to potential undiscovered or unpatched compiler-level bugs.H-02
Issue
The contract is compiled with Solidity version 0.4.24. This version is significantly outdated and no longer actively maintained. Newer compiler versions (e.g., 0.8.x) include numerous bug fixes, security enhancements, and gas optimizations that address known vulnerabilities and improve overall contract robustness. Deploying with an old compiler version exposes the contract to potential undiscovered or unpatched compiler-level bugs.
Fix
Migrate the contract to a recent, stable Solidity compiler version (e.g., 0.8.x). This will require careful testing and adaptation of the code to comply with newer syntax and semantics, such as explicit unchecked blocks for arithmetic and changes in visibility rules.
Status
Unresolved
MediumIrreversible Ownership Renunciation
The renounceOwnership function in the Ownable contract allows the current owner to set the owner address to address(0). If this function is called without a prior transfer of ownership to a new, valid address, the contract will become permanently unmanageable, as no address will have the onlyOwner permissions to perform administrative actions.M-01
Issue
The renounceOwnership function in the Ownable contract allows the current owner to set the owner address to address(0). If this function is called without a prior transfer of ownership to a new, valid address, the contract will become permanently unmanageable, as no address will have the onlyOwner permissions to perform administrative actions.
Fix
Consider removing the renounceOwnership function if permanent ownership is desired. If renunciation is a required feature, ensure clear documentation and operational procedures are in place to prevent accidental unmanageability. Alternatively, implement a multi-signature wallet as the owner to add an extra layer of security and prevent single points of failure.
Status
Unresolved
MediumEther Transfer Failure Risk in reclaimEther
The reclaimEther function in HasNoEther uses owner.transfer(address(this).balance) to send Ether to the owner. The transfer() function has a fixed gas stipend of 2300 gas. If the owner address is a contract with a fallback function that requires more than 2300 gas to execute, the Ether transfer will fail, potentially locking Ether in the contract if the owner is a contract.M-02
reclaimEtherIssue
The reclaimEther function in HasNoEther uses owner.transfer(address(this).balance) to send Ether to the owner. The transfer() function has a fixed gas stipend of 2300 gas. If the owner address is a contract with a fallback function that requires more than 2300 gas to execute, the Ether transfer will fail, potentially locking Ether in the contract if the owner is a contract.
Fix
Replace owner.transfer() with owner.call{value: address(this).balance}("") for more robust Ether transfers. This method forwards all available gas, making it more resilient to complex recipient fallback functions. Ensure proper checks for the success of the call operation (e.g., `(bool success,) = owner.call{value: address(this).balance}(""); require(success, "Ether transfer failed");`).
Status
Unresolved
LowSafeMath uses assert instead of require
The SafeMath library uses assert for its internal checks (e.g., assert(b <= a) in sub). In Solidity, assert consumes all remaining gas on failure, whereas require refunds the remaining gas. While SafeMath is an internal library, using require for input validation checks is generally considered a best practice for gas efficiency.L-01
SafeMath uses assert instead of requireIssue
The SafeMath library uses assert for its internal checks (e.g., assert(b <= a) in sub). In Solidity, assert consumes all remaining gas on failure, whereas require refunds the remaining gas. While SafeMath is an internal library, using require for input validation checks is generally considered a best practice for gas efficiency.
Fix
Consider updating the SafeMath library to use require statements instead of assert for conditions that validate inputs or state. This would improve gas efficiency in cases where an invalid operation occurs.
Status
Unresolved
InfoMissing Zero Address Check for approve _spender
The approve function does not explicitly check if the _spender address is address(0). While address(0) cannot effectively spend tokens, adding an explicit require(_spender != address(0)) check is a good practice to prevent accidental calls or wasted gas on invalid inputs.I-01
approve _spenderIssue
The approve function does not explicitly check if the _spender address is address(0). While address(0) cannot effectively spend tokens, adding an explicit require(_spender != address(0)) check is a good practice to prevent accidental calls or wasted gas on invalid inputs.
Fix
Add a require(_spender != address(0), "ERC20: approve to the zero address") check at the beginning of the approve function.
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The technical architecture (7.1) is modular, separating concerns into libraries and base contracts. Code security (7.2) benefits from SafeMath for arithmetic operations, mitigating overflow/underflow risks. However, the use of Solidity 0.4.24 is a significant concern, as newer compiler versions include critical bug fixes and security enhancements. The ERC-20 approve function (7.2) is susceptible to a known race condition, despite the presence of increaseApproval. Access control (7.3) is well-implemented using the Ownable pattern and a two-step Claimable process for ownership transfer. External interactions (7.6) are limited, primarily for ERC-20 transfers, reducing reentrancy risks.
The economic model (7.4) appears to be a standard fixed-supply ERC-20 token with no minting or burning mechanisms visible in the provided code. Governance (7.5) is centralized via a single owner, with a secure two-step transfer process. However, the renounceOwnership function allows the owner to permanently relinquish control, which could lead to an unmanageable contract (7.8 Operations). The HasNoEther contract effectively prevents accidental Ether accumulation, but the reclaimEther function's use of transfer() could fail if the owner is a complex contract.
The contract is not designed with upgradeability in mind (7.7 Architecture). There are no proxy patterns or upgrade mechanisms implemented, meaning the contract's logic is immutable once deployed. This eliminates upgrade-specific risks but also prevents future bug fixes or feature enhancements without a new deployment.
It is strongly recommended to migrate the contract to a newer, actively supported Solidity compiler version (e.g., 0.8.x) to benefit from critical security patches and improved gas efficiency.
Implement a more robust allowance management strategy for ERC-20 tokens, potentially deprecating the direct approve function in favor of increaseApproval and decreaseApproval. Review the renounceOwnership functionality to ensure it aligns with the intended operational strategy, considering a multi-signature wallet for ownership to enhance security. Finally, consider using call.value() with a gas stipend for Ether transfers in reclaimEther to ensure compatibility with contract recipients, or explicitly document that the owner should be an EOA.
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.
- Jul 28, 202688Critical
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
Would You Like a More Detailed Audit of COTI?
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