Quantum Audit Logo

Is Render Token Safe?

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

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

Render Token RNDR
0x6de0…eb24
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 today 1 audit on record
How is this score calculated? → Critical Risk
Executive SummaryAI Copilot

The RenderToken contract, serving as an implementation behind an AdminUpgradeabilityProxy, integrates ERC-20 token functionality with a custom migration system and an escrow mechanism. While it utilizes SafeMath and SafeERC20 for arithmetic safety and includes functions to mitigate ERC-20 approval front-running, a critical design flaw renders the escrow's funding mechanism unusable. Significant centralization exists in escrow disbursement, and the use of an older Solidity compiler version combined with a legacy proxy pattern and custom migration logic introduces elevated technical and upgrade risks.

1 Critical2 High1 Medium1 Low1 Informational
Volume 24h
$43.6K
Liquidity
$401.8K
Price
$1.8100
Token Age
6y
Top 10 Holders
93.8%

Security Findings

Critical

Critical Design Flaw: Escrow Funding Mechanism Unusable

C-01The `fundJob` function in the `Escrow` contract, intended for depositing tokens into job-specific balances, includes the requirement `require(msg.sender == renderTokenAddress)`. During initialization, `renderTokenAddress` is set to `address(this)`, meaning the contract's own address. Consequently, only the contract itself can call `fundJob`, making it impossible for external users or other contracts to deposit funds into the escrow. This renders the core functionality of the escrow system for receiving external funds completely non-functional.
IssueThe `fundJob` function in the `Escrow` contract, intended for depositing tokens into job-specific balances, includes the requirement `require(msg.sender == renderTokenAddress)`. During initialization, `renderTokenAddress` is set to `address(this)`, meaning the contract's own address. Consequently, only the contract itself can call `fundJob`, making it impossible for external users or other contracts to deposit funds into the escrow. This renders the core functionality of the escrow system for receiving external funds completely non-functional.
FixModify the `fundJob` function's access control to allow authorized external entities (e.g., the `owner`, a designated `funder` role, or any token holder) to deposit funds. For example, remove the `require(msg.sender == renderTokenAddress)` line and instead ensure that the `ERC20(renderTokenAddress).transferFrom(msg.sender, address(this), _tokens)` is called to pull tokens from the caller.
StatusUnresolved
High

Centralized Control Over Escrow Funds

H-01The `Escrow` contract's `disburseJob` function, which transfers tokens from job balances to recipients, is protected by the `canDisburse` modifier, allowing only the `disbursalAddress` to execute it. The `disbursalAddress` is initially set to the `owner` and can be changed by the `owner`. This design concentrates significant power in a single address, creating a single point of failure. If the `disbursalAddress` (or the `owner` who can change it) is compromised, all funds held within the escrow could be maliciously disbursed or stolen.
IssueThe `Escrow` contract's `disburseJob` function, which transfers tokens from job balances to recipients, is protected by the `canDisburse` modifier, allowing only the `disbursalAddress` to execute it. The `disbursalAddress` is initially set to the `owner` and can be changed by the `owner`. This design concentrates significant power in a single address, creating a single point of failure. If the `disbursalAddress` (or the `owner` who can change it) is compromised, all funds held within the escrow could be maliciously disbursed or stolen.
FixConsider implementing a multi-signature wallet for the `disbursalAddress` or introducing a more robust governance mechanism (e.g., a time-locked contract, a DAO vote) for critical operations like changing the `disbursalAddress` or executing large disbursements. This would distribute control and reduce the risk associated with a single point of failure.
StatusUnresolved
High

Legacy Proxy Pattern and Elevated Upgrade Risks

