DRX Token

CertiKRepository at commit bf95c81

CertiK reviewed DRX Token on 19 Feb 2025: 26 findings, 0 critical; 11 marked fixed, 2 acknowledged, 13 open.

No open critical findings
Open the reportOpen DRX Token’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings26

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High501
Medium020
Low8010
HighBroken Logic In `swapBack()`Open

The function `swapBack()` has a variety of flaws that reduce the efficiency and readability of the function, as well as, potentially breaking the logic of the function itself. In particular, the following problems are present in the current code: 1. The function initially checks if `BuyFee + SellFee ==0` and then tries to subtract a sell fee from the amount to swap back. Since the `SellFee` is zero the amount of the sell fee will also be zero so the operations calculating and subtracting the sell fee are not necessary. ```solidity=753 ... if ((BuyFee+SellFee) == 0) { if(contractBalance > 0 && contractBalance < swapTokensAtAmount) { tokensToSwap = contractBalance; } else { uint256 sellFeeTokens = tokens.mul(SellFee).div(100); tokens -= sellFeeTokens; if (tokens > swapTokensAtAmount) { tokensToSwap = swapTokensAtAmount; } else { tokensToSwap = tokens; } } } ... ``` 2. The function is called with the current transfer `amount` but there is no indication that this amount is less than the current contract balance. In this case, the following could happen: - The contract balance is higher than `swapTokensAtAmount`. - The input `amount` is higher than the current contract balance. - The function will execute the last `else` of the `if-else` branches and set `tokenToSwap` to the input `amount` (minus a sell fee). - The `swapTokensForEth` function call will fail reverting also the transfer. ```solidity=778 ... else { uint256 sellFeeTokens = tokens.mul(SellFee).div(100); tokens -= sellFeeTokens; if (tokens > swapTokensAtAmount) { tokensToSwap = swapTokensAtAmount; } else { tokensToSwap = tokens; } } } swapTokensForEth(tokensToSwap); } ... ``` 3. The function unexpectedly falls into the third case of the `if-else` branch if the contract balance is exactly `swapTokensAtAmount.div(5)`. ```solidity=775 ... else if (contractBalance > 0 && contractBalance > swapTokensAtAmount.div(5) && contractBalance < swapTokensAtAmount) { tokensToSwap = swapTokensAtAmount.div(5); } else { ... ``` 4. The function removes a `SellFee` from the amount to be swapped which will always leave a certain amount of tokens in the contract for no reason.

