Quantum Audit Logo

Is Chainlink Safe?

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

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

Chainlink LINK
0x5149…86ca
Ethereum
Not verifiedThis 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 →
Last checked 18d ago 1 audit on record
How is this score calculated? → Medium Risk
Executive SummaryAI Copilot

The ChainLink Token contract implements ERC-20 and ERC-677 standards, utilizing SafeMath for arithmetic safety. However, the audit identified a critical issue where the public `totalSupply()` function incorrectly returns zero due to variable shadowing, significantly impacting ERC-20 compliance and integrations. Inconsistent `Transfer` event signatures between standard transfers and `transferAndCall` also pose integration challenges. Additionally, the `approve` function is susceptible to a known race condition, and the `validRecipient` modifier's implementation is incomplete in the provided source. The contract uses an outdated Solidity compiler version.

1 Critical1 High2 Medium1 Low1 Informational
Volume 24h
$8.29M
Liquidity
$22.09M
Price
$11.8800
Token Age
5y
Top 10 Holders
31.5%

Security Findings

Critical

Incorrect ERC-20 `totalSupply` Implementation

C-01The `LinkToken` contract declares `uint public constant totalSupply = 10**27;`, which shadows the `uint256 public totalSupply;` state variable inherited from `ERC20Basic`. While the constructor correctly uses the constant `totalSupply` to assign initial balances, the public getter function `totalSupply()` (which refers to the state variable) will always return 0. This violates the ERC-20 standard and will cause any external application or exchange relying on this function to misinterpret the token's total supply.
IssueThe `LinkToken` contract declares `uint public constant totalSupply = 10**27;`, which shadows the `uint256 public totalSupply;` state variable inherited from `ERC20Basic`. While the constructor correctly uses the constant `totalSupply` to assign initial balances, the public getter function `totalSupply()` (which refers to the state variable) will always return 0. This violates the ERC-20 standard and will cause any external application or exchange relying on this function to misinterpret the token's total supply.
FixRemove the `constant` keyword from `LinkToken`'s `totalSupply` declaration and ensure the inherited `totalSupply` state variable is correctly initialized in the constructor, or explicitly set to the desired value. For example, `ERC20Basic.totalSupply = 10**27;` (if `ERC20Basic.totalSupply` was not `public` but `internal` or `protected` and accessible, or if `LinkToken` directly managed it). A common pattern is to set `_totalSupply = initialSupply;` in the constructor of the base token contract.
StatusUnresolved
High

Inconsistent ERC-677 `Transfer` Event Signatures

