Audit · firm’s term: audit report
QuillAudits reviewed Advon on 27 Mar 2023: 12 findings, 0 critical; 1 marked fixed, 11 open.
Report hosted on quillaudits.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 3 | 0 | 0 |
| Medium | 4 | 0 | 0 |
| Low | 4 | 0 | 1 |
The contract owner can adjust the tax to as high as 100% on transactions, limit the tradeable limit of each user’s balance. The owner account should be taken care to not be mismanaged else the privileges associated with the account can slip into the hands of the hacker. Also, if renouncing ownership is not done appropriately, the current contract owner can renounce ownership, and lose access to owner privileges. Functions like setting tax, and wallet addresses will be uncallable and any updates needed to be made will be inaccessible.
Upon deployment, the expected contract owner would have to call initialize( ) else the owner characteristics and privileges do not get set. Scenario 1: Initialize is frontrun by a malicious actor If anyone asides from the intended owner calls initialize, they automatically become the owner of the Advon contract with the privileges of the owner address. Bots could be listening on the network for scenarios set up just like this and take advantage of the exploit opportunity. Scenario 2: Initialize does not get called by anyone This would make the owner variable set to address(0), and core functionality will be unusable since address(0) currently does not have a signer and cannot pass the onlyOwner check. Remediation - With the current contract structure, it is recommended to call the functions in this order to mitigate risk: • deploy contract • call initialize( ) • set wallets, release time, etc to ensure funds are sent to the right address and proper timing follows. • call distribute( ) The contract deployer has to be aware of safe deployment practices, they can refer to OpenZeppelin’s guide linked: Writing Upgradeable Contracts - OpenZeppelin Docs
The ecosystemFund address is never set and if left unchecked would lead to loss of funds if the tokens (in the contract itself) are sent out to the ecosystemAddress which is the dead address perpetually. 50% of the supply is minted to the contract as well not sent to the respective addresses as well. A compromise of the contract will automatically put 50% of the total supply at risk. The dev also described eligibleWallets as those that do not need to go through the usual phase of locking and keeping tokens like normal accounts do. They could have the privilege of moving tokens without a fee or lockup period but they do not. The only privilege available to the eligibileWallets in the codebase is the ability to call transfer() and transferFrom() tokens before the saleEndTime. In the most recent inclusion, when transfers are made it first checks if the address is an eligible wallet, and also if it is an eligible reseller. If an address is an eligible reseller, it should not deduct any tokens to be locked when tokens pass through it. The flaw here is that the eligible reseller check the ‘to’ address and not the ‘owner’ address else it could have some tokens locked like every other non-privileged account. If the batch transfer function is called with an eligible reseller’s address as well, it would lead to same deduction for locked tokens which should not happen with privileged accounts.
The releaseTime is checked to confirm it’s not zero but does not check to see if releaseTime is greater than contractCreatedTime.
Although underflows and overflows are checked internally in solidity versions >0.8.0, multiple logical arithmetic checks would be needed in the codebase dependent on the client. setReleaseTime(), setSupply_Team_Allocation(), setBuyandSellTax(), setTokenPrice() are likely pivots to exploit this vulnerability. When eligible resellers are added, the NumberofResellers variable is incremented by 1. The function does not check if the address to be added is already an eligibleReseller so the NumberofResellers variable can be incremented to the limit of uint256. Due to the capacity of uint256 it is unlikely to result in a denial of service but it still is an issue of improper accounting.
The codebase lacks unit test coverage. It is advisable to have test coverage greater than 95% of the codebase to reduce unexpected functionality and help fuzz test as many invariants as possible.
On token transfers, the arithmetic calculations carried out determine how many tokens will be locked and how many can be transferred to users. Although the checks are implemented, the transfers from the caller to the msg.sender and the token do not happen
Changes to state in deployed contracts can be easily tracked using events, especially when logs would need to be kept. The contract allows multiple key variables to be reset and it would be advisable to emit events when this occurs.
The solidity pragma version in this codebase is unlocked.
The internal “_mint()” function is only called by the distribute() function which has the onlyOwner modifier attached to it as well. Calling it again internally will lead to extra costs spent on gas which can be avoided.
The contract declares IPancakeFactory, IPancakeRouter, and IPancakePair but they are not implemented in any form throughout the scope of the codebase. TradeableLimit, ProcessingFee, and NetworkingFee are declared but not implemented as well. The dev’s comment implied that tradeLimit allows only a certain percentage of the user’s tokens to be tradeable at a certain time. The current version of the codebase does not put this functionality to use.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (1)
350 projects reviewed · 459 reports · latest Apr 2025
See QuillAudits’s auditsSomething 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