HighCentralization Risk on Functions `clearStuckTokenOpen

The following functions allow the `owner` and the `deployerWallet` to withdraw any token from the DRX contract: ```solidity=716 function clearStuckTokens(address tokenAddress, uint256 toKeep) external { require(_msgSender() == deployerWallet, "Only deployer can clear tokens"); IERC20 tokenContract = IERC20(tokenAddress); uint256 totalBalance = tokenContract.balanceOf(address(this)); uint256 tokensToKeep = (initialTotalSupply * toKeep) / 100; require(totalBalance > tokensToKeep, "No excess tokens to clear"); uint256 tokensToClear = totalBalance - tokensToKeep; if (tokensToClear > 0) { tokenContract.transfer(deployerWallet, tokensToClear); } if (toKeep == 0) { tokenContract.transfer(deployerWallet, totalBalance); } } ``` ```solidity=739 function withdrawToken(address _tokenContract, uint256 _amount) onlyOwner public{ IERC20 tokenContract = IERC20(_tokenContract); tokenContract.transfer(msg.sender, _amount); } ``` In particular, the above functions can be used to withdraw DRX tokens from this contract. Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. Based on the collected information and further conducted investigation, the project passed the criteria with a certain amount of requirements satisfied for the investigation. Still we strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.

HighCentralization Risks in DRX_TOKEN.solOpen

In the contract `DRX`, the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and do the following: - set automated market maker pair. - add/remove addresses to/from the blacklist. - set buy and sell fees. - remove transaction and wallet limits. - **withdraw any token from the contract**. - open trading. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-5651-e6361b20-8fa7-e7e1580c09a4/diagrams/centralization_DRX_TOKEN-DRX-_owner.svg) In the contract `DRX`, the role `deployerWallet` has authority over the functions shown in the diagram below. Any compromise to the `deployerWallet` account may allow the hacker to take advantage of this authority and **withdraw any type of token held by the contract including any ETH**. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-5651-e6361b20-8fa7-e7e1580c09a4/diagrams/centralization_DRX_TOKEN-DRX-deployerWallet.svg) In the contract `Ownable`, the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and renounce ownership, transfer ownership to a new owner. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-5651-e6361b20-8fa7-e7e1580c09a4/diagrams/centralization_DRX_TOKEN-Ownable-_owner.svg) Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. Based on the collected information and further conducted investigation, the project passed the criteria with a certain amount of requirements satisfied for the investigation. Still we strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.

HighInitial Token DistributionOpen

All of the `DRX` tokens are sent to the contract deployer or one or several externally-owned account (EOA) addresses. This is a centralization risk because the deployer or the owner(s) of the EOAs can distribute tokens without obtaining the consensus of the community. Any compromise to these addresses may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project. Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. Based on the collected information and further conducted investigation, the project passed the criteria with a certain amount of requirements satisfied for the investigation. Still we strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.

HighUnchecked ERC-20 `transfer()`/`transferFrom()` CaOpen

The return values of the `transfer()` and `transferFrom()` calls in the smart contract are not checked. Some ERC-20 tokens' transfer functions return no values, while others return a bool value, they should be handled with care. If a function returns `false` instead of reverting upon failure, an unchecked failed transfer could be mistakenly considered successful in the contract. ```solidity=729 tokenContract.transfer(deployerWallet, totalBalance); ``` ```solidity=725 tokenContract.transfer(deployerWallet, tokensToClear); ``` ```solidity=743 tokenContract.transfer(msg.sender, _amount); ```

LowMiscalculation of Max HoldingOpen

The transaction may be charged fees, so the max holding of the receiver should be the sum of the held tokens and the amount received from the transfer. The fees should not be included in the max holding. ```solidity=638 require(amount + balanceOf(to) <= maxWallet, "Max wallet exceeded"); ``` - Max holding is checked. ```solidity=671 amount -= fees; ``` - Receiving amount is adjusted. ```solidity=438 _balances[to] += amount; ``` - Balance is increased by the adjusted amount.

LowMissing Emit EventsOpen

It is important to emit events for sensitive actions, particularly those that can be executed by centralized roles or administrators. This ensures transparency and enables tracking of critical changes, which is essential for security and trust in the system. The absence of event logs can lead to a lack of visibility and potential information loss.

LowPotential Sandwich AttacksOpen

A sandwich attack can occur when an attacker notices a transaction involving token swaps or liquidity additions that lacks slippage restrictions or minimum output amount settings. The attacker can exploit this by frontrunning the transaction to purchase one of the assets, thereby manipulating the exchange rate, and then backrunning the transaction to sell the asset for a profit. The referenced functions are invoked without setting slippage restrictions or minimum output amounts, making transactions that trigger these functions particularly vulnerable to sandwich attacks, especially when large input amounts are involved.

LowPull-Over-Push Pattern In `transferOwnership()` FOpen

The change of `_owner` by function `transferOwnership()` overrides the previously set `_owner` with the new one without guaranteeing the new `_owner` is able to actuate transactions on-chain.

LowState variable shadowingOpen

A state variable in a derived contract is shadowing a similarly named component in a parent contract. This means that when the derived contract accesses the state variable by its name, it will use the one defined in the derived contract, not the one in the parent contract. Variable `_symbol` in `DRX` shadows the variable `_symbol` in `ERC20`. ```solidity=527 string private constant _symbol = "DRX"; ``` ```solidity=353 string private _symbol; ``` Variable `_name` in `DRX` shadows the variable `_name` in `ERC20`. ```solidity=526 string private constant _name = "DRX"; ``` ```solidity=352 string private _name; ```

Show 3 more
LowUsage of `transfer()` for sending EtherOpen

It is not recommended to use Solidity's `transfer()` and `send()` functions for transferring native tokens, since some contracts may not be able to receive the funds. Those functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Also, EVM instructions' gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation. ```solidity=713 payable(msg.sender).transfer(address(this).balance); ``` - `DRX.clearStuckEth` uses `transfer()`.

LowUsing `bool` for storage incurs overheadOpen

Booleans are more expensive than `uint256` or any type that takes up a full word because each write operation emits an extra `SLOAD` to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.

LowVariables That Could Be Declared as ImmutableOpen

The variables at the pointed locations are assigned in the constructor and never changed, therefore they should be declared as immutable to save gas.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (1)

  • https://github.com/ipds13/drxtoken/smart_contract/DRX_TOKEN.sol at commit bf95c815c6d43a5118ca6e7a9d9ca36e97c97326

Part of DRX Token’s security record

DRX Token
Audits1 audit by 1 firmLast audit Feb 2025, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open DRX Token’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

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