H-01The `ERC677Token` contract defines a `Transfer` event with an additional `bytes data` parameter, which conflicts with the standard `ERC20Basic` `Transfer` event signature. Consequently, `transferAndCall` emits the `ERC677` specific `Transfer` event, while standard `transfer` and `transferFrom` functions (inherited from `BasicToken` and `StandardToken`) emit the `ERC20Basic` `Transfer` event. This inconsistency can lead to issues for block explorers, indexers, and applications that expect a single, consistent `Transfer` event signature for all token movements.
IssueThe `ERC677Token` contract defines a `Transfer` event with an additional `bytes data` parameter, which conflicts with the standard `ERC20Basic` `Transfer` event signature. Consequently, `transferAndCall` emits the `ERC677` specific `Transfer` event, while standard `transfer` and `transferFrom` functions (inherited from `BasicToken` and `StandardToken`) emit the `ERC20Basic` `Transfer` event. This inconsistency can lead to issues for block explorers, indexers, and applications that expect a single, consistent `Transfer` event signature for all token movements.
FixTo maintain full ERC-20 compatibility while supporting ERC-677, consider emitting both the ERC-20 `Transfer` event and the ERC-677 `Transfer` event (with `data`) for `transferAndCall` operations, or ensure that the `ERC677` event is emitted for all transfers, potentially with empty `data` for standard transfers, if the consuming applications can handle it. The most robust solution for full compatibility is often to emit the ERC-20 event for all transfers, and a separate, distinct event for `tra…
StatusUnresolved
Medium

ERC-20 `approve` Race Condition Vulnerability

M-01The `approve` function is susceptible to a known front-running attack. If a user attempts to change an allowance from amount X to amount Y, a malicious spender could front-run the transaction, spend X tokens, and then allow the original `approve` transaction to proceed, resulting in the spender having an allowance of Y tokens in addition to the X tokens already spent. While `increaseApproval` and `decreaseApproval` functions are provided to mitigate this, the base `approve` function remains callable and vulnerable.
IssueThe `approve` function is susceptible to a known front-running attack. If a user attempts to change an allowance from amount X to amount Y, a malicious spender could front-run the transaction, spend X tokens, and then allow the original `approve` transaction to proceed, resulting in the spender having an allowance of Y tokens in addition to the X tokens already spent. While `increaseApproval` and `decreaseApproval` functions are provided to mitigate this, the base `approve` function remains callable and vulnerable.
FixEducate users to primarily use `increaseApproval` and `decreaseApproval` instead of `approve` when modifying existing allowances. For new allowances, `approve` is generally safe. Consider deprecating or adding a warning to the `approve` function if `allowed[msg.sender][_spender]` is not zero, forcing users to use the safer `increaseApproval`/`decreaseApproval` pattern.
StatusUnresolved
Medium

Truncated `validRecipient` Modifier Implementation

M-02The provided source code for the `validRecipient` modifier is truncated. This prevents a full security assessment of its intended checks. Without the complete implementation, it's impossible to verify if critical checks, such as preventing transfers to `address(0)` (the zero address), are correctly enforced. A missing `address(0)` check could lead to tokens being permanently locked if sent to the zero address.
IssueThe provided source code for the `validRecipient` modifier is truncated. This prevents a full security assessment of its intended checks. Without the complete implementation, it's impossible to verify if critical checks, such as preventing transfers to `address(0)` (the zero address), are correctly enforced. A missing `address(0)` check could lead to tokens being permanently locked if sent to the zero address.
FixProvide the complete and correct implementation of the `validRecipient` modifier. Ensure it includes checks to prevent transfers to `address(0)` and any other necessary recipient validations to prevent loss of funds or unexpected behavior.
StatusUnresolved
Low

Outdated Solidity Compiler Version

L-01The contract uses `pragma solidity ^0.4.16;`. This is an outdated compiler version. Newer Solidity versions include numerous bug fixes, security enhancements, and gas optimizations. Using older versions may expose the contract to known compiler-related vulnerabilities or result in less efficient bytecode.
IssueThe contract uses `pragma solidity ^0.4.16;`. This is an outdated compiler version. Newer Solidity versions include numerous bug fixes, security enhancements, and gas optimizations. Using older versions may expose the contract to known compiler-related vulnerabilities or result in less efficient bytecode.
FixConsider upgrading the contract to a more recent and stable Solidity compiler version (e.g., `^0.8.x`). This would require thorough re-auditing and testing to ensure compatibility and prevent new issues introduced by syntax changes or new compiler behaviors.
StatusUnresolved
Info

Potential DoS via `onTokenTransfer` Revert

I-01The `transferAndCall` function calls the `onTokenTransfer` function on the recipient contract. If a malicious recipient contract implements `onTokenTransfer` to always revert, it could prevent successful `transferAndCall` operations to that specific contract. While this is standard behavior for external calls and not a vulnerability in the token contract itself, it's a consideration for users interacting with potentially untrusted recipient contracts.
IssueThe `transferAndCall` function calls the `onTokenTransfer` function on the recipient contract. If a malicious recipient contract implements `onTokenTransfer` to always revert, it could prevent successful `transferAndCall` operations to that specific contract. While this is standard behavior for external calls and not a vulnerability in the token contract itself, it's a consideration for users interacting with potentially untrusted recipient contracts.
FixUsers should be aware that `transferAndCall` operations to untrusted or poorly implemented contracts might fail if the recipient's `onTokenTransfer` function reverts. This is an inherent risk when interacting with external contracts. No direct change is needed in the token contract, but documentation could highlight this behavior.
StatusUnresolved

Category Ratings

TechnicalLow7/10

The contract architecture (7.1) is a standard ERC-20 and ERC-677 token implementation, leveraging the SafeMath library for robust integer overflow/underflow protection in arithmetic operations. This is a significant strength for code security (7.2). However, a critical flaw exists where the public `totalSupply()` getter returns 0 due to variable shadowing, violating ERC-20 compliance. Furthermore, the contract emits inconsistent `Transfer` event signatures depending on the transfer method, which can cause issues for indexers and integrations. The `approve` function (7.3) is also vulnerable to a known race condition, despite the presence of `increaseApproval` and `decreaseApproval` functions.

GovernanceHigh3/10

The economic model (7.4) of the LinkToken is straightforward, featuring a fixed total supply minted to the deployer. There are no complex fee structures, staking, or governance mechanisms (7.5) within this contract. However, the critical technical issue regarding the `totalSupply()` function returning zero directly impacts the economic interpretation and integration of the token, as external systems will incorrectly perceive the token's total supply. This misrepresentation could lead to significant economic confusion or errors in applications relying on this data.

UpgradesMedium5/10

The contract is not designed with any upgradeability patterns (7.7) such as UUPS or Transparent proxies. Therefore, there are no specific upgrade-related risks. Any changes to the token's logic would require a new deployment and migration of assets, which is a standard approach for non-upgradeable contracts.

Security Checklist

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

Holder Composition

4.2% in wallets27.3% in contracts
Effective Concentration15.1%

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

Show 4 more pairsShow less

The 15 remaining pairs hold $185.2K between them and are not listed.

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 Holder24.6%
Top-3 Unlocked50.3%

Key Addresses

Deployer
0xf550…1780
Unlocked LP Held By
0xfcba…97c00xd14f…c91c0x72f0…90830x5792…46190x5310…ba660x72af…51e00x96c1…07fb0x5b2e…696c0xbeb9…42730x691a…d3a5

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)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • 1 Critical finding(s) from audit
  • 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

KiteMedium RiskOctra (OCT)Medium RiskArtificial Superintelligence Alliance (FET)Medium RiskOndoMedium RiskRequest Token (REQ)Medium RiskProgrammable (V4)Medium Risk

Would You Like a More Detailed Audit of Chainlink?

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

Get Detailed Audit