H-02The contract is deployed as an implementation behind an `AdminUpgradeabilityProxy`, a legacy proxy pattern from OpenZeppelin (formerly ZeppelinOS). This, combined with the use of `pragma solidity ^0.4.24` and a custom `Migratable` initialization system, introduces elevated risks for future upgrades. Storage collisions are a significant concern with multiple inheritance and older Solidity versions if new state variables are not carefully managed in upgrade implementations. The custom `Migratable` pattern adds another layer of complexity to the standard proxy upgrade process, increasing the potential for misconfiguration or errors during upgrades.
IssueThe contract is deployed as an implementation behind an `AdminUpgradeabilityProxy`, a legacy proxy pattern from OpenZeppelin (formerly ZeppelinOS). This, combined with the use of `pragma solidity ^0.4.24` and a custom `Migratable` initialization system, introduces elevated risks for future upgrades. Storage collisions are a significant concern with multiple inheritance and older Solidity versions if new state variables are not carefully managed in upgrade implementations. The custom `Migratable` pattern adds another layer of complexity to the standard proxy upgrade process, increasing the potential for misconfiguration or errors during upgrades.
FixThoroughly review the upgrade strategy, including the interaction between the `AdminUpgradeabilityProxy` and the custom `Migratable` logic. Ensure a robust testing framework for upgrades, specifically focusing on storage layout compatibility and correct initialization across versions. Consider migrating to a more modern and well-audited proxy pattern (e.g., UUPS with a newer Solidity version) in a future major upgrade to reduce inherent risks.
StatusUnresolved
Medium

Custom String-Based Migration Logic Complexity

M-01The `Migratable` contract implements a custom migration and initialization system using string-based `contractName` and `migrationId` parameters. This approach, while functional, is less standardized than typical proxy-based upgrade mechanisms. Relying on exact string matching for migration IDs can be prone to human error (e.g., typos), potentially leading to failed initializations or migrations, leaving the contract in an inconsistent or uninitialized state. The complexity of managing these string identifiers across multiple inherited contracts adds to the maintenance burden.
IssueThe `Migratable` contract implements a custom migration and initialization system using string-based `contractName` and `migrationId` parameters. This approach, while functional, is less standardized than typical proxy-based upgrade mechanisms. Relying on exact string matching for migration IDs can be prone to human error (e.g., typos), potentially leading to failed initializations or migrations, leaving the contract in an inconsistent or uninitialized state. The complexity of managing these string identifiers across multiple inherited contracts adds to the maintenance burden.
FixWhile the system is in place, ensure rigorous testing of all initialization and migration paths. For future iterations or new contracts, consider adopting more standardized and less error-prone initialization patterns, such as those provided by OpenZeppelin's `Initializable` contract, which typically use a boolean flag or version number for initialization control.
StatusUnresolved
Low

Use of `assert` for External Call Validation in `SafeERC20`

L-01The `SafeERC20` library uses `assert(token.transfer(to, value))` and `assert(token.transferFrom(from, to, value))` to validate the success of external ERC-20 token transfers. In Solidity 0.4.x, `assert` consumes all remaining gas on failure. While this ensures that failed transfers revert, it is less gas-efficient than using `require` for input validation or checking return values, which refunds unused gas on failure. This is a minor gas inefficiency rather than a direct security vulnerability.
IssueThe `SafeERC20` library uses `assert(token.transfer(to, value))` and `assert(token.transferFrom(from, to, value))` to validate the success of external ERC-20 token transfers. In Solidity 0.4.x, `assert` consumes all remaining gas on failure. While this ensures that failed transfers revert, it is less gas-efficient than using `require` for input validation or checking return values, which refunds unused gas on failure. This is a minor gas inefficiency rather than a direct security vulnerability.
FixFor future development or if upgrading to a newer Solidity version, consider replacing `assert` with `require` for external call success checks. For example, `require(token.transfer(to, value), 'ERC20 transfer failed');` would be more gas-efficient on failure.
StatusUnresolved
Info

Outdated Solidity Compiler Version

