---
# System prepended metadata

title: Final Security Audit of `DEXI` token

---

# Final Security Audit of `DEXI` token

![](https://i.imgur.com/DreWe7g.png)


## Conclusion

This audit was made by [Web3Go](https://web3go.tech) 
Auditor: Vladimir Smelov <vsmelov.job@gmail.com>.
Date: 2022-08-09

In the final contract were **NOT FOUND**:
- Backdoors for investor funds withdrawal by anyone.
- Bugs allow stealing money from the contract.
- Any severe security problems.
- Any serious problems with gas consumption.

The client was acknowledged about all notes below.

## Scope

#### Pre-audit

- DEXI.sol (md5 hash - `4669ec9cc43e556f5901a998a60825a3`)

#### Final audit

- DEXI.sol
https://gist.github.com/vsmelov/7d66ce139b6996c82dae8eb80efeaf09

## Methodology

1. Blind audit. Understand the structure of the code without reading any docs.
2. Ask questions to developers.
3. Draw the scheme of cross-contracts interactions.
4. Write user stories and usage cases.
5. Run static analyzers.
6. Find problems with:
- backdoors;
- bugs;
- math;
- potential leaking of funds;
- potential locking of the contract;
- validate arguments and events;
- others.

## Result

### Critical

There are no critical in the final version of the DEXI token.

___


### Major


#### MAJOR-1. DEXI does not allow zero-amount transfers.
At

- contracts/DEXI.sol:721

```solidity=721
function _transfer(
    address from,
    address to,
    uint256 amount
) private {
    require(from != address(0), "ERC20: transfer from the zero address");
    require(to != address(0), "ERC20: transfer to the zero address");
    require(amount > 0, "Transfer amount must be greater than zero");
```

there is an incompatibility with 
https://eips.ethereum.org/EIPS/eip-20 
amount=0 is the correct value, and some DeFi projects may not work with DEXI. 

It's **explicitly** stated in EIP-20, whose author is **Vitalik Buterin**, that erc-20 tokens **MUST** support `amount=0` transfers. For example, if some developer of some marketplace will rely on eip-20 Standart and will think that `IERC20(dexi).transfer(amount * fee)` will always work, even in case if `fee=0`, it will break integration with your token in case if `fee=0`.

Let's check any popular erc-20 token, e.g., usdt https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7#code
they all support amount=0 transfers.

This is not a SECURITY ISSUE because no one may steal money. But it's a major defi-ecosystem-integration issue.

##### **Recommendation.**
Accept `amount=0`.
##### **Status.**
ACKNOWLEDGED

Since it's the client's strong opinion not to allow zero transfers, they can leave it as it is. **This is not a security issue.**
Be aware, then use the DEXI token with other DeFi applications.
##### **Client's commentary.**
> We decided to move forward with certain functionality. 

___

### Warning

There are no warnings in the final version of the DEXI token.

___

### Comment.

#### COMMENT-1. Variables should be constants
At

- contracts/DEXI.sol:405-406

```solidity=405
uint256 private _tTotal = 50000000 * 10**uint256(_decimals);
address public _burnpoolWalletAddress = address(0x000000000000000000000000000000000000dEaD);
```

The variables are never changed.

##### Recommendation.
Consider the usage of constants to save gas.
##### Status.
FIXED - Variables were declared as constants.

___

#### COMMENT-2. Use scientific notation for clarity
At

- contracts/DEXI.sol:405

```solidity=405
uint256 private _tTotal = 50000000 * 10**uint256(_decimals);
```

"50000000" has too many zeros.
##### Recommendation.
Replace it with "50 * 1e6" for better readability.
##### Status.
FIXED - Scientific notations were used.

___

#### COMMENT-3. No need to initialize "previous" values
At

- contracts/DEXI.sol:410,413,416

```solidity=409
uint256 public _taxFee = 3;
uint256 private _previousTaxFee = _taxFee;

uint256 public _burnFee = 3;
uint256 private _previousBurnFee = _burnFee;

uint256 public _liquidityFee = 3;
uint256 private _previousLiquidityFee = _liquidityFee;
```

There is no reason to initialize previous values.
##### Recommendation.
Consider removing the initialization to save gas at deployment time.
##### Status.
FIXED - These variables were removed.

___

#### COMMENT-4. Unclear reason to use _maxTxAmount
At

- contracts/DEXI.sol:418
- contracts/DEXI.sol:724

```solidity=724
if(from != owner() && to != owner())
    require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount.");
```

It's unclear what the motivation is to limit the max transfer amount—just wasting gas.

It does not change anything because someone may do a significant transfer in a row of smaller transfers.

But it may induce a problem if some huge holder wants to withdraw his big share, e.g., from the DEX pool.
##### Recommendation.
Remove `_maxTxAmount` restriction.
##### Status.
ACKNOWLEDGED

##### Client's commentary.
> We would like to keep it to restrict manipulations in a single transaction.

___

#### COMMENT-5. Use the same style of variable and getter function.

- contracts/DEXI.sol:429

In the final version, it looks like this:

```solidity=437
mapping (address => mapping (address => uint256)) private _allowances;
mapping (uint16 => uint256) public _yearMintedAmount;
mapping (uint16 => uint256) public _yearCanMintAmount;
mapping (address => bool) public _isBlacklisted;
mapping (address => bool) private _isExcludedFromFee;
```

Some variables are public (but prefixed with an underscore), and others are private.

##### Recommendation.
Use the same style. E.g., name public variables with no underscore prefix and private variables with underscore prefix, or make all variables public to use the default getter.
##### Status.
ACKNOWLEDGED - The style remained the same.

---

#### COMMENT-6. Index important event parameters

- contracts/DEXI.sol:450-454

In the final contract, it looks like

```solidity=446
event IsBlackListed(address indexed user, bool indexed flag);
event ExcludeFromFee(address account, bool isExcludedFromFee);
event SetEnabledFlag(bool _enableFlag, TAX_TYPE _flagType);
event TaxesSet(uint8 _buyTax, uint8 _sellTax, uint8 _transferTax, uint8 _burnFee);
event AddNewSwapPair(address pair);
```

##### Recommendation.
Index important event parameters
##### Status.
ACKNOWLEDGED - Some important event parameters are still not indexed.

___

#### COMMENT-7. The event is never used

- contracts/DEXI.sol:451
- contracts/DEXI.sol:453
- contracts/DEXI.sol:454


```solidity=451
event IncludeInReward(address account, bool isExclude);
event ExcludeFromFee(address account, bool isExcludedFromFee);
event IncludeInFee(address account, bool isExcludedFromFee);
event TokenTranfer(address from, address to, uint256 amount, bool takeFee);
```

##### Recommendation.
Consider removing unused events.
##### Status.
FIXED - Unused events were removed.

___

#### COMMENT-8. Use "external pure" declarations

- contracts/DEXI.sol:486
- contracts/DEXI.sol:490
- contracts/DEXI.sol:494

```solidity=486
function name() public view returns (string memory) {
    return _name;
}

function symbol() public view returns (string memory) {
    return _symbol;
}

function decimals() public view returns (uint8) {
    return _decimals;
}
```

##### Recommendation.
Use `external pure` declaration for pure functions.
##### Status.
FIXED - `external pure` declaration was used.

___

#### COMMENT-9. Local variable shadows external declaration

There is an Ownable.owner() function, but it's being shadown by the "owner" argument:

- contracts/DEXI.sol:512
- contracts/DEXI.sol:706

##### Recommendation.
Rename to _owner
##### Status.
ACKNOWLEDGED

___


#### COMMENT-10. No need to use `_msgSender()`

- contracts/DEXI.sol:523
- contracts/DEXI.sol:528
...

In fact "Context" base class is needed in case you change the context of the transaction execution inside the contract (e.g., in meta transactions as described in https://eips.ethereum.org/EIPS/eip-2771)

You never change the code execution context, so you don't need to use `_msgSender`. It's just wasting gas.


##### Recommendation.
Use msg.sender instead.
##### Status.
FIXED - "Context" library usage was removed.

___

#### COMMENT-11. The owner may set `_maxTxAmount` too low
At

- contracts/DEXI.sol:892

```solidity=892
function _setMaxTxAmount(uint256 maxTxAmount) external onlyOwner() {
    require(maxTxAmount > 0, "maxTxAmount should be greater than zero");
    _maxTxAmount = maxTxAmount;
    emit SetMaxTxAmount(maxTxAmount);
}
```

The owner can make the token impossible to use just by setting `_maxTxAmount` to some minimal value (e.g. =1).
##### Recommendation.
Remove.

The owner must be multisig!
##### Status.
ACKNOWLEDGED

