IXS Launchpad Info
IX Swap is the Uniswap for RWA and bridges the gap between traditional finance and decentralized finance by offering a regulated and innovative platform for trading tokenized Real-World Assets.
TrustNet Score
The TrustNet Score evaluates crypto projects based on audit results, security, KYC verification, and social media presence. This score offers a quick, transparent view of a project's credibility, helping users make informed decisions in the Web3 space.
Real-Time Threat Detection
Real-time threat detection, powered by Cyvers.io,
is currently not
activated
for this project.
This advanced feature provides continuous monitoring and instant alerts to safeguard your assets from potential security threats. Real-time detection enhances your project's security by proactively identifying and mitigating risks.
For more information, click here.
Security Assessments
Summary and Final Words
No crucial issues found
The contract does not contain issues of high or medium criticality. This means that no known vulnerabilities were found in the source code.
Contract owner cannot mint
It is not possible to mint new tokens.
Contract owner cannot blacklist addresses.
It is not possible to lock user funds by blacklisting addresses.
Contract owner can set high fees
Contract owner is able to set fees above 25%. Very high fees can also prevent token transfer.
Token transfer can be locked
Owner can lock user funds with owner functions.
Token cannot be burned
There is no burning within the contract without any allowances
Ownership is not renounced
The owner retains significant control, which could potentially be used to modify key contract parameters.
Contract is upgradeable
The contract uses a proxy pattern or similar mechanism, enabling future upgrades. This can introduce risks if the upgrade mechanism is not securely managed.
Scope of Work
This audit encompasses the evaluation of the files listed below, each verified with a SHA-1 Hash. The team referenced above has provided the necessary files for assessment.
The auditing process consists of the following systematic steps:
- Specification Review: Analyze the provided specifications, source code, and instructions to fully understand the smart contract's size, scope, and functionality.
- Manual Code Examination: Conduct a thorough line-by-line review of the source code to identify potential vulnerabilities and areas for improvement.
- Specification Alignment: Ensure that the code accurately implements the provided specifications and intended functionalities.
- Test Coverage Assessment: Evaluate the extent and effectiveness of test cases in covering the codebase, identifying any gaps in testing.
- Symbolic Execution: Analyze the smart contract to determine how various inputs affect execution paths, identifying potential edge cases and vulnerabilities.
- Best Practices Evaluation: Assess the smart contracts against established industry and academic best practices to enhance efficiency, maintainability, and security.
- Actionable Recommendations: Provide detailed, specific, and actionable steps to secure and optimize the smart contracts.
A file with a different Hash has been intentionally or otherwise modified after the security review. A different Hash may indicate a changed condition or potential vulnerability that was not within the scope of this review.
Final Words
The following provides a concise summary of the audit report, accompanied by insightful comments from the auditor. This overview captures the key findings and observations, offering valuable context and clarity.
Ownership Privileges
EarnV2.sol
- The DEFAULT_ADMIN_ROLE can grant/revoke any role (including OPERATOR_ROLE, PAUSER_ROLE, and DEFAULT_ADMIN_ROLE) to other addresses.
- The DEFAULT_ADMIN_ROLE can be assigned to the contract deployer during initialization.
- The DEFAULT_ADMIN_ROLE can authorize new implementations for contract upgrades.
- The DEFAULT_ADMIN_ROLE can unpause the contract, resuming its operations.
- The DEFAULT_ADMIN_ROLE can remove a user from the whitelist.
- The DEFAULT_ADMIN_ROLE can update the flat fee for claims.
- The DEFAULT_ADMIN_ROLE can update the percentage-based fee (BPS) for claims.
- The DEFAULT_ADMIN_ROLE can update the wallet address that receives claim fees.
- The DEFAULT_ADMIN_ROLE can update the minimum deposit amount required.
- The DEFAULT_ADMIN_ROLE can withdraw (rescue) any ERC20 tokens held by the contract to a specified address.
- The OPERATOR_ROLE can be assigned to the contract deployer during initialization.
- The OPERATOR_ROLE has its signature considered valid for users to self-whitelist (as checked by verifyWhitelistSignature).
- The OPERAOR_ROLE can directly add a user to the whitelist without requiring a user signature.
- The PAUSER_ROLE can pause the contract, which stops new deposits, withdrawal requests, and claims.
Note - This Audit report consists of a security analysis of the IXS Launchpad smart contract. This analysis did not include functional testing (or unit testing) of the contract’s logic. Moreover, we only audited the mentioned contract for the IXS Launchpad team. Other contracts associated with the project were not audited by our team. We recommend investors do their own research before investing.
Files and details
Functions
public
/
State variables
public
/
Total lines
of code
/
Capabilities
Hover on items
/
Findings and Audit result
high Issues | 1 findings
Pending
#1 high Issue
Centralized Control Over Core Functionalities via PAUSER_ROLE.
The PAUSER_ROLE holds centralized power to halt critical contract operations, specifically deposit, withdrawalRequest, and claim, by invoking the pause() function. If this role is compromised, or if the entity controlling it acts maliciously or becomes unavailable, all primary user interactions with their funds can be indefinitely suspended. Furthermore, the ability to unpause the contract is restricted to the even more privileged DEFAULT_ADMIN_ROLE, creating a dependency on this higher-level admin for restoring functionality. This concentration of control presents a significant denial-of-service risk for users.
medium Issues | 6 findings
Pending
#1 medium Issue
Missing Initial PAUSER_ROLE Assignment During Contract Initialization.
The initialize function, responsible for setting up the initial state of the EarnV2 contract, does not assign the PAUSER_ROLE to any account. Consequently, upon deployment, no entity possesses the immediate capability to execute the pause() function. This oversight means that if an urgent situation requiring a contract pause arises shortly after deployment (e.g., discovery of a critical vulnerability or an ongoing attack), there would be a delay as the DEFAULT_ADMIN_ROLE would first need to execute a separate transaction to grant the PAUSER_ROLE before the contract could be paused, potentially extending the window of vulnerability.
Pending
#2 medium Issue
Missing Non-reentrant check.
The deposit and withdrawalRequest functions are susceptible to reentrancy attacks as they execute external calls to the poolFlexi contract before all associated internal state modifications, such as updating user share or asset balances, are finalized. This ordering violates the Checks-Effects-Interactions pattern, creating a window where a malicious poolFlexi contract could re-enter EarnV2 during an intermediate state, potentially leading to inconsistent balance accounting, unauthorized fund manipulations, or other exploits. The claim function is better structured by zeroing out the user's claimable balance before external transfers, but the general principle of completing effects before interactions is paramount.
Pending
#3 medium Issue
Lack of Slippage Protection in Financial Operations
The deposit function allows users to deposit assetToken in exchange for shares (vault tokens), and similarly, the withdrawalRequest function allows users to exchange shares back for assetToken, with the conversion rates determined by an external poolFlexi contract. Critically, neither function provides a mechanism for users to specify a minimum acceptable output (minimum shares for deposits, or minimum assets for withdrawals), exposing them to the risk of receiving significantly less than anticipated due to price volatility or unfavorable exchange rates within poolFlexi at the time of transaction execution, potentially leading to value loss.
Pending
#4 medium Issue
Unbounded claimFlatFee Poses Risk of Arbitrarily High Fees
The updateClaimFlatFee function grants the DEFAULT_ADMIN_ROLE unchecked authority to set the claimFlatFee to any value, lacking an upper limit or validation similar to the percentage fee's 100% cap. This allows a malicious or negligent admin to impose excessively high flat fees, potentially exceeding users' claimable amounts, rendering claims economically unviable, trapping user funds effectively, or causing claim transactions to revert, thus centralizing significant control over user assets.
Pending
#5 medium Issue
Unchecked minimumDeposit Value Allows Potential Disruption of Deposits
The updateMinimumDeposit function permits an admin to set the minimumDeposit to any arbitrary uint256 value without validation, including zero or excessively large amounts. This lack of checks could lead to the minimumDeposit being set so low it permits dust deposits (if that's undesirable) or so high that it effectively blocks all new user deposits, thereby centralizing control over a core contract functionality and potentially disrupting the system's intended operation. This also doesn't address the underlying issue that minimumDeposit is not sensitive to the assetToken's decimals.
Pending
#6 medium Issue
Unrestricted rescueErc20Tokens Function Allows Admin to Drain Core Contract Assets
The rescueErc20Tokens function grants the DEFAULT_ADMIN_ROLE the ability to withdraw the entire balance of any ERC20 token held by the contract to an arbitrary address. Crucially, this function does not restrict the admin from targeting the primary assetToken (which comprises user deposits and funds pending claim) or the vaultToken (representing users' shares). A malicious or compromised admin can therefore exploit this function to drain all user-related funds (assetToken and vaultToken) from the contract, leading to a complete loss for users.
low Issues | 6 findings
Pending
#1 low Issue
Stale Signature Exploitation Leading to Unintended Whitelisting
The whitelistUser function allows users to be whitelisted using signatures from an operator. These signatures lack an expiration mechanism. Consequently, a user can hold a valid signature, and if the project's whitelisting criteria or the operator's intent changes later, the user can still use this old (stale) signature to get whitelisted, provided the signing operator still holds the OPERATOR_ROLE and the user's nonce matches. This bypasses the current access control policies by leveraging an outdated but technically still valid permission.
Pending
#2 low Issue
Missing 'isContract' check.
The contract lacks a validation check to ensure that specific parameters are contract addresses. Without this check, there is a risk that non-contract addresses (such as externally owned accounts, or EOAs) could be mistakenly set for parameters intended to reference other contracts. This could lead to failures in executing critical interactions within the contract, as EOAs do not support contract-specific functions.
Pending
#3 low Issue
Fixed minimumDeposit Ignores Token Decimals
The minimum deposit is a fixed value (1_000_000) set during initialization. This value doesn't consider the decimal precision of the assetToken. For an 18-decimal token, 1,000,000 (as indivisible units) is extremely small (0.000000000001 of the token), making the minimum deposit check virtually useless. For a 6-decimal token, it's one full token. This inconsistency can lead to ineffective dust filtering or create unintended barriers.
Pending
#4 low Issue
Potential for Zero Shares Received (Leading to Loss of Deposit).
The contract does not check if the shares received from poolFlexi.deposit() is greater than zero. If poolFlexi returns 0 shares (e.g., due to an extremely small deposit amount, a quirk in its internal logic, or high internal fees within the pool), the user's assetToken (already transferred to EarnV2 and potentially to poolFlexi) would be lost, and they would receive no userVaultTokenBalances in return.
Pending
#5 low Issue
Potential for Zero Assets Received.
The contract does not check if the convertedSharesToAsset received from poolFlexi.requestRedeem() is greater than zero. If poolFlexi returns 0 assets (e.g., due to an extremely small share amount being redeemed, a quirk in its internal logic, or high internal fees within the pool that consume the entire value), the user's userVaultTokenBalances would have already been debited (on Line userVaultTokenBalances[_msgSender()] -= amount;), effectively losing their shares and receiving no assetToken in their userAssetBalances in return.
Pending
#6 low Issue
Missing zero or dead address check.
It is recommended to check that the address cannot be set to zero or dead address.
informational Issues | 1 findings
Pending
#1 informational Issue
Floating pragma solidity version.
Adding the constant version of solidity is recommended, as this prevents the unintentional deployment of a contract with an outdated compiler that contains unresolved bugs.