I-01The contract is compiled with `pragma solidity ^0.4.24`. This is an outdated compiler version. While `SafeMath` is used to mitigate common arithmetic issues, newer Solidity versions (e.g., 0.8.x) offer significant improvements in security features (e.g., default checked arithmetic, `try/catch` for external calls), optimizations, and bug fixes. Using an older compiler might expose the contract to known compiler-specific vulnerabilities that have since been patched, or prevent the use of modern security patterns.
IssueThe contract is compiled with `pragma solidity ^0.4.24`. This is an outdated compiler version. While `SafeMath` is used to mitigate common arithmetic issues, newer Solidity versions (e.g., 0.8.x) offer significant improvements in security features (e.g., default checked arithmetic, `try/catch` for external calls), optimizations, and bug fixes. Using an older compiler might expose the contract to known compiler-specific vulnerabilities that have since been patched, or prevent the use of modern security patterns.
FixConsider upgrading the contract to a more recent and actively maintained Solidity compiler version (e.g., 0.8.x) during a future major upgrade. This would allow the contract to benefit from the latest security enhancements, compiler optimizations, and improved developer tooling. A thorough re-audit would be required after such an upgrade.
StatusUnresolved

Category Ratings

TechnicalMedium4/10

7.1 Architecture and 7.2 Code Security are generally robust due to the use of SafeMath and SafeERC20 libraries, mitigating common integer overflow/underflow issues. The implementation of `increaseApproval` and `decreaseApproval` also addresses known ERC-20 front-running vulnerabilities. However, a critical flaw in the `Escrow.fundJob` function (7.3 Access Control) prevents external funding, rendering the escrow non-functional. The use of `assert` in `SafeERC20` (7.2 Code Security) for external call validation is less gas-efficient than `require` in Solidity 0.4.x.

GovernanceHigh1/10

7.4 Economic and 7.5 Governance aspects present significant risks. The `Escrow.fundJob` function's access control (7.3 Access Control) is critically flawed, making it impossible for external users to deposit funds, which severely impacts the economic viability of the escrow system. Furthermore, the `disbursalAddress` holds centralized control over all escrow fund disbursements (7.3 Access Control), creating a single point of failure where compromise could lead to total fund loss. The `owner` role can transfer ownership and change the `disbursalAddress`, concentrating significant power.

UpgradesHigh1/10

7.7 Upgrades are managed via an `AdminUpgradeabilityProxy`, a legacy proxy pattern, combined with a custom `Migratable` contract for initialization and migration steps. This combination, along with the outdated Solidity compiler (0.4.24) and multiple inheritance, significantly increases the risk of storage collisions or improper initialization during future upgrades. The string-based migration IDs in the `Migratable` contract introduce potential for human error and complexity compared to standard upgrade patterns.

Security Checklist

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

Proxy Upgrade Controls

Proxy TypeZeppelin Os Legacy
AdminEOA (single key controls upgrades)
ImplementationVerified source
Upgrades (30d)0 · stable

Holder Composition

3.1% in wallets90.7% in contracts
Effective Concentration39.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 Holder85.8%
Top-3 Unlocked96.9%

Key Addresses

Deployer
0x7b52…68fc
Unlocked LP Held By
0xb6b0…6e7e0x2058…7d7e0xb888…ae840x2b58…a53b0xef19…2f0b0x3740…57990xa748…10620xcaca…2e330x7bb8…9a6b0xed29…78d2

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 an EOA (single private key)
  • Proxy contract (upgradeable — admin can replace logic)
  • Admin is EOA (single key controls upgrades)
  • Top-10 concentration > 30% (93.8% total → 39.4% effective; 3.1% in EOAs, 90.7% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 85.8% (independent LP — depth risk, pool = 41% of DEX liquidity)
  • LP top3 unlocked holders = 96.9% (independent LP — depth risk, pool = 41% of DEX liquidity)
  • 1 Critical finding(s) from audit
  • 2 High finding(s) from audit
  • 1 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

Eden Token (EDEN)Critical RiskZK Coin (ZKC)Critical RiskGensyn (AI)Critical RiskSpark (SPK)Critical RiskCircle Wrapped Bitcoin (CIRBTC)Critical RiskapyUSDCritical Risk

Would You Like a More Detailed Audit of Render Token?

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

Get Detailed Audit