As of 3 Nov 2026, Ecotrader has 1 audit report on Trustblock, by QuillAudits, dated 9 Apr 2024. That report lists no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Ecotrader | Security firm: QuillAudits | Date: | Scope: Files named in the report | No open critical findings | Open · quillaudits.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 0 | 7 |
| Low | 8 | 0 | 6 |
_getUsdcEquivalent() function currently supports wMatic to USDC path while getting the amountOut. Because on L170 the path[0] is assigned as uniswapRouter.WETH() which would be wMATIC and not WETH on the Quickswap router this can be verified by checking this address.Invest() calls _getUsdcEquivalent() on L110 also for getting USDC equivalent for WETH. But in this case, because the _getUsdcEquivalent() only supports the wMATIC to USDC path. The USDC equivalent that it returns is incorrect when checking for WETH to USDC.
Open the reportBecause of the public nature of blockchain, it's possible to monitor broadcasted transactions. Anyone can monitor the investment transactions and may try to frontrun the transaction where before executing the victim transaction the malicious user will manipulate the token pool(s) so that when the investment contract fetches the equivalent price in USDC for WETH/wMATIC, the price fetched would be less than what it was expected by the user before sending the transaction.
Open the reportThe contract has a function named withdrawMintedTokens(), This can be used by the admin to withdraw the minted tokens to the contract which gets minted when the user invests so that can be claimed by the user.
Open the reportCurrently investedValue is calculated using investedAmount / TOKEN_PER_DOLLAR / 1e6 this is incorrect. On L334 the calculation for investedValue should be changed to investedValue = investedAmount * 1e6 / TOKEN_PER_DOLLAR;
Open the reportAccording to the comment on L18, 6.67 tokens per dollar should be minted. Currently, TOKEN_PER_DOLLAR is assigned as 667. which is getting used while minting tokens on L147 and for division on L349.While calculating tokenAmount on L147, let's say the total investment amount (totalInvestmentAmount) is 1e6 and its getting multiplied with TOKEN_PER_DOLLAR So the answer would be 1e6 * 667 = 667000000 which is equal to 667e6. This is incorrect because according to the comment, it should mint only mint 6.67 tokens per USDC. This can be corrected by making TOKEN_PER_DOLLAR = 6670000 ( i.e 6.67e6) on L18. so the calculation for tokenAmount on L147 would be: tokenAmount = (totalInvestmentAmount * TOKEN_PER_DOLLAR) / 1e6 So when the totalInvestmentAmount would be 1e6: tokenAmount = (1e6 * 6670000) / 1e6 tokenAmount = 6670000 (i.e 6.67e6)
Open the reportIn getInvestorDetails() while finding vestingMonthsRemaining, subtraction happens for (vestingDuration - elapsedTime). here if the elapsedTime is greater than vestingDuration which is 20 months timestamp, then the the call will revert with the panic code 0x11. because of arithmetic overflow.This can fail some off-chain systems that check the investor's details for important logic
Open the reportThe contract has a syntactical error on L324-L347. Because of this, the contract won’t be able to compile. The function declaration + definition should be checked again for syntactical errors and should be fixed.
Open the reportWhile minting an Investment token amount on L148 it's minting tokenAmount which would be in 6 decimals. according to the contract's ERC.decimal() function the contract uses 18 decimals to represent one whole token. It needs to be checked it's intended to use 6 decimal values while minting.
Open the reportsetAdmin1() and setAdmin2() are emitting AdminUpdated() event, the AdminUpdated() has second parameter name as isAdmin1 whereas this should be isAdmin2 when getting emitted by setAdmin2() function.This is happening because of using the same event for both functions. This may create confusion while reading these events.
Open the reportAccording to the specification document, the user can invest USDC, MATIC and ETH. The invest() function accepts the MATIC as msg.value but invest() still takes maticAmount as a parameter. Additionally, the constructor sets the maticAddress. According to a discussion with the project team, it should be WETH address because the function allows the user to invest three tokens MATIC (paid via msg.value), USDC and ETH(WETH). So in the code maticAmount should be renamed to wethAmount and maticAddress should be renamed to wethAddress.Also, change the name of withdrawMatic() to withdrawWeth().
Open the report1. getInvestorDetails() returns vestingMonthsRemaining as 0 for not invested address. This can create a problem if any incorrect assumption is made for not invested address (maybe in off-chain service) in this case apart from 0.2. investorTokenBalance[user address] is not getting subtracted after claiming all the amount. Any incorrect assumption regarding this can create problems in another system (smart contract or off-chain service) where that system will expect that the investorTokenBalance for the address that claimed all the amount is 0.
Open the reportInvestmentToken uses some OZ libraries like Ownable, Pausable, ReentrancyGuard. These libraries should be imported for the updated version. Changing/updating the OZ dependency version will change the path for some of the imported libs
Open the reportView functions like getEthBalance(), getUsdcBalance(), getMaticBalance(), getInvestorDetails() are using onlyAdmin. The view functions should not use the modifier(s) because these functions are needed by the users (or other contracts in some cases when integrating) to know the state of the contract e.g. getInvestorDetails() can be used by users to know details about the their investment. Additionally, it makes the contract state more transparent.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="ecotrader"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us